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 
93  m_deltaLinearVelocity.setZero();
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