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  BT_PROFILE("stepSimulation");
406 
407  int numSimulationSubSteps = 0;
408 
409  if (maxSubSteps)
410  {
411  //fixed timestep with interpolation
412  m_fixedTimeStep = fixedTimeStep;
413  m_localTime += timeStep;
414  if (m_localTime >= fixedTimeStep)
415  {
416  numSimulationSubSteps = int( m_localTime / fixedTimeStep);
417  m_localTime -= numSimulationSubSteps * fixedTimeStep;
418  }
419  } else
420  {
421  //variable timestep
422  fixedTimeStep = timeStep;
424  m_fixedTimeStep = 0;
425  if (btFuzzyZero(timeStep))
426  {
427  numSimulationSubSteps = 0;
428  maxSubSteps = 0;
429  } else
430  {
431  numSimulationSubSteps = 1;
432  maxSubSteps = 1;
433  }
434  }
435 
436  //process some debugging flags
437  if (getDebugDrawer())
438  {
439  btIDebugDraw* debugDrawer = getDebugDrawer ();
441  }
442  if (numSimulationSubSteps)
443  {
444 
445  //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
446  int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
447 
448  saveKinematicState(fixedTimeStep*clampedSimulationSteps);
449 
450  applyGravity();
451 
452 
453 
454  for (int i=0;i<clampedSimulationSteps;i++)
455  {
456  internalSingleStepSimulation(fixedTimeStep);
458  }
459 
460  } else
461  {
463  }
464 
465  clearForces();
466 
467 #ifndef BT_NO_PROFILE
469 #endif //BT_NO_PROFILE
470 
471  return numSimulationSubSteps;
472 }
473 
475 {
476 
477  BT_PROFILE("internalSingleStepSimulation");
478 
479  if(0 != m_internalPreTickCallback) {
480  (*m_internalPreTickCallback)(this, timeStep);
481  }
482 
484  predictUnconstraintMotion(timeStep);
485 
486  btDispatcherInfo& dispatchInfo = getDispatchInfo();
487 
488  dispatchInfo.m_timeStep = timeStep;
489  dispatchInfo.m_stepCount = 0;
490  dispatchInfo.m_debugDraw = getDebugDrawer();
491 
492 
493  createPredictiveContacts(timeStep);
494 
497 
499 
500 
501  getSolverInfo().m_timeStep = timeStep;
502 
503 
504 
507 
509 
511 
512  integrateTransforms(timeStep);
513 
515  updateActions(timeStep);
516 
517  updateActivationState( timeStep );
518 
519  if(0 != m_internalTickCallback) {
520  (*m_internalTickCallback)(this, timeStep);
521  }
522 }
523 
525 {
526  m_gravity = gravity;
527  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
528  {
530  if (body->isActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
531  {
532  body->setGravity(gravity);
533  }
534  }
535 }
536 
538 {
539  return m_gravity;
540 }
541 
542 void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
543 {
544  btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask);
545 }
546 
548 {
549  btRigidBody* body = btRigidBody::upcast(collisionObject);
550  if (body)
551  removeRigidBody(body);
552  else
554 }
555 
557 {
560 }
561 
562 
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  {
575  } else
576  {
578  }
579 
580  bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
581  short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
582  short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
583 
584  addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
585  }
586 }
587 
588 void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
589 {
590  if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
591  {
592  body->setGravity(m_gravity);
593  }
594 
595  if (body->getCollisionShape())
596  {
597  if (!body->isStaticObject())
598  {
600  }
601  else
602  {
604  }
605  addCollisionObject(body,group,mask);
606  }
607 }
608 
609 
611 {
612  BT_PROFILE("updateActions");
613 
614  for ( int i=0;i<m_actions.size();i++)
615  {
616  m_actions[i]->updateAction( this, timeStep);
617  }
618 }
619 
620 
622 {
623  BT_PROFILE("updateActivationState");
624 
625  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
626  {
628  if (body)
629  {
630  body->updateDeactivation(timeStep);
631 
632  if (body->wantsSleeping())
633  {
634  if (body->isStaticOrKinematicObject())
635  {
637  } else
638  {
639  if (body->getActivationState() == ACTIVE_TAG)
641  if (body->getActivationState() == ISLAND_SLEEPING)
642  {
643  body->setAngularVelocity(btVector3(0,0,0));
644  body->setLinearVelocity(btVector3(0,0,0));
645  }
646 
647  }
648  } else
649  {
652  }
653  }
654  }
655 }
656 
657 void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
658 {
659  m_constraints.push_back(constraint);
660  //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?)
661  btAssert(&constraint->getRigidBodyA()!=&constraint->getRigidBodyB());
662 
663  if (disableCollisionsBetweenLinkedBodies)
664  {
665  constraint->getRigidBodyA().addConstraintRef(constraint);
666  constraint->getRigidBodyB().addConstraintRef(constraint);
667  }
668 }
669 
671 {
672  m_constraints.remove(constraint);
673  constraint->getRigidBodyA().removeConstraintRef(constraint);
674  constraint->getRigidBodyB().removeConstraintRef(constraint);
675 }
676 
678 {
679  m_actions.push_back(action);
680 }
681 
683 {
684  m_actions.remove(action);
685 }
686 
687 
689 {
690  addAction(vehicle);
691 }
692 
694 {
695  removeAction(vehicle);
696 }
697 
699 {
700  addAction(character);
701 }
702 
704 {
705  removeAction(character);
706 }
707 
708 
709 
710 
712 {
713  BT_PROFILE("solveConstraints");
714 
716  int i;
717  for (i=0;i<getNumConstraints();i++)
718  {
720  }
721 
722 // btAssert(0);
723 
724 
725 
727 
728  btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0;
729 
730  m_solverIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer());
732 
735 
737 
739 }
740 
741 
743 {
744  BT_PROFILE("calculateSimulationIslands");
745 
747 
748  {
749  //merge islands based on speculative contact manifolds too
750  for (int i=0;i<this->m_predictiveManifolds.size();i++)
751  {
753 
754  const btCollisionObject* colObj0 = manifold->getBody0();
755  const btCollisionObject* colObj1 = manifold->getBody1();
756 
757  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
758  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
759  {
760  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
761  }
762  }
763  }
764 
765  {
766  int i;
767  int numConstraints = int(m_constraints.size());
768  for (i=0;i< numConstraints ; i++ )
769  {
770  btTypedConstraint* constraint = m_constraints[i];
771  if (constraint->isEnabled())
772  {
773  const btRigidBody* colObj0 = &constraint->getRigidBodyA();
774  const btRigidBody* colObj1 = &constraint->getRigidBodyB();
775 
776  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
777  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
778  {
779  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
780  }
781  }
782  }
783  }
784 
785  //Store the island id in each body
787 
788 
789 }
790 
791 
792 
793 
795 {
796 public:
797 
802 
803 public:
805  btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
806  m_me(me),
807  m_allowedPenetration(0.0f),
808  m_pairCache(pairCache),
809  m_dispatcher(dispatcher)
810  {
811  }
812 
813  virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
814  {
815  if (convexResult.m_hitCollisionObject == m_me)
816  return 1.0f;
817 
818  //ignore result if there is no contact response
819  if(!convexResult.m_hitCollisionObject->hasContactResponse())
820  return 1.0f;
821 
822  btVector3 linVelA,linVelB;
823  linVelA = m_convexToWorld-m_convexFromWorld;
824  linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin();
825 
826  btVector3 relativeVelocity = (linVelA-linVelB);
827  //don't report time of impact for motion away from the contact normal (or causes minor penetration)
828  if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration)
829  return 1.f;
830 
831  return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
832  }
833 
834  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
835  {
836  //don't collide with itself
837  if (proxy0->m_clientObject == m_me)
838  return false;
839 
842  return false;
843 
844  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
845 
846  //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
847  if (m_dispatcher->needsResponse(m_me,otherObj))
848  {
849 #if 0
852  btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
853  if (collisionPair)
854  {
855  if (collisionPair->m_algorithm)
856  {
857  manifoldArray.resize(0);
858  collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
859  for (int j=0;j<manifoldArray.size();j++)
860  {
861  btPersistentManifold* manifold = manifoldArray[j];
862  if (manifold->getNumContacts()>0)
863  return false;
864  }
865  }
866  }
867 #endif
868  return true;
869  }
870 
871  return false;
872  }
873 
874 
875 };
876 
879 
880 
882 {
883  BT_PROFILE("createPredictiveContacts");
884 
885  {
886  BT_PROFILE("release predictive contact manifolds");
887 
888  for (int i=0;i<m_predictiveManifolds.size();i++)
889  {
891  this->m_dispatcher1->releaseManifold(manifold);
892  }
894  }
895 
896  btTransform predictedTrans;
897  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
898  {
900  body->setHitFraction(1.f);
901 
902  if (body->isActive() && (!body->isStaticOrKinematicObject()))
903  {
904 
905  body->predictIntegratedTransform(timeStep, predictedTrans);
906 
907  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
908 
910  {
911  BT_PROFILE("predictive convexSweepTest");
912  if (body->getCollisionShape()->isConvex())
913  {
915 #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
916  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
917  {
918  public:
919 
920  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
921  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
922  {
923  }
924 
925  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
926  {
927  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
928  if (!otherObj->isStaticOrKinematicObject())
929  return false;
931  }
932  };
933 
934  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
935 #else
937 #endif
938  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
939  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
940  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
941 
942  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
943  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
944  btTransform modifiedPredictedTrans = predictedTrans;
945  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
946 
947  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
948  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
949  {
950 
951  btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction;
952  btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
953 
954 
955  btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject);
957 
958  btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec;
959  btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB;
960 
961  btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance);
962 
963  bool isPredictive = true;
964  int index = manifold->addManifoldPoint(newPoint, isPredictive);
965  btManifoldPoint& pt = manifold->getContactPoint(index);
966  pt.m_combinedRestitution = 0;
967  pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject);
969  pt.m_positionWorldOnB = worldPointB;
970 
971  }
972  }
973  }
974  }
975  }
976 }
978 {
979  BT_PROFILE("integrateTransforms");
980  btTransform predictedTrans;
981  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
982  {
984  body->setHitFraction(1.f);
985 
986  if (body->isActive() && (!body->isStaticOrKinematicObject()))
987  {
988 
989  body->predictIntegratedTransform(timeStep, predictedTrans);
990 
991  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
992 
993 
994 
996  {
997  BT_PROFILE("CCD motion clamping");
998  if (body->getCollisionShape()->isConvex())
999  {
1001 #ifdef USE_STATIC_ONLY
1002  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
1003  {
1004  public:
1005 
1006  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
1007  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
1008  {
1009  }
1010 
1011  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
1012  {
1013  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
1014  if (!otherObj->isStaticOrKinematicObject())
1015  return false;
1017  }
1018  };
1019 
1020  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
1021 #else
1023 #endif
1024  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1025  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1026  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
1027 
1028  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
1029  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
1030  btTransform modifiedPredictedTrans = predictedTrans;
1031  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
1032 
1033  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
1034  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
1035  {
1036 
1037  //printf("clamped integration to hit fraction = %f\n",fraction);
1038  body->setHitFraction(sweepResults.m_closestHitFraction);
1039  body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
1040  body->setHitFraction(0.f);
1041  body->proceedToTransform( predictedTrans);
1042 
1043 #if 0
1044  btVector3 linVel = body->getLinearVelocity();
1045 
1047  btScalar maxSpeedSqr = maxSpeed*maxSpeed;
1048  if (linVel.length2()>maxSpeedSqr)
1049  {
1050  linVel.normalize();
1051  linVel*= maxSpeed;
1052  body->setLinearVelocity(linVel);
1053  btScalar ms2 = body->getLinearVelocity().length2();
1054  body->predictIntegratedTransform(timeStep, predictedTrans);
1055 
1056  btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1057  btScalar smt = body->getCcdSquareMotionThreshold();
1058  printf("sm2=%f\n",sm2);
1059  }
1060 #else
1061 
1062  //don't apply the collision response right now, it will happen next frame
1063  //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
1064  //btScalar appliedImpulse = 0.f;
1065  //btScalar depth = 0.f;
1066  //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
1067 
1068 
1069 #endif
1070 
1071  continue;
1072  }
1073  }
1074  }
1075 
1076 
1077  body->proceedToTransform( predictedTrans);
1078 
1079  }
1080 
1081  }
1082 
1085  {
1086  BT_PROFILE("apply speculative contact restitution");
1087  for (int i=0;i<m_predictiveManifolds.size();i++)
1088  {
1092 
1093  for (int p=0;p<manifold->getNumContacts();p++)
1094  {
1095  const btManifoldPoint& pt = manifold->getContactPoint(p);
1096  btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1);
1097 
1098  if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1099  //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1100  {
1101  btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution;
1102 
1103  const btVector3& pos1 = pt.getPositionWorldOnA();
1104  const btVector3& pos2 = pt.getPositionWorldOnB();
1105 
1106  btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
1107  btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
1108 
1109  if (body0)
1110  body0->applyImpulse(imp,rel_pos0);
1111  if (body1)
1112  body1->applyImpulse(-imp,rel_pos1);
1113  }
1114  }
1115  }
1116  }
1117 
1118 }
1119 
1120 
1121 
1122 
1123 
1124 
1126 {
1127  BT_PROFILE("predictUnconstraintMotion");
1128  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
1129  {
1131  if (!body->isStaticOrKinematicObject())
1132  {
1133  //don't integrate/update velocities here, it happens in the constraint solver
1134 
1135  body->applyDamping(timeStep);
1136 
1138  }
1139  }
1140 }
1141 
1142 
1144 {
1145  (void)timeStep;
1146 
1147 #ifndef BT_NO_PROFILE
1149 #endif //BT_NO_PROFILE
1150 
1151 }
1152 
1153 
1154 
1155 
1156 
1157 
1159 {
1160  bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
1161  bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
1162  btScalar dbgDrawSize = constraint->getDbgDrawSize();
1163  if(dbgDrawSize <= btScalar(0.f))
1164  {
1165  return;
1166  }
1167 
1168  switch(constraint->getConstraintType())
1169  {
1171  {
1172  btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
1173  btTransform tr;
1174  tr.setIdentity();
1175  btVector3 pivot = p2pC->getPivotInA();
1176  pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1177  tr.setOrigin(pivot);
1178  getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1179  // that ideally should draw the same frame
1180  pivot = p2pC->getPivotInB();
1181  pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1182  tr.setOrigin(pivot);
1183  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1184  }
1185  break;
1186  case HINGE_CONSTRAINT_TYPE:
1187  {
1188  btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
1189  btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1190  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1191  tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1192  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1193  btScalar minAng = pHinge->getLowerLimit();
1194  btScalar maxAng = pHinge->getUpperLimit();
1195  if(minAng == maxAng)
1196  {
1197  break;
1198  }
1199  bool drawSect = true;
1200  if(!pHinge->hasLimit())
1201  {
1202  minAng = btScalar(0.f);
1203  maxAng = SIMD_2_PI;
1204  drawSect = false;
1205  }
1206  if(drawLimits)
1207  {
1208  btVector3& center = tr.getOrigin();
1209  btVector3 normal = tr.getBasis().getColumn(2);
1210  btVector3 axis = tr.getBasis().getColumn(0);
1211  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
1212  }
1213  }
1214  break;
1216  {
1217  btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
1219  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1220  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1221  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1222  if(drawLimits)
1223  {
1224  //const btScalar length = btScalar(5);
1225  const btScalar length = dbgDrawSize;
1226  static int nSegments = 8*4;
1227  btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
1228  btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1229  pPrev = tr * pPrev;
1230  for (int i=0; i<nSegments; i++)
1231  {
1232  fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
1233  btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1234  pCur = tr * pCur;
1235  getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
1236 
1237  if (i%(nSegments/8) == 0)
1238  getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
1239 
1240  pPrev = pCur;
1241  }
1242  btScalar tws = pCT->getTwistSpan();
1243  btScalar twa = pCT->getTwistAngle();
1244  bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1245  if(useFrameB)
1246  {
1247  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1248  }
1249  else
1250  {
1251  tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1252  }
1253  btVector3 pivot = tr.getOrigin();
1254  btVector3 normal = tr.getBasis().getColumn(0);
1255  btVector3 axis1 = tr.getBasis().getColumn(1);
1256  getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
1257 
1258  }
1259  }
1260  break;
1262  case D6_CONSTRAINT_TYPE:
1263  {
1264  btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
1265  btTransform tr = p6DOF->getCalculatedTransformA();
1266  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1267  tr = p6DOF->getCalculatedTransformB();
1268  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1269  if(drawLimits)
1270  {
1271  tr = p6DOF->getCalculatedTransformA();
1272  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1273  btVector3 up = tr.getBasis().getColumn(2);
1274  btVector3 axis = tr.getBasis().getColumn(0);
1275  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1276  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1277  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1278  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1279  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
1280  axis = tr.getBasis().getColumn(1);
1281  btScalar ay = p6DOF->getAngle(1);
1282  btScalar az = p6DOF->getAngle(2);
1283  btScalar cy = btCos(ay);
1284  btScalar sy = btSin(ay);
1285  btScalar cz = btCos(az);
1286  btScalar sz = btSin(az);
1287  btVector3 ref;
1288  ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1289  ref[1] = -sz*axis[0] + cz*axis[1];
1290  ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1291  tr = p6DOF->getCalculatedTransformB();
1292  btVector3 normal = -tr.getBasis().getColumn(0);
1293  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1294  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1295  if(minFi > maxFi)
1296  {
1297  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
1298  }
1299  else if(minFi < maxFi)
1300  {
1301  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
1302  }
1303  tr = p6DOF->getCalculatedTransformA();
1306  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
1307  }
1308  }
1309  break;
1312  {
1313  {
1315  btTransform tr = p6DOF->getCalculatedTransformA();
1316  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1317  tr = p6DOF->getCalculatedTransformB();
1318  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1319  if (drawLimits)
1320  {
1321  tr = p6DOF->getCalculatedTransformA();
1322  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1323  btVector3 up = tr.getBasis().getColumn(2);
1324  btVector3 axis = tr.getBasis().getColumn(0);
1325  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1326  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1327  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1328  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1329  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1330  axis = tr.getBasis().getColumn(1);
1331  btScalar ay = p6DOF->getAngle(1);
1332  btScalar az = p6DOF->getAngle(2);
1333  btScalar cy = btCos(ay);
1334  btScalar sy = btSin(ay);
1335  btScalar cz = btCos(az);
1336  btScalar sz = btSin(az);
1337  btVector3 ref;
1338  ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1339  ref[1] = -sz*axis[0] + cz*axis[1];
1340  ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1341  tr = p6DOF->getCalculatedTransformB();
1342  btVector3 normal = -tr.getBasis().getColumn(0);
1343  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1344  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1345  if (minFi > maxFi)
1346  {
1347  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1348  }
1349  else if (minFi < maxFi)
1350  {
1351  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1352  }
1353  tr = p6DOF->getCalculatedTransformA();
1356  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1357  }
1358  }
1359  break;
1360  }
1362  {
1363  btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
1364  btTransform tr = pSlider->getCalculatedTransformA();
1365  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1366  tr = pSlider->getCalculatedTransformB();
1367  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1368  if(drawLimits)
1369  {
1371  btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1372  btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1373  getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
1374  btVector3 normal = tr.getBasis().getColumn(0);
1375  btVector3 axis = tr.getBasis().getColumn(1);
1376  btScalar a_min = pSlider->getLowerAngLimit();
1377  btScalar a_max = pSlider->getUpperAngLimit();
1378  const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1379  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
1380  }
1381  }
1382  break;
1383  default :
1384  break;
1385  }
1386  return;
1387 }
1388 
1389 
1390 
1391 
1392 
1394 {
1396  {
1398  }
1399  m_ownsConstraintSolver = false;
1400  m_constraintSolver = solver;
1401  m_solverIslandCallback->m_solver = solver;
1402 }
1403 
1405 {
1406  return m_constraintSolver;
1407 }
1408 
1409 
1411 {
1412  return int(m_constraints.size());
1413 }
1415 {
1416  return m_constraints[index];
1417 }
1419 {
1420  return m_constraints[index];
1421 }
1422 
1423 
1424 
1426 {
1427  int i;
1428  //serialize all collision objects
1429  for (i=0;i<m_collisionObjects.size();i++)
1430  {
1433  {
1434  int len = colObj->calculateSerializeBufferSize();
1435  btChunk* chunk = serializer->allocate(len,1);
1436  const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1437  serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
1438  }
1439  }
1440 
1441  for (i=0;i<m_constraints.size();i++)
1442  {
1443  btTypedConstraint* constraint = m_constraints[i];
1444  int size = constraint->calculateSerializeBufferSize();
1445  btChunk* chunk = serializer->allocate(size,1);
1446  const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
1447  serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
1448  }
1449 }
1450 
1451 
1452 
1453 
1455 {
1456 #ifdef BT_USE_DOUBLE_PRECISION
1457  int len = sizeof(btDynamicsWorldDoubleData);
1458  btChunk* chunk = serializer->allocate(len,1);
1460 #else//BT_USE_DOUBLE_PRECISION
1461  int len = sizeof(btDynamicsWorldFloatData);
1462  btChunk* chunk = serializer->allocate(len,1);
1464 #endif//BT_USE_DOUBLE_PRECISION
1465 
1466  memset(worldInfo ,0x00,len);
1467 
1468  m_gravity.serialize(worldInfo->m_gravity);
1469  worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
1473 
1476  worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
1477  worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
1478 
1479  worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
1483 
1488 
1493 
1495 
1496 #ifdef BT_USE_DOUBLE_PRECISION
1497  const char* structType = "btDynamicsWorldDoubleData";
1498 #else//BT_USE_DOUBLE_PRECISION
1499  const char* structType = "btDynamicsWorldFloatData";
1500 #endif//BT_USE_DOUBLE_PRECISION
1501  serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo);
1502 }
1503 
1505 {
1506 
1507  serializer->startSerialization();
1508 
1509  serializeDynamicsWorldInfo(serializer);
1510 
1511  serializeCollisionObjects(serializer);
1512 
1513  serializeRigidBodies(serializer);
1514 
1515  serializer->finishSerialization();
1516 }
1517 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btScalar getInvMass() const
Definition: btRigidBody.h:270
virtual void setConstraintSolver(btConstraintSolver *solver)
const btCollisionShape * getCollisionShape() const
Definition: btRigidBody.h:251
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:200
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:835
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)
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:119
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:451
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btScalar m_loLimit
limit_parameters
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
short int m_collisionFilterGroup
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
bool wantsSleeping()
Definition: btRigidBody.h:435
btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis locatio...
virtual int calculateSerializeBufferSize() const
virtual int getDebugMode() const =0
bool gDisableDeactivation
Definition: btRigidBody.cpp:26
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:277
SimulationIslandManager creates and handles simulation islands, using btUnionFind.
virtual void addCollisionObject(btCollisionObject *collisionObject, short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, short int collisionFilterMask=btBroadphaseProxy::AllFilter)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
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:113
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:127
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:63
int getNumCollisionObjects() const
virtual void removeAction(btActionInterface *)
The btSphereShape implements an implicit sphere, centered around a local origin with radius...
Definition: btSphereShape.h:22
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:145
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:58
virtual btScalar addSingleResult(LocalConvexResult &convexResult, bool normalInWorldSpace)
virtual void updateActivationState(btCollisionWorld *colWorld, btDispatcher *dispatcher)
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
#define ISLAND_SLEEPING
virtual void addCollisionObject(btCollisionObject *collisionObject, short int collisionFilterGroup=btBroadphaseProxy::StaticFilter, short int collisionFilterMask=btBroadphaseProxy::AllFilter^btBroadphaseProxy::StaticFilter)
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:297
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:418
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:170
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:476
void setActivationState(int newState) const
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
#define SIMD_2_PI
Definition: btScalar.h:477
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:356
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:1340
#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:28
void setLinearVelocity(const btVector3 &lin_vel)
Definition: btRigidBody.h:367
virtual void flushLines()
Definition: btIDebugDraw.h:443
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:343
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
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
static btScalar calculateCombinedFriction(const btCollisionObject *body0, const btCollisionObject *body1)
User can override this material combiner by implementing gContactAddedCallback and setting body0->m_c...
const btTransform & getAFrame()
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
virtual void debugDrawConstraint(btTypedConstraint *constraint)
const btBroadphaseInterface * getBroadphase() const
#define BT_PROFILE(name)
Definition: btQuickprof.h:196
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
const btTransform & getBFrame()
virtual void prepareSolve(int, int)
#define WANTS_DEACTIVATION
void remove(const T &key)
btScalar m_allowedCcdPenetration
Definition: btDispatcher.h:62
virtual void drawTransform(const btTransform &transform, btScalar orthoLen)
Definition: btIDebugDraw.h:137
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:518
virtual void integrateTransforms(btScalar timeStep)
btRotationalLimitMotor * getRotationalLimitMotor(int index)
Retrieves the angular limit informacion.
const btRigidBody & getRigidBodyA() const
void setAngularVelocity(const btVector3 &ang_vel)
Definition: btRigidBody.h:373
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:118
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:457
btScalar m_combinedFriction
InplaceSolverIslandCallback * m_solverIslandCallback
const btVector3 & getPositionWorldOnA() const
virtual void addCharacter(btActionInterface *character)
obsolete, use addAction instead
#define btAlignedAlloc(size, alignment)
short int m_collisionFilterMask
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:471
const btRigidBody & getRigidBodyA() const
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:359
const btVector3 & getPivotInB() const
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:331
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...
btScalar m_timeStep
Definition: btDispatcher.h:53
const btRigidBody & getRigidBodyB() const
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:69
void removeConstraintRef(btTypedConstraint *c)
static btScalar calculateCombinedRestitution(const btCollisionObject *body0, const btCollisionObject *body1)
in the future we can let the user override the methods to combine restitution and friction ...
void * m_oldPtr
Definition: btSerializer.h:56
int getActivationState() const
btContactSolverInfo & getSolverInfo()
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
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:278
bool isActive() const
void quickSort(const L &CompareFunc)
int getFlags() const
Definition: btRigidBody.h:530
btScalar btCos(btScalar x)
Definition: btScalar.h:450
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.