Spinning Topp Logo BlackTopp Studios
inc
collidableproxy.cpp
1 // © Copyright 2010 - 2016 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 {
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 
82 
85 
88 }
89 
90 namespace Mezzanine
91 {
92  namespace Physics
93  {
94 /*
95 /// @cond DontDocumentInternal
96  ///////////////////////////////////////////////////////////////////////////////
97  // ScalingShape Methods
98 
99  ///////////////////////////////////////////////////////////////////////////////
100  /// @class ScalingShape
101  /// @brief This is a custom scaling shape that permits scaling specific to the object it is applied to.
102  /// @details Scaling portion of a transform does not exist on RigidBodies in Bullet. For an object to be
103  /// scaled it has to be done on the collision shape. However collision shapes can be shared and if they are
104  /// it would scale all other objects it is shared with as well. This shape is a simple scaling wrapper for
105  /// collision shapes that can be created just for a single object that allows re-use and sharing of
106  /// collision shapes when scaling them for different objects. @n @n
107  /// Bullet does have another scaling shape built in for different types of shapes. GImpact lacks one, but
108  /// BVHTriangleMesh have an appropriate wrapper. All the collision shapes under the Convex branch of the
109  /// inheritance tree have another that only applies custom scaling uniformly on all axes. This is
110  /// unacceptable and one that allows independant scaling on each axis is needed. That is where this class
111  /// comes in.
112  ///////////////////////////////////////
113  ATTRIBUTE_ALIGNED16(class) MEZZ_LIB ScalingShape : public btConvexShape
114  {
115  protected:
116  /// @brief The actual data in bullet this represents
117  btConvexShape* ChildConvexShape;
118 
119  /// @brief The actual data in bullet this represents
120  btVector3 ChildScaling;
121  public:
122  /// @cond false
123  BT_DECLARE_ALIGNED_ALLOCATOR();
124  /// @endcond
125 
126  /// @brief Class constructor.
127  ScalingShape(btConvexShape* ChildShape, const btVector3& Scaling) :
128  ChildConvexShape(ChildShape),
129  ChildScaling(Scaling)
130  { this->m_shapeType = UNIFORM_SCALING_SHAPE_PROXYTYPE; }
131  /// @brief Class destructor.
132  virtual ~ScalingShape()
133  { }
134 
135  ///////////////////////////////////////////////////////////////////////////////
136  // Configuration Methods
137 
138  /// @brief Sets the child shape to be scaled by this wrapper.
139  virtual void SetChildShape(btConvexShape* ChildShape)
140  {
141  this->ChildConvexShape = ChildShape;
142  }
143  /// @brief Gets the child shape being scaled by this wrapper.
144  virtual btConvexShape* GetChildShape() const
145  {
146  return this->ChildConvexShape;
147  }
148  /// @brief Sets the amount of scaling to be applied to the child shape.
149  virtual void SetChildScaling(const btVector3& Scaling)
150  {
151  this->ChildScaling = Scaling;
152  }
153  /// @brief Gets the amount of scaling being applied to the child shape.
154  virtual btVector3 GetChildScaling() const
155  {
156  return this->ChildScaling;
157  }
158  /// @brief Gets the serialization name of this shape.
159  virtual const char* getName()const
160  {
161  return "UniformScalingShape";
162  }
163 
164  ///////////////////////////////////////////////////////////////////////////////
165  // Internal Transform Methods
166 
167  /// @brief No Idea.
168  virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const
169  {
170  btVector3 tmpVertex;
171  tmpVertex = this->ChildConvexShape->localGetSupportingVertexWithoutMargin(vec);
172  return tmpVertex * this->ChildScaling;
173  }
174  /// @brief No Idea.
175  virtual btVector3 localGetSupportingVertex(const btVector3& vec)const
176  {
177  btVector3 tmpVertex;
178  btScalar ChildMargin = this->ChildConvexShape->getMargin();
179  tmpVertex = this->ChildConvexShape->localGetSupportingVertexWithoutMargin(vec);
180  return (tmpVertex * this->ChildScaling) + btVector3(ChildMargin,ChildMargin,ChildMargin);
181  }
182  /// @brief No Idea.
183  virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
184  {
185  this->ChildConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors);
186  for( int i = 0 ; i < numVectors ; i++ )
187  {
188  supportVerticesOut[i] *= this->ChildScaling;
189  }
190  }
191  /// @brief Calculates the local inertia for this shape and it's child shape.
192  virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const
193  {
194  btVector3 tmpInertia;
195  this->ChildConvexShape->calculateLocalInertia(mass,tmpInertia);
196  inertia = tmpInertia * this->ChildScaling;
197  }
198 
199  ///////////////////////////////////////////////////////////////////////////////
200  // Inherited from btCollisionShape
201 
202  /// @brief Gets the AABB of this shape.
203  virtual void getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
204  {
205  this->getAabbSlow(trans,aabbMin,aabbMax);
206  }
207  /// @brief Gets the AABB of this shape.
208  virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
209  {
210  btVector3 _directions[] =
211  {
212  btVector3( 1., 0., 0.),
213  btVector3( 0., 1., 0.),
214  btVector3( 0., 0., 1.),
215  btVector3( -1., 0., 0.),
216  btVector3( 0., -1., 0.),
217  btVector3( 0., 0., -1.)
218  };
219 
220  btVector3 _supporting[] =
221  {
222  btVector3( 0., 0., 0.),
223  btVector3( 0., 0., 0.),
224  btVector3( 0., 0., 0.),
225  btVector3( 0., 0., 0.),
226  btVector3( 0., 0., 0.),
227  btVector3( 0., 0., 0.)
228  };
229 
230  for( int i = 0 ; i < 6 ; i++ )
231  {
232  _directions[i] = _directions[i] * t.getBasis();
233  }
234 
235  this->batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6);
236 
237  btVector3 aabbMin1(0,0,0),aabbMax1(0,0,0);
238  for ( int i = 0; i < 3; ++i )
239  {
240  aabbMax1[i] = t(_supporting[i])[i];
241  aabbMin1[i] = t(_supporting[i + 3])[i];
242  }
243 
244  btVector3 marginVec(this->getMargin(),this->getMargin(),this->getMargin());
245  // convert to local to scale
246  aabbMin1 = ( aabbMin1 - t.getOrigin() ) * this->ChildScaling;
247  aabbMax1 = ( aabbMax1 - t.getOrigin() ) * this->ChildScaling;
248 
249  aabbMin = ( aabbMin1 + t.getOrigin() ) - marginVec;
250  aabbMax = ( aabbMax1 + t.getOrigin() ) + marginVec;
251  }
252 
253  /// @brief Sets the scaling to be applied to the sharable/global child collision shape.
254  virtual void setLocalScaling(const btVector3& scaling)
255  { this->SetChildScaling(scaling); }
256  /// @brief Gets the scaling being applied to the sharable/global child collision shape.
257  virtual const btVector3& getLocalScaling() const
258  { return this->ChildScaling; }
259  /// @brief Sets the collision margin of the sharable/global child collision shape.
260  virtual void setMargin(btScalar margin)
261  { this->ChildConvexShape->setMargin(margin); }
262  /// @brief Gets the collision margin of the sharable/global child collision shape.
263  virtual btScalar getMargin() const
264  { return this->ChildConvexShape->getMargin(); }
265  /// @brief Gets the number of directions available for the first parameter in "getPreferredPenetrationDirection".
266  virtual int getNumPreferredPenetrationDirections() const
267  { return this->ChildConvexShape->getNumPreferredPenetrationDirections(); }
268  /// @brief Gets the direction objects should follow for penetration recovery at the specified index.
269  virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
270  { this->ChildConvexShape->getPreferredPenetrationDirection(index,penetrationVector); }
271  };//ScalingShape
272 /// @endcond
273 // */
274  ///////////////////////////////////////////////////////////////////////////////
275  // CollidableProxy Methods
276 
278  //BodyScale(1,1,1),
279  ProxyShape(NULL),
280  ScalerShape(NULL),
281  Manager(Creator),
282  CollisionGroup(Physics::CF_GenericFilter),
283  CollisionMask(Physics::CF_AllFilter)
284  { }
285 
287  WorldProxy(ID),
288  //BodyScale(1,1,1),
289  ProxyShape(NULL),
290  ScalerShape(NULL),
291  Manager(Creator),
292  CollisionGroup(Physics::CF_GenericFilter),
293  CollisionMask(Physics::CF_AllFilter)
294  { }
295 
297  { }
298 
300  {
301  this->WorldProxy::ProtoSerializeImpl(SelfRoot);
302  this->ProtoSerializeShape(SelfRoot);
303  }
304 
306  {
307  this->WorldProxy::ProtoDeSerializeImpl(SelfRoot);
308  this->ProtoDeSerializeShape(SelfRoot);
309  }
310 
311  ///////////////////////////////////////////////////////////////////////////////
312  // Utility
313 
315  { return ( this->IsInWorld() ? AxisAlignedBox( Vector3( this->_GetBasePhysicsObject()->getBroadphaseHandle()->m_aabbMin ), Vector3( this->_GetBasePhysicsObject()->getBroadphaseHandle()->m_aabbMax ) ) : AxisAlignedBox() ); }
316 
318  { return ( this->_GetBasePhysicsObject()->getBroadphaseHandle() != NULL ); }
319 
321  { return this->Manager; }
322 
323  ///////////////////////////////////////////////////////////////////////////////
324  // Collision Settings
325 
327  {
328  this->CollisionGroup = Group;
329  this->CollisionMask = Mask;
330  }
331 
333  { this->CollisionGroup = Group; }
334 
336  { this->CollisionMask = Mask; }
337 
339  { return this->CollisionGroup; }
340 
342  { return this->CollisionMask; }
343 
345  {
346  if( this->ProxyShape != Shape )
347  {
348  /*if( Shape != NULL )
349  {
350  switch( Shape->GetType() )
351  {
352  // All the basic convex shapes
353  case CollisionShape::ST_Box:
354  case CollisionShape::ST_Capsule:
355  case CollisionShape::ST_Cone:
356  case CollisionShape::ST_ConvexHull:
357  case CollisionShape::ST_Cylinder:
358  case CollisionShape::ST_MultiSphere:
359  case CollisionShape::ST_Sphere:
360  {
361  btConvexShape* ScaledShape = static_cast<btConvexShape*>( Shape->_GetInternalShape() );
362  if( this->ScalerShape == NULL ) {
363  this->ScalerShape = new ScalingShape( ScaledShape, this->BodyScale.GetBulletVector3() );
364  }else{
365  static_cast<Physics::ScalingShape*>( this->ScalerShape )->SetChildShape( ScaledShape );
366  }
367  this->_GetBasePhysicsObject()->setCollisionShape( this->ScalerShape );
368  break;
369  }
370  // The static bvh trimesh
371  case CollisionShape::ST_StaticTriMesh:
372  {
373  btBvhTriangleMeshShape* ScaledShape = static_cast<btBvhTriangleMeshShape*>( Shape->_GetInternalShape() );
374  if( this->ScalerShape == NULL ) {
375  this->ScalerShape = new btScaledBvhTriangleMeshShape( ScaledShape, this->BodyScale.GetBulletVector3() );
376  }else{
377  this->ScalerShape->setLocalScaling( this->BodyScale.GetBulletVector3() );
378  }
379  this->_GetBasePhysicsObject()->setCollisionShape( this->ScalerShape );
380  break;
381  }
382  // No idea what to do about compound shapes
383  case CollisionShape::ST_Compound:
384  // GImpact doesn't have anything to give it per object scaling
385  case CollisionShape::ST_DynamicTriMesh:
386  // These shapes are either specifically tailored to the object or just don't make sense to scale
387  case CollisionShape::ST_Heightfield:
388  case CollisionShape::ST_Plane:
389  case CollisionShape::ST_Soft:
390  default:
391  {
392  if( this->ScalerShape != NULL ) {
393  delete this->ScalerShape;
394  this->ScalerShape = NULL;
395  }
396  this->_GetBasePhysicsObject()->setCollisionShape( Shape->_GetInternalShape() );
397  break;
398  }
399  }
400  this->ProxyShape = Shape;
401  }else{
402  if( this->ScalerShape != NULL ) {
403  delete this->ScalerShape;
404  this->ScalerShape = NULL;
405  }
406  this->ProxyShape = NULL;
407  }// */
408 
409  this->ProxyShape = Shape;
410  this->_GetBasePhysicsObject()->setCollisionShape( this->ProxyShape->_GetInternalShape() );
411 
412  // Gotta flicker to update the AABB appropriately
413  if( this->IsInWorld() ) {
414  this->RemoveFromWorld();
415  this->AddToWorld();
416  }
417  }
418  }
419 
421  {
422  return this->ProxyShape;
423  }
424 
426  {
427  if( Enable != this->GetCollisionResponse() )
428  {
429  btCollisionObject* Base = this->_GetBasePhysicsObject();
430  if( Enable ) {
431  Base->setCollisionFlags( Base->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE );
432  }else{
433  Base->setCollisionFlags( Base->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE );
434  }
435  }
436  }
437 
439  { return !(this->_GetBasePhysicsObject()->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE); }
440 
442  { this->_GetBasePhysicsObject()->setCollisionFlags(Flags); }
443 
445  { return this->_GetBasePhysicsObject()->getCollisionFlags(); }
446 
447  ///////////////////////////////////////////////////////////////////////////////
448  // Static or Kinematic Properties
449 
451  {
452  btCollisionObject* Base = this->_GetBasePhysicsObject();
453  Base->setCollisionFlags( Base->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT );
454  }
455 
457  {
458  btCollisionObject* Base = this->_GetBasePhysicsObject();
459  Base->setCollisionFlags( Base->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT );
460  }
461 
463  { return this->_GetBasePhysicsObject()->isKinematicObject(); }
464 
466  { return this->_GetBasePhysicsObject()->isStaticObject(); }
467 
469  { return this->_GetBasePhysicsObject()->isStaticOrKinematicObject(); }
470 
471  ///////////////////////////////////////////////////////////////////////////////
472  // Physics Properties
473 
474  void CollidableProxy::SetFriction(const Real Friction)
475  { this->_GetBasePhysicsObject()->setFriction(Friction); }
476 
478  { return this->_GetBasePhysicsObject()->getFriction(); }
479 
481  { this->_GetBasePhysicsObject()->setRollingFriction(Friction); }
482 
484  { return this->_GetBasePhysicsObject()->getRollingFriction(); }
485 
486  void CollidableProxy::SetAnisotropicFriction(const Vector3& Friction, const Whole Mode)
487  { this->_GetBasePhysicsObject()->setAnisotropicFriction(Friction.GetBulletVector3(),Mode); }
488 
490  {
491  if( this->IsAnisotropicFrictionModeSet(Physics::AFF_AnisotropicFrictionDisabled) )
492  return Physics::AFF_AnisotropicFrictionDisabled;
493  if( this->IsAnisotropicFrictionModeSet(Physics::AFF_AnisotropicFriction) )
494  return Physics::AFF_AnisotropicFriction;
495  if( this->IsAnisotropicFrictionModeSet(Physics::AFF_AnisotropicRollingFriction) )
496  return Physics::AFF_AnisotropicRollingFriction;
497 
498  return Physics::AFF_AnisotropicFrictionDisabled;
499  }
500 
502  { return this->_GetBasePhysicsObject()->hasAnisotropicFriction(Mode); }
503 
505  { return Vector3( this->_GetBasePhysicsObject()->getAnisotropicFriction() ); }
506 
507  void CollidableProxy::SetRestitution(const Real& Restitution)
508  { this->_GetBasePhysicsObject()->setRestitution(Restitution); }
509 
511  { return this->_GetBasePhysicsObject()->getRestitution(); }
512 
513  ///////////////////////////////////////////////////////////////////////////////
514  // Activation State
515 
517  {
518  if(Force) this->_GetBasePhysicsObject()->forceActivationState(State);
519  else this->_GetBasePhysicsObject()->setActivationState(State);
520  }
521 
523  { return static_cast<Physics::ActivationState>( this->_GetBasePhysicsObject()->getActivationState() ); }
524 
526  { return this->_GetBasePhysicsObject()->isActive(); }
527 
529  { this->_GetBasePhysicsObject()->setDeactivationTime(Time); }
530 
532  { return this->_GetBasePhysicsObject()->getDeactivationTime(); }
533 
534  ///////////////////////////////////////////////////////////////////////////////
535  // Transform Methods
536 
538  {
539  this->SetLocation(Loc.X,Loc.Y,Loc.Z);
540  }
541 
542  void CollidableProxy::SetLocation(const Real X, const Real Y, const Real Z)
543  {
544  btVector3 NewLoc(X,Y,Z);
545  this->_GetBasePhysicsObject()->getWorldTransform().setOrigin(NewLoc);
546  this->_GetBasePhysicsObject()->getInterpolationWorldTransform().setOrigin(NewLoc);
547  }
548 
550  {
551  return Vector3( this->_GetBasePhysicsObject()->getWorldTransform().getOrigin() );
552  }
553 
555  {
556  this->SetOrientation(Ori.X,Ori.Y,Ori.Z,Ori.W);
557  }
558 
559  void CollidableProxy::SetOrientation(const Real X, const Real Y, const Real Z, const Real W)
560  {
561  btQuaternion NewRot(X,Y,Z,W);
562  this->_GetBasePhysicsObject()->getWorldTransform().setRotation(NewRot);
563  this->_GetBasePhysicsObject()->getInterpolationWorldTransform().setRotation(NewRot);
564  }
565 
567  {
568  return Quaternion( this->_GetBasePhysicsObject()->getWorldTransform().getRotation() );
569  }
570 
572  {
573  /*this->BodyScale = Sc;
574  if( this->ScalerShape != NULL ) {
575  this->ScalerShape->setLocalScaling(Sc.GetBulletVector3());
576  }else*/ if( this->ProxyShape != NULL ) {
577  this->ProxyShape->SetScaling(Sc);
578  }
579  }
580 
581  void CollidableProxy::SetScale(const Real X, const Real Y, const Real Z)
582  {
583  this->SetScale( Vector3(X,Y,Z) );
584  }
585 
587  {
588  return this->ProxyShape->GetScaling();//this->BodyScale;
589  }
590 
592  {
593  this->SetLocation( this->GetLocation() + Trans );
594  }
595 
596  void CollidableProxy::Translate(const Real X, const Real Y, const Real Z)
597  {
598  Vector3 Trans(X,Y,Z);
599  this->SetLocation( this->GetLocation() + Trans );
600  }
601 
602  void CollidableProxy::Yaw(const Real Angle)
603  {
604  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Vector3::Unit_Y());
605  this->SetOrientation(NewRot);
606  }
607 
608  void CollidableProxy::Pitch(const Real Angle)
609  {
610  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Vector3::Unit_X());
611  this->SetOrientation(NewRot);
612  }
613 
614  void CollidableProxy::Roll(const Real Angle)
615  {
616  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Vector3::Unit_Z());
617  this->SetOrientation(NewRot);
618  }
619 
620  void CollidableProxy::Rotate(const Vector3& Axis, const Real Angle)
621  {
622  Quaternion NewRot = this->GetOrientation() * Quaternion(Angle,Axis);
623  this->SetOrientation(NewRot);
624  }
625 
626  void CollidableProxy::Rotate(const Quaternion& Rotation)
627  {
628  Quaternion NewRot = this->GetOrientation() * Rotation;
629  this->SetOrientation(NewRot);
630  }
631 
632  void CollidableProxy::Scale(const Vector3& Scale)
633  {
634  Vector3 NewScale = this->GetScale() * Scale;
635  this->SetScale(NewScale);
636  }
637 
638  void CollidableProxy::Scale(const Real X, const Real Y, const Real Z)
639  {
640  Vector3 NewScale = this->GetScale() * Vector3(X,Y,Z);
641  this->Scale(NewScale);
642  }
643 
644  ///////////////////////////////////////////////////////////////////////////////
645  // Serialization
646 
648  {
649  this->WorldProxy::ProtoSerializeProperties(SelfRoot);
650 
651  XML::Node PropertiesNode = SelfRoot.AppendChild( CollidableProxy::GetSerializableName() + "Properties" );
652 
653  if( PropertiesNode.AppendAttribute("Version").SetValue("1") &&
654  PropertiesNode.AppendAttribute("CollisionGroup").SetValue( this->GetCollisionGroup() ) &&
655  PropertiesNode.AppendAttribute("CollisionMask").SetValue( this->GetCollisionMask() ) &&
656  PropertiesNode.AppendAttribute("CollisionFlags").SetValue( this->GetCollisionFlags() ) &&
657  PropertiesNode.AppendAttribute("Friction").SetValue( this->GetFriction() ) &&
658  PropertiesNode.AppendAttribute("RollingFriction").SetValue( this->GetRollingFriction() ) &&
659  PropertiesNode.AppendAttribute("AnisotropicFrictionMode").SetValue( this->GetAnisotropicFrictionMode() ) &&
660  PropertiesNode.AppendAttribute("Restitution").SetValue( this->GetRestitution() ) &&
661  PropertiesNode.AppendAttribute("ActivationState").SetValue( static_cast<Whole>( this->GetActivationState() ) ) &&
662  PropertiesNode.AppendAttribute("DeactivationTime").SetValue( this->GetDeactivationTime() ) &&
663  PropertiesNode.AppendAttribute("ContactProcessingThreshold").SetValue( this->_GetContactProcessingThreshold() ) )
664  {
665  XML::Node AnisotropicFrictionNode = PropertiesNode.AppendChild("AnisotropicFriction");
666  this->GetAnisotropicFriction().ProtoSerialize( AnisotropicFrictionNode );
667 
668  return;
669  }else{
670  SerializeError("Create XML Attribute Values",CollidableProxy::GetSerializableName() + "Properties",true);
671  }
672  }
673 
675  {
676  XML::Node ShapeNode = SelfRoot.AppendChild( CollidableProxy::GetSerializableName() + "Shape" );
677 
678  if( ShapeNode.AppendAttribute("Version").SetValue("1") &&
679  ShapeNode.AppendAttribute("ProxyShape").SetValue( this->ProxyShape->GetName() ) )
680  {
681  return;
682  }else{
683  SerializeError("Create XML Attribute Values",CollidableProxy::GetSerializableName() + "Shape",true);
684  }
685  }
686 
688  {
690 
691  XML::Attribute CurrAttrib;
692  XML::Node PropertiesNode = SelfRoot.GetChild( CollidableProxy::GetSerializableName() + "Properties" );
693 
694  if( !PropertiesNode.Empty() ) {
695  if(PropertiesNode.GetAttribute("Version").AsInt() == 1) {
696  Whole AFMode = 0;
697 
698  CurrAttrib = PropertiesNode.GetAttribute("CollisionGroup");
699  if( !CurrAttrib.Empty() )
700  this->SetCollisionGroup( CurrAttrib.AsWhole() );
701 
702  CurrAttrib = PropertiesNode.GetAttribute("CollisionMask");
703  if( !CurrAttrib.Empty() )
704  this->SetCollisionMask( CurrAttrib.AsWhole() );
705 
706  CurrAttrib = PropertiesNode.GetAttribute("CollisionFlags");
707  if( !CurrAttrib.Empty() )
708  this->SetCollisionFlags( CurrAttrib.AsWhole() );
709 
710  CurrAttrib = PropertiesNode.GetAttribute("Friction");
711  if( !CurrAttrib.Empty() )
712  this->SetFriction( CurrAttrib.AsReal() );
713 
714  CurrAttrib = PropertiesNode.GetAttribute("RollingFriction");
715  if( !CurrAttrib.Empty() )
716  this->SetRollingFriction( CurrAttrib.AsReal() );
717 
718  CurrAttrib = PropertiesNode.GetAttribute("AnisotropicFrictionMode");
719  if( !CurrAttrib.Empty() )
720  AFMode = CurrAttrib.AsWhole();
721 
722  CurrAttrib = PropertiesNode.GetAttribute("Restitution");
723  if( !CurrAttrib.Empty() )
724  this->SetRestitution( CurrAttrib.AsReal() );
725 
726  CurrAttrib = PropertiesNode.GetAttribute("ActivationState");
727  if( !CurrAttrib.Empty() )
728  this->SetActivationState( static_cast<Physics::ActivationState>( CurrAttrib.AsWhole() ) );
729 
730  CurrAttrib = PropertiesNode.GetAttribute("DeactivationTime");
731  if( !CurrAttrib.Empty() )
732  this->SetDeactivationTime( CurrAttrib.AsReal() );
733 
734  CurrAttrib = PropertiesNode.GetAttribute("ContactProcessingThreshold");
735  if( !CurrAttrib.Empty() )
736  this->_SetContactProcessingThreshold( CurrAttrib.AsReal() );
737 
738  // Get the properties that need their own nodes
739  XML::Node AnisotropicFrictionNode = PropertiesNode.GetChild("AnisotropicFriction").GetFirstChild();
740  if( !AnisotropicFrictionNode.Empty() ) {
741  Vector3 AF(AnisotropicFrictionNode);
742  this->SetAnisotropicFriction(AF,AFMode);
743  }
744  }else{
745  MEZZ_EXCEPTION(ExceptionBase::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + (CollidableProxy::GetSerializableName() + "Properties" ) + ": Not Version 1.");
746  }
747  }else{
748  MEZZ_EXCEPTION(ExceptionBase::II_IDENTITY_NOT_FOUND_EXCEPTION,CollidableProxy::GetSerializableName() + "Properties" + " was not found in the provided XML node, which was expected.");
749  }
750  }
751 
753  {
754  XML::Attribute CurrAttrib;
755  XML::Node ShapeNode = SelfRoot.GetChild( CollidableProxy::GetSerializableName() + "Shape" );
756 
757  if( !ShapeNode.Empty() ) {
758  if(ShapeNode.GetAttribute("Version").AsInt() == 1) {
759  CurrAttrib = ShapeNode.GetAttribute("ProxyShape");
760  if( !CurrAttrib.Empty() ) {
761  CollisionShape* Shape = CollisionShapeManager::GetSingletonPtr()->GetShape( CurrAttrib.AsString() );
762  this->SetCollisionShape( Shape );
763  }
764  }
765  }
766  }
767 
770 
772  { return "CollidableProxy"; }
773 
774  ///////////////////////////////////////////////////////////////////////////////
775  // Internal Methods
776 
778  { return ( this->IsInWorld() ? this->_GetBasePhysicsObject()->getBroadphaseHandle()->m_uniqueId : 0 ); }
779 
781  { this->_GetBasePhysicsObject()->setContactProcessingThreshold(Threshold); }
782 
784  { return this->_GetBasePhysicsObject()->getContactProcessingThreshold(); }
785  }// Physics
786 }// Mezzanine
787 
788 #endif
virtual Int16 GetCollisionMask() const
Gets the object's collision mask.
This is the base class for all collision shapes.
virtual void Yaw(const Real Angle)
Rotate the object around the Y axis.
Attribute AppendAttribute(const Char8 *Name)
Creates an Attribute and puts it at the end of this Nodes attributes.
virtual Real GetDeactivationTime() const
Gets the current deactivation time for this object.
virtual void Pitch(const Real Angle)
Rotate the object around the X axis.
Indicates the class is a MultiSphereCollisionShape.
virtual ~CollidableProxy()
Class Destructor.
A light-weight handle for manipulating attributes in DOM tree.
Definition: attribute.h:74
virtual void ProtoDeSerializeShape(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the shape of this object with it.
virtual void SetRollingFriction(const Real Friction)
Sets the rolling friction coefficient.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
virtual void Rotate(const Vector3 &Axis, const Real Angle)
Rotates the object from it's existing rotation.
virtual Int16 GetCollisionGroup() const
Gets the objects collision group.
virtual void SetActivationState(const Physics::ActivationState State, Boole Force=false)
Sets the activation state of the world object.
Real X
Coordinate on the X vector.
Definition: vector3.h:85
virtual Real GetRestitution() const
Gets the World Object restitution coefficient.
Indicates the class is a ConeCollisionShape.
Real Z
Coordinate on the Z vector.
Definition: vector3.h:89
Indicates the class is a StaticMeshCollisionShape.
PhysicsManager * Manager
This is a pointer to the physics manager that created and owns this proxy.
virtual void SetCollisionMask(const Int16 Mask)
Sets the collision mask of this proxy, which determines which groups it will collide with...
Thrown when the requested identity could not be found.
Definition: exception.h:94
virtual void ProtoSerializeImpl(XML::Node &SelfRoot) const
Implementation method for serializing additional sets of data.
Definition: worldproxy.cpp:66
Node GetFirstChild() const
Get the first child Node of this Node.
#define MEZZ_EXCEPTION(num, desc)
An easy way to throw exceptions with rich information.
Definition: exception.h:3048
virtual Boole IsAnisotropicFrictionModeSet(const Whole Mode) const
Gets whether or not anisotropic friction is being used in a specified mode.
virtual Boole IsStaticOrKinematic() const
Checks if the object is either static or kinematic.
int Integer
A datatype used to represent any integer close to.
Definition: datatypes.h:154
virtual Real GetFriction() const
Gets the sliding friction coefficient.
Real Y
The Y component of the Axis.
Definition: quaternion.h:77
virtual Boole IsActive() const
Checks if the object is active in the simulation.
Thrown when a version is accessed/parsed/required and it cannot work correctly or is missing...
Definition: exception.h:112
virtual Vector3 GetLocation() const
Gets this objects current location.
virtual Vector3 GetScaling() const
Gets the current scaling being applied to the collision shape.
Indicates the class is a DynamicMeshCollisionShape.
const Char8 * AsString(const Char8 *def="") const
Attempts to convert the value of the attribute to a String and returns the results.
virtual btCollisionShape * _GetInternalShape() const
Gets the internal shape pointer this collision shape is based on.
virtual WorldManager * GetCreator() const
Gets a pointer to this proxies creator.
virtual Boole IsKinematic() const
Is the object kinematic.
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
Definition: worldproxy.cpp:129
ActivationState
This is used by physics proxies to monitor and set their physics activation.
bool Empty() const
Is this storing anything at all?
virtual void SetLocation(const Vector3 &Loc)
Sets the location of this object in parent space.
This implements the exception hiearchy for Mezzanine.
virtual void Roll(const Real Angle)
Rotate the object around the Z axis.
Indicates the class is a CompoundCollisionShape.
float Real
A Datatype used to represent a real floating point number.
Definition: datatypes.h:141
The interface for serialization.
virtual Real GetRollingFriction() const
Gets the rolling friction coefficient.
bool SetValue(const Char8 *rhs)
Set the value of this.
Whole AsWhole(Whole def=0) const
Attempts to convert the value of the attribute to a Whole and returns the results.
static CollisionShapeManager * GetSingletonPtr()
Fetches a pointer to the singleton.
Definition: singleton.h:97
virtual Vector3 GetScale() const
Gets the scaling currently being applied to this object.
virtual void SetOrientation(const Quaternion &Ori)
Sets the orientation of this object in parent space.
virtual void SetRestitution(const Real &Restitution)
Sets the restitution coefficient.
virtual void RemoveFromWorld()=0
Unhooks this proxy from it's respective world.
Int16 CollisionGroup
The classifications pertaining to this object in regards to collisions.
Indicates the class is a SphereCollisionShape.
virtual Boole IsStatic() const
Is the object static.
btVector3 GetBulletVector3() const
Gets a Bullet vector3.
Definition: vector3.cpp:555
A light-weight handle for manipulating nodes in DOM tree.
Definition: node.h:89
virtual void ProtoDeSerializeImpl(const XML::Node &SelfRoot)
Implementation method for deseriailizing additional sets of data.
virtual Vector3 GetAnisotropicFriction() const
Gets the anisotropic friction factor.
Real W
Rotation on the Axis X, Y and Z defined.
Definition: quaternion.h:81
virtual String GetDerivedSerializableName() const
Gets the most derived serializable name of this WorldProxy.
int AsInt(int def=0) const
Attempts to convert the value of the attribute to an int and returns the results. ...
This is the base class for proxy objects belonging to the various 3D subsystems.
Definition: worldproxy.h:53
uint32_t UInt32
An 32-bit unsigned integer.
Definition: datatypes.h:126
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
Definition: worldproxy.cpp:94
CollidableProxy(PhysicsManager *Creator)
XML-assist Constructor.
virtual void _SetContactProcessingThreshold(const Real Threshold)
Sets the maximum distance to be considered for processing collisions with this object.
static Vector3 Unit_Y()
Gets a vector representing the Y unit of a Vector3.
Definition: vector3.cpp:134
virtual void ProtoSerializeShape(XML::Node &SelfRoot) const
Convert the shape of this class to an XML::Node ready for serialization.
bool Empty() const
Is this storing anything at all?
virtual void SetScale(const Vector3 &Sc)
Sets the scaling to be applied to this object.
virtual void AddToWorld()=0
Performs all the necessary task to ensure this object is connected to it's respective world and ready...
ShapeType
This enum describes what kind of shape you are currently working with.
Real AsReal(Real def=0) const
Attempts to convert the value of the attribute to a Real and returns the results. ...
Real Y
Coordinate on the Y vector.
Definition: vector3.h:87
Indicates the class is a CylinderCollisionShape.
virtual void SetKinematic()
Sets the state of the object to Kinematic.
CollisionShape * ProxyShape
The physics shape of this proxy.
virtual void SetCollisionGroup(const Int16 Group)
Sets which collision group this proxy belongs to, which determines it's collision behavior...
virtual Quaternion GetOrientation() const
Gets this objects current orientation.
virtual btCollisionObject * _GetBasePhysicsObject() const =0
Accessor for the internal physics object.
static String GetSerializableName()
Get the name of the the XML tag the proxy class will leave behind as its instances are serialized...
This is the base class for all managers that belong to a single world instance.
Definition: worldmanager.h:55
virtual Boole GetCollisionResponse() const
Will this respond to 3d collisions.
int16_t Int16
An 16-bit integer.
Definition: datatypes.h:120
static Vector3 Unit_X()
Gets a vector representing the X unit of a Vector3.
Definition: vector3.cpp:131
This is simply a place for storing all the Physics Related functions.
virtual void SetScaling(const Vector3 &Scaling)
Scales the collision shape on each of it's axes.
A container for the metrics of time relevant for the timer class.
Definition: extendedtimer.h:52
virtual void SetFriction(const Real Friction)
Sets the sliding friction coefficient.
virtual void SetCollisionResponse(Boole Enable)
Sets the World Object to be able to collide with other objects in the world.
static Vector3 Unit_Z()
Gets a vector representing the Z unit of a Vector3.
Definition: vector3.cpp:137
Indicates the class is a BoxCollisionShape.
This is used to represent a point in space, or a vector through space.
Definition: vector3.h:77
virtual AxisAlignedBox GetAABB() const
Gets this proxies AABB.
virtual void Translate(const Vector3 &Trans)
Moves this object from it's current location.
virtual Integer _GetBroadphaseUniqueID() const
Gets the unique ID assigned to the internal object.
virtual Physics::ActivationState GetActivationState() const
Gets the current activation state of this proxy.
virtual void SetDeactivationTime(const Real Time)
Sets the amount of time this object needs to have no forces enacted upon it to be deactivated...
virtual void Scale(const Vector3 &Scale)
Scales the object from it's current size.
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
virtual Whole GetCollisionFlags() const
Gets the collection of flags that help determine collision response for this object.
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
virtual Boole IsInWorld() const
Gets whether or not this object is inside of it's world.
Int16 CollisionMask
Stores the kind of World Objects that can collide with each other.
virtual void ProtoSerializeImpl(XML::Node &SelfRoot) const
Implementation method for serializing additional sets of data.
virtual Physics::AnisotropicFrictionFlags GetAnisotropicFrictionMode() const
Gets the current Anisotropic friction mode being applied to this proxy.
virtual void SetCollisionShape(CollisionShape *Shape)
Sets the collision shape to be used.
Real X
The X component of the Axis.
Definition: quaternion.h:75
virtual void SetCollisionFlags(const Whole Flags)
Sets the collection of flags that help determine collision response for this object.
This is used to store information about rotation in 3d space.
Definition: quaternion.h:68
virtual void SetStatic()
Sets the state of the object to Static.
void SerializeError(const String &FailedTo, const String &ClassName, Boole SOrD)
Simply does some string concatenation, then throws an Exception.
virtual void ProtoSerializeProperties(XML::Node &SelfRoot) const
Convert the properties of this class to an XML::Node ready for serialization.
Node AppendChild(NodeType Type=NodeElement)
Creates a Node and makes it a child of this one.
virtual void SetCollisionGroupAndMask(const Int16 Group, const Int16 Mask)
Set the collision group and mask for the proxy to determine what it should collide with...
Real Z
The Z component of the Axis.
Definition: quaternion.h:79
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
AnisotropicFrictionFlags
This is used by physics proxies to help determine the behavior of it's anistropic friction behavior...
virtual CollisionShape * GetCollisionShape() const
Gets the collision shape currently in use by this object.
virtual Real _GetContactProcessingThreshold() const
Gets the maximum distance to be considered for processing collisions with this object.
Attribute GetAttribute(const Char8 *Name) const
Attempt to get an Attribute on this Node with a given name.
Indicates the class is a CapsuleCollisionShape.
Indicates the class is a ConvexHullCollisionShape.
void ProtoSerialize(XML::Node &CurrentRoot) const
Convert this class to an XML::Node ready for serialization.
Definition: vector3.cpp:588
Node GetChild(const Char8 *Name) const
Attempt to get a child Node with a given name.
virtual void ProtoDeSerializeProperties(const XML::Node &SelfRoot)
Take the data stored in an XML Node and overwrite the properties of this object with it...
virtual const String & GetName() const
Gets the name of this shape.
virtual void ProtoDeSerializeImpl(const XML::Node &SelfRoot)
Implementation method for deseriailizing additional sets of data.
Definition: worldproxy.cpp:69
virtual void SetAnisotropicFriction(const Vector3 &Friction, const Whole Mode)
Sets the anisotropic friction factor.
This is a utility class used to represent the Axis-Aligned Bounding Boxes of objects in various subsy...