Bullet Collision Detection & Physics Library
btRigidBody.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. 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
26 bool gDisableDeactivation = false;
27 static int uniqueId = 0;
28 
29 
31 {
32  setupRigidBody(constructionInfo);
33 }
34 
35 btRigidBody::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 
49  m_linearFactor.setValue(1,1,1);
50  m_gravity.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;
61  m_additionalDamping = constructionInfo.m_additionalDamping;
66 
68  {
70  } else
71  {
72  m_worldTransform = constructionInfo.m_startWorldTransform;
73  }
74 
78 
79  //moved to btCollisionObject
80  m_friction = constructionInfo.m_friction;
81  m_rollingFriction = constructionInfo.m_rollingFriction;
82  m_restitution = constructionInfo.m_restitution;
83 
84  setCollisionShape( constructionInfo.m_collisionShape );
86 
87  setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);
89 
90  m_rigidbodyFlags = 0;
91 
92 
98 
99 
100 
101 }
102 
103 
105 {
107 }
108 
110 {
111  //todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities
112  if (timeStep != btScalar(0.))
113  {
114  //if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform
115  if (getMotionState())
117  btVector3 linVel,angVel;
118 
123  //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ());
124  }
125 }
126 
127 void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const
128 {
129  getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax);
130 }
131 
132 
133 
134 
135 void btRigidBody::setGravity(const btVector3& acceleration)
136 {
137  if (m_inverseMass != btScalar(0.0))
138  {
139  m_gravity = acceleration * (btScalar(1.0) / m_inverseMass);
140  }
141  m_gravity_acceleration = acceleration;
142 }
143 
144 
145 
146 
147 
148 
149 void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
150 {
151  m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
152  m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
153 }
154 
155 
156 
157 
160 {
161  //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
162  //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
163 
164 //#define USE_OLD_DAMPING_METHOD 1
165 #ifdef USE_OLD_DAMPING_METHOD
166  m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
167  m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
168 #else
169  m_linearVelocity *= btPow(btScalar(1)-m_linearDamping, timeStep);
170  m_angularVelocity *= btPow(btScalar(1)-m_angularDamping, timeStep);
171 #endif
172 
174  {
175  //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
176  //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
179  {
182  }
183 
184 
185  btScalar speed = m_linearVelocity.length();
186  if (speed < m_linearDamping)
187  {
188  btScalar dampVel = btScalar(0.005);
189  if (speed > dampVel)
190  {
192  m_linearVelocity -= dir * dampVel;
193  } else
194  {
196  }
197  }
198 
199  btScalar angSpeed = m_angularVelocity.length();
200  if (angSpeed < m_angularDamping)
201  {
202  btScalar angDampVel = btScalar(0.005);
203  if (angSpeed > angDampVel)
204  {
206  m_angularVelocity -= dir * angDampVel;
207  } else
208  {
210  }
211  }
212  }
213 }
214 
215 
217 {
219  return;
220 
222 
223 }
224 
226 {
227  setCenterOfMassTransform( newTrans );
228 }
229 
230 
231 void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
232 {
233  if (mass == btScalar(0.))
234  {
236  m_inverseMass = btScalar(0.);
237  } else
238  {
240  m_inverseMass = btScalar(1.0) / mass;
241  }
242 
243  //Fg = m * a
245 
246  m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0),
247  inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0),
248  inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0));
249 
251 }
252 
253 
255 {
257 }
258 
259 
261 {
262  btVector3 inertiaLocal;
263  inertiaLocal[0] = 1.f/getInvInertiaDiagLocal()[0];
264  inertiaLocal[1] = 1.f/getInvInertiaDiagLocal()[1];
265  inertiaLocal[2] = 1.f/getInvInertiaDiagLocal()[2];
266  btMatrix3x3 inertiaTensorWorld = getWorldTransform().getBasis().scaled(inertiaLocal) * getWorldTransform().getBasis().transpose();
267  btVector3 tmp = inertiaTensorWorld*getAngularVelocity();
268  btVector3 gf = getAngularVelocity().cross(tmp);
269  btScalar l2 = gf.length2();
270  if (l2>maxGyroscopicForce*maxGyroscopicForce)
271  {
272  gf *= btScalar(1.)/btSqrt(l2)*maxGyroscopicForce;
273  }
274  return gf;
275 }
276 
278 {
280  return;
281 
284 
285 #define MAX_ANGVEL SIMD_HALF_PI
286  btScalar angvel = m_angularVelocity.length();
288  if (angvel*step > MAX_ANGVEL)
289  {
290  m_angularVelocity *= (MAX_ANGVEL/step) /angvel;
291  }
292 
293 }
294 
296 {
297  btQuaternion orn;
299  return orn;
300 }
301 
302 
304 {
305 
306  if (isKinematicObject())
307  {
309  } else
310  {
312  }
315  m_worldTransform = xform;
317 }
318 
319 
321 {
322  const btRigidBody* otherRb = btRigidBody::upcast(co);
323  if (!otherRb)
324  return true;
325 
326  for (int i = 0; i < m_constraintRefs.size(); ++i)
327  {
328  const btTypedConstraint* c = m_constraintRefs[i];
329  if (c->isEnabled())
330  if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
331  return false;
332  }
333 
334  return true;
335 }
336 
337 
338 
340 {
341  int index = m_constraintRefs.findLinearSearch(c);
342  if (index == m_constraintRefs.size())
344 
345  m_checkCollideWith = true;
346 }
347 
349 {
352 }
353 
355 {
356  int sz = sizeof(btRigidBodyData);
357  return sz;
358 }
359 
361 const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const
362 {
363  btRigidBodyData* rbd = (btRigidBodyData*) dataBuffer;
364 
365  btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer);
366 
367  m_invInertiaTensorWorld.serialize(rbd->m_invInertiaTensorWorld);
368  m_linearVelocity.serialize(rbd->m_linearVelocity);
369  m_angularVelocity.serialize(rbd->m_angularVelocity);
370  rbd->m_inverseMass = m_inverseMass;
371  m_angularFactor.serialize(rbd->m_angularFactor);
372  m_linearFactor.serialize(rbd->m_linearFactor);
373  m_gravity.serialize(rbd->m_gravity);
374  m_gravity_acceleration.serialize(rbd->m_gravity_acceleration);
375  m_invInertiaLocal.serialize(rbd->m_invInertiaLocal);
376  m_totalForce.serialize(rbd->m_totalForce);
377  m_totalTorque.serialize(rbd->m_totalTorque);
378  rbd->m_linearDamping = m_linearDamping;
379  rbd->m_angularDamping = m_angularDamping;
380  rbd->m_additionalDamping = m_additionalDamping;
381  rbd->m_additionalDampingFactor = m_additionalDampingFactor;
382  rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr;
383  rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr;
384  rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor;
385  rbd->m_linearSleepingThreshold=m_linearSleepingThreshold;
386  rbd->m_angularSleepingThreshold = m_angularSleepingThreshold;
387 
388  return btRigidBodyDataName;
389 }
390 
391 
392 
394 {
395  btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(),1);
396  const char* structType = serialize(chunk->m_oldPtr, serializer);
397  serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,(void*)this);
398 }
399 
400 
const btCollisionShape * getCollisionShape() const
Definition: btRigidBody.h:248
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
Definition: btRigidBody.h:197
void getAabb(btVector3 &aabbMin, btVector3 &aabbMax) const
void push_back(const T &_Val)
void applyGravity()
btVector3 m_totalTorque
Definition: btRigidBody.h:72
void serialize(struct btMatrix3x3Data &dataOut) const
Definition: btMatrix3x3.h:1335
int m_contactSolverType
Definition: btRigidBody.h:484
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition: btVector3.h:640
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
void updateInertiaTensor()
btVector3 m_totalForce
Definition: btRigidBody.h:71
btScalar m_angularDamping
Definition: btRigidBody.h:75
btTransform m_interpolationWorldTransform
m_interpolationWorldTransform is used for CCD and interpolation it can be either previous or future (...
bool gDisableDeactivation
Definition: btRigidBody.cpp:26
btVector3 m_turnVelocity
Definition: btRigidBody.h:105
btScalar btSqrt(btScalar y)
Definition: btScalar.h:387
btVector3 m_gravity
Definition: btRigidBody.h:68
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
btScalar gDeactivationTime
Definition: btRigidBody.cpp:25
btVector3 computeGyroscopicForce(btScalar maxGyroscopicForce) const
btRigidBody(const btRigidBodyConstructionInfo &constructionInfo)
btRigidBody constructor using construction info
Definition: btRigidBody.cpp:30
void setDamping(btScalar lin_damping, btScalar ang_damping)
btScalar m_angularSleepingThreshold
Definition: btRigidBody.h:85
bool m_additionalDamping
Definition: btRigidBody.h:77
#define btRigidBodyData
Definition: btRigidBody.h:36
btScalar m_additionalLinearDampingThresholdSqr
Definition: btRigidBody.h:79
int m_rigidbodyFlags
Definition: btRigidBody.h:93
btTransform m_worldTransform
btScalar m_rollingFriction
the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling f...
Definition: btRigidBody.h:134
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...
btVector3 m_pushVelocity
Definition: btRigidBody.h:104
const btScalar & x() const
Return the x value.
Definition: btVector3.h:575
btScalar m_inverseMass
Definition: btRigidBody.h:65
void applyCentralForce(const btVector3 &force)
Definition: btRigidBody.h:276
virtual void setCollisionShape(btCollisionShape *collisionShape)
void integrateVelocities(btScalar step)
virtual int calculateSerializeBufferSize() const
btVector3 m_invInertiaLocal
Definition: btRigidBody.h:70
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
void getRotation(btQuaternion &q) const
Get the matrix represented as a quaternion.
Definition: btMatrix3x3.h:400
btTransform & getWorldTransform()
btVector3 m_deltaLinearVelocity
Definition: btRigidBody.h:100
int m_internalType
m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
int size() const
return the number of elements in the array
void setupRigidBody(const btRigidBodyConstructionInfo &constructionInfo)
setupRigidBody is only used internally by the constructor
Definition: btRigidBody.cpp:41
btMatrix3x3 scaled(const btVector3 &s) const
Create a scaled copy of the matrix.
Definition: btMatrix3x3.h:590
bool isKinematicObject() const
void addConstraintRef(btTypedConstraint *c)
btQuaternion getOrientation() const
const btVector3 & getAngularVelocity() const
Definition: btRigidBody.h:359
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition: btVector3.h:377
btMotionState * m_optionalMotionState
Definition: btRigidBody.h:88
bool isStaticOrKinematicObject() const
void serialize(struct btVector3Data &dataOut) const
Definition: btVector3.h:1339
btScalar m_restitution
best simulation results using zero restitution.
Definition: btRigidBody.h:136
virtual bool checkCollideWithOverride(const btCollisionObject *co) const
btCollisionObject can be used to manage collision detection objects.
btScalar m_linearSleepingThreshold
Definition: btRigidBody.h:84
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
virtual void serializeSingleObject(class btSerializer *serializer) const
void setZero()
Definition: btVector3.h:671
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
btScalar length() const
Return the length of the vector.
Definition: btVector3.h:263
btVector3 m_angularFactor
Definition: btRigidBody.h:102
The btRigidBodyConstructionInfo structure provides information to create a rigid body.
Definition: btRigidBody.h:116
btVector3 m_angularVelocity
Definition: btRigidBody.h:64
void proceedToTransform(const btTransform &newTrans)
#define btRigidBodyDataName
Definition: btRigidBody.h:37
btScalar m_additionalDampingFactor
Definition: btRigidBody.h:78
btScalar m_linearDamping
Definition: btRigidBody.h:74
const btScalar & y() const
Return the y value.
Definition: btVector3.h:577
bool isEnabled() const
btVector3 m_linearFactor
Definition: btRigidBody.h:66
btVector3 m_linearVelocity
Definition: btRigidBody.h:63
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
btScalar btPow(btScalar x, btScalar y)
Definition: btScalar.h:429
static void integrateTransform(const btTransform &curTrans, const btVector3 &linvel, const btVector3 &angvel, btScalar timeStep, btTransform &predictedTransform)
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
int m_debugBodyId
Definition: btRigidBody.h:95
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
void setCenterOfMassTransform(const btTransform &xform)
void setMassProps(btScalar mass, const btVector3 &inertia)
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping ...
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:951
void remove(const T &key)
TypedConstraint is the baseclass for Bullet constraints and vehicles.
The btMotionState interface class allows the dynamics world to synchronize and interpolate the update...
Definition: btMotionState.h:23
void saveKinematicState(btScalar step)
btVector3 m_interpolationAngularVelocity
int findLinearSearch(const T &key) const
const btRigidBody & getRigidBodyA() const
btMatrix3x3 transpose() const
Return the transpose of the matrix.
Definition: btMatrix3x3.h:980
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:115
int m_checkCollideWith
If some object should have elaborate collision filtering by sub-classes.
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btScalar m_additionalAngularDampingThresholdSqr
Definition: btRigidBody.h:80
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition: btMatrix3x3.h:48
const btVector3 & getInvInertiaDiagLocal() const
Definition: btRigidBody.h:291
btMotionState * getMotionState()
Definition: btRigidBody.h:468
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:356
btVector3 m_gravity_acceleration
Definition: btRigidBody.h:69
btScalar m_additionalAngularDampingFactor
Definition: btRigidBody.h:81
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
Definition: btQuaternion.h:48
btAlignedObjectArray< btTypedConstraint * > m_constraintRefs
Definition: btRigidBody.h:91
btVector3 m_interpolationLinearVelocity
int m_frictionSolverType
Definition: btRigidBody.h:485
void removeConstraintRef(btTypedConstraint *c)
btVector3 m_deltaAngularVelocity
Definition: btRigidBody.h:101
static void calculateVelocity(const btTransform &transform0, const btTransform &transform1, btScalar timeStep, btVector3 &linVel, btVector3 &angVel)
void * m_oldPtr
Definition: btSerializer.h:56
const T & btClamped(const T &a, const T &lb, const T &ub)
Definition: btMinMax.h:35
const btRigidBody & getRigidBodyB() const
btMotionState * m_motionState
When a motionState is provided, the rigid body will initialize its world transform from the motion st...
Definition: btRigidBody.h:122
btScalar m_friction
best simulation results when friction is non-zero
Definition: btRigidBody.h:131
virtual btChunk * allocate(size_t size, int numElements)=0
#define MAX_ANGVEL
btVector3 m_invMass
Definition: btRigidBody.h:103
virtual void getWorldTransform(btTransform &worldTrans) const =0
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:266
static int uniqueId
Definition: btRigidBody.cpp:27
const btScalar & z() const
Return the z value.
Definition: btVector3.h:579
btMatrix3x3 m_invInertiaTensorWorld
Definition: btRigidBody.h:62
void setGravity(const btVector3 &acceleration)