btRigidBody.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #ifndef BT_RIGIDBODY_H
00017 #define BT_RIGIDBODY_H
00018 
00019 #include "LinearMath/btAlignedObjectArray.h"
00020 #include "LinearMath/btTransform.h"
00021 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
00022 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00023 
00024 class btCollisionShape;
00025 class btMotionState;
00026 class btTypedConstraint;
00027 
00028 
00029 extern btScalar gDeactivationTime;
00030 extern bool gDisableDeactivation;
00031 
00032 #ifdef BT_USE_DOUBLE_PRECISION
00033 #define btRigidBodyData btRigidBodyDoubleData
00034 #define btRigidBodyDataName     "btRigidBodyDoubleData"
00035 #else
00036 #define btRigidBodyData btRigidBodyFloatData
00037 #define btRigidBodyDataName     "btRigidBodyFloatData"
00038 #endif //BT_USE_DOUBLE_PRECISION
00039 
00040 
00041 enum    btRigidBodyFlags
00042 {
00043         BT_DISABLE_WORLD_GRAVITY = 1,
00047         BT_ENABLE_GYROPSCOPIC_FORCE = 2
00048 };
00049 
00050 
00059 class btRigidBody  : public btCollisionObject
00060 {
00061 
00062         btMatrix3x3     m_invInertiaTensorWorld;
00063         btVector3               m_linearVelocity;
00064         btVector3               m_angularVelocity;
00065         btScalar                m_inverseMass;
00066         btVector3               m_linearFactor;
00067 
00068         btVector3               m_gravity;      
00069         btVector3               m_gravity_acceleration;
00070         btVector3               m_invInertiaLocal;
00071         btVector3               m_totalForce;
00072         btVector3               m_totalTorque;
00073         
00074         btScalar                m_linearDamping;
00075         btScalar                m_angularDamping;
00076 
00077         bool                    m_additionalDamping;
00078         btScalar                m_additionalDampingFactor;
00079         btScalar                m_additionalLinearDampingThresholdSqr;
00080         btScalar                m_additionalAngularDampingThresholdSqr;
00081         btScalar                m_additionalAngularDampingFactor;
00082 
00083 
00084         btScalar                m_linearSleepingThreshold;
00085         btScalar                m_angularSleepingThreshold;
00086 
00087         //m_optionalMotionState allows to automatic synchronize the world transform for active objects
00088         btMotionState*  m_optionalMotionState;
00089 
00090         //keep track of typed constraints referencing this rigid body
00091         btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
00092 
00093         int                             m_rigidbodyFlags;
00094         
00095         int                             m_debugBodyId;
00096         
00097 
00098 protected:
00099 
00100         ATTRIBUTE_ALIGNED64(btVector3           m_deltaLinearVelocity);
00101         btVector3               m_deltaAngularVelocity;
00102         btVector3               m_angularFactor;
00103         btVector3               m_invMass;
00104         btVector3               m_pushVelocity;
00105         btVector3               m_turnVelocity;
00106 
00107 
00108 public:
00109 
00110 
00116         struct  btRigidBodyConstructionInfo
00117         {
00118                 btScalar                        m_mass;
00119 
00122                 btMotionState*          m_motionState;
00123                 btTransform     m_startWorldTransform;
00124 
00125                 btCollisionShape*       m_collisionShape;
00126                 btVector3                       m_localInertia;
00127                 btScalar                        m_linearDamping;
00128                 btScalar                        m_angularDamping;
00129 
00131                 btScalar                        m_friction;
00134                 btScalar                        m_rollingFriction;
00136                 btScalar                        m_restitution;
00137 
00138                 btScalar                        m_linearSleepingThreshold;
00139                 btScalar                        m_angularSleepingThreshold;
00140 
00141                 //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
00142                 //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
00143                 bool                            m_additionalDamping;
00144                 btScalar                        m_additionalDampingFactor;
00145                 btScalar                        m_additionalLinearDampingThresholdSqr;
00146                 btScalar                        m_additionalAngularDampingThresholdSqr;
00147                 btScalar                        m_additionalAngularDampingFactor;
00148 
00149                 btRigidBodyConstructionInfo(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
00150                 m_mass(mass),
00151                         m_motionState(motionState),
00152                         m_collisionShape(collisionShape),
00153                         m_localInertia(localInertia),
00154                         m_linearDamping(btScalar(0.)),
00155                         m_angularDamping(btScalar(0.)),
00156                         m_friction(btScalar(0.5)),
00157                         m_rollingFriction(btScalar(0)),
00158                         m_restitution(btScalar(0.)),
00159                         m_linearSleepingThreshold(btScalar(0.8)),
00160                         m_angularSleepingThreshold(btScalar(1.f)),
00161                         m_additionalDamping(false),
00162                         m_additionalDampingFactor(btScalar(0.005)),
00163                         m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
00164                         m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
00165                         m_additionalAngularDampingFactor(btScalar(0.01))
00166                 {
00167                         m_startWorldTransform.setIdentity();
00168                 }
00169         };
00170 
00172         btRigidBody(    const btRigidBodyConstructionInfo& constructionInfo);
00173 
00176         btRigidBody(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
00177 
00178 
00179         virtual ~btRigidBody()
00180         { 
00181                 //No constraints should point to this rigidbody
00182                 //Remove constraints from the dynamics world before you delete the related rigidbodies. 
00183                 btAssert(m_constraintRefs.size()==0); 
00184         }
00185 
00186 protected:
00187 
00189         void    setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
00190 
00191 public:
00192 
00193         void                    proceedToTransform(const btTransform& newTrans); 
00194         
00197         static const btRigidBody*       upcast(const btCollisionObject* colObj)
00198         {
00199                 if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
00200                         return (const btRigidBody*)colObj;
00201                 return 0;
00202         }
00203         static btRigidBody*     upcast(btCollisionObject* colObj)
00204         {
00205                 if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
00206                         return (btRigidBody*)colObj;
00207                 return 0;
00208         }
00209         
00211         void                    predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
00212         
00213         void                    saveKinematicState(btScalar step);
00214         
00215         void                    applyGravity();
00216         
00217         void                    setGravity(const btVector3& acceleration);  
00218 
00219         const btVector3&        getGravity() const
00220         {
00221                 return m_gravity_acceleration;
00222         }
00223 
00224         void                    setDamping(btScalar lin_damping, btScalar ang_damping);
00225 
00226         btScalar getLinearDamping() const
00227         {
00228                 return m_linearDamping;
00229         }
00230 
00231         btScalar getAngularDamping() const
00232         {
00233                 return m_angularDamping;
00234         }
00235 
00236         btScalar getLinearSleepingThreshold() const
00237         {
00238                 return m_linearSleepingThreshold;
00239         }
00240 
00241         btScalar getAngularSleepingThreshold() const
00242         {
00243                 return m_angularSleepingThreshold;
00244         }
00245 
00246         void                    applyDamping(btScalar timeStep);
00247 
00248         SIMD_FORCE_INLINE const btCollisionShape*       getCollisionShape() const {
00249                 return m_collisionShape;
00250         }
00251 
00252         SIMD_FORCE_INLINE btCollisionShape*     getCollisionShape() {
00253                         return m_collisionShape;
00254         }
00255         
00256         void                    setMassProps(btScalar mass, const btVector3& inertia);
00257         
00258         const btVector3& getLinearFactor() const
00259         {
00260                 return m_linearFactor;
00261         }
00262         void setLinearFactor(const btVector3& linearFactor)
00263         {
00264                 m_linearFactor = linearFactor;
00265                 m_invMass = m_linearFactor*m_inverseMass;
00266         }
00267         btScalar                getInvMass() const { return m_inverseMass; }
00268         const btMatrix3x3& getInvInertiaTensorWorld() const { 
00269                 return m_invInertiaTensorWorld; 
00270         }
00271                 
00272         void                    integrateVelocities(btScalar step);
00273 
00274         void                    setCenterOfMassTransform(const btTransform& xform);
00275 
00276         void                    applyCentralForce(const btVector3& force)
00277         {
00278                 m_totalForce += force*m_linearFactor;
00279         }
00280 
00281         const btVector3& getTotalForce() const
00282         {
00283                 return m_totalForce;
00284         };
00285 
00286         const btVector3& getTotalTorque() const
00287         {
00288                 return m_totalTorque;
00289         };
00290     
00291         const btVector3& getInvInertiaDiagLocal() const
00292         {
00293                 return m_invInertiaLocal;
00294         };
00295 
00296         void    setInvInertiaDiagLocal(const btVector3& diagInvInertia)
00297         {
00298                 m_invInertiaLocal = diagInvInertia;
00299         }
00300 
00301         void    setSleepingThresholds(btScalar linear,btScalar angular)
00302         {
00303                 m_linearSleepingThreshold = linear;
00304                 m_angularSleepingThreshold = angular;
00305         }
00306 
00307         void    applyTorque(const btVector3& torque)
00308         {
00309                 m_totalTorque += torque*m_angularFactor;
00310         }
00311         
00312         void    applyForce(const btVector3& force, const btVector3& rel_pos) 
00313         {
00314                 applyCentralForce(force);
00315                 applyTorque(rel_pos.cross(force*m_linearFactor));
00316         }
00317         
00318         void applyCentralImpulse(const btVector3& impulse)
00319         {
00320                 m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
00321         }
00322         
00323         void applyTorqueImpulse(const btVector3& torque)
00324         {
00325                         m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
00326         }
00327         
00328         void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
00329         {
00330                 if (m_inverseMass != btScalar(0.))
00331                 {
00332                         applyCentralImpulse(impulse);
00333                         if (m_angularFactor)
00334                         {
00335                                 applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor));
00336                         }
00337                 }
00338         }
00339 
00340         void clearForces() 
00341         {
00342                 m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00343                 m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00344         }
00345         
00346         void updateInertiaTensor();    
00347         
00348         const btVector3&     getCenterOfMassPosition() const { 
00349                 return m_worldTransform.getOrigin(); 
00350         }
00351         btQuaternion getOrientation() const;
00352         
00353         const btTransform&  getCenterOfMassTransform() const { 
00354                 return m_worldTransform; 
00355         }
00356         const btVector3&   getLinearVelocity() const { 
00357                 return m_linearVelocity; 
00358         }
00359         const btVector3&    getAngularVelocity() const { 
00360                 return m_angularVelocity; 
00361         }
00362         
00363 
00364         inline void setLinearVelocity(const btVector3& lin_vel)
00365         { 
00366                 m_linearVelocity = lin_vel; 
00367         }
00368 
00369         inline void setAngularVelocity(const btVector3& ang_vel) 
00370         { 
00371                 m_angularVelocity = ang_vel; 
00372         }
00373 
00374         btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
00375         {
00376                 //we also calculate lin/ang velocity for kinematic objects
00377                 return m_linearVelocity + m_angularVelocity.cross(rel_pos);
00378 
00379                 //for kinematic objects, we could also use use:
00380                 //              return  (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
00381         }
00382 
00383         void translate(const btVector3& v) 
00384         {
00385                 m_worldTransform.getOrigin() += v; 
00386         }
00387 
00388         
00389         void    getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
00390 
00391 
00392 
00393 
00394         
00395         SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
00396         {
00397                 btVector3 r0 = pos - getCenterOfMassPosition();
00398 
00399                 btVector3 c0 = (r0).cross(normal);
00400 
00401                 btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
00402 
00403                 return m_inverseMass + normal.dot(vec);
00404 
00405         }
00406 
00407         SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
00408         {
00409                 btVector3 vec = axis * getInvInertiaTensorWorld();
00410                 return axis.dot(vec);
00411         }
00412 
00413         SIMD_FORCE_INLINE void  updateDeactivation(btScalar timeStep)
00414         {
00415                 if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
00416                         return;
00417 
00418                 if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
00419                         (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
00420                 {
00421                         m_deactivationTime += timeStep;
00422                 } else
00423                 {
00424                         m_deactivationTime=btScalar(0.);
00425                         setActivationState(0);
00426                 }
00427 
00428         }
00429 
00430         SIMD_FORCE_INLINE bool  wantsSleeping()
00431         {
00432 
00433                 if (getActivationState() == DISABLE_DEACTIVATION)
00434                         return false;
00435 
00436                 //disable deactivation
00437                 if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
00438                         return false;
00439 
00440                 if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
00441                         return true;
00442 
00443                 if (m_deactivationTime> gDeactivationTime)
00444                 {
00445                         return true;
00446                 }
00447                 return false;
00448         }
00449 
00450 
00451         
00452         const btBroadphaseProxy*        getBroadphaseProxy() const
00453         {
00454                 return m_broadphaseHandle;
00455         }
00456         btBroadphaseProxy*      getBroadphaseProxy() 
00457         {
00458                 return m_broadphaseHandle;
00459         }
00460         void    setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
00461         {
00462                 m_broadphaseHandle = broadphaseProxy;
00463         }
00464 
00465         //btMotionState allows to automatic synchronize the world transform for active objects
00466         btMotionState*  getMotionState()
00467         {
00468                 return m_optionalMotionState;
00469         }
00470         const btMotionState*    getMotionState() const
00471         {
00472                 return m_optionalMotionState;
00473         }
00474         void    setMotionState(btMotionState* motionState)
00475         {
00476                 m_optionalMotionState = motionState;
00477                 if (m_optionalMotionState)
00478                         motionState->getWorldTransform(m_worldTransform);
00479         }
00480 
00481         //for experimental overriding of friction/contact solver func
00482         int     m_contactSolverType;
00483         int     m_frictionSolverType;
00484 
00485         void    setAngularFactor(const btVector3& angFac)
00486         {
00487                 m_angularFactor = angFac;
00488         }
00489 
00490         void    setAngularFactor(btScalar angFac)
00491         {
00492                 m_angularFactor.setValue(angFac,angFac,angFac);
00493         }
00494         const btVector3&        getAngularFactor() const
00495         {
00496                 return m_angularFactor;
00497         }
00498 
00499         //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
00500         bool    isInWorld() const
00501         {
00502                 return (getBroadphaseProxy() != 0);
00503         }
00504 
00505         virtual bool checkCollideWithOverride(const  btCollisionObject* co) const;
00506 
00507         void addConstraintRef(btTypedConstraint* c);
00508         void removeConstraintRef(btTypedConstraint* c);
00509 
00510         btTypedConstraint* getConstraintRef(int index)
00511         {
00512                 return m_constraintRefs[index];
00513         }
00514 
00515         int getNumConstraintRefs() const
00516         {
00517                 return m_constraintRefs.size();
00518         }
00519 
00520         void    setFlags(int flags)
00521         {
00522                 m_rigidbodyFlags = flags;
00523         }
00524 
00525         int getFlags() const
00526         {
00527                 return m_rigidbodyFlags;
00528         }
00529 
00530         btVector3 computeGyroscopicForce(btScalar maxGyroscopicForce) const;
00531 
00533 
00534         virtual int     calculateSerializeBufferSize()  const;
00535 
00537         virtual const char*     serialize(void* dataBuffer,  class btSerializer* serializer) const;
00538 
00539         virtual void serializeSingleObject(class btSerializer* serializer) const;
00540 
00541 };
00542 
00543 //@todo add m_optionalMotionState and m_constraintRefs to btRigidBodyData
00545 struct  btRigidBodyFloatData
00546 {
00547         btCollisionObjectFloatData      m_collisionObjectData;
00548         btMatrix3x3FloatData            m_invInertiaTensorWorld;
00549         btVector3FloatData              m_linearVelocity;
00550         btVector3FloatData              m_angularVelocity;
00551         btVector3FloatData              m_angularFactor;
00552         btVector3FloatData              m_linearFactor;
00553         btVector3FloatData              m_gravity;      
00554         btVector3FloatData              m_gravity_acceleration;
00555         btVector3FloatData              m_invInertiaLocal;
00556         btVector3FloatData              m_totalForce;
00557         btVector3FloatData              m_totalTorque;
00558         float                                   m_inverseMass;
00559         float                                   m_linearDamping;
00560         float                                   m_angularDamping;
00561         float                                   m_additionalDampingFactor;
00562         float                                   m_additionalLinearDampingThresholdSqr;
00563         float                                   m_additionalAngularDampingThresholdSqr;
00564         float                                   m_additionalAngularDampingFactor;
00565         float                                   m_linearSleepingThreshold;
00566         float                                   m_angularSleepingThreshold;
00567         int                                             m_additionalDamping;
00568 };
00569 
00571 struct  btRigidBodyDoubleData
00572 {
00573         btCollisionObjectDoubleData     m_collisionObjectData;
00574         btMatrix3x3DoubleData           m_invInertiaTensorWorld;
00575         btVector3DoubleData             m_linearVelocity;
00576         btVector3DoubleData             m_angularVelocity;
00577         btVector3DoubleData             m_angularFactor;
00578         btVector3DoubleData             m_linearFactor;
00579         btVector3DoubleData             m_gravity;      
00580         btVector3DoubleData             m_gravity_acceleration;
00581         btVector3DoubleData             m_invInertiaLocal;
00582         btVector3DoubleData             m_totalForce;
00583         btVector3DoubleData             m_totalTorque;
00584         double                                  m_inverseMass;
00585         double                                  m_linearDamping;
00586         double                                  m_angularDamping;
00587         double                                  m_additionalDampingFactor;
00588         double                                  m_additionalLinearDampingThresholdSqr;
00589         double                                  m_additionalAngularDampingThresholdSqr;
00590         double                                  m_additionalAngularDampingFactor;
00591         double                                  m_linearSleepingThreshold;
00592         double                                  m_angularSleepingThreshold;
00593         int                                             m_additionalDamping;
00594         char    m_padding[4];
00595 };
00596 
00597 
00598 
00599 #endif //BT_RIGIDBODY_H
00600