MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
collidableproxy.cpp
1 // © Copyright 2010 - 2012 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4 The Mezzanine Engine is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8 
9 The Mezzanine Engine is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License
15 along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18 'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21 Build professional software and charge for their product.
22 
23 However there are some practical restrictions, so if your project involves
24 any of the following you should contact us and we will try to work something
25 out:
26 - DRM or Copy Protection of any kind(except Copyrights)
27 - Software Patents You Do Not Wish to Freely License
28 - Any Kind of Linking to Non-GPL licensed Works
29 - Are Currently In Violation of Another Copyright Holder's GPL License
30 - If You want to change our code and not add a few hundred MB of stuff to
31 your distribution
32 
33 These and other limitations could cause serious legal problems if you ignore
34 them, so it is best to simply contact us or the Free Software Foundation, if
35 you have any questions.
36 
37 Joseph Toppi - toppij@gmail.com
38 John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _collidableproxy_cpp
41 #define _collidableproxy_cpp
42 
43 #include "Physics/collidableproxy.h"
44 #include "Physics/collisionshape.h"
45 #include "Physics/physicsmanager.h"
46 #include "Physics/collisionshapemanager.h"
47 
48 #include "stringtool.h"
49 #include "serialization.h"
50 #include "exception.h"
51 
52 #include <btBulletDynamicsCommon.h>
53 
54 namespace
55 {
56  Mezzanine::Boolean IsConvex(const Mezzanine::Physics::CollisionShape::ShapeType Type)
57  {
58  switch( Type )
59  {
60  // All the basic convex shapes
68  {
69  return true;
70  break;
71  }
72  default:
73  {
74  return false;
75  break;
76  }
77  }
78  }
79 
80  Mezzanine::Boolean IsCompound(const Mezzanine::Physics::CollisionShape::ShapeType Type)
81  {
83  }
84 
85  Mezzanine::Boolean IsStaticTrimesh(const Mezzanine::Physics::CollisionShape::ShapeType Type)
86  {
88  }
89 
90  Mezzanine::Boolean IsDynamicTrimesh(const Mezzanine::Physics::CollisionShape::ShapeType Type)
91  {
93  }
94 }
95 
96 namespace Mezzanine
97 {
98  namespace Physics
99  {
100 /*
101 /// @cond 0
102  ///////////////////////////////////////////////////////////////////////////////
103  // ScalingShape Methods
104 
105  ///////////////////////////////////////////////////////////////////////////////
106  /// @class ScalingShape
107  /// @brief This is a custom scaling shape that permits scaling specific to the object it is applied to.
108  /// @details Scaling portion of a transform does not exist on RigidBodies in Bullet. For an object to be
109  /// scaled it has to be done on the collision shape. However collision shapes can be shared and if they are
110  /// it would scale all other objects it is shared with as well. This shape is a simple scaling wrapper for
111  /// collision shapes that can be created just for a single object that allows re-use and sharing of
112  /// collision shapes when scaling them for different objects. @n @n
113  /// Bullet does have another scaling shape built in for different types of shapes. GImpact lacks one, but
114  /// BVHTriangleMesh have an appropriate wrapper. All the collision shapes under the Convex branch of the
115  /// inheritance tree have another that only applies custom scaling uniformly on all axes. This is
116  /// unacceptable and one that allows independant scaling on each axis is needed. That is where this class
117  /// comes in.
118  ///////////////////////////////////////
119  ATTRIBUTE_ALIGNED16(class) MEZZ_LIB ScalingShape : public btConvexShape
120  {
121  protected:
122  /// @brief The actual data in bullet this represents
123  btConvexShape* ChildConvexShape;
124 
125  /// @brief The actual data in bullet this represents
126  btVector3 ChildScaling;
127  public:
128  /// @cond false
129  BT_DECLARE_ALIGNED_ALLOCATOR();
130  /// @endcond
131 
132  /// @brief Class constructor.
133  ScalingShape(btConvexShape* ChildShape, const btVector3& Scaling) :
134  ChildConvexShape(ChildShape),
135  ChildScaling(Scaling)
136  { this->m_shapeType = UNIFORM_SCALING_SHAPE_PROXYTYPE; }
137  /// @brief Class destructor.
138  virtual ~ScalingShape()
139  { }
140 
141  ///////////////////////////////////////////////////////////////////////////////
142  // Configuration Methods
143 
144  /// @brief Sets the child shape to be scaled by this wrapper.
145  virtual void SetChildShape(btConvexShape* ChildShape)
146  {
147  this->ChildConvexShape = ChildShape;
148  }
149  /// @brief Gets the child shape being scaled by this wrapper.
150  virtual btConvexShape* GetChildShape() const
151  {
152  return this->ChildConvexShape;
153  }
154  /// @brief Sets the amount of scaling to be applied to the child shape.
155  virtual void SetChildScaling(const btVector3& Scaling)
156  {
157  this->ChildScaling = Scaling;
158  }
159  /// @brief Gets the amount of scaling being applied to the child shape.
160  virtual btVector3 GetChildScaling() const
161  {
162  return this->ChildScaling;
163  }
164  /// @brief Gets the serialization name of this shape.
165  virtual const char* getName()const
166  {
167  return "UniformScalingShape";
168  }
169 
170  ///////////////////////////////////////////////////////////////////////////////
171  // Internal Transform Methods
172 
173  /// @brief No Idea.
174  virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
175  {
176  btVector3 tmpVertex;
177  tmpVertex = this->ChildConvexShape->localGetSupportingVertexWithoutMargin(vec);
178  return tmpVertex * this->ChildScaling;
179  }
180  /// @brief No Idea.
181  virtual btVector3 localGetSupportingVertex(const btVector3& vec)const
182  {
183  btVector3 tmpVertex;
184  btScalar ChildMargin = this->ChildConvexShape->getMargin();
185  tmpVertex = this->ChildConvexShape->localGetSupportingVertexWithoutMargin(vec);
186  return (tmpVertex * this->ChildScaling) + btVector3(ChildMargin,ChildMargin,ChildMargin);
187  }
188  /// @brief No Idea.
189  virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
190  {
191  this->ChildConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors);
192  for( int i = 0 ; i < numVectors ; i++ )
193  {
194  supportVerticesOut[i] *= this->ChildScaling;
195  }
196  }
197  /// @brief Calculates the local inertia for this shape and it's child shape.
198  virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const
199  {
200  btVector3 tmpInertia;
201  this->ChildConvexShape->calculateLocalInertia(mass,tmpInertia);
202  inertia = tmpInertia * this->ChildScaling;
203  }
204 
205  ///////////////////////////////////////////////////////////////////////////////
206  // Inherited from btCollisionShape
207 
208  /// @brief Gets the AABB of this shape.
209  virtual void getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
210  {
211  this->getAabbSlow(trans,aabbMin,aabbMax);
212  }
213  /// @brief Gets the AABB of this shape.
214  virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
215  {
216  btVector3 _directions[] =
217  {
218  btVector3( 1., 0., 0.),
219  btVector3( 0., 1., 0.),
220  btVector3( 0., 0., 1.),
221  btVector3( -1., 0., 0.),
222  btVector3( 0., -1., 0.),
223  btVector3( 0., 0., -1.)
224  };
225 
226  btVector3 _supporting[] =
227  {
228  btVector3( 0., 0., 0.),
229  btVector3( 0., 0., 0.),
230  btVector3( 0., 0., 0.),
231  btVector3( 0., 0., 0.),
232  btVector3( 0., 0., 0.),
233  btVector3( 0., 0., 0.)
234  };
235 
236  for( int i = 0 ; i < 6 ; i++ )
237  {
238  _directions[i] = _directions[i] * t.getBasis();
239  }
240 
241  this->batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6);
242 
243  btVector3 aabbMin1(0,0,0),aabbMax1(0,0,0);
244  for ( int i = 0; i < 3; ++i )
245  {
246  aabbMax1[i] = t(_supporting[i])[i];
247  aabbMin1[i] = t(_supporting[i + 3])[i];
248  }
249 
250  btVector3 marginVec(this->getMargin(),this->getMargin(),this->getMargin());
251  // convert to local to scale
252  aabbMin1 = ( aabbMin1 - t.getOrigin() ) * this->ChildScaling;
253  aabbMax1 = ( aabbMax1 - t.getOrigin() ) * this->ChildScaling;
254 
255  aabbMin = ( aabbMin1 + t.getOrigin() ) - marginVec;
256  aabbMax = ( aabbMax1 + t.getOrigin() ) + marginVec;
257  }
258 
259  /// @brief Sets the scaling to be applied to the sharable/global child collision shape.
260  virtual void setLocalScaling(const btVector3& scaling)
261  { this->SetChildScaling(scaling); }
262  /// @brief Gets the scaling being applied to the sharable/global child collision shape.
263  virtual const btVector3& getLocalScaling() const
264  { return this->ChildScaling; }
265  /// @brief Sets the collision margin of the sharable/global child collision shape.
266  virtual void setMargin(btScalar margin)
267  { this->ChildConvexShape->setMargin(margin); }
268  /// @brief Gets the collision margin of the sharable/global child collision shape.
269  virtual btScalar getMargin() const
270  { return this->ChildConvexShape->getMargin(); }
271  /// @brief Gets the number of directions available for the first parameter in "getPreferredPenetrationDirection".
272  virtual int getNumPreferredPenetrationDirections() const
273  { return this->ChildConvexShape->getNumPreferredPenetrationDirections(); }
274  /// @brief Gets the direction objects should follow for penetration recovery at the specified index.
275  virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
276  { this->ChildConvexShape->getPreferredPenetrationDirection(index,penetrationVector); }
277  };//ScalingShape
278 /// @endcond
279 //*/
280  ///////////////////////////////////////////////////////////////////////////////
281  // CollidableProxy Methods
282 
284  //BodyScale(1,1,1),
285  ProxyShape(NULL),
286  ScalerShape(NULL),
287  Manager(Creator),
288  CollisionGroup(Physics::CF_GenericFilter),
289  CollisionMask(Physics::CF_AllFilter)
290  { }
291 
293  { }
294 
295  ///////////////////////////////////////////////////////////////////////////////
296  // Utility
297 
299  { return ( this->IsInWorld() ? AxisAlignedBox( Vector3( this->_GetBasePhysicsObject()->getBroadphaseHandle()->m_aabbMin ), Vector3( this->_GetBasePhysicsObject()->getBroadphaseHandle()->m_aabbMax ) ) : AxisAlignedBox() ); }
300 
302  { return ( this->_GetBasePhysicsObject()->getBroadphaseHandle() != NULL ); }
303 
305  { return this->Manager; }
306 
307  ///////////////////////////////////////////////////////////////////////////////
308  // Collision Settings
309 
311  {
312  this->CollisionGroup = Group;
313  this->CollisionMask = Mask;
314  }
315 
317  {
318  this->CollisionGroup = Group;
319  }
320 
322  {
323  this->CollisionMask = Mask;
324  }
325 
327  {
328  return this->CollisionGroup;
329  }
330 
332  {
333  return this->CollisionMask;
334  }
335 
337  {
338  if( this->ProxyShape != Shape )
339  {
340  /*if( Shape != NULL )
341  {
342  switch( Shape->GetType() )
343  {
344  // All the basic convex shapes
345  case CollisionShape::ST_Box:
346  case CollisionShape::ST_Capsule:
347  case CollisionShape::ST_Cone:
348  case CollisionShape::ST_ConvexHull:
349  case CollisionShape::ST_Cylinder:
350  case CollisionShape::ST_MultiSphere:
351  case CollisionShape::ST_Sphere:
352  {
353  btConvexShape* ScaledShape = static_cast<btConvexShape*>( Shape->_GetInternalShape() );
354  if( this->ScalerShape == NULL ) {
355  this->ScalerShape = new ScalingShape( ScaledShape, this->BodyScale.GetBulletVector3() );
356  }else{
357  static_cast<Physics::ScalingShape*>( this->ScalerShape )->SetChildShape( ScaledShape );
358  }
359  this->_GetBasePhysicsObject()->setCollisionShape( this->ScalerShape );
360  break;
361  }
362  // The static bvh trimesh
363  case CollisionShape::ST_StaticTriMesh:
364  {
365  btBvhTriangleMeshShape* ScaledShape = static_cast<btBvhTriangleMeshShape*>( Shape->_GetInternalShape() );
366  if( this->ScalerShape == NULL ) {
367  this->ScalerShape = new btScaledBvhTriangleMeshShape( ScaledShape, this->BodyScale.GetBulletVector3() );
368  }else{
369  this->ScalerShape->setLocalScaling( this->BodyScale.GetBulletVector3() );
370  }
371  this->_GetBasePhysicsObject()->setCollisionShape( this->ScalerShape );
372  break;
373  }
374  // No idea what to do about compound shapes
375  case CollisionShape::ST_Compound:
376  // GImpact doesn't have anything to give it per object scaling
377  case CollisionShape::ST_DynamicTriMesh:
378  // These shapes are either specifically tailored to the object or just don't make sense to scale
379  case CollisionShape::ST_Heightfield:
380  case CollisionShape::ST_Plane:
381  case CollisionShape::ST_Soft:
382  default:
383  {
384  if( this->ScalerShape != NULL ) {
385  delete this->ScalerShape;
386  this->ScalerShape = NULL;
387  }
388  this->_GetBasePhysicsObject()->setCollisionShape( Shape->_GetInternalShape() );
389  break;
390  }
391  }
392  this->ProxyShape = Shape;
393  }else{
394  if( this->ScalerShape != NULL ) {
395  delete this->ScalerShape;
396  this->ScalerShape = NULL;
397  }
398  this->ProxyShape = NULL;
399  }//*/
400 
401  this->ProxyShape = Shape;
402  this->_GetBasePhysicsObject()->setCollisionShape( this->ProxyShape->_GetInternalShape() );
403 
404  // Gotta flicker to update the AABB appropriately
405  if( this->IsInWorld() ) {
406  this->RemoveFromWorld();
407  this->AddToWorld();
408  }
409  }
410  }
411 
413  {
414  return this->ProxyShape;
415  }
416 
418  {
419  if( Enable != this->GetCollisionResponse() )
420  {
421  btCollisionObject* Base = this->_GetBasePhysicsObject();
422  if( Enable ) {
423  Base->setCollisionFlags( Base->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE );
424  }else{
425  Base->setCollisionFlags( Base->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE );
426  }
427  }
428  }
429 
431  {
432  return !(this->_GetBasePhysicsObject()->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE);
433  }
434 
436  {
437  this->_GetBasePhysicsObject()->setCollisionFlags(Flags);
438  }
439 
441  {
442  return this->_GetBasePhysicsObject()->getCollisionFlags();
443  }
444 
445  ///////////////////////////////////////////////////////////////////////////////
446  // Static or Kinematic Properties
447 
449  {
450  btCollisionObject* Base = this->_GetBasePhysicsObject();
451  Base->setCollisionFlags( Base->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT );
452  }
453 
455  {
456  btCollisionObject* Base = this->_GetBasePhysicsObject();
457  Base->setCollisionFlags( Base->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT );
458  }
459 
461  {
462  return this->_GetBasePhysicsObject()->isKinematicObject();
463  }
464 
466  {
467  return this->_GetBasePhysicsObject()->isStaticObject();
468  }
469 
471  {
472  return this->_GetBasePhysicsObject()->isStaticOrKinematicObject();
473  }
474 
475  ///////////////////////////////////////////////////////////////////////////////
476  // Physics Properties
477 
478  void CollidableProxy::SetFriction(const Real Friction)
479  { this->_GetBasePhysicsObject()->setFriction(Friction); }
480 
482  { return this->_GetBasePhysicsObject()->getFriction(); }
483 
485  { this->_GetBasePhysicsObject()->setRollingFriction(Friction); }
486 
488  { return this->_GetBasePhysicsObject()->getRollingFriction(); }
489 
490  void CollidableProxy::SetAnisotropicFriction(const Vector3& Friction, const Whole Mode)
491  { this->_GetBasePhysicsObject()->setAnisotropicFriction(Friction.GetBulletVector3(),Mode); }
492 
494  {
495  if( this->IsAnisotropicFrictionModeSet(Physics::AFF_AnisotropicFrictionDisabled) )
496  return Physics::AFF_AnisotropicFrictionDisabled;
497  if( this->IsAnisotropicFrictionModeSet(Physics::AFF_AnisotropicFriction) )
498  return Physics::AFF_AnisotropicFriction;
499  if( this->IsAnisotropicFrictionModeSet(Physics::AFF_AnisotropicRollingFriction) )
500  return Physics::AFF_AnisotropicRollingFriction;
501 
502  return Physics::AFF_AnisotropicFrictionDisabled;
503  }
504 
506  { return this->_GetBasePhysicsObject()->hasAnisotropicFriction(Mode); }
507 
509  { return Vector3( this->_GetBasePhysicsObject()->getAnisotropicFriction() ); }
510 
511  void CollidableProxy::SetRestitution(const Real& Restitution)
512  { this->_GetBasePhysicsObject()->setRestitution(Restitution); }
513 
515  { return this->_GetBasePhysicsObject()->getRestitution(); }
516 
517  ///////////////////////////////////////////////////////////////////////////////
518  // Activation State
519 
521  {
522  if(Force) this->_GetBasePhysicsObject()->forceActivationState(State);
523  else this->_GetBasePhysicsObject()->setActivationState(State);
524  }
525 
527  {
528  return static_cast<Physics::ActivationState>( this->_GetBasePhysicsObject()->getActivationState() );
529  }
530 
532  {
533  return this->_GetBasePhysicsObject()->isActive();
534  }
535 
537  {
538  this->_GetBasePhysicsObject()->setDeactivationTime(Time);
539  }
540 
542  {
543  return this->_GetBasePhysicsObject()->getDeactivationTime();
544  }
545 
546  ///////////////////////////////////////////////////////////////////////////////
547  // Transform Methods
548 
550  {
551  this->SetLocation(Loc.X,Loc.Y,Loc.Z);
552  }
553 
554  void CollidableProxy::SetLocation(const Real X, const Real Y, const Real Z)
555  {
556  btVector3 NewLoc(X,Y,Z);
557  this->_GetBasePhysicsObject()->getWorldTransform().setOrigin(NewLoc);
558  this->_GetBasePhysicsObject()->getInterpolationWorldTransform().setOrigin(NewLoc);
559  }
560 
562  {
563  return Vector3( this->_GetBasePhysicsObject()->getWorldTransform().getOrigin() );
564  }
565 
567  {
568  this->SetOrientation(Ori.X,Ori.Y,Ori.Z,Ori.W);
569  }
570 
571  void CollidableProxy::SetOrientation(const Real X, const Real Y, const Real Z, const Real W)
572  {
573  btQuaternion NewRot(X,Y,Z,W);
574  this->_GetBasePhysicsObject()->getWorldTransform().setRotation(NewRot);
575  this->_GetBasePhysicsObject()->getInterpolationWorldTransform().setRotation(NewRot);
576  }
577 
579  {
580  return Quaternion( this->_GetBasePhysicsObject()->getWorldTransform().getRotation() );
581  }
582 
584  {
585  /*this->BodyScale = Sc;
586  if( this->ScalerShape != NULL ) {
587  this->ScalerShape->setLocalScaling(Sc.GetBulletVector3());
588  }else*/ if( this->ProxyShape != NULL ) {
589  this->ProxyShape->SetScaling(Sc);
590  }
591  }
592 
593  void CollidableProxy::SetScale(const Real X, const Real Y, const Real Z)
594  {
595  this->SetScale( Vector3(X,Y,Z) );
596  }
597 
599  {
600  return this->ProxyShape->GetScaling();//this->BodyScale;
601  }
602 
604  {
605  this->SetLocation( this->GetLocation() + Trans );
606  }
607 
608  void CollidableProxy::Translate(const Real X, const Real Y, const Real Z)
609  {
610  Vector3 Trans(X,Y,Z);
611  this->SetLocation( this->GetLocation() + Trans );
612  }
613 
614  void CollidableProxy::Yaw(const Real Angle)
615  {
616  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Vector3::Unit_Y());
617  this->SetOrientation(NewRot);
618  }
619 
620  void CollidableProxy::Pitch(const Real Angle)
621  {
622  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Vector3::Unit_X());
623  this->SetOrientation(NewRot);
624  }
625 
626  void CollidableProxy::Roll(const Real Angle)
627  {
628  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Vector3::Unit_Z());
629  this->SetOrientation(NewRot);
630  }
631 
632  void CollidableProxy::Rotate(const Vector3& Axis, const Real Angle)
633  {
634  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Axis);
635  this->SetOrientation(NewRot);
636  }
637 
638  void CollidableProxy::Rotate(const Quaternion& Rotation)
639  {
640  Quaternion NewRot = this->GetOrientation() * Rotation;
641  this->SetOrientation(NewRot);
642  }
643 
644  void CollidableProxy::Scale(const Vector3& Scale)
645  {
646  Vector3 NewScale = this->GetScale() * Scale;
647  this->SetScale(NewScale);
648  }
649 
650  void CollidableProxy::Scale(const Real X, const Real Y, const Real Z)
651  {
652  Vector3 NewScale = this->GetScale() * Vector3(X,Y,Z);
653  this->Scale(NewScale);
654  }
655 
656  ///////////////////////////////////////////////////////////////////////////////
657  // Serialization
658 
660  {
661  XML::Node SelfRoot = ParentNode.AppendChild(this->GetDerivedSerializableName());
662  if( !SelfRoot.AppendAttribute("InWorld").SetValue( this->IsInWorld() ? "true" : "false" ) ) {
663  SerializeError("Create XML Attribute Values",CollidableProxy::GetSerializableName(),true);
664  }
665 
666  this->ProtoSerializeProperties(SelfRoot);
667  this->ProtoSerializeShape(SelfRoot);
668  }
669 
671  {
672  this->WorldProxy::ProtoSerializeProperties(SelfRoot);
673 
674  XML::Node PropertiesNode = SelfRoot.AppendChild( CollidableProxy::GetSerializableName() + "Properties" );
675 
676  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
677  PropertiesNode.AppendAttribute("CollisionGroup").SetValue( this->GetCollisionGroup() ) &&
678  PropertiesNode.AppendAttribute("CollisionMask").SetValue( this->GetCollisionMask() ) &&
679  PropertiesNode.AppendAttribute("CollisionFlags").SetValue( this->GetCollisionFlags() ) &&
680  PropertiesNode.AppendAttribute("Friction").SetValue( this->GetFriction() ) &&
681  PropertiesNode.AppendAttribute("RollingFriction").SetValue( this->GetRollingFriction() ) &&
682  PropertiesNode.AppendAttribute("AnisotropicFrictionMode").SetValue( this->GetAnisotropicFrictionMode() ) &&
683  PropertiesNode.AppendAttribute("Restitution").SetValue( this->GetRestitution() ) &&
684  PropertiesNode.AppendAttribute("ActivationState").SetValue( static_cast<Whole>( this->GetActivationState() ) ) &&
685  PropertiesNode.AppendAttribute("DeactivationTime").SetValue( this->GetDeactivationTime() ) &&
686  PropertiesNode.AppendAttribute("ContactProcessingThreshold").SetValue( this->_GetContactProcessingThreshold() ) )
687  {
688  XML::Node AnisotropicFrictionNode = PropertiesNode.AppendChild("AnisotropicFriction");
689  this->GetAnisotropicFriction().ProtoSerialize( AnisotropicFrictionNode );
690 
691  return;
692  }else{
693  SerializeError("Create XML Attribute Values",CollidableProxy::GetSerializableName() + "Properties",true);
694  }
695  }
696 
698  {
699  XML::Node ShapeNode = SelfRoot.AppendChild( CollidableProxy::GetSerializableName() + "Shape" );
700 
701  if( ShapeNode.AppendAttribute("Version").SetValue("1") &&
702  ShapeNode.AppendAttribute("ProxyShape").SetValue( this->ProxyShape->GetName() ) )
703  {
704  return;
705  }else{
706  SerializeError("Create XML Attribute Values",CollidableProxy::GetSerializableName() + "Shape",true);
707  }
708  }
709 
711  {
712  Boolean WasInWorld = false;
713  XML::Attribute InWorldAttrib = SelfRoot.GetAttribute("InWorld");
714  if( !InWorldAttrib.Empty() ) {
715  WasInWorld = StringTools::ConvertToBool( InWorldAttrib.AsString() );
716  }
717 
718  this->ProtoDeSerializeProperties(SelfRoot);
719  this->ProtoDeSerializeShape(SelfRoot);
720 
721  if( WasInWorld ) {
722  this->AddToWorld();
723  }
724  }
725 
727  {
729 
730  XML::Attribute CurrAttrib;
731  XML::Node PropertiesNode = SelfRoot.GetChild( CollidableProxy::GetSerializableName() + "Properties" );
732 
733  if( !PropertiesNode.Empty() ) {
734  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
735  Whole AFMode = 0;
736 
737  CurrAttrib = PropertiesNode.GetAttribute("CollisionGroup");
738  if( !CurrAttrib.Empty() )
739  this->SetCollisionGroup( CurrAttrib.AsWhole() );
740 
741  CurrAttrib = PropertiesNode.GetAttribute("CollisionMask");
742  if( !CurrAttrib.Empty() )
743  this->SetCollisionMask( CurrAttrib.AsWhole() );
744 
745  CurrAttrib = PropertiesNode.GetAttribute("CollisionFlags");
746  if( !CurrAttrib.Empty() )
747  this->SetCollisionFlags( CurrAttrib.AsWhole() );
748 
749  CurrAttrib = PropertiesNode.GetAttribute("Friction");
750  if( !CurrAttrib.Empty() )
751  this->SetFriction( CurrAttrib.AsReal() );
752 
753  CurrAttrib = PropertiesNode.GetAttribute("RollingFriction");
754  if( !CurrAttrib.Empty() )
755  this->SetRollingFriction( CurrAttrib.AsReal() );
756 
757  CurrAttrib = PropertiesNode.GetAttribute("AnisotropicFrictionMode");
758  if( !CurrAttrib.Empty() )
759  AFMode = CurrAttrib.AsWhole();
760 
761  CurrAttrib = PropertiesNode.GetAttribute("Restitution");
762  if( !CurrAttrib.Empty() )
763  this->SetRestitution( CurrAttrib.AsReal() );
764 
765  CurrAttrib = PropertiesNode.GetAttribute("ActivationState");
766  if( !CurrAttrib.Empty() )
767  this->SetActivationState( static_cast<Physics::ActivationState>( CurrAttrib.AsWhole() ) );
768 
769  CurrAttrib = PropertiesNode.GetAttribute("DeactivationTime");
770  if( !CurrAttrib.Empty() )
771  this->SetDeactivationTime( CurrAttrib.AsReal() );
772 
773  CurrAttrib = PropertiesNode.GetAttribute("ContactProcessingThreshold");
774  if( !CurrAttrib.Empty() )
775  this->_SetContactProcessingThreshold( CurrAttrib.AsReal() );
776 
777  // Get the properties that need their own nodes
778  XML::Node AnisotropicFrictionNode = PropertiesNode.GetChild("AnisotropicFriction").GetFirstChild();
779  if( !AnisotropicFrictionNode.Empty() ) {
780  Vector3 AF(AnisotropicFrictionNode);
781  this->SetAnisotropicFriction(AF,AFMode);
782  }
783  }else{
784  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (CollidableProxy::GetSerializableName() + "Properties" ) + ": Not Version 1.");
785  }
786  }else{
787  MEZZ_EXCEPTION(Exception::II_IDENTITY_NOT_FOUND_EXCEPTION,CollidableProxy::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
788  }
789  }
790 
792  {
793  XML::Attribute CurrAttrib;
794  XML::Node ShapeNode = SelfRoot.GetChild( CollidableProxy::GetSerializableName() + "Shape" );
795 
796  if( !ShapeNode.Empty() ) {
797  if(ShapeNode.GetAttribute("Version").AsInt() == 1) {
798  CurrAttrib = ShapeNode.GetAttribute("ProxyShape");
799  if( !CurrAttrib.Empty() ) {
800  CollisionShape* Shape = CollisionShapeManager::GetSingletonPtr()->GetShape( CurrAttrib.AsString() );
801  this->SetCollisionShape( Shape );
802  }
803  }
804  }
805  }
806 
809 
811  { return "CollidableProxy"; }
812 
813  ///////////////////////////////////////////////////////////////////////////////
814  // Internal Methods
815 
817  { return ( this->IsInWorld() ? this->_GetBasePhysicsObject()->getBroadphaseHandle()->m_uniqueId : 0 ); }
818 
820  { this->_GetBasePhysicsObject()->setContactProcessingThreshold(Threshold); }
821 
823  { return this->_GetBasePhysicsObject()->getContactProcessingThreshold(); }
824  }// Physics
825 }// Mezzanine
826 
827 #endif