Bullet Collision Detection & Physics Library
btRigidBody.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include "btRigidBody.h"
18#include "LinearMath/btMinMax.h"
23
24//'temporarily' global variables
27static int uniqueId = 0;
28
30{
32}
33
35{
38}
39
41{
43
47 m_linearFactor.setValue(1, 1, 1);
52 setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
53
54 m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold;
55 m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold;
59 m_additionalDamping = constructionInfo.m_additionalDamping;
60 m_additionalDampingFactor = constructionInfo.m_additionalDampingFactor;
61 m_additionalLinearDampingThresholdSqr = constructionInfo.m_additionalLinearDampingThresholdSqr;
62 m_additionalAngularDampingThresholdSqr = constructionInfo.m_additionalAngularDampingThresholdSqr;
63 m_additionalAngularDampingFactor = constructionInfo.m_additionalAngularDampingFactor;
64
66 {
68 }
69 else
70 {
71 m_worldTransform = constructionInfo.m_startWorldTransform;
72 }
73
77
78 //moved to btCollisionObject
79 m_friction = constructionInfo.m_friction;
80 m_rollingFriction = constructionInfo.m_rollingFriction;
81 m_spinningFriction = constructionInfo.m_spinningFriction;
82
83 m_restitution = constructionInfo.m_restitution;
84
85 setCollisionShape(constructionInfo.m_collisionShape);
87
88 setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);
90
92
98}
99
101{
103}
104
106{
107 //todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities
108 if (timeStep != btScalar(0.))
109 {
110 //if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform
111 if (getMotionState())
114
119 //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ());
120 }
121}
122
124{
126}
127
129{
130 if (m_inverseMass != btScalar(0.0))
131 {
133 }
135}
136
138{
139#ifdef BT_USE_OLD_DAMPING_METHOD
142#else
145#endif
146}
147
150{
151 //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
152 //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
153
154#ifdef BT_USE_OLD_DAMPING_METHOD
155 m_linearVelocity *= btMax((btScalar(1.0) - timeStep * m_linearDamping), btScalar(0.0));
156 m_angularVelocity *= btMax((btScalar(1.0) - timeStep * m_angularDamping), btScalar(0.0));
157#else
160#endif
161
163 {
164 //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
165 //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
168 {
171 }
172
175 {
176 btScalar dampVel = btScalar(0.005);
177 if (speed > dampVel)
178 {
181 }
182 else
183 {
185 }
186 }
187
190 {
192 if (angSpeed > angDampVel)
193 {
196 }
197 else
198 {
200 }
201 }
202 }
203}
204
206{
208 return;
209
211}
212
214{
216 return;
217
219}
220
222{
224}
225
227{
228 if (mass == btScalar(0.))
229 {
232 }
233 else
234 {
236 m_inverseMass = btScalar(1.0) / mass;
237 }
238
239 //Fg = m * a
241
242 m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x() : btScalar(0.0),
243 inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0),
244 inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0));
245
247}
248
250{
252}
253
255{
258 inertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x() : btScalar(0.0),
259 inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0),
260 inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0));
261 return inertiaLocal;
262}
263
264inline btVector3 evalEulerEqn(const btVector3& w1, const btVector3& w0, const btVector3& T, const btScalar dt,
265 const btMatrix3x3& I)
266{
267 const btVector3 w2 = I * w1 + w1.cross(I * w1) * dt - (T * dt + I * w0);
268 return w2;
269}
270
272 const btMatrix3x3& I)
273{
275 const btVector3 Iwi = (I * w1);
276 w1.getSkewSymmetricMatrix(&w1x[0], &w1x[1], &w1x[2]);
277 Iwi.getSkewSymmetricMatrix(&Iw1x[0], &Iw1x[1], &Iw1x[2]);
278
279 const btMatrix3x3 dfw1 = I + (w1x * I - Iw1x) * dt;
280 return dfw1;
281}
282
284{
289 btScalar l2 = gf.length2();
291 {
293 }
294 return gf;
295}
296
298{
302
303 // Convert to body coordinates
304 btVector3 omegab = quatRotate(q.inverse(), omega1);
306 Ib.setValue(idl.x(), 0, 0,
307 0, idl.y(), 0,
308 0, 0, idl.z());
309
311
312 // Residual vector
314
316 omegab.getSkewSymmetricMatrix(&skew0[0], &skew0[1], &skew0[2]);
317 btVector3 om = Ib * omegab;
319 om.getSkewSymmetricMatrix(&skew1[0], &skew1[1], &skew1[2]);
320
321 // Jacobian
322 btMatrix3x3 J = Ib + (skew0 * Ib - skew1) * step;
323
324 // btMatrix3x3 Jinv = J.inverse();
325 // btVector3 omega_div = Jinv*f;
326 btVector3 omega_div = J.solve33(f);
327
328 // Single Newton-Raphson update
329 omegab = omegab - omega_div; //Solve33(J, f);
330 // Back to world coordinates
333 return gf;
334}
335
337{
338 // use full newton-euler equations. common practice to drop the wxIw term. want it for better tumbling behavior.
339 // calculate using implicit euler step so it's stable.
340
343
345
348
349 // use newtons method to find implicit solution for new angular velocity (w')
350 // f(w') = -(T*step + Iw) + Iw' + w' + w'xIw'*step = 0
351 // df/dw' = I + 1xIw'*step + w'xI*step
352
353 btVector3 w1 = w0;
354
355 // one step of newton's method
356 {
357 const btVector3 fw = evalEulerEqn(w1, w0, btVector3(0, 0, 0), step, I);
359
361 dw = dfw.solve33(fw);
362 //const btMatrix3x3 dfw_inv = dfw.inverse();
363 //dw = dfw_inv*fw;
364
365 w1 -= dw;
366 }
367
368 btVector3 gf = (w1 - w0);
369 return gf;
370}
371
373{
375 return;
376
379
380#define MAX_ANGVEL SIMD_HALF_PI
383 if (angvel * step > MAX_ANGVEL)
384 {
386 }
387 #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
389 #endif
390}
391
393{
396 return orn;
397}
398
400{
401 if (isKinematicObject())
402 {
404 }
405 else
406 {
408 }
411 m_worldTransform = xform;
413}
414
416{
418
419 int index = m_constraintRefs.findLinearSearch(c);
420 //don't add constraints that are already referenced
421 //btAssert(index == m_constraintRefs.size());
422 if (index == m_constraintRefs.size())
423 {
427 if (colObjA == this)
428 {
430 }
431 else
432 {
433 colObjB->setIgnoreCollisionCheck(colObjA, true);
434 }
435 }
436}
437
439{
440 int index = m_constraintRefs.findLinearSearch(c);
441 //don't remove constraints that are not referenced
442 if (index < m_constraintRefs.size())
443 {
447 if (colObjA == this)
448 {
450 }
451 else
452 {
453 colObjB->setIgnoreCollisionCheck(colObjA, false);
454 }
455 }
456}
457
459{
460 int sz = sizeof(btRigidBodyData);
461 return sz;
462}
463
466{
468
469 btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer);
470
471 m_invInertiaTensorWorld.serialize(rbd->m_invInertiaTensorWorld);
472 m_linearVelocity.serialize(rbd->m_linearVelocity);
473 m_angularVelocity.serialize(rbd->m_angularVelocity);
474 rbd->m_inverseMass = m_inverseMass;
475 m_angularFactor.serialize(rbd->m_angularFactor);
476 m_linearFactor.serialize(rbd->m_linearFactor);
477 m_gravity.serialize(rbd->m_gravity);
478 m_gravity_acceleration.serialize(rbd->m_gravity_acceleration);
479 m_invInertiaLocal.serialize(rbd->m_invInertiaLocal);
480 m_totalForce.serialize(rbd->m_totalForce);
481 m_totalTorque.serialize(rbd->m_totalTorque);
482 rbd->m_linearDamping = m_linearDamping;
483 rbd->m_angularDamping = m_angularDamping;
484 rbd->m_additionalDamping = m_additionalDamping;
485 rbd->m_additionalDampingFactor = m_additionalDampingFactor;
486 rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr;
487 rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr;
488 rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor;
489 rbd->m_linearSleepingThreshold = m_linearSleepingThreshold;
490 rbd->m_angularSleepingThreshold = m_angularSleepingThreshold;
491
492 // Fill padding with zeros to appease msan.
493#ifdef BT_USE_DOUBLE_PRECISION
494 memset(rbd->m_padding, 0, sizeof(rbd->m_padding));
495#endif
496
497 return btRigidBodyDataName;
498}
499
501{
503 const char* structType = serialize(chunk->m_oldPtr, serializer);
504 serializer->finalizeChunk(chunk, structType, BT_RIGIDBODY_CODE, (void*)this);
505}
const T & btClamped(const T &a, const T &lb, const T &ub)
Definition btMinMax.h:33
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
bool gDisableDeactivation
#define MAX_ANGVEL
btVector3 evalEulerEqn(const btVector3 &w1, const btVector3 &w0, const btVector3 &T, const btScalar dt, const btMatrix3x3 &I)
btScalar gDeactivationTime
static int uniqueId
btMatrix3x3 evalEulerEqnDeriv(const btVector3 &w1, const btVector3 &w0, const btScalar dt, const btMatrix3x3 &I)
#define btRigidBodyDataName
Definition btRigidBody.h:36
#define btRigidBodyData
Definition btRigidBody.h:35
@ BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY
Definition btRigidBody.h:47
btScalar btPow(btScalar x, btScalar y)
Definition btScalar.h:521
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
btScalar btSqrt(btScalar y)
Definition btScalar.h:466
#define BT_RIGIDBODY_CODE
int size() const
return the number of elements in the array
int findLinearSearch(const T &key) const
void remove(const T &key)
void push_back(const T &_Val)
btCollisionObject can be used to manage collision detection objects.
bool isStaticOrKinematicObject() const
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTransform & getWorldTransform()
btTransform m_worldTransform
virtual void setCollisionShape(btCollisionShape *collisionShape)
btVector3 m_interpolationLinearVelocity
void setIgnoreCollisionCheck(const btCollisionObject *co, bool ignoreCollisionCheck)
btVector3 m_interpolationAngularVelocity
int m_internalType
m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody,...
btTransform m_interpolationWorldTransform
m_interpolationWorldTransform is used for CCD and interpolation it can be either previous or future (...
bool isKinematicObject() const
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
virtual void getAabb(const btTransform &t, btVector3 &aabbMin, btVector3 &aabbMax) const =0
getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition btMatrix3x3.h:50
btMatrix3x3 transpose() const
Return the transpose of the matrix.
void getRotation(btQuaternion &q) const
Get the matrix represented as a quaternion.
btMatrix3x3 scaled(const btVector3 &s) const
Create a scaled copy of the matrix.
void serialize(struct btMatrix3x3Data &dataOut) const
void setValue(const btScalar &xx, const btScalar &xy, const btScalar &xz, const btScalar &yx, const btScalar &yy, const btScalar &yz, const btScalar &zx, const btScalar &zy, const btScalar &zz)
Set the values of the matrix explicitly (row major)
The btMotionState interface class allows the dynamics world to synchronize and interpolate the update...
virtual void getWorldTransform(btTransform &worldTrans) const =0
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
void getAabb(btVector3 &aabbMin, btVector3 &aabbMax) const
btScalar m_additionalAngularDampingFactor
Definition btRigidBody.h:80
void applyGravity()
void integrateVelocities(btScalar step)
void addConstraintRef(btTypedConstraint *c)
virtual void serializeSingleObject(class btSerializer *serializer) const
btScalar m_linearDamping
Definition btRigidBody.h:73
btMatrix3x3 m_invInertiaTensorWorld
Definition btRigidBody.h:61
int m_frictionSolverType
btVector3 m_invInertiaLocal
Definition btRigidBody.h:69
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
btMotionState * m_optionalMotionState
Definition btRigidBody.h:86
btVector3 m_gravity
Definition btRigidBody.h:67
int m_contactSolverType
void applyCentralForce(const btVector3 &force)
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btVector3 m_turnVelocity
btScalar m_additionalDampingFactor
Definition btRigidBody.h:77
virtual int calculateSerializeBufferSize() const
int m_rigidbodyFlags
Definition btRigidBody.h:91
btScalar m_additionalAngularDampingThresholdSqr
Definition btRigidBody.h:79
void setGravity(const btVector3 &acceleration)
btRigidBody(const btRigidBodyConstructionInfo &constructionInfo)
btRigidBody constructor using construction info
btScalar m_linearSleepingThreshold
Definition btRigidBody.h:82
btQuaternion getOrientation() const
void proceedToTransform(const btTransform &newTrans)
const btCollisionShape * getCollisionShape() const
btVector3 m_linearFactor
Definition btRigidBody.h:65
void saveKinematicState(btScalar step)
btVector3 getLocalInertia() const
btVector3 computeGyroscopicImpulseImplicit_World(btScalar dt) const
perform implicit force computation in world space
btVector3 m_angularFactor
Definition btRigidBody.h:98
btVector3 m_totalForce
Definition btRigidBody.h:70
btScalar m_inverseMass
Definition btRigidBody.h:64
btVector3 computeGyroscopicImpulseImplicit_Body(btScalar step) const
perform implicit force computation in body space (inertial frame)
btVector3 m_totalTorque
Definition btRigidBody.h:71
const btVector3 & getAngularVelocity() const
btMotionState * getMotionState()
btScalar m_angularDamping
Definition btRigidBody.h:74
void removeConstraintRef(btTypedConstraint *c)
void setMassProps(btScalar mass, const btVector3 &inertia)
btVector3 m_deltaAngularVelocity
Definition btRigidBody.h:97
btVector3 m_pushVelocity
bool m_additionalDamping
Definition btRigidBody.h:76
int m_debugBodyId
Definition btRigidBody.h:93
btScalar m_angularSleepingThreshold
Definition btRigidBody.h:83
void clearGravity()
btScalar m_additionalLinearDampingThresholdSqr
Definition btRigidBody.h:78
btVector3 m_linearVelocity
Definition btRigidBody.h:62
void setDamping(btScalar lin_damping, btScalar ang_damping)
btVector3 m_deltaLinearVelocity
Definition btRigidBody.h:96
btVector3 m_angularVelocity
Definition btRigidBody.h:63
void setupRigidBody(const btRigidBodyConstructionInfo &constructionInfo)
setupRigidBody is only used internally by the constructor
void setCenterOfMassTransform(const btTransform &xform)
btAlignedObjectArray< btTypedConstraint * > m_constraintRefs
Definition btRigidBody.h:89
void updateInertiaTensor()
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
btVector3 computeGyroscopicForceExplicit(btScalar maxGyroscopicForce) const
explicit version is best avoided, it gains energy
btVector3 m_invMass
Definition btRigidBody.h:99
const btVector3 & getLinearVelocity() const
btVector3 m_gravity_acceleration
Definition btRigidBody.h:68
static void integrateTransform(const btTransform &curTrans, const btVector3 &linvel, const btVector3 &angvel, btScalar timeStep, btTransform &predictedTransform)
static void calculateVelocity(const btTransform &transform0, const btTransform &transform1, btScalar timeStep, btVector3 &linVel, btVector3 &angVel)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:30
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
btQuaternion getRotation() const
Return a quaternion representing the rotation.
TypedConstraint is the baseclass for Bullet constraints and vehicles.
const btRigidBody & getRigidBodyA() const
const btRigidBody & getRigidBodyB() const
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition btVector3.h:380
void getSkewSymmetricMatrix(btVector3 *v0, btVector3 *v1, btVector3 *v2) const
Definition btVector3.h:648
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:640
btVector3 normalized() const
Return a normalized version of this vector.
Definition btVector3.h:949
btScalar length2() const
Return the length of the vector squared.
Definition btVector3.h:251
void setZero()
Definition btVector3.h:671
void serialize(struct btVector3Data &dataOut) const
Definition btVector3.h:1317
The btRigidBodyConstructionInfo structure provides information to create a rigid body.