Back to index

supertuxkart  0.5+dfsg1
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 RIGIDBODY_H
00017 #define RIGIDBODY_H
00018 
00019 #include "LinearMath/btAlignedObjectArray.h"
00020 #include "LinearMath/btPoint3.h"
00021 #include "LinearMath/btTransform.h"
00022 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
00023 #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
00024 
00025 class btCollisionShape;
00026 class btMotionState;
00027 class btTypedConstraint;
00028 
00029 
00030 extern btScalar gDeactivationTime;
00031 extern bool gDisableDeactivation;
00032 
00033 
00042 class btRigidBody  : public btCollisionObject
00043 {
00044 
00045        btMatrix3x3   m_invInertiaTensorWorld;
00046        btVector3            m_linearVelocity;
00047        btVector3            m_angularVelocity;
00048        btScalar             m_inverseMass;
00049        btScalar             m_angularFactor;
00050 
00051        btVector3            m_gravity;    
00052        btVector3            m_invInertiaLocal;
00053        btVector3            m_totalForce;
00054        btVector3            m_totalTorque;
00055        
00056        btScalar             m_linearDamping;
00057        btScalar             m_angularDamping;
00058 
00059        bool                 m_additionalDamping;
00060        btScalar             m_additionalDampingFactor;
00061        btScalar             m_additionalLinearDampingThresholdSqr;
00062        btScalar             m_additionalAngularDampingThresholdSqr;
00063        btScalar             m_additionalAngularDampingFactor;
00064 
00065 
00066        btScalar             m_linearSleepingThreshold;
00067        btScalar             m_angularSleepingThreshold;
00068 
00069        //m_optionalMotionState allows to automatic synchronize the world transform for active objects
00070        btMotionState*       m_optionalMotionState;
00071 
00072        //keep track of typed constraints referencing this rigid body
00073        btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
00074 
00075 public:
00076 
00077 
00083        struct btRigidBodyConstructionInfo
00084        {
00085               btScalar                    m_mass;
00086 
00089               btMotionState*              m_motionState;
00090               btTransform   m_startWorldTransform;
00091 
00092               btCollisionShape*    m_collisionShape;
00093               btVector3                   m_localInertia;
00094               btScalar                    m_linearDamping;
00095               btScalar                    m_angularDamping;
00096 
00098               btScalar                    m_friction;
00100               btScalar                    m_restitution;
00101 
00102               btScalar                    m_linearSleepingThreshold;
00103               btScalar                    m_angularSleepingThreshold;
00104 
00105               //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
00106               //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
00107               bool                        m_additionalDamping;
00108               btScalar                    m_additionalDampingFactor;
00109               btScalar                    m_additionalLinearDampingThresholdSqr;
00110               btScalar                    m_additionalAngularDampingThresholdSqr;
00111               btScalar                    m_additionalAngularDampingFactor;
00112 
00113               
00114               btRigidBodyConstructionInfo(       btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
00115               m_mass(mass),
00116                      m_motionState(motionState),
00117                      m_collisionShape(collisionShape),
00118                      m_localInertia(localInertia),
00119                      m_linearDamping(btScalar(0.)),
00120                      m_angularDamping(btScalar(0.)),
00121                      m_friction(btScalar(0.5)),
00122                      m_restitution(btScalar(0.)),
00123                      m_linearSleepingThreshold(btScalar(0.8)),
00124                      m_angularSleepingThreshold(btScalar(1.f)),
00125                      m_additionalDamping(false),
00126                      m_additionalDampingFactor(btScalar(0.005)),
00127                      m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
00128                      m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
00129                      m_additionalAngularDampingFactor(btScalar(0.01))
00130               {
00131                      m_startWorldTransform.setIdentity();
00132               }
00133        };
00134 
00136        btRigidBody(  const btRigidBodyConstructionInfo& constructionInfo);
00137 
00140        btRigidBody(  btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
00141 
00142 
00143        virtual ~btRigidBody()
00144         { 
00145                 //No constraints should point to this rigidbody
00146               //Remove constraints from the dynamics world before you delete the related rigidbodies. 
00147                 btAssert(m_constraintRefs.size()==0); 
00148         }
00149 
00150 protected:
00151 
00153        void   setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
00154 
00155 public:
00156 
00157        void                 proceedToTransform(const btTransform& newTrans); 
00158        
00161        static const btRigidBody*   upcast(const btCollisionObject* colObj)
00162        {
00163               if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
00164                      return (const btRigidBody*)colObj;
00165               return 0;
00166        }
00167        static btRigidBody*  upcast(btCollisionObject* colObj)
00168        {
00169               if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
00170                      return (btRigidBody*)colObj;
00171               return 0;
00172        }
00173        
00175        void                 predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
00176        
00177        void                 saveKinematicState(btScalar step);
00178        
00179        void                 applyGravity();
00180        
00181        void                 setGravity(const btVector3& acceleration);  
00182 
00183        const btVector3&     getGravity() const
00184        {
00185               return m_gravity;
00186        }
00187 
00188        void                 setDamping(btScalar lin_damping, btScalar ang_damping);
00189 
00190        void                 applyDamping(btScalar timeStep);
00191 
00192        SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const {
00193               return m_collisionShape;
00194        }
00195 
00196        SIMD_FORCE_INLINE btCollisionShape*       getCollisionShape() {
00197                      return m_collisionShape;
00198        }
00199        
00200        void                 setMassProps(btScalar mass, const btVector3& inertia);
00201        
00202        btScalar             getInvMass() const { return m_inverseMass; }
00203        const btMatrix3x3& getInvInertiaTensorWorld() const { 
00204               return m_invInertiaTensorWorld; 
00205        }
00206               
00207        void                 integrateVelocities(btScalar step);
00208 
00209        void                 setCenterOfMassTransform(const btTransform& xform);
00210 
00211        void                 applyCentralForce(const btVector3& force)
00212        {
00213               m_totalForce += force;
00214        }
00215     
00216        const btVector3& getInvInertiaDiagLocal()
00217        {
00218               return m_invInertiaLocal;
00219        };
00220 
00221        void   setInvInertiaDiagLocal(const btVector3& diagInvInertia)
00222        {
00223               m_invInertiaLocal = diagInvInertia;
00224        }
00225 
00226        void   setSleepingThresholds(btScalar linear,btScalar angular)
00227        {
00228               m_linearSleepingThreshold = linear;
00229               m_angularSleepingThreshold = angular;
00230        }
00231 
00232        void   applyTorque(const btVector3& torque)
00233        {
00234               m_totalTorque += torque;
00235        }
00236        
00237        void   applyForce(const btVector3& force, const btVector3& rel_pos) 
00238        {
00239               applyCentralForce(force);
00240               applyTorque(rel_pos.cross(force));
00241        }
00242        
00243        void applyCentralImpulse(const btVector3& impulse)
00244        {
00245               m_linearVelocity += impulse * m_inverseMass;
00246        }
00247        
00248        void applyTorqueImpulse(const btVector3& torque)
00249        {
00250                      m_angularVelocity += m_invInertiaTensorWorld * torque;
00251        }
00252        
00253        void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
00254        {
00255               if (m_inverseMass != btScalar(0.))
00256               {
00257                      applyCentralImpulse(impulse);
00258                      if (m_angularFactor)
00259                      {
00260                             applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor);
00261                      }
00262               }
00263        }
00264 
00265        //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
00266        SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
00267        {
00268               if (m_inverseMass != btScalar(0.))
00269               {
00270                      m_linearVelocity += linearComponent*impulseMagnitude;
00271                      if (m_angularFactor)
00272                      {
00273                             m_angularVelocity += angularComponent*impulseMagnitude*m_angularFactor;
00274                      }
00275               }
00276        }
00277        
00278        void clearForces() 
00279        {
00280               m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00281               m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00282        }
00283        
00284        void updateInertiaTensor();    
00285        
00286        const btPoint3&     getCenterOfMassPosition() const { 
00287               return m_worldTransform.getOrigin(); 
00288        }
00289        btQuaternion getOrientation() const;
00290        
00291        const btTransform&  getCenterOfMassTransform() const { 
00292               return m_worldTransform; 
00293        }
00294        const btVector3&   getLinearVelocity() const { 
00295               return m_linearVelocity; 
00296        }
00297        const btVector3&    getAngularVelocity() const { 
00298               return m_angularVelocity; 
00299        }
00300        
00301 
00302        inline void setLinearVelocity(const btVector3& lin_vel)
00303        { 
00304               assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
00305               m_linearVelocity = lin_vel; 
00306        }
00307 
00308        inline void setAngularVelocity(const btVector3& ang_vel) { 
00309               assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
00310               {
00311                      m_angularVelocity = ang_vel; 
00312               }
00313        }
00314 
00315        btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
00316        {
00317               //we also calculate lin/ang velocity for kinematic objects
00318               return m_linearVelocity + m_angularVelocity.cross(rel_pos);
00319 
00320               //for kinematic objects, we could also use use:
00321               //            return        (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
00322        }
00323 
00324        void translate(const btVector3& v) 
00325        {
00326               m_worldTransform.getOrigin() += v; 
00327        }
00328 
00329        
00330        void   getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
00331 
00332 
00333 
00334 
00335        
00336        SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const
00337        {
00338               btVector3 r0 = pos - getCenterOfMassPosition();
00339 
00340               btVector3 c0 = (r0).cross(normal);
00341 
00342               btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
00343 
00344               return m_inverseMass + normal.dot(vec);
00345 
00346        }
00347 
00348        SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
00349        {
00350               btVector3 vec = axis * getInvInertiaTensorWorld();
00351               return axis.dot(vec);
00352        }
00353 
00354        SIMD_FORCE_INLINE void      updateDeactivation(btScalar timeStep)
00355        {
00356               if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
00357                      return;
00358 
00359               if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
00360                      (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
00361               {
00362                      m_deactivationTime += timeStep;
00363               } else
00364               {
00365                      m_deactivationTime=btScalar(0.);
00366                      setActivationState(0);
00367               }
00368 
00369        }
00370 
00371        SIMD_FORCE_INLINE bool      wantsSleeping()
00372        {
00373 
00374               if (getActivationState() == DISABLE_DEACTIVATION)
00375                      return false;
00376 
00377               //disable deactivation
00378               if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
00379                      return false;
00380 
00381               if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
00382                      return true;
00383 
00384               if (m_deactivationTime> gDeactivationTime)
00385               {
00386                      return true;
00387               }
00388               return false;
00389        }
00390 
00391 
00392        
00393        const btBroadphaseProxy*    getBroadphaseProxy() const
00394        {
00395               return m_broadphaseHandle;
00396        }
00397        btBroadphaseProxy*   getBroadphaseProxy() 
00398        {
00399               return m_broadphaseHandle;
00400        }
00401        void   setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
00402        {
00403               m_broadphaseHandle = broadphaseProxy;
00404        }
00405 
00406        //btMotionState allows to automatic synchronize the world transform for active objects
00407        btMotionState*       getMotionState()
00408        {
00409               return m_optionalMotionState;
00410        }
00411        const btMotionState* getMotionState() const
00412        {
00413               return m_optionalMotionState;
00414        }
00415        void   setMotionState(btMotionState* motionState)
00416        {
00417               m_optionalMotionState = motionState;
00418               if (m_optionalMotionState)
00419                      motionState->getWorldTransform(m_worldTransform);
00420        }
00421 
00422        //for experimental overriding of friction/contact solver func
00423        int    m_contactSolverType;
00424        int    m_frictionSolverType;
00425 
00426        void   setAngularFactor(btScalar angFac)
00427        {
00428               m_angularFactor = angFac;
00429        }
00430        btScalar      getAngularFactor() const
00431        {
00432               return m_angularFactor;
00433        }
00434 
00435        //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
00436        bool   isInWorld() const
00437        {
00438               return (getBroadphaseProxy() != 0);
00439        }
00440 
00441        virtual bool checkCollideWithOverride(btCollisionObject* co);
00442 
00443        void addConstraintRef(btTypedConstraint* c);
00444        void removeConstraintRef(btTypedConstraint* c);
00445 
00446        btTypedConstraint* getConstraintRef(int index)
00447        {
00448               return m_constraintRefs[index];
00449        }
00450 
00451        int getNumConstraintRefs()
00452        {
00453               return m_constraintRefs.size();
00454        }
00455 
00456        int    m_debugBodyId;
00457 };
00458 
00459 
00460 
00461 #endif
00462