Bullet Collision Detection & Physics Library
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 
16 
18 
19 //collision detection
26 #include "LinearMath/btQuickprof.h"
27 
28 //rigidbody & constraints
40 
41 
44 
45 
47 #include "LinearMath/btQuickprof.h"
49 
51 
52 #if 0
55 int startHit=2;
56 int firstHit=startHit;
57 #endif
58 
60 {
61  int islandId;
62 
63  const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
64  const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
65  islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag();
66  return islandId;
67 
68 }
69 
70 
72 {
73  public:
74 
75  bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) const
76  {
77  int rIslandId0,lIslandId0;
78  rIslandId0 = btGetConstraintIslandId(rhs);
79  lIslandId0 = btGetConstraintIslandId(lhs);
80  return lIslandId0 < rIslandId0;
81  }
82 };
83 
85 {
92 
96 
97 
99  btConstraintSolver* solver,
100  btStackAlloc* stackAlloc,
101  btDispatcher* dispatcher)
102  :m_solverInfo(NULL),
103  m_solver(solver),
104  m_sortedConstraints(NULL),
105  m_numConstraints(0),
106  m_debugDrawer(NULL),
107  m_dispatcher(dispatcher)
108  {
109 
110  }
111 
113  {
114  btAssert(0);
115  (void)other;
116  return *this;
117  }
118 
119  SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer)
120  {
121  btAssert(solverInfo);
122  m_solverInfo = solverInfo;
123  m_sortedConstraints = sortedConstraints;
124  m_numConstraints = numConstraints;
125  m_debugDrawer = debugDrawer;
126  m_bodies.resize (0);
127  m_manifolds.resize (0);
128  m_constraints.resize (0);
129  }
130 
131 
132  virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId)
133  {
134  if (islandId<0)
135  {
137  m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
138  } else
139  {
140  //also add all non-contact constraints/joints for this island
141  btTypedConstraint** startConstraint = 0;
142  int numCurConstraints = 0;
143  int i;
144 
145  //find the first constraint for this island
146  for (i=0;i<m_numConstraints;i++)
147  {
148  if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
149  {
150  startConstraint = &m_sortedConstraints[i];
151  break;
152  }
153  }
154  //count the number of constraints in this island
155  for (;i<m_numConstraints;i++)
156  {
157  if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
158  {
159  numCurConstraints++;
160  }
161  }
162 
163  if (m_solverInfo->m_minimumSolverBatchSize<=1)
164  {
165  m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
166  } else
167  {
168 
169  for (i=0;i<numBodies;i++)
170  m_bodies.push_back(bodies[i]);
171  for (i=0;i<numManifolds;i++)
172  m_manifolds.push_back(manifolds[i]);
173  for (i=0;i<numCurConstraints;i++)
174  m_constraints.push_back(startConstraint[i]);
175  if ((m_constraints.size()+m_manifolds.size())>m_solverInfo->m_minimumSolverBatchSize)
176  {
177  processConstraints();
178  } else
179  {
180  //printf("deferred\n");
181  }
182  }
183  }
184  }
186  {
187 
188  btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0;
189  btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0;
190  btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0;
191 
192  m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_dispatcher);
193  m_bodies.resize(0);
194  m_manifolds.resize(0);
195  m_constraints.resize(0);
196 
197  }
198 
199 };
200 
201 
202 
204 :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
205 m_sortedConstraints (),
206 m_solverIslandCallback ( NULL ),
207 m_constraintSolver(constraintSolver),
208 m_gravity(0,-10,0),
209 m_localTime(0),
210 m_fixedTimeStep(0),
211 m_synchronizeAllMotionStates(false),
212 m_applySpeculativeContactRestitution(false),
213 m_profileTimings(0),
214 m_latencyMotionStateInterpolation(true)
215 
216 {
217  if (!m_constraintSolver)
218  {
219  void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16);
221  m_ownsConstraintSolver = true;
222  } else
223  {
224  m_ownsConstraintSolver = false;
225  }
226 
227  {
228  void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16);
230  }
231 
232  m_ownsIslandManager = true;
233 
234  {
235  void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback),16);
237  }
238 }
239 
240 
242 {
243  //only delete it when we created it
245  {
248  }
250  {
251  m_solverIslandCallback->~InplaceSolverIslandCallback();
253  }
255  {
256 
259  }
260 }
261 
263 {
267  for (int i=0;i<m_collisionObjects.size();i++)
268  {
270  btRigidBody* body = btRigidBody::upcast(colObj);
271  if (body && body->getActivationState() != ISLAND_SLEEPING)
272  {
273  if (body->isKinematicObject())
274  {
275  //to calculate velocities next frame
276  body->saveKinematicState(timeStep);
277  }
278  }
279  }
280 
281 }
282 
284 {
285  BT_PROFILE("debugDrawWorld");
286 
288 
289  bool drawConstraints = false;
290  if (getDebugDrawer())
291  {
292  int mode = getDebugDrawer()->getDebugMode();
294  {
295  drawConstraints = true;
296  }
297  }
298  if(drawConstraints)
299  {
300  for(int i = getNumConstraints()-1; i>=0 ;i--)
301  {
302  btTypedConstraint* constraint = getConstraint(i);
303  debugDrawConstraint(constraint);
304  }
305  }
306 
307 
308 
310  {
311  int i;
312 
313  if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
314  {
315  for (i=0;i<m_actions.size();i++)
316  {
317  m_actions[i]->debugDraw(m_debugDrawer);
318  }
319  }
320  }
321  if (getDebugDrawer())
323 
324 }
325 
327 {
329  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
330  {
332  //need to check if next line is ok
333  //it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up
334  body->clearForces();
335  }
336 }
337 
340 {
342  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
343  {
345  if (body->isActive())
346  {
347  body->applyGravity();
348  }
349  }
350 }
351 
352 
354 {
355  btAssert(body);
356 
357  if (body->getMotionState() && !body->isStaticOrKinematicObject())
358  {
359  //we need to call the update at least once, even for sleeping objects
360  //otherwise the 'graphics' transform never updates properly
362  //if (body->getActivationState() != ISLAND_SLEEPING)
363  {
364  btTransform interpolatedTransform;
368  interpolatedTransform);
369  body->getMotionState()->setWorldTransform(interpolatedTransform);
370  }
371  }
372 }
373 
374 
376 {
377 // BT_PROFILE("synchronizeMotionStates");
379  {
380  //iterate over all collision objects
381  for ( int i=0;i<m_collisionObjects.size();i++)
382  {
384  btRigidBody* body = btRigidBody::upcast(colObj);
385  if (body)
387  }
388  } else
389  {
390  //iterate over all active rigid bodies
391  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
392  {
394  if (body->isActive())
396  }
397  }
398 }
399 
400 
401 int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
402 {
403  startProfiling(timeStep);
404 
405 
406  int numSimulationSubSteps = 0;
407 
408  if (maxSubSteps)
409  {
410  //fixed timestep with interpolation
411  m_fixedTimeStep = fixedTimeStep;
412  m_localTime += timeStep;
413  if (m_localTime >= fixedTimeStep)
414  {
415  numSimulationSubSteps = int( m_localTime / fixedTimeStep);
416  m_localTime -= numSimulationSubSteps * fixedTimeStep;
417  }
418  } else
419  {
420  //variable timestep
421  fixedTimeStep = timeStep;
423  m_fixedTimeStep = 0;
424  if (btFuzzyZero(timeStep))
425  {
426  numSimulationSubSteps = 0;
427  maxSubSteps = 0;
428  } else
429  {
430  numSimulationSubSteps = 1;
431  maxSubSteps = 1;
432  }
433  }
434 
435  //process some debugging flags
436  if (getDebugDrawer())
437  {
438  btIDebugDraw* debugDrawer = getDebugDrawer ();
440  }
441  if (numSimulationSubSteps)
442  {
443 
444  //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
445  int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
446 
447  saveKinematicState(fixedTimeStep*clampedSimulationSteps);
448 
449  applyGravity();
450 
451 
452 
453  for (int i=0;i<clampedSimulationSteps;i++)
454  {
455  internalSingleStepSimulation(fixedTimeStep);
457  }
458 
459  } else
460  {
462  }
463 
464  clearForces();
465 
466 #ifndef BT_NO_PROFILE
468 #endif //BT_NO_PROFILE
469 
470  return numSimulationSubSteps;
471 }
472 
474 {
475 
476  BT_PROFILE("internalSingleStepSimulation");
477 
478  if(0 != m_internalPreTickCallback) {
479  (*m_internalPreTickCallback)(this, timeStep);
480  }
481 
483  predictUnconstraintMotion(timeStep);
484 
485  btDispatcherInfo& dispatchInfo = getDispatchInfo();
486 
487  dispatchInfo.m_timeStep = timeStep;
488  dispatchInfo.m_stepCount = 0;
489  dispatchInfo.m_debugDraw = getDebugDrawer();
490 
491 
492  createPredictiveContacts(timeStep);
493 
496 
498 
499 
500  getSolverInfo().m_timeStep = timeStep;
501 
502 
503 
506 
508 
510 
511  integrateTransforms(timeStep);
512 
514  updateActions(timeStep);
515 
516  updateActivationState( timeStep );
517 
518  if(0 != m_internalTickCallback) {
519  (*m_internalTickCallback)(this, timeStep);
520  }
521 }
522 
524 {
525  m_gravity = gravity;
526  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
527  {
529  if (body->isActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
530  {
531  body->setGravity(gravity);
532  }
533  }
534 }
535 
537 {
538  return m_gravity;
539 }
540 
541 void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
542 {
543  btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask);
544 }
545 
547 {
548  btRigidBody* body = btRigidBody::upcast(collisionObject);
549  if (body)
550  removeRigidBody(body);
551  else
553 }
554 
556 {
559 }
560 
561 
563 {
564  if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
565  {
566  body->setGravity(m_gravity);
567  }
568 
569  if (body->getCollisionShape())
570  {
571  if (!body->isStaticObject())
572  {
574  } else
575  {
577  }
578 
579  bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
580  int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
581  int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
582 
583  addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
584  }
585 }
586 
587 void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask)
588 {
589  if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
590  {
591  body->setGravity(m_gravity);
592  }
593 
594  if (body->getCollisionShape())
595  {
596  if (!body->isStaticObject())
597  {
599  }
600  else
601  {
603  }
604  addCollisionObject(body,group,mask);
605  }
606 }
607 
608 
610 {
611  BT_PROFILE("updateActions");
612 
613  for ( int i=0;i<m_actions.size();i++)
614  {
615  m_actions[i]->updateAction( this, timeStep);
616  }
617 }
618 
619 
621 {
622  BT_PROFILE("updateActivationState");
623 
624  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
625  {
627  if (body)
628  {
629  body->updateDeactivation(timeStep);
630 
631  if (body->wantsSleeping())
632  {
633  if (body->isStaticOrKinematicObject())
634  {
636  } else
637  {
638  if (body->getActivationState() == ACTIVE_TAG)
640  if (body->getActivationState() == ISLAND_SLEEPING)
641  {
642  body->setAngularVelocity(btVector3(0,0,0));
643  body->setLinearVelocity(btVector3(0,0,0));
644  }
645 
646  }
647  } else
648  {
651  }
652  }
653  }
654 }
655 
656 void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
657 {
658  m_constraints.push_back(constraint);
659  //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?)
660  btAssert(&constraint->getRigidBodyA()!=&constraint->getRigidBodyB());
661 
662  if (disableCollisionsBetweenLinkedBodies)
663  {
664  constraint->getRigidBodyA().addConstraintRef(constraint);
665  constraint->getRigidBodyB().addConstraintRef(constraint);
666  }
667 }
668 
670 {
671  m_constraints.remove(constraint);
672  constraint->getRigidBodyA().removeConstraintRef(constraint);
673  constraint->getRigidBodyB().removeConstraintRef(constraint);
674 }
675 
677 {
678  m_actions.push_back(action);
679 }
680 
682 {
683  m_actions.remove(action);
684 }
685 
686 
688 {
689  addAction(vehicle);
690 }
691 
693 {
694  removeAction(vehicle);
695 }
696 
698 {
699  addAction(character);
700 }
701 
703 {
704  removeAction(character);
705 }
706 
707 
708 
709 
711 {
712  BT_PROFILE("solveConstraints");
713 
715  int i;
716  for (i=0;i<getNumConstraints();i++)
717  {
719  }
720 
721 // btAssert(0);
722 
723 
724 
726 
727  btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0;
728 
729  m_solverIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer());
731 
734 
736 
738 }
739 
740 
742 {
743  BT_PROFILE("calculateSimulationIslands");
744 
746 
747  {
748  //merge islands based on speculative contact manifolds too
749  for (int i=0;i<this->m_predictiveManifolds.size();i++)
750  {
752 
753  const btCollisionObject* colObj0 = manifold->getBody0();
754  const btCollisionObject* colObj1 = manifold->getBody1();
755 
756  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
757  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
758  {
759  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
760  }
761  }
762  }
763 
764  {
765  int i;
766  int numConstraints = int(m_constraints.size());
767  for (i=0;i< numConstraints ; i++ )
768  {
769  btTypedConstraint* constraint = m_constraints[i];
770  if (constraint->isEnabled())
771  {
772  const btRigidBody* colObj0 = &constraint->getRigidBodyA();
773  const btRigidBody* colObj1 = &constraint->getRigidBodyB();
774 
775  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
776  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
777  {
778  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
779  }
780  }
781  }
782  }
783 
784  //Store the island id in each body
786 
787 
788 }
789 
790 
791 
792 
794 {
795 public:
796 
801 
802 public:
804  btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
805  m_me(me),
806  m_allowedPenetration(0.0f),
807  m_pairCache(pairCache),
808  m_dispatcher(dispatcher)
809  {
810  }
811 
812  virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
813  {
814  if (convexResult.m_hitCollisionObject == m_me)
815  return 1.0f;
816 
817  //ignore result if there is no contact response
818  if(!convexResult.m_hitCollisionObject->hasContactResponse())
819  return 1.0f;
820 
821  btVector3 linVelA,linVelB;
822  linVelA = m_convexToWorld-m_convexFromWorld;
823  linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin();
824 
825  btVector3 relativeVelocity = (linVelA-linVelB);
826  //don't report time of impact for motion away from the contact normal (or causes minor penetration)
827  if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration)
828  return 1.f;
829 
830  return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
831  }
832 
833  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
834  {
835  //don't collide with itself
836  if (proxy0->m_clientObject == m_me)
837  return false;
838 
841  return false;
842 
843  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
844 
845  if(!m_dispatcher->needsCollision(m_me, otherObj))
846  return false;
847 
848  //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
849  if (m_dispatcher->needsResponse(m_me,otherObj))
850  {
851 #if 0
854  btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
855  if (collisionPair)
856  {
857  if (collisionPair->m_algorithm)
858  {
859  manifoldArray.resize(0);
860  collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
861  for (int j=0;j<manifoldArray.size();j++)
862  {
863  btPersistentManifold* manifold = manifoldArray[j];
864  if (manifold->getNumContacts()>0)
865  return false;
866  }
867  }
868  }
869 #endif
870  return true;
871  }
872 
873  return false;
874  }
875 
876 
877 };
878 
881 
882 
884 {
885  btTransform predictedTrans;
886  for ( int i=0;i<numBodies;i++)
887  {
888  btRigidBody* body = bodies[i];
889  body->setHitFraction(1.f);
890 
891  if (body->isActive() && (!body->isStaticOrKinematicObject()))
892  {
893 
894  body->predictIntegratedTransform(timeStep, predictedTrans);
895 
896  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
897 
899  {
900  BT_PROFILE("predictive convexSweepTest");
901  if (body->getCollisionShape()->isConvex())
902  {
904 #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
905  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
906  {
907  public:
908 
909  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
910  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
911  {
912  }
913 
914  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
915  {
916  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
917  if (!otherObj->isStaticOrKinematicObject())
918  return false;
920  }
921  };
922 
923  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
924 #else
926 #endif
927  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
928  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
929  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
930 
931  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
932  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
933  btTransform modifiedPredictedTrans = predictedTrans;
934  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
935 
936  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
937  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
938  {
939 
940  btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction;
941  btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
942 
943 
944  btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject);
948 
949  btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec;
950  btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB;
951 
952  btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance);
953 
954  bool isPredictive = true;
955  int index = manifold->addManifoldPoint(newPoint, isPredictive);
956  btManifoldPoint& pt = manifold->getContactPoint(index);
957  pt.m_combinedRestitution = 0;
958  pt.m_combinedFriction = gCalculateCombinedFrictionCallback(body,sweepResults.m_hitCollisionObject);
960  pt.m_positionWorldOnB = worldPointB;
961 
962  }
963  }
964  }
965  }
966  }
967 }
968 
970 {
971  BT_PROFILE( "release predictive contact manifolds" );
972 
973  for ( int i = 0; i < m_predictiveManifolds.size(); i++ )
974  {
976  this->m_dispatcher1->releaseManifold( manifold );
977  }
979 }
980 
982 {
983  BT_PROFILE("createPredictiveContacts");
985  if (m_nonStaticRigidBodies.size() > 0)
986  {
988  }
989 }
990 
992 {
993  btTransform predictedTrans;
994  for (int i=0;i<numBodies;i++)
995  {
996  btRigidBody* body = bodies[i];
997  body->setHitFraction(1.f);
998 
999  if (body->isActive() && (!body->isStaticOrKinematicObject()))
1000  {
1001 
1002  body->predictIntegratedTransform(timeStep, predictedTrans);
1003 
1004  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1005 
1006 
1007 
1009  {
1010  BT_PROFILE("CCD motion clamping");
1011  if (body->getCollisionShape()->isConvex())
1012  {
1014 #ifdef USE_STATIC_ONLY
1015  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
1016  {
1017  public:
1018 
1019  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
1020  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
1021  {
1022  }
1023 
1024  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
1025  {
1026  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
1027  if (!otherObj->isStaticOrKinematicObject())
1028  return false;
1030  }
1031  };
1032 
1033  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
1034 #else
1036 #endif
1037  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1038  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1039  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
1040 
1041  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
1042  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
1043  btTransform modifiedPredictedTrans = predictedTrans;
1044  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
1045 
1046  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
1047  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
1048  {
1049 
1050  //printf("clamped integration to hit fraction = %f\n",fraction);
1051  body->setHitFraction(sweepResults.m_closestHitFraction);
1052  body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
1053  body->setHitFraction(0.f);
1054  body->proceedToTransform( predictedTrans);
1055 
1056 #if 0
1057  btVector3 linVel = body->getLinearVelocity();
1058 
1060  btScalar maxSpeedSqr = maxSpeed*maxSpeed;
1061  if (linVel.length2()>maxSpeedSqr)
1062  {
1063  linVel.normalize();
1064  linVel*= maxSpeed;
1065  body->setLinearVelocity(linVel);
1066  btScalar ms2 = body->getLinearVelocity().length2();
1067  body->predictIntegratedTransform(timeStep, predictedTrans);
1068 
1069  btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1070  btScalar smt = body->getCcdSquareMotionThreshold();
1071  printf("sm2=%f\n",sm2);
1072  }
1073 #else
1074 
1075  //don't apply the collision response right now, it will happen next frame
1076  //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
1077  //btScalar appliedImpulse = 0.f;
1078  //btScalar depth = 0.f;
1079  //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
1080 
1081 
1082 #endif
1083 
1084  continue;
1085  }
1086  }
1087  }
1088 
1089 
1090  body->proceedToTransform( predictedTrans);
1091 
1092  }
1093 
1094  }
1095 
1096 }
1097 
1099 {
1100  BT_PROFILE("integrateTransforms");
1101  if (m_nonStaticRigidBodies.size() > 0)
1102  {
1104  }
1105 
1108  {
1109  BT_PROFILE("apply speculative contact restitution");
1110  for (int i=0;i<m_predictiveManifolds.size();i++)
1111  {
1115 
1116  for (int p=0;p<manifold->getNumContacts();p++)
1117  {
1118  const btManifoldPoint& pt = manifold->getContactPoint(p);
1119  btScalar combinedRestitution = gCalculateCombinedRestitutionCallback(body0, body1);
1120 
1121  if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1122  //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1123  {
1124  btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution;
1125 
1126  const btVector3& pos1 = pt.getPositionWorldOnA();
1127  const btVector3& pos2 = pt.getPositionWorldOnB();
1128 
1129  btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
1130  btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
1131 
1132  if (body0)
1133  body0->applyImpulse(imp,rel_pos0);
1134  if (body1)
1135  body1->applyImpulse(-imp,rel_pos1);
1136  }
1137  }
1138  }
1139  }
1140 }
1141 
1142 
1143 
1144 
1145 
1147 {
1148  BT_PROFILE("predictUnconstraintMotion");
1149  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
1150  {
1152  if (!body->isStaticOrKinematicObject())
1153  {
1154  //don't integrate/update velocities here, it happens in the constraint solver
1155 
1156  body->applyDamping(timeStep);
1157 
1159  }
1160  }
1161 }
1162 
1163 
1165 {
1166  (void)timeStep;
1167 
1168 #ifndef BT_NO_PROFILE
1170 #endif //BT_NO_PROFILE
1171 
1172 }
1173 
1174 
1175 
1176 
1177 
1178 
1180 {
1181  bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
1182  bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
1183  btScalar dbgDrawSize = constraint->getDbgDrawSize();
1184  if(dbgDrawSize <= btScalar(0.f))
1185  {
1186  return;
1187  }
1188 
1189  switch(constraint->getConstraintType())
1190  {
1192  {
1193  btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
1194  btTransform tr;
1195  tr.setIdentity();
1196  btVector3 pivot = p2pC->getPivotInA();
1197  pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1198  tr.setOrigin(pivot);
1199  getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1200  // that ideally should draw the same frame
1201  pivot = p2pC->getPivotInB();
1202  pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1203  tr.setOrigin(pivot);
1204  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1205  }
1206  break;
1207  case HINGE_CONSTRAINT_TYPE:
1208  {
1209  btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
1210  btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1211  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1212  tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1213  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1214  btScalar minAng = pHinge->getLowerLimit();
1215  btScalar maxAng = pHinge->getUpperLimit();
1216  if(minAng == maxAng)
1217  {
1218  break;
1219  }
1220  bool drawSect = true;
1221  if(!pHinge->hasLimit())
1222  {
1223  minAng = btScalar(0.f);
1224  maxAng = SIMD_2_PI;
1225  drawSect = false;
1226  }
1227  if(drawLimits)
1228  {
1229  btVector3& center = tr.getOrigin();
1230  btVector3 normal = tr.getBasis().getColumn(2);
1231  btVector3 axis = tr.getBasis().getColumn(0);
1232  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
1233  }
1234  }
1235  break;
1237  {
1238  btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
1240  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1241  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1242  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1243  if(drawLimits)
1244  {
1245  //const btScalar length = btScalar(5);
1246  const btScalar length = dbgDrawSize;
1247  static int nSegments = 8*4;
1248  btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
1249  btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1250  pPrev = tr * pPrev;
1251  for (int i=0; i<nSegments; i++)
1252  {
1253  fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
1254  btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1255  pCur = tr * pCur;
1256  getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
1257 
1258  if (i%(nSegments/8) == 0)
1259  getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
1260 
1261  pPrev = pCur;
1262  }
1263  btScalar tws = pCT->getTwistSpan();
1264  btScalar twa = pCT->getTwistAngle();
1265  bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1266  if(useFrameB)
1267  {
1268  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1269  }
1270  else
1271  {
1272  tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1273  }
1274  btVector3 pivot = tr.getOrigin();
1275  btVector3 normal = tr.getBasis().getColumn(0);
1276  btVector3 axis1 = tr.getBasis().getColumn(1);
1277  getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
1278 
1279  }
1280  }
1281  break;
1283  case D6_CONSTRAINT_TYPE:
1284  {
1285  btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
1286  btTransform tr = p6DOF->getCalculatedTransformA();
1287  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1288  tr = p6DOF->getCalculatedTransformB();
1289  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1290  if(drawLimits)
1291  {
1292  tr = p6DOF->getCalculatedTransformA();
1293  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1294  btVector3 up = tr.getBasis().getColumn(2);
1295  btVector3 axis = tr.getBasis().getColumn(0);
1296  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1297  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1298  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1299  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1300  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
1301  axis = tr.getBasis().getColumn(1);
1302  btScalar ay = p6DOF->getAngle(1);
1303  btScalar az = p6DOF->getAngle(2);
1304  btScalar cy = btCos(ay);
1305  btScalar sy = btSin(ay);
1306  btScalar cz = btCos(az);
1307  btScalar sz = btSin(az);
1308  btVector3 ref;
1309  ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1310  ref[1] = -sz*axis[0] + cz*axis[1];
1311  ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1312  tr = p6DOF->getCalculatedTransformB();
1313  btVector3 normal = -tr.getBasis().getColumn(0);
1314  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1315  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1316  if(minFi > maxFi)
1317  {
1318  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
1319  }
1320  else if(minFi < maxFi)
1321  {
1322  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
1323  }
1324  tr = p6DOF->getCalculatedTransformA();
1327  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
1328  }
1329  }
1330  break;
1333  {
1334  {
1336  btTransform tr = p6DOF->getCalculatedTransformA();
1337  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1338  tr = p6DOF->getCalculatedTransformB();
1339  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1340  if (drawLimits)
1341  {
1342  tr = p6DOF->getCalculatedTransformA();
1343  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1344  btVector3 up = tr.getBasis().getColumn(2);
1345  btVector3 axis = tr.getBasis().getColumn(0);
1346  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1347  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1348  if (minTh <= maxTh)
1349  {
1350  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1351  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1352  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1353  }
1354  axis = tr.getBasis().getColumn(1);
1355  btScalar ay = p6DOF->getAngle(1);
1356  btScalar az = p6DOF->getAngle(2);
1357  btScalar cy = btCos(ay);
1358  btScalar sy = btSin(ay);
1359  btScalar cz = btCos(az);
1360  btScalar sz = btSin(az);
1361  btVector3 ref;
1362  ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1363  ref[1] = -sz*axis[0] + cz*axis[1];
1364  ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1365  tr = p6DOF->getCalculatedTransformB();
1366  btVector3 normal = -tr.getBasis().getColumn(0);
1367  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1368  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1369  if (minFi > maxFi)
1370  {
1371  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1372  }
1373  else if (minFi < maxFi)
1374  {
1375  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1376  }
1377  tr = p6DOF->getCalculatedTransformA();
1380  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1381  }
1382  }
1383  break;
1384  }
1386  {
1387  btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
1388  btTransform tr = pSlider->getCalculatedTransformA();
1389  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1390  tr = pSlider->getCalculatedTransformB();
1391  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1392  if(drawLimits)
1393  {
1395  btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1396  btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1397  getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
1398  btVector3 normal = tr.getBasis().getColumn(0);
1399  btVector3 axis = tr.getBasis().getColumn(1);
1400  btScalar a_min = pSlider->getLowerAngLimit();
1401  btScalar a_max = pSlider->getUpperAngLimit();
1402  const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1403  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
1404  }
1405  }
1406  break;
1407  default :
1408  break;
1409  }
1410  return;
1411 }
1412 
1413 
1414 
1415 
1416 
1418 {
1420  {
1422  }
1423  m_ownsConstraintSolver = false;
1424  m_constraintSolver = solver;
1425  m_solverIslandCallback->m_solver = solver;
1426 }
1427 
1429 {
1430  return m_constraintSolver;
1431 }
1432 
1433 
1435 {
1436  return int(m_constraints.size());
1437 }
1439 {
1440  return m_constraints[index];
1441 }
1443 {
1444  return m_constraints[index];
1445 }
1446 
1447 
1448 
1450 {
1451  int i;
1452  //serialize all collision objects
1453  for (i=0;i<m_collisionObjects.size();i++)
1454  {
1457  {
1458  int len = colObj->calculateSerializeBufferSize();
1459  btChunk* chunk = serializer->allocate(len,1);
1460  const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1461  serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
1462  }
1463  }
1464 
1465  for (i=0;i<m_constraints.size();i++)
1466  {
1467  btTypedConstraint* constraint = m_constraints[i];
1468  int size = constraint->calculateSerializeBufferSize();
1469  btChunk* chunk = serializer->allocate(size,1);
1470  const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
1471  serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
1472  }
1473 }
1474 
1475 
1476 
1477 
1479 {
1480 #ifdef BT_USE_DOUBLE_PRECISION
1481  int len = sizeof(btDynamicsWorldDoubleData);
1482  btChunk* chunk = serializer->allocate(len,1);
1484 #else//BT_USE_DOUBLE_PRECISION
1485  int len = sizeof(btDynamicsWorldFloatData);
1486  btChunk* chunk = serializer->allocate(len,1);
1488 #endif//BT_USE_DOUBLE_PRECISION
1489 
1490  memset(worldInfo ,0x00,len);
1491 
1492  m_gravity.serialize(worldInfo->m_gravity);
1493  worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
1497 
1500  worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
1501  worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
1502 
1503  worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
1507 
1512 
1517 
1519 
1520  // Fill padding with zeros to appease msan.
1521  memset(worldInfo->m_solverInfo.m_padding, 0, sizeof(worldInfo->m_solverInfo.m_padding));
1522 
1523 #ifdef BT_USE_DOUBLE_PRECISION
1524  const char* structType = "btDynamicsWorldDoubleData";
1525 #else//BT_USE_DOUBLE_PRECISION
1526  const char* structType = "btDynamicsWorldFloatData";
1527 #endif//BT_USE_DOUBLE_PRECISION
1528  serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo);
1529 }
1530 
1532 {
1533 
1534  serializer->startSerialization();
1535 
1536  serializeDynamicsWorldInfo(serializer);
1537 
1538  serializeCollisionObjects(serializer);
1539 
1540  serializeRigidBodies(serializer);
1541 
1542  serializeContactManifolds(serializer);
1543 
1544  serializer->finishSerialization();
1545 }
1546 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btScalar getInvMass() const
Definition: btRigidBody.h:273
virtual void setConstraintSolver(btConstraintSolver *solver)
const btCollisionShape * getCollisionShape() const
Definition: btRigidBody.h:254
virtual void internalSingleStepSimulation(btScalar timeStep)
virtual void finishSerialization()=0
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don&#39;t store a rigidbody pointer but a rigidbody ...
Definition: btRigidBody.h:203
void serializeDynamicsWorldInfo(btSerializer *serializer)
void startProfiling(btScalar timeStep)
#define ACTIVE_TAG
virtual void releaseManifold(btPersistentManifold *manifold)=0
btScalar getCcdMotionThreshold() const
virtual void clearForces()
the forces on each rigidbody is accumulating together with gravity. clear this after each timestep...
const btTransform & getAFrame() const
void serializeCollisionObjects(btSerializer *serializer)
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:906
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
void setup(btContactSolverInfo *solverInfo, btTypedConstraint **sortedConstraints, int numConstraints, btIDebugDraw *debugDrawer)
void push_back(const T &_Val)
const btTransform & getCalculatedTransformA() const
virtual void addAction(btActionInterface *)
virtual void solveConstraints(btContactSolverInfo &solverInfo)
point to point constraint between two rigidbodies each with a pivotpoint that descibes the &#39;ballsocke...
void applyGravity()
btTypedConstraintType getConstraintType() const
const btTransform & getCalculatedTransformB() const
virtual void addConstraint(btTypedConstraint *constraint, bool disableCollisionsBetweenLinkedBodies=false)
btScalar getCcdSweptSphereRadius() const
Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
virtual void removeVehicle(btActionInterface *vehicle)
obsolete, use removeAction instead
virtual btVector3 getGravity() const
int btGetConstraintIslandId(const btTypedConstraint *lhs)
void serializeContactManifolds(btSerializer *serializer)
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:123
btSimulationIslandManager * m_islandManager
const btTransform & getCalculatedTransformA() const
Gets the global transform of the offset for body A.
btAlignedObjectArray< btRigidBody * > m_nonStaticRigidBodies
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
virtual void addRigidBody(btRigidBody *body)
btScalar btSin(btScalar x)
Definition: btScalar.h:477
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btScalar m_loLimit
limit_parameters
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
virtual void setGravity(const btVector3 &gravity)
const btTransform & getCalculatedTransformB() const
Gets the global transform of the offset for body B.
const btRigidBody & getRigidBodyB() const
btAlignedObjectArray< btTypedConstraint * > m_sortedConstraints
btScalar m_combinedRestitution
virtual void removeCharacter(btActionInterface *character)
obsolete, use removeAction instead
void setBasis(const btMatrix3x3 &basis)
Set the rotational element by btMatrix3x3.
Definition: btTransform.h:159
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
virtual void startSerialization()=0
btTranslationalLimitMotor * getTranslationalLimitMotor()
Retrieves the limit informacion.
int getInternalType() const
reserved for Bullet internal usage
const btVector3 & getInterpolationAngularVelocity() const
void integrateTransformsInternal(btRigidBody **bodies, int numBodies, btScalar timeStep)
bool wantsSleeping()
Definition: btRigidBody.h:438
btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis locatio...
virtual int calculateSerializeBufferSize() const
bool gDisableDeactivation
Definition: btRigidBody.cpp:26
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:306
SimulationIslandManager creates and handles simulation islands, using btUnionFind.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
CalculateCombinedCallback gCalculateCombinedRestitutionCallback
const btTransform & getBFrame() const
btScalar m_appliedImpulse
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
btInternalTickCallback m_internalTickCallback
#define btAssert(x)
Definition: btScalar.h:131
The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc.
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size...
void buildAndProcessIslands(btDispatcher *dispatcher, btCollisionWorld *collisionWorld, IslandCallback *callback)
btAlignedObjectArray< btActionInterface * > m_actions
virtual void processIsland(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifolds, int numManifolds, int islandId)
void setHitFraction(btScalar hitFraction)
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:131
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
btScalar m_singleAxisRollingFrictionThreshold
btSimulationIslandManager * getSimulationIslandManager()
virtual void removeCollisionObject(btCollisionObject *collisionObject)
removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise ca...
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
int getNumCollisionObjects() const
virtual void removeAction(btActionInterface *)
The btSphereShape implements an implicit sphere, centered around a local origin with radius...
Definition: btSphereShape.h:22
btScalar getTwistSpan() const
virtual void drawArc(const btVector3 &center, const btVector3 &normal, const btVector3 &axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle, const btVector3 &color, bool drawSect, btScalar stepDegrees=btScalar(10.f))
Definition: btIDebugDraw.h:174
Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWor...
btVector3 m_upperLimit
the constraint upper limits
ManifoldContactPoint collects and maintains persistent contactpoints.
const btCollisionObject * getBody0() const
btDispatcher * m_dispatcher1
btVector3 getColumn(int i) const
Get a column of the matrix as a vector.
Definition: btMatrix3x3.h:134
const btRigidBody & getRigidBodyA() const
class btIDebugDraw * m_debugDraw
Definition: btDispatcher.h:59
virtual btScalar addSingleResult(LocalConvexResult &convexResult, bool normalInWorldSpace)
virtual void updateActivationState(btCollisionWorld *colWorld, btDispatcher *dispatcher)
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
#define ISLAND_SLEEPING
const btVector3 & getInterpolationLinearVelocity() const
hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in lo...
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
bool hasContactResponse() const
btVector3FloatData m_gravity
The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out) ...
Definition: btStackAlloc.h:34
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
btScalar getCcdSquareMotionThreshold() const
const btTransform & getInterpolationWorldTransform() const
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
btContactSolverInfoFloatData m_solverInfo
void updateDeactivation(btScalar timeStep)
Definition: btRigidBody.h:421
const btCollisionObject * m_hitCollisionObject
virtual void drawSpherePatch(const btVector3 &center, const btVector3 &up, const btVector3 &axis, btScalar radius, btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3 &color, btScalar stepDegrees=btScalar(10.f), bool drawCenter=true)
Definition: btIDebugDraw.h:199
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
virtual btOverlappingPairCache * getOverlappingPairCache()=0
btCollisionWorld * getCollisionWorld()
#define SIMD_PI
Definition: btScalar.h:504
void setActivationState(int newState) const
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
#define SIMD_2_PI
Definition: btScalar.h:505
btVector3 m_positionWorldOnB
btTranslationalLimitMotor2 * getTranslationalLimitMotor()
btInternalTickCallback m_internalPreTickCallback
int size() const
return the number of elements in the array
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
btBroadphaseProxy * getBroadphaseHandle()
virtual void serialize(btSerializer *serializer)
Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see B...
bool hasLimit() const
btScalar getUpperLimit() const
btIDebugDraw * m_debugDrawer
btAlignedObjectArray< btCollisionObject * > m_bodies
virtual btIDebugDraw * getDebugDrawer()
const btTransform & getCenterOfMassTransform() const
Definition: btRigidBody.h:359
bool isKinematicObject() const
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
void addConstraintRef(btTypedConstraint *c)
bool isStaticObject() const
const btVector3 & getPivotInA() const
btScalar getAngle(int axis_index) const
Get the relative Euler angle.
virtual void predictUnconstraintMotion(btScalar timeStep)
bool isStaticOrKinematicObject() const
void serialize(struct btVector3Data &dataOut) const
Definition: btVector3.h:1352
#define btAlignedFree(ptr)
btCollisionObject can be used to manage collision detection objects.
virtual void saveKinematicState(btScalar timeStep)
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
btScalar getLowerLimit() const
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations...
Definition: btIDebugDraw.h:29
void setLinearVelocity(const btVector3 &lin_vel)
Definition: btRigidBody.h:370
virtual void flushLines()
Definition: btIDebugDraw.h:476
btAlignedObjectArray< btPersistentManifold * > m_predictiveManifolds
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:62
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity ...
virtual void removeCollisionObject(btCollisionObject *collisionObject)
btVector3 m_lowerLimit
the constraint lower limits
void clearForces()
Definition: btRigidBody.h:346
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)=0
static void Reset(void)
btRotationalLimitMotor2 * getRotationalLimitMotor(int index)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
void proceedToTransform(const btTransform &newTrans)
const btManifoldPoint & getContactPoint(int index) const
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
btDispatcher * getDispatcher()
virtual btConstraintSolver * getConstraintSolver()
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
int gNumClampedCcdMotions
internal debugging variable. this value shouldn&#39;t be too high
btAlignedObjectArray< btPersistentManifold * > m_manifolds
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
virtual int stepSimulation(btScalar timeStep, int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))
if maxSubSteps > 0, it will interpolate motion between fixedTimeStep&#39;s
virtual void createPredictiveContacts(btScalar timeStep)
btCollisionAlgorithm * m_algorithm
const btTransform & getCalculatedTransformB() const
virtual void applyGravity()
apply gravity, call this once per timestep
bool isEnabled() const
The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (...
InplaceSolverIslandCallback(btConstraintSolver *solver, btStackAlloc *stackAlloc, btDispatcher *dispatcher)
btScalar getHitFraction() const
const btVector3 & getPositionWorldOnB() const
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)=0
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
const btTransform & getAFrame() const
virtual void debugDrawConstraint(btTypedConstraint *constraint)
const btBroadphaseInterface * getBroadphase() const
#define BT_PROFILE(name)
Definition: btQuickprof.h:216
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) ...
virtual int getNumConstraints() const
bool operator()(const btTypedConstraint *lhs, const btTypedConstraint *rhs) const
virtual void removeConstraint(btTypedConstraint *constraint)
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
static void Increment_Frame_Counter(void)
btScalar m_hiLimit
joint limit
CollisionWorld is interface and container for the collision detection.
virtual void allSolved(const btContactSolverInfo &, class btIDebugDraw *)
void updateActions(btScalar timeStep)
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping ...
virtual btTypedConstraint * getConstraint(int index)
bool isConvex() const
int getIslandTag() const
btDispatcherInfo & getDispatchInfo()
const btTransform & getCalculatedTransformA() const
virtual void prepareSolve(int, int)
#define WANTS_DEACTIVATION
void remove(const T &key)
btScalar m_allowedCcdPenetration
Definition: btDispatcher.h:63
virtual void drawTransform(const btTransform &transform, btScalar orthoLen)
Definition: btIDebugDraw.h:166
TypedConstraint is the baseclass for Bullet constraints and vehicles.
void synchronizeSingleMotionState(btRigidBody *body)
this can be useful to synchronize a single rigid body -> graphics object
void saveKinematicState(btScalar step)
void resize(int newsize, const T &fillData=T())
bool btFuzzyZero(btScalar x)
Definition: btScalar.h:550
virtual void integrateTransforms(btScalar timeStep)
btRotationalLimitMotor * getRotationalLimitMotor(int index)
Retrieves the angular limit informacion.
const btRigidBody & getRigidBodyA() const
void btMutexUnlock(btSpinMutex *mutex)
Definition: btThreads.h:82
void setAngularVelocity(const btVector3 &ang_vel)
Definition: btRigidBody.h:376
virtual int getDebugMode() const =0
btClosestNotMeConvexResultCallback(btCollisionObject *me, const btVector3 &fromA, const btVector3 &toA, btOverlappingPairCache *pairCache, btDispatcher *dispatcher)
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
btDiscreteDynamicsWorld(btDispatcher *dispatcher, btBroadphaseInterface *pairCache, btConstraintSolver *constraintSolver, btCollisionConfiguration *collisionConfiguration)
this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete thos...
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:122
virtual void storeIslandActivationState(btCollisionWorld *world)
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1)=0
#define DISABLE_DEACTIVATION
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
virtual int calculateSerializeBufferSize() const
virtual void performDiscreteCollisionDetection()
const btBroadphaseProxy * getBroadphaseProxy() const
Definition: btRigidBody.h:460
btScalar m_combinedFriction
void btMutexLock(btSpinMutex *mutex)
Definition: btThreads.h:73
InplaceSolverIslandCallback * m_solverIslandCallback
const btVector3 & getPositionWorldOnA() const
virtual void addCharacter(btActionInterface *character)
obsolete, use addAction instead
#define btAlignedAlloc(size, alignment)
btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btConstraintSolver * m_constraintSolver
btMotionState * getMotionState()
Definition: btRigidBody.h:474
const btRigidBody & getRigidBodyA() const
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:362
const btVector3 & getPivotInB() const
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:334
void serializeRigidBodies(btSerializer *serializer)
virtual void updateActivationState(btScalar timeStep)
btAlignedObjectArray< btTypedConstraint * > m_constraints
void convexSweepTest(const btConvexShape *castShape, const btTransform &from, const btTransform &to, ConvexResultCallback &resultCallback, btScalar allowedCcdPenetration=btScalar(0.)) const
convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultC...
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)=0
btScalar m_timeStep
Definition: btDispatcher.h:54
const btRigidBody & getRigidBodyB() const
void createPredictiveContactsInternal(btRigidBody **bodies, int numBodies, btScalar timeStep)
void unite(int p, int q)
Definition: btUnionFind.h:81
virtual void addVehicle(btActionInterface *vehicle)
obsolete, use addAction instead
InplaceSolverIslandCallback & operator=(InplaceSolverIslandCallback &other)
virtual void removeRigidBody(btRigidBody *body)
virtual void debugDrawWorld()
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:77
void removeConstraintRef(btTypedConstraint *c)
const btTransform & getBFrame() const
btScalar getTwistAngle() const
void * m_oldPtr
Definition: btSerializer.h:56
int getActivationState() const
btContactSolverInfo & getSolverInfo()
CalculateCombinedCallback gCalculateCombinedFrictionCallback
const btRigidBody & getRigidBodyB() const
virtual void setWorldTransform(const btTransform &worldTrans)=0
const btCollisionObject * getBody1() const
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::StaticFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter^btBroadphaseProxy::StaticFilter)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
bool isActive() const
void quickSort(const L &CompareFunc)
int getFlags() const
Definition: btRigidBody.h:533
btScalar btCos(btScalar x)
Definition: btScalar.h:476
btAlignedObjectArray< btTypedConstraint * > m_constraints
void setGravity(const btVector3 &acceleration)
btScalar getAngle(int axis_index) const
btTypedConstraint ** m_sortedConstraints
The btBroadphasePair class contains a pair of aabb-overlapping objects.