Blender  V3.3
btDiscreteDynamicsWorld.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
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 
17 
18 //collision detection
25 #include "LinearMath/btQuickprof.h"
26 
27 //rigidbody & constraints
39 
42 
44 #include "LinearMath/btQuickprof.h"
46 
48 
49 #if 0
52 int startHit=2;
53 int firstHit=startHit;
54 #endif
55 
57 {
58  int islandId;
59 
60  const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
61  const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
62  islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag();
63  return islandId;
64 }
65 
67 {
68 public:
69  bool operator()(const btTypedConstraint* lhs, const btTypedConstraint* rhs) const
70  {
71  int rIslandId0, lIslandId0;
72  rIslandId0 = btGetConstraintIslandId(rhs);
73  lIslandId0 = btGetConstraintIslandId(lhs);
74  return lIslandId0 < rIslandId0;
75  }
76 };
77 
79 {
86 
90 
92  btConstraintSolver* solver,
93  btStackAlloc* stackAlloc,
94  btDispatcher* dispatcher)
95  : m_solverInfo(NULL),
96  m_solver(solver),
100  m_dispatcher(dispatcher)
101  {
102  }
103 
105  {
106  btAssert(0);
107  (void)other;
108  return *this;
109  }
110 
111  SIMD_FORCE_INLINE void setup(btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer)
112  {
113  btAssert(solverInfo);
114  m_solverInfo = solverInfo;
115  m_sortedConstraints = sortedConstraints;
117  m_debugDrawer = debugDrawer;
118  m_bodies.resize(0);
119  m_manifolds.resize(0);
121  }
122 
123  virtual void processIsland(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifolds, int numManifolds, int islandId)
124  {
125  if (islandId < 0)
126  {
129  }
130  else
131  {
132  //also add all non-contact constraints/joints for this island
134  int numCurConstraints = 0;
135  int i;
136 
137  //find the first constraint for this island
138  for (i = 0; i < m_numConstraints; i++)
139  {
140  if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
141  {
143  break;
144  }
145  }
146  //count the number of constraints in this island
147  for (; i < m_numConstraints; i++)
148  {
149  if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
150  {
151  numCurConstraints++;
152  }
153  }
154 
156  {
157  m_solver->solveGroup(bodies, numBodies, manifolds, numManifolds, startConstraint, numCurConstraints, *m_solverInfo, m_debugDrawer, m_dispatcher);
158  }
159  else
160  {
161  for (i = 0; i < numBodies; i++)
162  m_bodies.push_back(bodies[i]);
163  for (i = 0; i < numManifolds; i++)
164  m_manifolds.push_back(manifolds[i]);
165  for (i = 0; i < numCurConstraints; i++)
168  {
170  }
171  else
172  {
173  //printf("deferred\n");
174  }
175  }
176  }
177  }
179  {
180  btCollisionObject** bodies = m_bodies.size() ? &m_bodies[0] : 0;
181  btPersistentManifold** manifold = m_manifolds.size() ? &m_manifolds[0] : 0;
183 
185  m_bodies.resize(0);
186  m_manifolds.resize(0);
188  }
189 };
190 
192  : btDynamicsWorld(dispatcher, pairCache, collisionConfiguration),
193  m_sortedConstraints(),
195  m_constraintSolver(constraintSolver),
196  m_gravity(0, -10, 0),
197  m_localTime(0),
198  m_fixedTimeStep(0),
201  m_profileTimings(0),
203 
204 {
205  if (!m_constraintSolver)
206  {
207  void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver), 16);
209  m_ownsConstraintSolver = true;
210  }
211  else
212  {
213  m_ownsConstraintSolver = false;
214  }
215 
216  {
217  void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager), 16);
219  }
220 
221  m_ownsIslandManager = true;
222 
223  {
224  void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback), 16);
226  }
227 }
228 
230 {
231  //only delete it when we created it
233  {
236  }
238  {
239  m_solverIslandCallback->~InplaceSolverIslandCallback();
241  }
243  {
246  }
247 }
248 
250 {
254  for (int i = 0; i < m_collisionObjects.size(); i++)
255  {
256  btCollisionObject* colObj = m_collisionObjects[i];
257  btRigidBody* body = btRigidBody::upcast(colObj);
258  if (body && body->getActivationState() != ISLAND_SLEEPING)
259  {
260  if (body->isKinematicObject())
261  {
262  //to calculate velocities next frame
263  body->saveKinematicState(timeStep);
264  }
265  }
266  }
267 }
268 
270 {
271  BT_PROFILE("debugDrawWorld");
272 
274 
275  bool drawConstraints = false;
276  if (getDebugDrawer())
277  {
278  int mode = getDebugDrawer()->getDebugMode();
280  {
281  drawConstraints = true;
282  }
283  }
284  if (drawConstraints)
285  {
286  for (int i = getNumConstraints() - 1; i >= 0; i--)
287  {
288  btTypedConstraint* constraint = getConstraint(i);
289  debugDrawConstraint(constraint);
290  }
291  }
292 
293  if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawNormals)))
294  {
295  int i;
296 
297  if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
298  {
299  for (i = 0; i < m_actions.size(); i++)
300  {
301  m_actions[i]->debugDraw(m_debugDrawer);
302  }
303  }
304  }
305  if (getDebugDrawer())
306  getDebugDrawer()->flushLines();
307 }
308 
310 {
312  for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
313  {
315  //need to check if next line is ok
316  //it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up
317  body->clearForces();
318  }
319 }
320 
323 {
325  for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
326  {
328  if (body->isActive())
329  {
330  body->applyGravity();
331  }
332  }
333 }
334 
336 {
337  btAssert(body);
338 
339  if (body->getMotionState() && !body->isStaticOrKinematicObject())
340  {
341  //we need to call the update at least once, even for sleeping objects
342  //otherwise the 'graphics' transform never updates properly
344  //if (body->getActivationState() != ISLAND_SLEEPING)
345  {
346  btTransform interpolatedTransform;
347  btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
348  body->getInterpolationLinearVelocity(), body->getInterpolationAngularVelocity(),
350  interpolatedTransform);
351  body->getMotionState()->setWorldTransform(interpolatedTransform);
352  }
353  }
354 }
355 
357 {
358  // BT_PROFILE("synchronizeMotionStates");
360  {
361  //iterate over all collision objects
362  for (int i = 0; i < m_collisionObjects.size(); i++)
363  {
364  btCollisionObject* colObj = m_collisionObjects[i];
365  btRigidBody* body = btRigidBody::upcast(colObj);
366  if (body)
368  }
369  }
370  else
371  {
372  //iterate over all active rigid bodies
373  for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
374  {
376  if (body->isActive())
378  }
379  }
380 }
381 
382 int btDiscreteDynamicsWorld::stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep)
383 {
384  startProfiling(timeStep);
385 
386  int numSimulationSubSteps = 0;
387 
388  if (maxSubSteps)
389  {
390  //fixed timestep with interpolation
391  m_fixedTimeStep = fixedTimeStep;
392  m_localTime += timeStep;
393  if (m_localTime >= fixedTimeStep)
394  {
395  numSimulationSubSteps = int(m_localTime / fixedTimeStep);
396  m_localTime -= numSimulationSubSteps * fixedTimeStep;
397  }
398  }
399  else
400  {
401  //variable timestep
402  fixedTimeStep = timeStep;
404  m_fixedTimeStep = 0;
405  if (btFuzzyZero(timeStep))
406  {
407  numSimulationSubSteps = 0;
408  maxSubSteps = 0;
409  }
410  else
411  {
412  numSimulationSubSteps = 1;
413  maxSubSteps = 1;
414  }
415  }
416 
417  //process some debugging flags
418  if (getDebugDrawer())
419  {
420  btIDebugDraw* debugDrawer = getDebugDrawer();
422  }
423  if (numSimulationSubSteps)
424  {
425  //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
426  int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps) ? maxSubSteps : numSimulationSubSteps;
427 
428  saveKinematicState(fixedTimeStep * clampedSimulationSteps);
429 
430  applyGravity();
431 
432  for (int i = 0; i < clampedSimulationSteps; i++)
433  {
434  internalSingleStepSimulation(fixedTimeStep);
436  }
437  }
438  else
439  {
441  }
442 
443  clearForces();
444 
445 #ifndef BT_NO_PROFILE
446  CProfileManager::Increment_Frame_Counter();
447 #endif //BT_NO_PROFILE
448 
449  return numSimulationSubSteps;
450 }
451 
453 {
454  BT_PROFILE("internalSingleStepSimulation");
455 
456  if (0 != m_internalPreTickCallback)
457  {
458  (*m_internalPreTickCallback)(this, timeStep);
459  }
460 
462  predictUnconstraintMotion(timeStep);
463 
464  btDispatcherInfo& dispatchInfo = getDispatchInfo();
465 
466  dispatchInfo.m_timeStep = timeStep;
467  dispatchInfo.m_stepCount = 0;
468  dispatchInfo.m_debugDraw = getDebugDrawer();
469 
470  createPredictiveContacts(timeStep);
471 
473  performDiscreteCollisionDetection();
474 
476 
477  getSolverInfo().m_timeStep = timeStep;
478 
480  solveConstraints(getSolverInfo());
481 
483 
485 
486  integrateTransforms(timeStep);
487 
489  updateActions(timeStep);
490 
491  updateActivationState(timeStep);
492 
493  if (0 != m_internalTickCallback)
494  {
495  (*m_internalTickCallback)(this, timeStep);
496  }
497 }
498 
500 {
501  m_gravity = gravity;
502  for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
503  {
505  if (body->isActive() && !(body->getFlags() & BT_DISABLE_WORLD_GRAVITY))
506  {
507  body->setGravity(gravity);
508  }
509  }
510 }
511 
513 {
514  return m_gravity;
515 }
516 
517 void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
518 {
519  btCollisionWorld::addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask);
520 }
521 
523 {
524  btRigidBody* body = btRigidBody::upcast(collisionObject);
525  if (body)
526  removeRigidBody(body);
527  else
529 }
530 
532 {
533  m_nonStaticRigidBodies.remove(body);
535 }
536 
538 {
539  if (!body->isStaticOrKinematicObject() && !(body->getFlags() & BT_DISABLE_WORLD_GRAVITY))
540  {
541  body->setGravity(m_gravity);
542  }
543 
544  if (body->getCollisionShape())
545  {
546  if (!body->isStaticObject())
547  {
548  m_nonStaticRigidBodies.push_back(body);
549  }
550  else
551  {
552  body->setActivationState(ISLAND_SLEEPING);
553  }
554 
555  bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
556  int collisionFilterGroup = isDynamic ? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
557  int collisionFilterMask = isDynamic ? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
558 
559  addCollisionObject(body, collisionFilterGroup, collisionFilterMask);
560  }
561 }
562 
563 void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask)
564 {
565  if (!body->isStaticOrKinematicObject() && !(body->getFlags() & BT_DISABLE_WORLD_GRAVITY))
566  {
567  body->setGravity(m_gravity);
568  }
569 
570  if (body->getCollisionShape())
571  {
572  if (!body->isStaticObject())
573  {
574  m_nonStaticRigidBodies.push_back(body);
575  }
576  else
577  {
578  body->setActivationState(ISLAND_SLEEPING);
579  }
580  addCollisionObject(body, group, mask);
581  }
582 }
583 
585 {
586  BT_PROFILE("updateActions");
587 
588  for (int i = 0; i < m_actions.size(); i++)
589  {
590  m_actions[i]->updateAction(this, timeStep);
591  }
592 }
593 
595 {
596  BT_PROFILE("updateActivationState");
597 
598  for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
599  {
601  if (body)
602  {
603  body->updateDeactivation(timeStep);
604 
605  if (body->wantsSleeping())
606  {
607  if (body->isStaticOrKinematicObject())
608  {
609  body->setActivationState(ISLAND_SLEEPING);
610  }
611  else
612  {
613  if (body->getActivationState() == ACTIVE_TAG)
614  body->setActivationState(WANTS_DEACTIVATION);
615  if (body->getActivationState() == ISLAND_SLEEPING)
616  {
617  body->setAngularVelocity(btVector3(0, 0, 0));
618  body->setLinearVelocity(btVector3(0, 0, 0));
619  }
620  }
621  }
622  else
623  {
624  if (body->getActivationState() != DISABLE_DEACTIVATION)
625  body->setActivationState(ACTIVE_TAG);
626  }
627  }
628  }
629 }
630 
631 void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies)
632 {
633  m_constraints.push_back(constraint);
634  //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?)
635  btAssert(&constraint->getRigidBodyA() != &constraint->getRigidBodyB());
636 
637  if (disableCollisionsBetweenLinkedBodies)
638  {
639  constraint->getRigidBodyA().addConstraintRef(constraint);
640  constraint->getRigidBodyB().addConstraintRef(constraint);
641  }
642 }
643 
645 {
646  m_constraints.remove(constraint);
647  constraint->getRigidBodyA().removeConstraintRef(constraint);
648  constraint->getRigidBodyB().removeConstraintRef(constraint);
649 }
650 
652 {
653  m_actions.push_back(action);
654 }
655 
657 {
658  m_actions.remove(action);
659 }
660 
662 {
663  addAction(vehicle);
664 }
665 
667 {
668  removeAction(vehicle);
669 }
670 
672 {
673  addAction(character);
674 }
675 
677 {
678  removeAction(character);
679 }
680 
682 {
683  BT_PROFILE("solveConstraints");
684 
685  m_sortedConstraints.resize(m_constraints.size());
686  int i;
687  for (i = 0; i < getNumConstraints(); i++)
688  {
689  m_sortedConstraints[i] = m_constraints[i];
690  }
691 
692  // btAssert(0);
693 
694  m_sortedConstraints.quickSort(btSortConstraintOnIslandPredicate());
695 
696  btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0;
697 
698  m_solverIslandCallback->setup(&solverInfo, constraintsPtr, m_sortedConstraints.size(), getDebugDrawer());
699  m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
700 
703 
705 
706  m_constraintSolver->allSolved(solverInfo, m_debugDrawer);
707 }
708 
710 {
711  BT_PROFILE("calculateSimulationIslands");
712 
714 
715  {
716  //merge islands based on speculative contact manifolds too
717  for (int i = 0; i < this->m_predictiveManifolds.size(); i++)
718  {
720 
721  const btCollisionObject* colObj0 = manifold->getBody0();
722  const btCollisionObject* colObj1 = manifold->getBody1();
723 
724  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
725  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
726  {
727  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag());
728  }
729  }
730  }
731 
732  {
733  int i;
734  int numConstraints = int(m_constraints.size());
735  for (i = 0; i < numConstraints; i++)
736  {
737  btTypedConstraint* constraint = m_constraints[i];
738  if (constraint->isEnabled())
739  {
740  const btRigidBody* colObj0 = &constraint->getRigidBodyA();
741  const btRigidBody* colObj1 = &constraint->getRigidBodyB();
742 
743  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
744  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
745  {
746  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag());
747  }
748  }
749  }
750  }
751 
752  //Store the island id in each body
754 }
755 
757 {
758 public:
763 
764 public:
766  m_me(me),
767  m_allowedPenetration(0.0f),
768  m_pairCache(pairCache),
769  m_dispatcher(dispatcher)
770  {
771  }
772 
773  virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace)
774  {
775  if (convexResult.m_hitCollisionObject == m_me)
776  return 1.0f;
777 
778  //ignore result if there is no contact response
779  if (!convexResult.m_hitCollisionObject->hasContactResponse())
780  return 1.0f;
781 
782  btVector3 linVelA, linVelB;
784  linVelB = btVector3(0, 0, 0); //toB.getOrigin()-fromB.getOrigin();
785 
786  btVector3 relativeVelocity = (linVelA - linVelB);
787  //don't report time of impact for motion away from the contact normal (or causes minor penetration)
788  if (convexResult.m_hitNormalLocal.dot(relativeVelocity) >= -m_allowedPenetration)
789  return 1.f;
790 
791  return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
792  }
793 
794  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
795  {
796  //don't collide with itself
797  if (proxy0->m_clientObject == m_me)
798  return false;
799 
802  return false;
804  btBroadphaseProxy* proxy1 = m_me->getBroadphaseHandle();
805  bool collides = m_pairCache->needsBroadphaseCollision(proxy0, proxy1);
806  if (!collides)
807  {
808  return false;
809  }
810  }
811 
812  btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject;
813 
814  if (!m_dispatcher->needsCollision(m_me, otherObj))
815  return false;
816 
817  //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
818  if (m_dispatcher->needsResponse(m_me, otherObj))
819  {
820 #if 0
823  btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
824  if (collisionPair)
825  {
826  if (collisionPair->m_algorithm)
827  {
828  manifoldArray.resize(0);
829  collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
830  for (int j=0;j<manifoldArray.size();j++)
831  {
832  btPersistentManifold* manifold = manifoldArray[j];
833  if (manifold->getNumContacts()>0)
834  return false;
835  }
836  }
837  }
838 #endif
839  return true;
840  }
841 
842  return false;
843  }
844 };
845 
848 
850 {
851  btTransform predictedTrans;
852  for (int i = 0; i < numBodies; i++)
853  {
854  btRigidBody* body = bodies[i];
855  body->setHitFraction(1.f);
856 
857  if (body->isActive() && (!body->isStaticOrKinematicObject()))
858  {
859  body->predictIntegratedTransform(timeStep, predictedTrans);
860 
861  btScalar squareMotion = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()).length2();
862 
863  if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
864  {
865  BT_PROFILE("predictive convexSweepTest");
866  if (body->getCollisionShape()->isConvex())
867  {
869 #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
870  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
871  {
872  public:
873  StaticOnlyCallback(btCollisionObject* me, const btVector3& fromA, const btVector3& toA, btOverlappingPairCache* pairCache, btDispatcher* dispatcher) : btClosestNotMeConvexResultCallback(me, fromA, toA, pairCache, dispatcher)
874  {
875  }
876 
877  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
878  {
879  btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject;
880  if (!otherObj->isStaticOrKinematicObject())
881  return false;
883  }
884  };
885 
886  StaticOnlyCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
887 #else
888  btClosestNotMeConvexResultCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
889 #endif
890  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
891  btSphereShape tmpSphere(body->getCcdSweptSphereRadius()); //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
892  sweepResults.m_allowedPenetration = getDispatchInfo().m_allowedCcdPenetration;
893 
894  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
895  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
896  btTransform modifiedPredictedTrans = predictedTrans;
897  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
898 
899  convexSweepTest(&tmpSphere, body->getWorldTransform(), modifiedPredictedTrans, sweepResults);
900  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
901  {
902  btVector3 distVec = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()) * sweepResults.m_closestHitFraction;
903  btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
904 
905  btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body, sweepResults.m_hitCollisionObject);
909 
910  btVector3 worldPointB = body->getWorldTransform().getOrigin() + distVec;
911  btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse() * worldPointB;
912 
913  btManifoldPoint newPoint(btVector3(0, 0, 0), localPointB, sweepResults.m_hitNormalWorld, distance);
914 
915  bool isPredictive = true;
916  int index = manifold->addManifoldPoint(newPoint, isPredictive);
917  btManifoldPoint& pt = manifold->getContactPoint(index);
918  pt.m_combinedRestitution = 0;
919  pt.m_combinedFriction = gCalculateCombinedFrictionCallback(body, sweepResults.m_hitCollisionObject);
920  pt.m_positionWorldOnA = body->getWorldTransform().getOrigin();
921  pt.m_positionWorldOnB = worldPointB;
922  }
923  }
924  }
925  }
926  }
927 }
928 
930 {
931  BT_PROFILE("release predictive contact manifolds");
932 
933  for (int i = 0; i < m_predictiveManifolds.size(); i++)
934  {
936  this->m_dispatcher1->releaseManifold(manifold);
937  }
939 }
940 
942 {
943  BT_PROFILE("createPredictiveContacts");
945  if (m_nonStaticRigidBodies.size() > 0)
946  {
948  }
949 }
950 
952 {
953  btTransform predictedTrans;
954  for (int i = 0; i < numBodies; i++)
955  {
956  btRigidBody* body = bodies[i];
957  body->setHitFraction(1.f);
958 
959  if (body->isActive() && (!body->isStaticOrKinematicObject()))
960  {
961  body->predictIntegratedTransform(timeStep, predictedTrans);
962 
963  btScalar squareMotion = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()).length2();
964 
965  if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
966  {
967  BT_PROFILE("CCD motion clamping");
968  if (body->getCollisionShape()->isConvex())
969  {
971 #ifdef USE_STATIC_ONLY
972  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
973  {
974  public:
975  StaticOnlyCallback(btCollisionObject* me, const btVector3& fromA, const btVector3& toA, btOverlappingPairCache* pairCache, btDispatcher* dispatcher) : btClosestNotMeConvexResultCallback(me, fromA, toA, pairCache, dispatcher)
976  {
977  }
978 
979  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
980  {
981  btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject;
982  if (!otherObj->isStaticOrKinematicObject())
983  return false;
985  }
986  };
987 
988  StaticOnlyCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
989 #else
990  btClosestNotMeConvexResultCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
991 #endif
992  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
993  btSphereShape tmpSphere(body->getCcdSweptSphereRadius()); //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
994  sweepResults.m_allowedPenetration = getDispatchInfo().m_allowedCcdPenetration;
995 
996  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
997  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
998  btTransform modifiedPredictedTrans = predictedTrans;
999  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
1000 
1001  convexSweepTest(&tmpSphere, body->getWorldTransform(), modifiedPredictedTrans, sweepResults);
1002  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
1003  {
1004  //printf("clamped integration to hit fraction = %f\n",fraction);
1005  body->setHitFraction(sweepResults.m_closestHitFraction);
1006  body->predictIntegratedTransform(timeStep * body->getHitFraction(), predictedTrans);
1007  body->setHitFraction(0.f);
1008  body->proceedToTransform(predictedTrans);
1009 
1010 #if 0
1011  btVector3 linVel = body->getLinearVelocity();
1012 
1013  btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep;
1014  btScalar maxSpeedSqr = maxSpeed*maxSpeed;
1015  if (linVel.length2()>maxSpeedSqr)
1016  {
1017  linVel.normalize();
1018  linVel*= maxSpeed;
1019  body->setLinearVelocity(linVel);
1020  btScalar ms2 = body->getLinearVelocity().length2();
1021  body->predictIntegratedTransform(timeStep, predictedTrans);
1022 
1023  btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1024  btScalar smt = body->getCcdSquareMotionThreshold();
1025  printf("sm2=%f\n",sm2);
1026  }
1027 #else
1028 
1029  //don't apply the collision response right now, it will happen next frame
1030  //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
1031  //btScalar appliedImpulse = 0.f;
1032  //btScalar depth = 0.f;
1033  //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
1034 
1035 #endif
1036 
1037  continue;
1038  }
1039  }
1040  }
1041 
1042  body->proceedToTransform(predictedTrans);
1043  }
1044  }
1045 }
1046 
1048 {
1049  BT_PROFILE("integrateTransforms");
1050  if (m_nonStaticRigidBodies.size() > 0)
1051  {
1053  }
1054 
1057  {
1058  BT_PROFILE("apply speculative contact restitution");
1059  for (int i = 0; i < m_predictiveManifolds.size(); i++)
1060  {
1062  btRigidBody* body0 = btRigidBody::upcast((btCollisionObject*)manifold->getBody0());
1063  btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1());
1064 
1065  for (int p = 0; p < manifold->getNumContacts(); p++)
1066  {
1067  const btManifoldPoint& pt = manifold->getContactPoint(p);
1068  btScalar combinedRestitution = gCalculateCombinedRestitutionCallback(body0, body1);
1069 
1070  if (combinedRestitution > 0 && pt.m_appliedImpulse != 0.f)
1071  //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1072  {
1073  btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse * combinedRestitution;
1074 
1075  const btVector3& pos1 = pt.getPositionWorldOnA();
1076  const btVector3& pos2 = pt.getPositionWorldOnB();
1077 
1078  btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
1079  btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
1080 
1081  if (body0)
1082  body0->applyImpulse(imp, rel_pos0);
1083  if (body1)
1084  body1->applyImpulse(-imp, rel_pos1);
1085  }
1086  }
1087  }
1088  }
1089 }
1090 
1092 {
1093  BT_PROFILE("predictUnconstraintMotion");
1094  for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
1095  {
1097  if (!body->isStaticOrKinematicObject())
1098  {
1099  //don't integrate/update velocities here, it happens in the constraint solver
1100 
1101  body->applyDamping(timeStep);
1102 
1103  body->predictIntegratedTransform(timeStep, body->getInterpolationWorldTransform());
1104  }
1105  }
1106 }
1107 
1109 {
1110  (void)timeStep;
1111 
1112 #ifndef BT_NO_PROFILE
1113  CProfileManager::Reset();
1114 #endif //BT_NO_PROFILE
1115 }
1116 
1118 {
1119  bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
1120  bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
1121  btScalar dbgDrawSize = constraint->getDbgDrawSize();
1122  if (dbgDrawSize <= btScalar(0.f))
1123  {
1124  return;
1125  }
1126 
1127  switch (constraint->getConstraintType())
1128  {
1130  {
1131  btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
1132  btTransform tr;
1133  tr.setIdentity();
1134  btVector3 pivot = p2pC->getPivotInA();
1135  pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1136  tr.setOrigin(pivot);
1137  getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1138  // that ideally should draw the same frame
1139  pivot = p2pC->getPivotInB();
1140  pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1141  tr.setOrigin(pivot);
1142  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1143  }
1144  break;
1145  case HINGE_CONSTRAINT_TYPE:
1146  {
1147  btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
1148  btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1149  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1150  tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1151  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1152  btScalar minAng = pHinge->getLowerLimit();
1153  btScalar maxAng = pHinge->getUpperLimit();
1154  if (minAng == maxAng)
1155  {
1156  break;
1157  }
1158  bool drawSect = true;
1159  if (!pHinge->hasLimit())
1160  {
1161  minAng = btScalar(0.f);
1162  maxAng = SIMD_2_PI;
1163  drawSect = false;
1164  }
1165  if (drawLimits)
1166  {
1167  btVector3& center = tr.getOrigin();
1168  btVector3 normal = tr.getBasis().getColumn(2);
1169  btVector3 axis = tr.getBasis().getColumn(0);
1170  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0, 0, 0), drawSect);
1171  }
1172  }
1173  break;
1175  {
1176  btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
1177  btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1178  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1179  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1180  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1181  if (drawLimits)
1182  {
1183  //const btScalar length = btScalar(5);
1184  const btScalar length = dbgDrawSize;
1185  static int nSegments = 8 * 4;
1186  btScalar fAngleInRadians = btScalar(2. * 3.1415926) * (btScalar)(nSegments - 1) / btScalar(nSegments);
1187  btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1188  pPrev = tr * pPrev;
1189  for (int i = 0; i < nSegments; i++)
1190  {
1191  fAngleInRadians = btScalar(2. * 3.1415926) * (btScalar)i / btScalar(nSegments);
1192  btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1193  pCur = tr * pCur;
1194  getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0, 0, 0));
1195 
1196  if (i % (nSegments / 8) == 0)
1197  getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0, 0, 0));
1198 
1199  pPrev = pCur;
1200  }
1201  btScalar tws = pCT->getTwistSpan();
1202  btScalar twa = pCT->getTwistAngle();
1203  bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1204  if (useFrameB)
1205  {
1206  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1207  }
1208  else
1209  {
1210  tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1211  }
1212  btVector3 pivot = tr.getOrigin();
1213  btVector3 normal = tr.getBasis().getColumn(0);
1214  btVector3 axis1 = tr.getBasis().getColumn(1);
1215  getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa - tws, -twa + tws, btVector3(0, 0, 0), true);
1216  }
1217  }
1218  break;
1220  case D6_CONSTRAINT_TYPE:
1221  {
1222  btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
1223  btTransform tr = p6DOF->getCalculatedTransformA();
1224  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1225  tr = p6DOF->getCalculatedTransformB();
1226  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1227  if (drawLimits)
1228  {
1229  tr = p6DOF->getCalculatedTransformA();
1230  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1231  btVector3 up = tr.getBasis().getColumn(2);
1232  btVector3 axis = tr.getBasis().getColumn(0);
1233  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1234  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1235  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1236  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1237  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1238  axis = tr.getBasis().getColumn(1);
1239  btScalar ay = p6DOF->getAngle(1);
1240  btScalar az = p6DOF->getAngle(2);
1241  btScalar cy = btCos(ay);
1242  btScalar sy = btSin(ay);
1243  btScalar cz = btCos(az);
1244  btScalar sz = btSin(az);
1245  btVector3 ref;
1246  ref[0] = cy * cz * axis[0] + cy * sz * axis[1] - sy * axis[2];
1247  ref[1] = -sz * axis[0] + cz * axis[1];
1248  ref[2] = cz * sy * axis[0] + sz * sy * axis[1] + cy * axis[2];
1249  tr = p6DOF->getCalculatedTransformB();
1250  btVector3 normal = -tr.getBasis().getColumn(0);
1251  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1252  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1253  if (minFi > maxFi)
1254  {
1255  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1256  }
1257  else if (minFi < maxFi)
1258  {
1259  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1260  }
1261  tr = p6DOF->getCalculatedTransformA();
1262  btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
1263  btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
1264  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1265  }
1266  }
1267  break;
1270  {
1271  {
1273  btTransform tr = p6DOF->getCalculatedTransformA();
1274  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1275  tr = p6DOF->getCalculatedTransformB();
1276  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1277  if (drawLimits)
1278  {
1279  tr = p6DOF->getCalculatedTransformA();
1280  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1281  btVector3 up = tr.getBasis().getColumn(2);
1282  btVector3 axis = tr.getBasis().getColumn(0);
1283  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1284  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1285  if (minTh <= maxTh)
1286  {
1287  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1288  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1289  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1290  }
1291  axis = tr.getBasis().getColumn(1);
1292  btScalar ay = p6DOF->getAngle(1);
1293  btScalar az = p6DOF->getAngle(2);
1294  btScalar cy = btCos(ay);
1295  btScalar sy = btSin(ay);
1296  btScalar cz = btCos(az);
1297  btScalar sz = btSin(az);
1298  btVector3 ref;
1299  ref[0] = cy * cz * axis[0] + cy * sz * axis[1] - sy * axis[2];
1300  ref[1] = -sz * axis[0] + cz * axis[1];
1301  ref[2] = cz * sy * axis[0] + sz * sy * axis[1] + cy * axis[2];
1302  tr = p6DOF->getCalculatedTransformB();
1303  btVector3 normal = -tr.getBasis().getColumn(0);
1304  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1305  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1306  if (minFi > maxFi)
1307  {
1308  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1309  }
1310  else if (minFi < maxFi)
1311  {
1312  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1313  }
1314  tr = p6DOF->getCalculatedTransformA();
1315  btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
1316  btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
1317  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1318  }
1319  }
1320  break;
1321  }
1323  {
1324  btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
1325  btTransform tr = pSlider->getCalculatedTransformA();
1326  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1327  tr = pSlider->getCalculatedTransformB();
1328  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1329  if (drawLimits)
1330  {
1331  btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB();
1332  btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1333  btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1334  getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
1335  btVector3 normal = tr.getBasis().getColumn(0);
1336  btVector3 axis = tr.getBasis().getColumn(1);
1337  btScalar a_min = pSlider->getLowerAngLimit();
1338  btScalar a_max = pSlider->getUpperAngLimit();
1339  const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1340  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0, 0, 0), true);
1341  }
1342  }
1343  break;
1344  default:
1345  break;
1346  }
1347  return;
1348 }
1349 
1351 {
1353  {
1355  }
1356  m_ownsConstraintSolver = false;
1357  m_constraintSolver = solver;
1358  m_solverIslandCallback->m_solver = solver;
1359 }
1360 
1362 {
1363  return m_constraintSolver;
1364 }
1365 
1367 {
1368  return int(m_constraints.size());
1369 }
1371 {
1372  return m_constraints[index];
1373 }
1375 {
1376  return m_constraints[index];
1377 }
1378 
1380 {
1381  int i;
1382  //serialize all collision objects
1383  for (i = 0; i < m_collisionObjects.size(); i++)
1384  {
1385  btCollisionObject* colObj = m_collisionObjects[i];
1386  if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY)
1387  {
1388  int len = colObj->calculateSerializeBufferSize();
1389  btChunk* chunk = serializer->allocate(len, 1);
1390  const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1391  serializer->finalizeChunk(chunk, structType, BT_RIGIDBODY_CODE, colObj);
1392  }
1393  }
1394 
1395  for (i = 0; i < m_constraints.size(); i++)
1396  {
1397  btTypedConstraint* constraint = m_constraints[i];
1398  int size = constraint->calculateSerializeBufferSize();
1399  btChunk* chunk = serializer->allocate(size, 1);
1400  const char* structType = constraint->serialize(chunk->m_oldPtr, serializer);
1401  serializer->finalizeChunk(chunk, structType, BT_CONSTRAINT_CODE, constraint);
1402  }
1403 }
1404 
1406 {
1407 #ifdef BT_USE_DOUBLE_PRECISION
1408  int len = sizeof(btDynamicsWorldDoubleData);
1409  btChunk* chunk = serializer->allocate(len, 1);
1411 #else //BT_USE_DOUBLE_PRECISION
1412  int len = sizeof(btDynamicsWorldFloatData);
1413  btChunk* chunk = serializer->allocate(len, 1);
1415 #endif //BT_USE_DOUBLE_PRECISION
1416 
1417  memset(worldInfo, 0x00, len);
1418 
1419  m_gravity.serialize(worldInfo->m_gravity);
1420  worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
1421  worldInfo->m_solverInfo.m_damping = getSolverInfo().m_damping;
1422  worldInfo->m_solverInfo.m_friction = getSolverInfo().m_friction;
1423  worldInfo->m_solverInfo.m_timeStep = getSolverInfo().m_timeStep;
1424 
1425  worldInfo->m_solverInfo.m_restitution = getSolverInfo().m_restitution;
1426  worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction;
1427  worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
1428  worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
1429 
1430  worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
1431  worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm;
1432  worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold;
1433  worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp;
1434 
1435  worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop;
1436  worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor;
1437  worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce;
1438  worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold;
1439 
1440  worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations;
1441  worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode;
1442  worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold;
1443  worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize;
1444 
1445  worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse;
1446 
1447 
1448 #ifdef BT_USE_DOUBLE_PRECISION
1449  const char* structType = "btDynamicsWorldDoubleData";
1450 #else //BT_USE_DOUBLE_PRECISION
1451  const char* structType = "btDynamicsWorldFloatData";
1452 #endif //BT_USE_DOUBLE_PRECISION
1453  serializer->finalizeChunk(chunk, structType, BT_DYNAMICSWORLD_CODE, worldInfo);
1454 }
1455 
1457 {
1458  serializer->startSerialization();
1459 
1460  serializeDynamicsWorldInfo(serializer);
1461 
1462  serializeCollisionObjects(serializer);
1463 
1464  serializeRigidBodies(serializer);
1465 
1466  serializeContactManifolds(serializer);
1467 
1468  serializer->finishSerialization();
1469 }
NSNotificationCenter * center
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
@ AllFilter
@ DefaultFilter
@ StaticFilter
btBroadphasePair
btBroadphaseProxy
SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const
btCollisionObject
#define ACTIVE_TAG
#define DISABLE_DEACTIVATION
@ CO_RIGID_BODY
#define WANTS_DEACTIVATION
SIMD_FORCE_INLINE int getIslandTag() const
#define ISLAND_SLEEPING
btConeTwistConstraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &rbAFrame, const btTransform &rbBFrame)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint *lhs)
int gNumClampedCcdMotions
internal debugging variable. this value shouldn't be too high
void updateActions(btScalar timeStep)
virtual void clearForces()
the forces on each rigidbody is accumulating together with gravity. clear this after each timestep.
void integrateTransformsInternal(btRigidBody **bodies, int numBodies, btScalar timeStep)
btSimulationIslandManager * m_islandManager
virtual void saveKinematicState(btScalar timeStep)
virtual void solveConstraints(btContactSolverInfo &solverInfo)
virtual btConstraintSolver * getConstraintSolver()
virtual void removeRigidBody(btRigidBody *body)
InplaceSolverIslandCallback * m_solverIslandCallback
virtual void removeConstraint(btTypedConstraint *constraint)
bool m_applySpeculativeContactRestitution
virtual void createPredictiveContacts(btScalar timeStep)
void synchronizeSingleMotionState(btRigidBody *body)
this can be useful to synchronize a single rigid body -> graphics object
void createPredictiveContactsInternal(btRigidBody **bodies, int numBodies, btScalar timeStep)
virtual void addRigidBody(btRigidBody *body)
virtual void removeCharacter(btActionInterface *character)
obsolete, use removeAction instead
bool m_ownsConstraintSolver
void serializeRigidBodies(btSerializer *serializer)
btAlignedObjectArray< btRigidBody * > m_nonStaticRigidBodies
virtual void synchronizeMotionStates()
bool m_synchronizeAllMotionStates
virtual btTypedConstraint * getConstraint(int index)
void serializeDynamicsWorldInfo(btSerializer *serializer)
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::StaticFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter)
virtual void addAction(btActionInterface *)
virtual void addVehicle(btActionInterface *vehicle)
obsolete, use addAction instead
virtual void updateActivationState(btScalar timeStep)
btDiscreteDynamicsWorld(btDispatcher *dispatcher, btBroadphaseInterface *pairCache, btConstraintSolver *constraintSolver, btCollisionConfiguration *collisionConfiguration)
this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete thos...
virtual int getNumConstraints() const
btScalar m_fixedTimeStep
virtual void addConstraint(btTypedConstraint *constraint, bool disableCollisionsBetweenLinkedBodies=false)
bool m_ownsIslandManager
virtual void removeAction(btActionInterface *)
virtual void calculateSimulationIslands()
virtual void debugDrawWorld()
virtual void predictUnconstraintMotion(btScalar timeStep)
btAlignedObjectArray< btTypedConstraint * > m_constraints
btAlignedObjectArray< btPersistentManifold * > m_predictiveManifolds
virtual void integrateTransforms(btScalar timeStep)
btSimulationIslandManager * getSimulationIslandManager()
virtual void removeCollisionObject(btCollisionObject *collisionObject)
removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise ca...
btCollisionWorld * getCollisionWorld()
virtual void addCharacter(btActionInterface *character)
obsolete, use addAction instead
btAlignedObjectArray< btActionInterface * > m_actions
virtual void setConstraintSolver(btConstraintSolver *solver)
bool m_latencyMotionStateInterpolation
btScalar m_localTime
virtual int stepSimulation(btScalar timeStep, int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))
if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
virtual void removeVehicle(btActionInterface *vehicle)
obsolete, use removeAction instead
virtual void debugDrawConstraint(btTypedConstraint *constraint)
int m_profileTimings
btSpinMutex m_predictiveManifoldsMutex
btConstraintSolver * m_constraintSolver
virtual ~btDiscreteDynamicsWorld()
virtual void applyGravity()
apply gravity, call this once per timestep
virtual void internalSingleStepSimulation(btScalar timeStep)
void releasePredictiveContacts()
void startProfiling(btScalar timeStep)
btGeneric6DofConstraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &frameInA, const btTransform &frameInB, bool useLinearReferenceFrameA)
btGeneric6DofSpring2Constraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &frameInA, const btTransform &frameInB, RotateOrder rotOrder=RO_XYZ)
void convexSweepTest(const class btConvexShape *castShape, const btTransform &convexFromWorld, const btTransform &convexToWorld, btCollisionWorld::ConvexResultCallback &resultCallback, btScalar allowedCcdPenetration=0.f) const
btHingeConstraint(btRigidBody &rbA, btRigidBody &rbB, const btVector3 &pivotInA, const btVector3 &pivotInB, const btVector3 &axisInA, const btVector3 &axisInB, bool useReferenceFrameA=false)
btVector3 getGravity() const
btScalar m_gravity
void setGravity(const btVector3 &gravity)
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)
CalculateCombinedCallback gCalculateCombinedFrictionCallback
CalculateCombinedCallback gCalculateCombinedRestitutionCallback
btPersistentManifold()
btPoint2PointConstraint(btRigidBody &rbA, btRigidBody &rbB, const btVector3 &pivotInA, const btVector3 &pivotInB)
virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const
Data buffer MUST be 16 byte aligned.
#define BT_PROFILE(name)
Definition: btQuickprof.h:198
bool gDisableDeactivation
Definition: btRigidBody.cpp:26
@ BT_DISABLE_WORLD_GRAVITY
Definition: btRigidBody.h:41
SIMD_FORCE_INLINE btScalar btCos(btScalar x)
Definition: btScalar.h:498
#define SIMD_PI
Definition: btScalar.h:526
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
SIMD_FORCE_INLINE btScalar btSin(btScalar x)
Definition: btScalar.h:499
SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x)
Definition: btScalar.h:572
#define SIMD_FORCE_INLINE
Definition: btScalar.h:280
#define SIMD_2_PI
Definition: btScalar.h:527
#define btAssert(x)
Definition: btScalar.h:295
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint ** constraints
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint int numConstraints
btSequentialImpulseConstraintSolverMt int numBodies
btSequentialImpulseConstraintSolverMt int btPersistentManifold int numManifolds
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:112
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:121
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:113
btSliderConstraint(btRigidBody &rbA, btRigidBody &rbB, const btTransform &frameInA, const btTransform &frameInB, bool useLinearReferenceFrameA)
btSphereShape(btScalar radius)
Definition: btSphereShape.h:29
SIMD_FORCE_INLINE void btMutexUnlock(btSpinMutex *mutex)
Definition: btThreads.h:79
SIMD_FORCE_INLINE void btMutexLock(btSpinMutex *mutex)
Definition: btThreads.h:70
btTransform
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:30
btTypedConstraint(btTypedConstraintType type, btRigidBody &rbA)
@ SLIDER_CONSTRAINT_TYPE
@ CONETWIST_CONSTRAINT_TYPE
@ POINT2POINT_CONSTRAINT_TYPE
@ D6_SPRING_2_CONSTRAINT_TYPE
@ HINGE_CONSTRAINT_TYPE
@ D6_SPRING_CONSTRAINT_TYPE
@ D6_CONSTRAINT_TYPE
SIMD_FORCE_INLINE btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:251
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
Definition: btVector3.h:82
Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWor...
SIMD_FORCE_INLINE void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0),...
SIMD_FORCE_INLINE int size() const
return the number of elements in the array
void remove(const T &key)
SIMD_FORCE_INLINE void resize(int newsize, const T &fillData=T())
void quickSort(const L &CompareFunc)
SIMD_FORCE_INLINE void push_back(const T &_Val)
void * m_oldPtr
Definition: btSerializer.h:52
btClosestNotMeConvexResultCallback(btCollisionObject *me, const btVector3 &fromA, const btVector3 &toA, btOverlappingPairCache *pairCache, btDispatcher *dispatcher)
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
CollisionWorld is interface and container for the collision detection.
virtual void debugDrawWorld()
virtual void removeCollisionObject(btCollisionObject *collisionObject)
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
virtual void allSolved(const btContactSolverInfo &, class btIDebugDraw *)
virtual void prepareSolve(int, int)
virtual btScalar solveGroup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifold, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &info, class btIDebugDraw *debugDrawer, btDispatcher *dispatcher)=0
solve a group of constraints
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)=0
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1)=0
The btDynamicsWorld is the interface class for several dynamics implementation, basic,...
virtual int getDebugMode() const =0
@ DBG_DrawConstraintLimits
Definition: btIDebugDraw.h:67
const btVector3 & getPositionWorldOnB() const
btScalar m_combinedRestitution
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity
btScalar m_appliedImpulse
const btVector3 & getPositionWorldOnA() const
btVector3 m_normalWorldOnB
btScalar m_combinedFriction
btVector3 m_positionWorldOnB
virtual void setWorldTransform(const btTransform &worldTrans)=0
virtual btOverlapFilterCallback * getOverlapFilterCallback()=0
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
virtual bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const =0
void applyGravity()
SIMD_FORCE_INLINE const btCollisionShape * getCollisionShape() const
Definition: btRigidBody.h:242
void clearForces()
Definition: btRigidBody.h:415
int getFlags() const
Definition: btRigidBody.h:608
btMotionState * getMotionState()
Definition: btRigidBody.h:549
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
static const btRigidBody * upcast(const btCollisionObject *colObj)
Definition: btRigidBody.h:189
void setGravity(const btVector3 &acceleration)
void proceedToTransform(const btTransform &newTrans)
void saveKinematicState(btScalar step)
const btBroadphaseProxy * getBroadphaseProxy() const
Definition: btRigidBody.h:535
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:335
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:433
SIMD_FORCE_INLINE bool wantsSleeping()
Definition: btRigidBody.h:516
SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep)
Definition: btRigidBody.h:499
void setAngularVelocity(const btVector3 &ang_vel)
Definition: btRigidBody.h:451
void setLinearVelocity(const btVector3 &lin_vel)
Definition: btRigidBody.h:442
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void finishSerialization()=0
virtual void startSerialization()=0
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
SimulationIslandManager creates and handles simulation islands, using btUnionFind.
virtual void storeIslandActivationState(btCollisionWorld *world)
virtual void updateActivationState(btCollisionWorld *colWorld, btDispatcher *dispatcher)
void buildAndProcessIslands(btDispatcher *dispatcher, btCollisionWorld *collisionWorld, IslandCallback *callback)
bool operator()(const btTypedConstraint *lhs, const btTypedConstraint *rhs) const
The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out)
Definition: btStackAlloc.h:35
static void integrateTransform(const btTransform &curTrans, const btVector3 &linvel, const btVector3 &angvel, btScalar timeStep, btTransform &predictedTransform)
void unite(int p, int q)
Definition: btUnionFind.h:76
SyclQueue void void size_t num_bytes void
int len
Definition: draw_manager.c:108
IconTextureDrawCall normal
ccl_gpu_kernel_postfix ccl_global float int int sy
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
T length(const vec_base< T, Size > &a)
T distance(const T &a, const T &b)
btAlignedObjectArray< btCollisionObject * > m_bodies
InplaceSolverIslandCallback(btConstraintSolver *solver, btStackAlloc *stackAlloc, btDispatcher *dispatcher)
btAlignedObjectArray< btTypedConstraint * > m_constraints
InplaceSolverIslandCallback & operator=(InplaceSolverIslandCallback &other)
btAlignedObjectArray< btPersistentManifold * > m_manifolds
virtual void processIsland(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifolds, int numManifolds, int islandId)
btTypedConstraint ** m_sortedConstraints
SIMD_FORCE_INLINE void setup(btContactSolverInfo *solverInfo, btTypedConstraint **sortedConstraints, int numConstraints, btIDebugDraw *debugDrawer)
ClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld)
const btCollisionObject * m_hitCollisionObject
double m_singleAxisRollingFrictionThreshold
it is only used for 'explicit' version of gyroscopic force
btScalar m_timeStep
Definition: btDispatcher.h:53
class btIDebugDraw * m_debugDraw
Definition: btDispatcher.h:58
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btContactSolverInfoDoubleData m_solverInfo
btVector3DoubleData m_gravity
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
void startConstraint(TransInfo *t)