Blender V2.61 - r43446
|
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