00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "btRigidBody.h"
00017 #include "BulletCollision/CollisionShapes/btConvexShape.h"
00018 #include "LinearMath/btMinMax.h"
00019 #include "LinearMath/btTransformUtil.h"
00020 #include "LinearMath/btMotionState.h"
00021 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
00022
00023
00024 btScalar gDeactivationTime = btScalar(2.);
00025 bool gDisableDeactivation = false;
00026 static int uniqueId = 0;
00027
00028
00029 btRigidBody::btRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo)
00030 {
00031 setupRigidBody(constructionInfo);
00032 }
00033
00034 btRigidBody::btRigidBody(btScalar mass, btMotionState *motionState, btCollisionShape *collisionShape, const btVector3 &localInertia)
00035 {
00036 btRigidBodyConstructionInfo cinfo(mass,motionState,collisionShape,localInertia);
00037 setupRigidBody(cinfo);
00038 }
00039
00040 void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo)
00041 {
00042
00043 m_internalType=CO_RIGID_BODY;
00044
00045 m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00046 m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
00047 m_angularFactor.setValue(1,1,1);
00048 m_linearFactor.setValue(1,1,1);
00049 m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00050 m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00051 m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
00052 m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
00053 m_linearDamping = btScalar(0.);
00054 m_angularDamping = btScalar(0.5);
00055 m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold;
00056 m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold;
00057 m_optionalMotionState = constructionInfo.m_motionState;
00058 m_contactSolverType = 0;
00059 m_frictionSolverType = 0;
00060 m_additionalDamping = constructionInfo.m_additionalDamping;
00061 m_additionalDampingFactor = constructionInfo.m_additionalDampingFactor;
00062 m_additionalLinearDampingThresholdSqr = constructionInfo.m_additionalLinearDampingThresholdSqr;
00063 m_additionalAngularDampingThresholdSqr = constructionInfo.m_additionalAngularDampingThresholdSqr;
00064 m_additionalAngularDampingFactor = constructionInfo.m_additionalAngularDampingFactor;
00065
00066 if (m_optionalMotionState)
00067 {
00068 m_optionalMotionState->getWorldTransform(m_worldTransform);
00069 } else
00070 {
00071 m_worldTransform = constructionInfo.m_startWorldTransform;
00072 }
00073
00074 m_interpolationWorldTransform = m_worldTransform;
00075 m_interpolationLinearVelocity.setValue(0,0,0);
00076 m_interpolationAngularVelocity.setValue(0,0,0);
00077
00078
00079 m_friction = constructionInfo.m_friction;
00080 m_restitution = constructionInfo.m_restitution;
00081
00082 setCollisionShape( constructionInfo.m_collisionShape );
00083 m_debugBodyId = uniqueId++;
00084
00085 setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);
00086 setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
00087 updateInertiaTensor();
00088
00089 m_rigidbodyFlags = 0;
00090
00091
00092 m_deltaLinearVelocity.setZero();
00093 m_deltaAngularVelocity.setZero();
00094 m_invMass = m_inverseMass*m_linearFactor;
00095 m_pushVelocity.setZero();
00096 m_turnVelocity.setZero();
00097
00098
00099
00100 }
00101
00102
00103 void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform)
00104 {
00105 btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform);
00106 }
00107
00108 void btRigidBody::saveKinematicState(btScalar timeStep)
00109 {
00110
00111 if (timeStep != btScalar(0.))
00112 {
00113
00114 if (getMotionState())
00115 getMotionState()->getWorldTransform(m_worldTransform);
00116 btVector3 linVel,angVel;
00117
00118 btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity);
00119 m_interpolationLinearVelocity = m_linearVelocity;
00120 m_interpolationAngularVelocity = m_angularVelocity;
00121 m_interpolationWorldTransform = m_worldTransform;
00122
00123 }
00124 }
00125
00126 void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const
00127 {
00128 getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax);
00129 }
00130
00131
00132
00133
00134 void btRigidBody::setGravity(const btVector3& acceleration)
00135 {
00136 if (m_inverseMass != btScalar(0.0))
00137 {
00138 m_gravity = acceleration * (btScalar(1.0) / m_inverseMass);
00139 }
00140 m_gravity_acceleration = acceleration;
00141 }
00142
00143
00144
00145
00146
00147
00148 void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
00149 {
00150 m_linearDamping = GEN_clamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
00151 m_angularDamping = GEN_clamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
00152 }
00153
00154
00155
00156
00158 void btRigidBody::applyDamping(btScalar timeStep)
00159 {
00160
00161
00162
00163
00164 #ifdef USE_OLD_DAMPING_METHOD
00165 m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
00166 m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
00167 #else
00168 m_linearVelocity *= btPow(btScalar(1)-m_linearDamping, timeStep);
00169 m_angularVelocity *= btPow(btScalar(1)-m_angularDamping, timeStep);
00170 #endif
00171
00172 if (m_additionalDamping)
00173 {
00174
00175
00176 if ((m_angularVelocity.length2() < m_additionalAngularDampingThresholdSqr) &&
00177 (m_linearVelocity.length2() < m_additionalLinearDampingThresholdSqr))
00178 {
00179 m_angularVelocity *= m_additionalDampingFactor;
00180 m_linearVelocity *= m_additionalDampingFactor;
00181 }
00182
00183
00184 btScalar speed = m_linearVelocity.length();
00185 if (speed < m_linearDamping)
00186 {
00187 btScalar dampVel = btScalar(0.005);
00188 if (speed > dampVel)
00189 {
00190 btVector3 dir = m_linearVelocity.normalized();
00191 m_linearVelocity -= dir * dampVel;
00192 } else
00193 {
00194 m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
00195 }
00196 }
00197
00198 btScalar angSpeed = m_angularVelocity.length();
00199 if (angSpeed < m_angularDamping)
00200 {
00201 btScalar angDampVel = btScalar(0.005);
00202 if (angSpeed > angDampVel)
00203 {
00204 btVector3 dir = m_angularVelocity.normalized();
00205 m_angularVelocity -= dir * angDampVel;
00206 } else
00207 {
00208 m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
00209 }
00210 }
00211 }
00212 }
00213
00214
00215 void btRigidBody::applyGravity()
00216 {
00217 if (isStaticOrKinematicObject())
00218 return;
00219
00220 applyCentralForce(m_gravity);
00221
00222 }
00223
00224 void btRigidBody::proceedToTransform(const btTransform& newTrans)
00225 {
00226 setCenterOfMassTransform( newTrans );
00227 }
00228
00229
00230 void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
00231 {
00232 if (mass == btScalar(0.))
00233 {
00234 m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
00235 m_inverseMass = btScalar(0.);
00236 } else
00237 {
00238 m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT);
00239 m_inverseMass = btScalar(1.0) / mass;
00240 }
00241
00242 m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0),
00243 inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0),
00244 inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0));
00245
00246 m_invMass = m_linearFactor*m_inverseMass;
00247 }
00248
00249
00250
00251 void btRigidBody::updateInertiaTensor()
00252 {
00253 m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose();
00254 }
00255
00256
00257 void btRigidBody::integrateVelocities(btScalar step)
00258 {
00259 if (isStaticOrKinematicObject())
00260 return;
00261
00262 m_linearVelocity += m_totalForce * (m_inverseMass * step);
00263 m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step;
00264
00265 #define MAX_ANGVEL SIMD_HALF_PI
00267 btScalar angvel = m_angularVelocity.length();
00268 if (angvel*step > MAX_ANGVEL)
00269 {
00270 m_angularVelocity *= (MAX_ANGVEL/step) /angvel;
00271 }
00272
00273 }
00274
00275 btQuaternion btRigidBody::getOrientation() const
00276 {
00277 btQuaternion orn;
00278 m_worldTransform.getBasis().getRotation(orn);
00279 return orn;
00280 }
00281
00282
00283 void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
00284 {
00285
00286 if (isStaticOrKinematicObject())
00287 {
00288 m_interpolationWorldTransform = m_worldTransform;
00289 } else
00290 {
00291 m_interpolationWorldTransform = xform;
00292 }
00293 m_interpolationLinearVelocity = getLinearVelocity();
00294 m_interpolationAngularVelocity = getAngularVelocity();
00295 m_worldTransform = xform;
00296 updateInertiaTensor();
00297 }
00298
00299
00300 bool btRigidBody::checkCollideWithOverride(btCollisionObject* co)
00301 {
00302 btRigidBody* otherRb = btRigidBody::upcast(co);
00303 if (!otherRb)
00304 return true;
00305
00306 for (int i = 0; i < m_constraintRefs.size(); ++i)
00307 {
00308 btTypedConstraint* c = m_constraintRefs[i];
00309 if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
00310 return false;
00311 }
00312
00313 return true;
00314 }
00315
00316 void btRigidBody::internalWritebackVelocity(btScalar timeStep)
00317 {
00318 (void) timeStep;
00319 if (m_inverseMass)
00320 {
00321 setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity);
00322 setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity);
00323
00324
00325 btTransform newTransform;
00326 btTransformUtil::integrateTransform(getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform);
00327 setWorldTransform(newTransform);
00328
00329 }
00330 m_deltaLinearVelocity.setZero();
00331 m_deltaAngularVelocity .setZero();
00332 m_pushVelocity.setZero();
00333 m_turnVelocity.setZero();
00334 }
00335
00336
00337
00338 void btRigidBody::addConstraintRef(btTypedConstraint* c)
00339 {
00340 int index = m_constraintRefs.findLinearSearch(c);
00341 if (index == m_constraintRefs.size())
00342 m_constraintRefs.push_back(c);
00343
00344 m_checkCollideWith = true;
00345 }
00346
00347 void btRigidBody::removeConstraintRef(btTypedConstraint* c)
00348 {
00349 m_constraintRefs.remove(c);
00350 m_checkCollideWith = m_constraintRefs.size() > 0;
00351 }
00352
00353 int btRigidBody::calculateSerializeBufferSize() const
00354 {
00355 int sz = sizeof(btRigidBodyData);
00356 return sz;
00357 }
00358
00360 const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const
00361 {
00362 btRigidBodyData* rbd = (btRigidBodyData*) dataBuffer;
00363
00364 btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer);
00365
00366 m_invInertiaTensorWorld.serialize(rbd->m_invInertiaTensorWorld);
00367 m_linearVelocity.serialize(rbd->m_linearVelocity);
00368 m_angularVelocity.serialize(rbd->m_angularVelocity);
00369 rbd->m_inverseMass = m_inverseMass;
00370 m_angularFactor.serialize(rbd->m_angularFactor);
00371 m_linearFactor.serialize(rbd->m_linearFactor);
00372 m_gravity.serialize(rbd->m_gravity);
00373 m_gravity_acceleration.serialize(rbd->m_gravity_acceleration);
00374 m_invInertiaLocal.serialize(rbd->m_invInertiaLocal);
00375 m_totalForce.serialize(rbd->m_totalForce);
00376 m_totalTorque.serialize(rbd->m_totalTorque);
00377 rbd->m_linearDamping = m_linearDamping;
00378 rbd->m_angularDamping = m_angularDamping;
00379 rbd->m_additionalDamping = m_additionalDamping;
00380 rbd->m_additionalDampingFactor = m_additionalDampingFactor;
00381 rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr;
00382 rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr;
00383 rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor;
00384 rbd->m_linearSleepingThreshold=m_linearSleepingThreshold;
00385 rbd->m_angularSleepingThreshold = m_angularSleepingThreshold;
00386
00387 return btRigidBodyDataName;
00388 }
00389
00390