Blender V2.61 - r43446

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/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
00044 };
00045 
00046 
00055 class btRigidBody  : public btCollisionObject
00056 {
00057 
00058     btMatrix3x3 m_invInertiaTensorWorld;
00059     btVector3       m_linearVelocity;
00060     btVector3       m_angularVelocity;
00061     btScalar        m_inverseMass;
00062     btVector3       m_linearFactor;
00063 
00064     btVector3       m_gravity;  
00065     btVector3       m_gravity_acceleration;
00066     btVector3       m_invInertiaLocal;
00067     btVector3       m_totalForce;
00068     btVector3       m_totalTorque;
00069     
00070     btScalar        m_linearDamping;
00071     btScalar        m_angularDamping;
00072 
00073     bool            m_additionalDamping;
00074     btScalar        m_additionalDampingFactor;
00075     btScalar        m_additionalLinearDampingThresholdSqr;
00076     btScalar        m_additionalAngularDampingThresholdSqr;
00077     btScalar        m_additionalAngularDampingFactor;
00078 
00079 
00080     btScalar        m_linearSleepingThreshold;
00081     btScalar        m_angularSleepingThreshold;
00082 
00083     //m_optionalMotionState allows to automatic synchronize the world transform for active objects
00084     btMotionState*  m_optionalMotionState;
00085 
00086     //keep track of typed constraints referencing this rigid body
00087     btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
00088 
00089     int             m_rigidbodyFlags;
00090     
00091     int             m_debugBodyId;
00092     
00093 
00094 protected:
00095 
00096     ATTRIBUTE_ALIGNED64(btVector3       m_deltaLinearVelocity);
00097     btVector3       m_deltaAngularVelocity;
00098     btVector3       m_angularFactor;
00099     btVector3       m_invMass;
00100     btVector3       m_pushVelocity;
00101     btVector3       m_turnVelocity;
00102 
00103 
00104 public:
00105 
00106 
00112     struct  btRigidBodyConstructionInfo
00113     {
00114         btScalar            m_mass;
00115 
00118         btMotionState*      m_motionState;
00119         btTransform m_startWorldTransform;
00120 
00121         btCollisionShape*   m_collisionShape;
00122         btVector3           m_localInertia;
00123         btScalar            m_linearDamping;
00124         btScalar            m_angularDamping;
00125 
00127         btScalar            m_friction;
00129         btScalar            m_restitution;
00130 
00131         btScalar            m_linearSleepingThreshold;
00132         btScalar            m_angularSleepingThreshold;
00133 
00134         //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
00135         //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
00136         bool                m_additionalDamping;
00137         btScalar            m_additionalDampingFactor;
00138         btScalar            m_additionalLinearDampingThresholdSqr;
00139         btScalar            m_additionalAngularDampingThresholdSqr;
00140         btScalar            m_additionalAngularDampingFactor;
00141 
00142         btRigidBodyConstructionInfo(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
00143         m_mass(mass),
00144             m_motionState(motionState),
00145             m_collisionShape(collisionShape),
00146             m_localInertia(localInertia),
00147             m_linearDamping(btScalar(0.)),
00148             m_angularDamping(btScalar(0.)),
00149             m_friction(btScalar(0.5)),
00150             m_restitution(btScalar(0.)),
00151             m_linearSleepingThreshold(btScalar(0.8)),
00152             m_angularSleepingThreshold(btScalar(1.f)),
00153             m_additionalDamping(false),
00154             m_additionalDampingFactor(btScalar(0.005)),
00155             m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
00156             m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
00157             m_additionalAngularDampingFactor(btScalar(0.01))
00158         {
00159             m_startWorldTransform.setIdentity();
00160         }
00161     };
00162 
00164     btRigidBody(    const btRigidBodyConstructionInfo& constructionInfo);
00165 
00168     btRigidBody(    btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
00169 
00170 
00171     virtual ~btRigidBody()
00172         { 
00173                 //No constraints should point to this rigidbody
00174         //Remove constraints from the dynamics world before you delete the related rigidbodies. 
00175                 btAssert(m_constraintRefs.size()==0); 
00176         }
00177 
00178 protected:
00179 
00181     void    setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
00182 
00183 public:
00184 
00185     void            proceedToTransform(const btTransform& newTrans); 
00186     
00189     static const btRigidBody*   upcast(const btCollisionObject* colObj)
00190     {
00191         if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
00192             return (const btRigidBody*)colObj;
00193         return 0;
00194     }
00195     static btRigidBody* upcast(btCollisionObject* colObj)
00196     {
00197         if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY)
00198             return (btRigidBody*)colObj;
00199         return 0;
00200     }
00201     
00203     void            predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
00204     
00205     void            saveKinematicState(btScalar step);
00206     
00207     void            applyGravity();
00208     
00209     void            setGravity(const btVector3& acceleration);  
00210 
00211     const btVector3&    getGravity() const
00212     {
00213         return m_gravity_acceleration;
00214     }
00215 
00216     void            setDamping(btScalar lin_damping, btScalar ang_damping);
00217 
00218     btScalar getLinearDamping() const
00219     {
00220         return m_linearDamping;
00221     }
00222 
00223     btScalar getAngularDamping() const
00224     {
00225         return m_angularDamping;
00226     }
00227 
00228     btScalar getLinearSleepingThreshold() const
00229     {
00230         return m_linearSleepingThreshold;
00231     }
00232 
00233     btScalar getAngularSleepingThreshold() const
00234     {
00235         return m_angularSleepingThreshold;
00236     }
00237 
00238     void            applyDamping(btScalar timeStep);
00239 
00240     SIMD_FORCE_INLINE const btCollisionShape*   getCollisionShape() const {
00241         return m_collisionShape;
00242     }
00243 
00244     SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() {
00245             return m_collisionShape;
00246     }
00247     
00248     void            setMassProps(btScalar mass, const btVector3& inertia);
00249     
00250     const btVector3& getLinearFactor() const
00251     {
00252         return m_linearFactor;
00253     }
00254     void setLinearFactor(const btVector3& linearFactor)
00255     {
00256         m_linearFactor = linearFactor;
00257         m_invMass = m_linearFactor*m_inverseMass;
00258     }
00259     btScalar        getInvMass() const { return m_inverseMass; }
00260     const btMatrix3x3& getInvInertiaTensorWorld() const { 
00261         return m_invInertiaTensorWorld; 
00262     }
00263         
00264     void            integrateVelocities(btScalar step);
00265 
00266     void            setCenterOfMassTransform(const btTransform& xform);
00267 
00268     void            applyCentralForce(const btVector3& force)
00269     {
00270         m_totalForce += force*m_linearFactor;
00271     }
00272 
00273     const btVector3& getTotalForce() const
00274     {
00275         return m_totalForce;
00276     };
00277 
00278     const btVector3& getTotalTorque() const
00279     {
00280         return m_totalTorque;
00281     };
00282     
00283     const btVector3& getInvInertiaDiagLocal() const
00284     {
00285         return m_invInertiaLocal;
00286     };
00287 
00288     void    setInvInertiaDiagLocal(const btVector3& diagInvInertia)
00289     {
00290         m_invInertiaLocal = diagInvInertia;
00291     }
00292 
00293     void    setSleepingThresholds(btScalar linear,btScalar angular)
00294     {
00295         m_linearSleepingThreshold = linear;
00296         m_angularSleepingThreshold = angular;
00297     }
00298 
00299     void    applyTorque(const btVector3& torque)
00300     {
00301         m_totalTorque += torque*m_angularFactor;
00302     }
00303     
00304     void    applyForce(const btVector3& force, const btVector3& rel_pos) 
00305     {
00306         applyCentralForce(force);
00307         applyTorque(rel_pos.cross(force*m_linearFactor));
00308     }
00309     
00310     void applyCentralImpulse(const btVector3& impulse)
00311     {
00312         m_linearVelocity += impulse *m_linearFactor * m_inverseMass;
00313     }
00314     
00315     void applyTorqueImpulse(const btVector3& torque)
00316     {
00317             m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
00318     }
00319     
00320     void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
00321     {
00322         if (m_inverseMass != btScalar(0.))
00323         {
00324             applyCentralImpulse(impulse);
00325             if (m_angularFactor)
00326             {
00327                 applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor));
00328             }
00329         }
00330     }
00331 
00332     void clearForces() 
00333     {
00334         m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00335         m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00336     }
00337     
00338     void updateInertiaTensor();    
00339     
00340     const btVector3&     getCenterOfMassPosition() const { 
00341         return m_worldTransform.getOrigin(); 
00342     }
00343     btQuaternion getOrientation() const;
00344     
00345     const btTransform&  getCenterOfMassTransform() const { 
00346         return m_worldTransform; 
00347     }
00348     const btVector3&   getLinearVelocity() const { 
00349         return m_linearVelocity; 
00350     }
00351     const btVector3&    getAngularVelocity() const { 
00352         return m_angularVelocity; 
00353     }
00354     
00355 
00356     inline void setLinearVelocity(const btVector3& lin_vel)
00357     { 
00358         m_linearVelocity = lin_vel; 
00359     }
00360 
00361     inline void setAngularVelocity(const btVector3& ang_vel) 
00362     { 
00363         m_angularVelocity = ang_vel; 
00364     }
00365 
00366     btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
00367     {
00368         //we also calculate lin/ang velocity for kinematic objects
00369         return m_linearVelocity + m_angularVelocity.cross(rel_pos);
00370 
00371         //for kinematic objects, we could also use use:
00372         //      return  (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
00373     }
00374 
00375     void translate(const btVector3& v) 
00376     {
00377         m_worldTransform.getOrigin() += v; 
00378     }
00379 
00380     
00381     void    getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
00382 
00383 
00384 
00385 
00386     
00387     SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
00388     {
00389         btVector3 r0 = pos - getCenterOfMassPosition();
00390 
00391         btVector3 c0 = (r0).cross(normal);
00392 
00393         btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
00394 
00395         return m_inverseMass + normal.dot(vec);
00396 
00397     }
00398 
00399     SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
00400     {
00401         btVector3 vec = axis * getInvInertiaTensorWorld();
00402         return axis.dot(vec);
00403     }
00404 
00405     SIMD_FORCE_INLINE void  updateDeactivation(btScalar timeStep)
00406     {
00407         if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
00408             return;
00409 
00410         if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
00411             (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
00412         {
00413             m_deactivationTime += timeStep;
00414         } else
00415         {
00416             m_deactivationTime=btScalar(0.);
00417             setActivationState(0);
00418         }
00419 
00420     }
00421 
00422     SIMD_FORCE_INLINE bool  wantsSleeping()
00423     {
00424 
00425         if (getActivationState() == DISABLE_DEACTIVATION)
00426             return false;
00427 
00428         //disable deactivation
00429         if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
00430             return false;
00431 
00432         if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
00433             return true;
00434 
00435         if (m_deactivationTime> gDeactivationTime)
00436         {
00437             return true;
00438         }
00439         return false;
00440     }
00441 
00442 
00443     
00444     const btBroadphaseProxy*    getBroadphaseProxy() const
00445     {
00446         return m_broadphaseHandle;
00447     }
00448     btBroadphaseProxy*  getBroadphaseProxy() 
00449     {
00450         return m_broadphaseHandle;
00451     }
00452     void    setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
00453     {
00454         m_broadphaseHandle = broadphaseProxy;
00455     }
00456 
00457     //btMotionState allows to automatic synchronize the world transform for active objects
00458     btMotionState*  getMotionState()
00459     {
00460         return m_optionalMotionState;
00461     }
00462     const btMotionState*    getMotionState() const
00463     {
00464         return m_optionalMotionState;
00465     }
00466     void    setMotionState(btMotionState* motionState)
00467     {
00468         m_optionalMotionState = motionState;
00469         if (m_optionalMotionState)
00470             motionState->getWorldTransform(m_worldTransform);
00471     }
00472 
00473     //for experimental overriding of friction/contact solver func
00474     int m_contactSolverType;
00475     int m_frictionSolverType;
00476 
00477     void    setAngularFactor(const btVector3& angFac)
00478     {
00479         m_angularFactor = angFac;
00480     }
00481 
00482     void    setAngularFactor(btScalar angFac)
00483     {
00484         m_angularFactor.setValue(angFac,angFac,angFac);
00485     }
00486     const btVector3&    getAngularFactor() const
00487     {
00488         return m_angularFactor;
00489     }
00490 
00491     //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
00492     bool    isInWorld() const
00493     {
00494         return (getBroadphaseProxy() != 0);
00495     }
00496 
00497     virtual bool checkCollideWithOverride(btCollisionObject* co);
00498 
00499     void addConstraintRef(btTypedConstraint* c);
00500     void removeConstraintRef(btTypedConstraint* c);
00501 
00502     btTypedConstraint* getConstraintRef(int index)
00503     {
00504         return m_constraintRefs[index];
00505     }
00506 
00507     int getNumConstraintRefs() const
00508     {
00509         return m_constraintRefs.size();
00510     }
00511 
00512     void    setFlags(int flags)
00513     {
00514         m_rigidbodyFlags = flags;
00515     }
00516 
00517     int getFlags() const
00518     {
00519         return m_rigidbodyFlags;
00520     }
00521 
00522     const btVector3& getDeltaLinearVelocity() const
00523     {
00524         return m_deltaLinearVelocity;
00525     }
00526 
00527     const btVector3& getDeltaAngularVelocity() const
00528     {
00529         return m_deltaAngularVelocity;
00530     }
00531 
00532     const btVector3& getPushVelocity() const 
00533     {
00534         return m_pushVelocity;
00535     }
00536 
00537     const btVector3& getTurnVelocity() const 
00538     {
00539         return m_turnVelocity;
00540     }
00541 
00542 
00545         
00546     btVector3& internalGetDeltaLinearVelocity()
00547     {
00548         return m_deltaLinearVelocity;
00549     }
00550 
00551     btVector3& internalGetDeltaAngularVelocity()
00552     {
00553         return m_deltaAngularVelocity;
00554     }
00555 
00556     const btVector3& internalGetAngularFactor() const
00557     {
00558         return m_angularFactor;
00559     }
00560 
00561     const btVector3& internalGetInvMass() const
00562     {
00563         return m_invMass;
00564     }
00565     
00566     btVector3& internalGetPushVelocity()
00567     {
00568         return m_pushVelocity;
00569     }
00570 
00571     btVector3& internalGetTurnVelocity()
00572     {
00573         return m_turnVelocity;
00574     }
00575 
00576     SIMD_FORCE_INLINE void  internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
00577     {
00578         velocity = getLinearVelocity()+m_deltaLinearVelocity + (getAngularVelocity()+m_deltaAngularVelocity).cross(rel_pos);
00579     }
00580 
00581     SIMD_FORCE_INLINE void  internalGetAngularVelocity(btVector3& angVel) const
00582     {
00583         angVel = getAngularVelocity()+m_deltaAngularVelocity;
00584     }
00585 
00586 
00587     //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
00588     SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
00589     {
00590         if (m_inverseMass)
00591         {
00592             m_deltaLinearVelocity += linearComponent*impulseMagnitude;
00593             m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
00594         }
00595     }
00596 
00597     SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
00598     {
00599         if (m_inverseMass)
00600         {
00601             m_pushVelocity += linearComponent*impulseMagnitude;
00602             m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
00603         }
00604     }
00605     
00606     void    internalWritebackVelocity()
00607     {
00608         if (m_inverseMass)
00609         {
00610             setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity);
00611             setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity);
00612             //m_deltaLinearVelocity.setZero();
00613             //m_deltaAngularVelocity .setZero();
00614             //m_originalBody->setCompanionId(-1);
00615         }
00616     }
00617 
00618 
00619     void    internalWritebackVelocity(btScalar timeStep);
00620 
00621     
00622 
00624 
00625     virtual int calculateSerializeBufferSize()  const;
00626 
00628     virtual const char* serialize(void* dataBuffer,  class btSerializer* serializer) const;
00629 
00630     virtual void serializeSingleObject(class btSerializer* serializer) const;
00631 
00632 };
00633 
00634 //@todo add m_optionalMotionState and m_constraintRefs to btRigidBodyData
00636 struct  btRigidBodyFloatData
00637 {
00638     btCollisionObjectFloatData  m_collisionObjectData;
00639     btMatrix3x3FloatData        m_invInertiaTensorWorld;
00640     btVector3FloatData      m_linearVelocity;
00641     btVector3FloatData      m_angularVelocity;
00642     btVector3FloatData      m_angularFactor;
00643     btVector3FloatData      m_linearFactor;
00644     btVector3FloatData      m_gravity;  
00645     btVector3FloatData      m_gravity_acceleration;
00646     btVector3FloatData      m_invInertiaLocal;
00647     btVector3FloatData      m_totalForce;
00648     btVector3FloatData      m_totalTorque;
00649     float                   m_inverseMass;
00650     float                   m_linearDamping;
00651     float                   m_angularDamping;
00652     float                   m_additionalDampingFactor;
00653     float                   m_additionalLinearDampingThresholdSqr;
00654     float                   m_additionalAngularDampingThresholdSqr;
00655     float                   m_additionalAngularDampingFactor;
00656     float                   m_linearSleepingThreshold;
00657     float                   m_angularSleepingThreshold;
00658     int                     m_additionalDamping;
00659 };
00660 
00662 struct  btRigidBodyDoubleData
00663 {
00664     btCollisionObjectDoubleData m_collisionObjectData;
00665     btMatrix3x3DoubleData       m_invInertiaTensorWorld;
00666     btVector3DoubleData     m_linearVelocity;
00667     btVector3DoubleData     m_angularVelocity;
00668     btVector3DoubleData     m_angularFactor;
00669     btVector3DoubleData     m_linearFactor;
00670     btVector3DoubleData     m_gravity;  
00671     btVector3DoubleData     m_gravity_acceleration;
00672     btVector3DoubleData     m_invInertiaLocal;
00673     btVector3DoubleData     m_totalForce;
00674     btVector3DoubleData     m_totalTorque;
00675     double                  m_inverseMass;
00676     double                  m_linearDamping;
00677     double                  m_angularDamping;
00678     double                  m_additionalDampingFactor;
00679     double                  m_additionalLinearDampingThresholdSqr;
00680     double                  m_additionalAngularDampingThresholdSqr;
00681     double                  m_additionalAngularDampingFactor;
00682     double                  m_linearSleepingThreshold;
00683     double                  m_angularSleepingThreshold;
00684     int                     m_additionalDamping;
00685     char    m_padding[4];
00686 };
00687 
00688 
00689 
00690 #endif
00691