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 http://continuousphysics.com/Bullet/
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
29
31{
32 setupRigidBody(constructionInfo);
33}
34
35btRigidBody::btRigidBody(btScalar mass, btMotionState *motionState, btCollisionShape *collisionShape, const btVector3 &localInertia)
36{
37 btRigidBodyConstructionInfo cinfo(mass,motionState,collisionShape,localInertia);
38 setupRigidBody(cinfo);
39}
40
42{
43
45
46 m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
47 m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
48 m_angularFactor.setValue(1,1,1);
49 m_linearFactor.setValue(1,1,1);
50 m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
51 m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
52 m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
53 m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
54 setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
55
58 m_optionalMotionState = constructionInfo.m_motionState;
66
68 {
69 m_optionalMotionState->getWorldTransform(m_worldTransform);
70 } else
71 {
72 m_worldTransform = constructionInfo.m_startWorldTransform;
73 }
74
76 m_interpolationLinearVelocity.setValue(0,0,0);
77 m_interpolationAngularVelocity.setValue(0,0,0);
78
79 //moved to btCollisionObject
80 m_friction = constructionInfo.m_friction;
81 m_rollingFriction = constructionInfo.m_rollingFriction;
82 m_spinningFriction = constructionInfo.m_spinningFriction;
83
84 m_restitution = constructionInfo.m_restitution;
85
86 setCollisionShape( constructionInfo.m_collisionShape );
88
89 setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);
91
93
94
95 m_deltaLinearVelocity.setZero();
96 m_deltaAngularVelocity.setZero();
98 m_pushVelocity.setZero();
99 m_turnVelocity.setZero();
100
101
102
103}
104
105
110
112{
113 //todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities
114 if (timeStep != btScalar(0.))
115 {
116 //if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform
117 if (getMotionState())
119 btVector3 linVel,angVel;
120
125 //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ());
126 }
127}
128
129void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const
130{
131 getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax);
132}
133
134
135
136
137void btRigidBody::setGravity(const btVector3& acceleration)
138{
139 if (m_inverseMass != btScalar(0.0))
140 {
141 m_gravity = acceleration * (btScalar(1.0) / m_inverseMass);
142 }
143 m_gravity_acceleration = acceleration;
144}
145
146
147
148
149
150
151void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
152{
153 m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
154 m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
155}
156
157
158
159
162{
163 //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
164 //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
165
166//#define USE_OLD_DAMPING_METHOD 1
167#ifdef USE_OLD_DAMPING_METHOD
168 m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
169 m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
170#else
173#endif
174
176 {
177 //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
178 //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
181 {
184 }
185
186
187 btScalar speed = m_linearVelocity.length();
188 if (speed < m_linearDamping)
189 {
190 btScalar dampVel = btScalar(0.005);
191 if (speed > dampVel)
192 {
193 btVector3 dir = m_linearVelocity.normalized();
194 m_linearVelocity -= dir * dampVel;
195 } else
196 {
197 m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
198 }
199 }
200
201 btScalar angSpeed = m_angularVelocity.length();
202 if (angSpeed < m_angularDamping)
203 {
204 btScalar angDampVel = btScalar(0.005);
205 if (angSpeed > angDampVel)
206 {
207 btVector3 dir = m_angularVelocity.normalized();
208 m_angularVelocity -= dir * angDampVel;
209 } else
210 {
211 m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
212 }
213 }
214 }
215}
216
217
219{
221 return;
222
224
225}
226
228{
229 setCenterOfMassTransform( newTrans );
230}
231
232
234{
235 if (mass == btScalar(0.))
236 {
239 } else
240 {
242 m_inverseMass = btScalar(1.0) / mass;
243 }
244
245 //Fg = m * a
247
248 m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0),
249 inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0),
250 inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0));
251
253}
254
255
257{
258 m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose();
259}
260
261
262
264{
265
266 btVector3 inertiaLocal;
267 const btVector3 inertia = m_invInertiaLocal;
268 inertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x() : btScalar(0.0),
269 inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0),
270 inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0));
271 return inertiaLocal;
272}
273
274inline btVector3 evalEulerEqn(const btVector3& w1, const btVector3& w0, const btVector3& T, const btScalar dt,
275 const btMatrix3x3 &I)
276{
277 const btVector3 w2 = I*w1 + w1.cross(I*w1)*dt - (T*dt + I*w0);
278 return w2;
279}
280
281inline btMatrix3x3 evalEulerEqnDeriv(const btVector3& w1, const btVector3& w0, const btScalar dt,
282 const btMatrix3x3 &I)
283{
284
285 btMatrix3x3 w1x, Iw1x;
286 const btVector3 Iwi = (I*w1);
287 w1.getSkewSymmetricMatrix(&w1x[0], &w1x[1], &w1x[2]);
288 Iwi.getSkewSymmetricMatrix(&Iw1x[0], &Iw1x[1], &Iw1x[2]);
289
290 const btMatrix3x3 dfw1 = I + (w1x*I - Iw1x)*dt;
291 return dfw1;
292}
293
295{
296 btVector3 inertiaLocal = getLocalInertia();
297 btMatrix3x3 inertiaTensorWorld = getWorldTransform().getBasis().scaled(inertiaLocal) * getWorldTransform().getBasis().transpose();
298 btVector3 tmp = inertiaTensorWorld*getAngularVelocity();
300 btScalar l2 = gf.length2();
301 if (l2>maxGyroscopicForce*maxGyroscopicForce)
302 {
303 gf *= btScalar(1.)/btSqrt(l2)*maxGyroscopicForce;
304 }
305 return gf;
306}
307
308
310{
312 btVector3 omega1 = getAngularVelocity();
314
315 // Convert to body coordinates
316 btVector3 omegab = quatRotate(q.inverse(), omega1);
317 btMatrix3x3 Ib;
318 Ib.setValue(idl.x(),0,0,
319 0,idl.y(),0,
320 0,0,idl.z());
321
322 btVector3 ibo = Ib*omegab;
323
324 // Residual vector
325 btVector3 f = step * omegab.cross(ibo);
326
327 btMatrix3x3 skew0;
328 omegab.getSkewSymmetricMatrix(&skew0[0], &skew0[1], &skew0[2]);
329 btVector3 om = Ib*omegab;
330 btMatrix3x3 skew1;
331 om.getSkewSymmetricMatrix(&skew1[0],&skew1[1],&skew1[2]);
332
333 // Jacobian
334 btMatrix3x3 J = Ib + (skew0*Ib - skew1)*step;
335
336// btMatrix3x3 Jinv = J.inverse();
337// btVector3 omega_div = Jinv*f;
338 btVector3 omega_div = J.solve33(f);
339
340 // Single Newton-Raphson update
341 omegab = omegab - omega_div;//Solve33(J, f);
342 // Back to world coordinates
343 btVector3 omega2 = quatRotate(q,omegab);
344 btVector3 gf = omega2-omega1;
345 return gf;
346}
347
348
349
351{
352 // use full newton-euler equations. common practice to drop the wxIw term. want it for better tumbling behavior.
353 // calculate using implicit euler step so it's stable.
354
355 const btVector3 inertiaLocal = getLocalInertia();
356 const btVector3 w0 = getAngularVelocity();
357
358 btMatrix3x3 I;
359
360 I = m_worldTransform.getBasis().scaled(inertiaLocal) *
361 m_worldTransform.getBasis().transpose();
362
363 // use newtons method to find implicit solution for new angular velocity (w')
364 // f(w') = -(T*step + Iw) + Iw' + w' + w'xIw'*step = 0
365 // df/dw' = I + 1xIw'*step + w'xI*step
366
367 btVector3 w1 = w0;
368
369 // one step of newton's method
370 {
371 const btVector3 fw = evalEulerEqn(w1, w0, btVector3(0, 0, 0), step, I);
372 const btMatrix3x3 dfw = evalEulerEqnDeriv(w1, w0, step, I);
373
374 btVector3 dw;
375 dw = dfw.solve33(fw);
376 //const btMatrix3x3 dfw_inv = dfw.inverse();
377 //dw = dfw_inv*fw;
378
379 w1 -= dw;
380 }
381
382 btVector3 gf = (w1 - w0);
383 return gf;
384}
385
386
388{
390 return;
391
394
395#define MAX_ANGVEL SIMD_HALF_PI
397 btScalar angvel = m_angularVelocity.length();
398 if (angvel*step > MAX_ANGVEL)
399 {
400 m_angularVelocity *= (MAX_ANGVEL/step) /angvel;
401 }
402
403}
404
406{
407 btQuaternion orn;
408 m_worldTransform.getBasis().getRotation(orn);
409 return orn;
410}
411
412
428
429
430
431
432
434{
436
437 int index = m_constraintRefs.findLinearSearch(c);
438 //don't add constraints that are already referenced
439 //btAssert(index == m_constraintRefs.size());
440 if (index == m_constraintRefs.size())
441 {
442 m_constraintRefs.push_back(c);
443 btCollisionObject* colObjA = &c->getRigidBodyA();
444 btCollisionObject* colObjB = &c->getRigidBodyB();
445 if (colObjA == this)
446 {
447 colObjA->setIgnoreCollisionCheck(colObjB, true);
448 }
449 else
450 {
451 colObjB->setIgnoreCollisionCheck(colObjA, true);
452 }
453 }
454}
455
457{
458 int index = m_constraintRefs.findLinearSearch(c);
459 //don't remove constraints that are not referenced
460 if(index < m_constraintRefs.size())
461 {
462 m_constraintRefs.remove(c);
463 btCollisionObject* colObjA = &c->getRigidBodyA();
464 btCollisionObject* colObjB = &c->getRigidBodyB();
465 if (colObjA == this)
466 {
467 colObjA->setIgnoreCollisionCheck(colObjB, false);
468 }
469 else
470 {
471 colObjB->setIgnoreCollisionCheck(colObjA, false);
472 }
473 }
474}
475
477{
478 int sz = sizeof(btRigidBodyData);
479 return sz;
480}
481
483const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const
484{
485 btRigidBodyData* rbd = (btRigidBodyData*) dataBuffer;
486
487 btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer);
488
489 m_invInertiaTensorWorld.serialize(rbd->m_invInertiaTensorWorld);
490 m_linearVelocity.serialize(rbd->m_linearVelocity);
491 m_angularVelocity.serialize(rbd->m_angularVelocity);
492 rbd->m_inverseMass = m_inverseMass;
493 m_angularFactor.serialize(rbd->m_angularFactor);
494 m_linearFactor.serialize(rbd->m_linearFactor);
495 m_gravity.serialize(rbd->m_gravity);
496 m_gravity_acceleration.serialize(rbd->m_gravity_acceleration);
497 m_invInertiaLocal.serialize(rbd->m_invInertiaLocal);
498 m_totalForce.serialize(rbd->m_totalForce);
499 m_totalTorque.serialize(rbd->m_totalTorque);
500 rbd->m_linearDamping = m_linearDamping;
501 rbd->m_angularDamping = m_angularDamping;
502 rbd->m_additionalDamping = m_additionalDamping;
503 rbd->m_additionalDampingFactor = m_additionalDampingFactor;
504 rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr;
505 rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr;
506 rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor;
507 rbd->m_linearSleepingThreshold=m_linearSleepingThreshold;
508 rbd->m_angularSleepingThreshold = m_angularSleepingThreshold;
509
510 // Fill padding with zeros to appease msan.
511#ifdef BT_USE_DOUBLE_PRECISION
512 memset(rbd->m_padding, 0, sizeof(rbd->m_padding));
513#endif
514
515 return btRigidBodyDataName;
516}
517
518
519
521{
522 btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(),1);
523 const char* structType = serialize(chunk->m_oldPtr, serializer);
524 serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,(void*)this);
525}
526
527
const T & btClamped(const T &a, const T &lb, const T &ub)
Definition btMinMax.h:35
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:37
#define btRigidBodyData
Definition btRigidBody.h:36
@ BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY
Definition btRigidBody.h:49
btScalar btPow(btScalar x, btScalar y)
Definition btScalar.h:499
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:292
btScalar btSqrt(btScalar y)
Definition btScalar.h:444
#define BT_RIGIDBODY_CODE
void * m_oldPtr
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:48
btVector3 solve33(const btVector3 &b) const
Solve A * x = b, where b is a column vector.
btMatrix3x3 transpose() const
Return the transpose of the matrix.
btMatrix3x3 scaled(const btVector3 &s) const
Create a scaled copy of the matrix.
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...
btQuaternion inverse() const
Return the inverse of this quaternion.
void getAabb(btVector3 &aabbMin, btVector3 &aabbMax) const
btScalar m_additionalAngularDampingFactor
Definition btRigidBody.h:84
void applyGravity()
void integrateVelocities(btScalar step)
void addConstraintRef(btTypedConstraint *c)
virtual void serializeSingleObject(class btSerializer *serializer) const
btScalar m_linearDamping
Definition btRigidBody.h:77
btMatrix3x3 m_invInertiaTensorWorld
Definition btRigidBody.h:65
int m_frictionSolverType
btVector3 m_invInertiaLocal
Definition btRigidBody.h:73
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
btMotionState * m_optionalMotionState
Definition btRigidBody.h:91
btVector3 m_gravity
Definition btRigidBody.h:71
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:81
virtual int calculateSerializeBufferSize() const
int m_rigidbodyFlags
Definition btRigidBody.h:96
btScalar m_additionalAngularDampingThresholdSqr
Definition btRigidBody.h:83
void setGravity(const btVector3 &acceleration)
btRigidBody(const btRigidBodyConstructionInfo &constructionInfo)
btRigidBody constructor using construction info
btScalar m_linearSleepingThreshold
Definition btRigidBody.h:87
btQuaternion getOrientation() const
void proceedToTransform(const btTransform &newTrans)
const btCollisionShape * getCollisionShape() const
btVector3 m_linearFactor
Definition btRigidBody.h:69
void saveKinematicState(btScalar step)
btVector3 getLocalInertia() const
btVector3 computeGyroscopicImpulseImplicit_World(btScalar dt) const
perform implicit force computation in world space
btVector3 m_angularFactor
btVector3 m_totalForce
Definition btRigidBody.h:74
btScalar m_inverseMass
Definition btRigidBody.h:68
btVector3 computeGyroscopicImpulseImplicit_Body(btScalar step) const
perform implicit force computation in body space (inertial frame)
btVector3 m_totalTorque
Definition btRigidBody.h:75
const btVector3 & getAngularVelocity() const
btMotionState * getMotionState()
btScalar m_angularDamping
Definition btRigidBody.h:78
void removeConstraintRef(btTypedConstraint *c)
void setMassProps(btScalar mass, const btVector3 &inertia)
btVector3 m_deltaAngularVelocity
btVector3 m_pushVelocity
bool m_additionalDamping
Definition btRigidBody.h:80
int m_debugBodyId
Definition btRigidBody.h:98
btScalar m_angularSleepingThreshold
Definition btRigidBody.h:88
btScalar m_additionalLinearDampingThresholdSqr
Definition btRigidBody.h:82
btVector3 m_linearVelocity
Definition btRigidBody.h:66
void setDamping(btScalar lin_damping, btScalar ang_damping)
btVector3 m_deltaLinearVelocity
btVector3 m_angularVelocity
Definition btRigidBody.h:67
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:94
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
const btVector3 & getLinearVelocity() const
btVector3 m_gravity_acceleration
Definition btRigidBody.h:72
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
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:34
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:84
const btScalar & z() const
Return the z value.
Definition btVector3.h:591
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition btVector3.h:389
void getSkewSymmetricMatrix(btVector3 *v0, btVector3 *v1, btVector3 *v2) const
Definition btVector3.h:660
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:652
btScalar length2() const
Return the length of the vector squared.
Definition btVector3.h:257
const btScalar & x() const
Return the x value.
Definition btVector3.h:587
const btScalar & y() const
Return the y value.
Definition btVector3.h:589
The btRigidBodyConstructionInfo structure provides information to create a rigid body.
btScalar m_friction
best simulation results when friction is non-zero
btScalar m_restitution
best simulation results using zero restitution.
btMotionState * m_motionState
When a motionState is provided, the rigid body will initialize its world transform from the motion st...
btScalar m_rollingFriction
the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling f...