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, int collisionFilterGroup, 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  int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
582  int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
583 
584  addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
585  }
586 }
587 
588 void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, int group, int 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  btTransform predictedTrans;
884  for ( int i=0;i<numBodies;i++)
885  {
886  btRigidBody* body = bodies[i];
887  body->setHitFraction(1.f);
888 
889  if (body->isActive() && (!body->isStaticOrKinematicObject()))
890  {
891 
892  body->predictIntegratedTransform(timeStep, predictedTrans);
893 
894  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
895 
897  {
898  BT_PROFILE("predictive convexSweepTest");
899  if (body->getCollisionShape()->isConvex())
900  {
902 #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
903  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
904  {
905  public:
906 
907  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
908  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
909  {
910  }
911 
912  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
913  {
914  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
915  if (!otherObj->isStaticOrKinematicObject())
916  return false;
918  }
919  };
920 
921  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
922 #else
924 #endif
925  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
926  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
927  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
928 
929  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
930  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
931  btTransform modifiedPredictedTrans = predictedTrans;
932  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
933 
934  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
935  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
936  {
937 
938  btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction;
939  btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
940 
941 
942  btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject);
946 
947  btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec;
948  btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB;
949 
950  btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance);
951 
952  bool isPredictive = true;
953  int index = manifold->addManifoldPoint(newPoint, isPredictive);
954  btManifoldPoint& pt = manifold->getContactPoint(index);
955  pt.m_combinedRestitution = 0;
956  pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject);
958  pt.m_positionWorldOnB = worldPointB;
959 
960  }
961  }
962  }
963  }
964  }
965 }
966 
968 {
969  BT_PROFILE( "release predictive contact manifolds" );
970 
971  for ( int i = 0; i < m_predictiveManifolds.size(); i++ )
972  {
974  this->m_dispatcher1->releaseManifold( manifold );
975  }
977 }
978 
980 {
981  BT_PROFILE("createPredictiveContacts");
983  if (m_nonStaticRigidBodies.size() > 0)
984  {
986  }
987 }
988 
990 {
991  btTransform predictedTrans;
992  for (int i=0;i<numBodies;i++)
993  {
994  btRigidBody* body = bodies[i];
995  body->setHitFraction(1.f);
996 
997  if (body->isActive() && (!body->isStaticOrKinematicObject()))
998  {
999 
1000  body->predictIntegratedTransform(timeStep, predictedTrans);
1001 
1002  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1003 
1004 
1005 
1007  {
1008  BT_PROFILE("CCD motion clamping");
1009  if (body->getCollisionShape()->isConvex())
1010  {
1012 #ifdef USE_STATIC_ONLY
1013  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
1014  {
1015  public:
1016 
1017  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
1018  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
1019  {
1020  }
1021 
1022  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
1023  {
1024  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
1025  if (!otherObj->isStaticOrKinematicObject())
1026  return false;
1028  }
1029  };
1030 
1031  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
1032 #else
1034 #endif
1035  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1036  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1037  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
1038 
1039  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
1040  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
1041  btTransform modifiedPredictedTrans = predictedTrans;
1042  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
1043 
1044  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
1045  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
1046  {
1047 
1048  //printf("clamped integration to hit fraction = %f\n",fraction);
1049  body->setHitFraction(sweepResults.m_closestHitFraction);
1050  body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
1051  body->setHitFraction(0.f);
1052  body->proceedToTransform( predictedTrans);
1053 
1054 #if 0
1055  btVector3 linVel = body->getLinearVelocity();
1056 
1058  btScalar maxSpeedSqr = maxSpeed*maxSpeed;
1059  if (linVel.length2()>maxSpeedSqr)
1060  {
1061  linVel.normalize();
1062  linVel*= maxSpeed;
1063  body->setLinearVelocity(linVel);
1064  btScalar ms2 = body->getLinearVelocity().length2();
1065  body->predictIntegratedTransform(timeStep, predictedTrans);
1066 
1067  btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1068  btScalar smt = body->getCcdSquareMotionThreshold();
1069  printf("sm2=%f\n",sm2);
1070  }
1071 #else
1072 
1073  //don't apply the collision response right now, it will happen next frame
1074  //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
1075  //btScalar appliedImpulse = 0.f;
1076  //btScalar depth = 0.f;
1077  //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
1078 
1079 
1080 #endif
1081 
1082  continue;
1083  }
1084  }
1085  }
1086 
1087 
1088  body->proceedToTransform( predictedTrans);
1089 
1090  }
1091 
1092  }
1093 
1094 }
1095 
1097 {
1098  BT_PROFILE("integrateTransforms");
1099  if (m_nonStaticRigidBodies.size() > 0)
1100  {
1102  }
1103 
1106  {
1107  BT_PROFILE("apply speculative contact restitution");
1108  for (int i=0;i<m_predictiveManifolds.size();i++)
1109  {
1113 
1114  for (int p=0;p<manifold->getNumContacts();p++)
1115  {
1116  const btManifoldPoint& pt = manifold->getContactPoint(p);
1117  btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1);
1118 
1119  if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1120  //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1121  {
1122  btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution;
1123 
1124  const btVector3& pos1 = pt.getPositionWorldOnA();
1125  const btVector3& pos2 = pt.getPositionWorldOnB();
1126 
1127  btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
1128  btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
1129 
1130  if (body0)
1131  body0->applyImpulse(imp,rel_pos0);
1132  if (body1)
1133  body1->applyImpulse(-imp,rel_pos1);
1134  }
1135  }
1136  }
1137  }
1138 }
1139 
1140 
1141 
1142 
1143 
1145 {
1146  BT_PROFILE("predictUnconstraintMotion");
1147  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
1148  {
1150  if (!body->isStaticOrKinematicObject())
1151  {
1152  //don't integrate/update velocities here, it happens in the constraint solver
1153 
1154  body->applyDamping(timeStep);
1155 
1157  }
1158  }
1159 }
1160 
1161 
1163 {
1164  (void)timeStep;
1165 
1166 #ifndef BT_NO_PROFILE
1168 #endif //BT_NO_PROFILE
1169 
1170 }
1171 
1172 
1173 
1174 
1175 
1176 
1178 {
1179  bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
1180  bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
1181  btScalar dbgDrawSize = constraint->getDbgDrawSize();
1182  if(dbgDrawSize <= btScalar(0.f))
1183  {
1184  return;
1185  }
1186 
1187  switch(constraint->getConstraintType())
1188  {
1190  {
1191  btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
1192  btTransform tr;
1193  tr.setIdentity();
1194  btVector3 pivot = p2pC->getPivotInA();
1195  pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1196  tr.setOrigin(pivot);
1197  getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1198  // that ideally should draw the same frame
1199  pivot = p2pC->getPivotInB();
1200  pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1201  tr.setOrigin(pivot);
1202  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1203  }
1204  break;
1205  case HINGE_CONSTRAINT_TYPE:
1206  {
1207  btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
1208  btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1209  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1210  tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1211  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1212  btScalar minAng = pHinge->getLowerLimit();
1213  btScalar maxAng = pHinge->getUpperLimit();
1214  if(minAng == maxAng)
1215  {
1216  break;
1217  }
1218  bool drawSect = true;
1219  if(!pHinge->hasLimit())
1220  {
1221  minAng = btScalar(0.f);
1222  maxAng = SIMD_2_PI;
1223  drawSect = false;
1224  }
1225  if(drawLimits)
1226  {
1227  btVector3& center = tr.getOrigin();
1228  btVector3 normal = tr.getBasis().getColumn(2);
1229  btVector3 axis = tr.getBasis().getColumn(0);
1230  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
1231  }
1232  }
1233  break;
1235  {
1236  btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
1238  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1239  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1240  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1241  if(drawLimits)
1242  {
1243  //const btScalar length = btScalar(5);
1244  const btScalar length = dbgDrawSize;
1245  static int nSegments = 8*4;
1246  btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
1247  btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1248  pPrev = tr * pPrev;
1249  for (int i=0; i<nSegments; i++)
1250  {
1251  fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
1252  btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1253  pCur = tr * pCur;
1254  getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
1255 
1256  if (i%(nSegments/8) == 0)
1257  getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
1258 
1259  pPrev = pCur;
1260  }
1261  btScalar tws = pCT->getTwistSpan();
1262  btScalar twa = pCT->getTwistAngle();
1263  bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1264  if(useFrameB)
1265  {
1266  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1267  }
1268  else
1269  {
1270  tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1271  }
1272  btVector3 pivot = tr.getOrigin();
1273  btVector3 normal = tr.getBasis().getColumn(0);
1274  btVector3 axis1 = tr.getBasis().getColumn(1);
1275  getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
1276 
1277  }
1278  }
1279  break;
1281  case D6_CONSTRAINT_TYPE:
1282  {
1283  btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
1284  btTransform tr = p6DOF->getCalculatedTransformA();
1285  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1286  tr = p6DOF->getCalculatedTransformB();
1287  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1288  if(drawLimits)
1289  {
1290  tr = p6DOF->getCalculatedTransformA();
1291  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1292  btVector3 up = tr.getBasis().getColumn(2);
1293  btVector3 axis = tr.getBasis().getColumn(0);
1294  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1295  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1296  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1297  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1298  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
1299  axis = tr.getBasis().getColumn(1);
1300  btScalar ay = p6DOF->getAngle(1);
1301  btScalar az = p6DOF->getAngle(2);
1302  btScalar cy = btCos(ay);
1303  btScalar sy = btSin(ay);
1304  btScalar cz = btCos(az);
1305  btScalar sz = btSin(az);
1306  btVector3 ref;
1307  ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1308  ref[1] = -sz*axis[0] + cz*axis[1];
1309  ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1310  tr = p6DOF->getCalculatedTransformB();
1311  btVector3 normal = -tr.getBasis().getColumn(0);
1312  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1313  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1314  if(minFi > maxFi)
1315  {
1316  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
1317  }
1318  else if(minFi < maxFi)
1319  {
1320  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
1321  }
1322  tr = p6DOF->getCalculatedTransformA();
1325  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
1326  }
1327  }
1328  break;
1331  {
1332  {
1334  btTransform tr = p6DOF->getCalculatedTransformA();
1335  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1336  tr = p6DOF->getCalculatedTransformB();
1337  if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1338  if (drawLimits)
1339  {
1340  tr = p6DOF->getCalculatedTransformA();
1341  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1342  btVector3 up = tr.getBasis().getColumn(2);
1343  btVector3 axis = tr.getBasis().getColumn(0);
1344  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1345  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1346  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1347  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1348  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1349  axis = tr.getBasis().getColumn(1);
1350  btScalar ay = p6DOF->getAngle(1);
1351  btScalar az = p6DOF->getAngle(2);
1352  btScalar cy = btCos(ay);
1353  btScalar sy = btSin(ay);
1354  btScalar cz = btCos(az);
1355  btScalar sz = btSin(az);
1356  btVector3 ref;
1357  ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1358  ref[1] = -sz*axis[0] + cz*axis[1];
1359  ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1360  tr = p6DOF->getCalculatedTransformB();
1361  btVector3 normal = -tr.getBasis().getColumn(0);
1362  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1363  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1364  if (minFi > maxFi)
1365  {
1366  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1367  }
1368  else if (minFi < maxFi)
1369  {
1370  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1371  }
1372  tr = p6DOF->getCalculatedTransformA();
1375  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1376  }
1377  }
1378  break;
1379  }
1381  {
1382  btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
1383  btTransform tr = pSlider->getCalculatedTransformA();
1384  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1385  tr = pSlider->getCalculatedTransformB();
1386  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1387  if(drawLimits)
1388  {
1390  btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1391  btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1392  getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
1393  btVector3 normal = tr.getBasis().getColumn(0);
1394  btVector3 axis = tr.getBasis().getColumn(1);
1395  btScalar a_min = pSlider->getLowerAngLimit();
1396  btScalar a_max = pSlider->getUpperAngLimit();
1397  const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1398  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
1399  }
1400  }
1401  break;
1402  default :
1403  break;
1404  }
1405  return;
1406 }
1407 
1408 
1409 
1410 
1411 
1413 {
1415  {
1417  }
1418  m_ownsConstraintSolver = false;
1419  m_constraintSolver = solver;
1420  m_solverIslandCallback->m_solver = solver;
1421 }
1422 
1424 {
1425  return m_constraintSolver;
1426 }
1427 
1428 
1430 {
1431  return int(m_constraints.size());
1432 }
1434 {
1435  return m_constraints[index];
1436 }
1438 {
1439  return m_constraints[index];
1440 }
1441 
1442 
1443 
1445 {
1446  int i;
1447  //serialize all collision objects
1448  for (i=0;i<m_collisionObjects.size();i++)
1449  {
1452  {
1453  int len = colObj->calculateSerializeBufferSize();
1454  btChunk* chunk = serializer->allocate(len,1);
1455  const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1456  serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
1457  }
1458  }
1459 
1460  for (i=0;i<m_constraints.size();i++)
1461  {
1462  btTypedConstraint* constraint = m_constraints[i];
1463  int size = constraint->calculateSerializeBufferSize();
1464  btChunk* chunk = serializer->allocate(size,1);
1465  const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
1466  serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
1467  }
1468 }
1469 
1470 
1471 
1472 
1474 {
1475 #ifdef BT_USE_DOUBLE_PRECISION
1476  int len = sizeof(btDynamicsWorldDoubleData);
1477  btChunk* chunk = serializer->allocate(len,1);
1479 #else//BT_USE_DOUBLE_PRECISION
1480  int len = sizeof(btDynamicsWorldFloatData);
1481  btChunk* chunk = serializer->allocate(len,1);
1483 #endif//BT_USE_DOUBLE_PRECISION
1484 
1485  memset(worldInfo ,0x00,len);
1486 
1487  m_gravity.serialize(worldInfo->m_gravity);
1488  worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
1492 
1495  worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
1496  worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
1497 
1498  worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
1502 
1507 
1512 
1514 
1515 #ifdef BT_USE_DOUBLE_PRECISION
1516  const char* structType = "btDynamicsWorldDoubleData";
1517 #else//BT_USE_DOUBLE_PRECISION
1518  const char* structType = "btDynamicsWorldFloatData";
1519 #endif//BT_USE_DOUBLE_PRECISION
1520  serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo);
1521 }
1522 
1524 {
1525 
1526  serializer->startSerialization();
1527 
1528  serializeDynamicsWorldInfo(serializer);
1529 
1530  serializeCollisionObjects(serializer);
1531 
1532  serializeRigidBodies(serializer);
1533 
1534  serializer->finishSerialization();
1535 }
1536 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
virtual void setConstraintSolver(btConstraintSolver *solver)
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)
const btRigidBody & getRigidBodyA() const
void startProfiling(btScalar timeStep)
#define ACTIVE_TAG
virtual void releaseManifold(btPersistentManifold *manifold)=0
virtual void clearForces()
the forces on each rigidbody is accumulating together with gravity. clear this after each timestep...
void serializeCollisionObjects(btSerializer *serializer)
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:856
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
const btVector3 & getInterpolationAngularVelocity() const
void setup(btContactSolverInfo *solverInfo, btTypedConstraint **sortedConstraints, int numConstraints, btIDebugDraw *debugDrawer)
void push_back(const T &_Val)
void btMutexLock(btSpinMutex *)
Definition: btThreads.h:69
btScalar getUpperLimit() 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...
bool operator()(const btTypedConstraint *lhs, const btTypedConstraint *rhs) const
void applyGravity()
virtual void addConstraint(btTypedConstraint *constraint, bool disableCollisionsBetweenLinkedBodies=false)
virtual void removeVehicle(btActionInterface *vehicle)
obsolete, use removeAction instead
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
const btRigidBody & getRigidBodyB() const
int btGetConstraintIslandId(const btTypedConstraint *lhs)
const btVector3 & getPositionWorldOnA() const
const btVector3 & getPivotInA() const
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:121
const btTransform & getBFrame() const
btSimulationIslandManager * m_islandManager
const btTransform & getCalculatedTransformA() const
btScalar getLowerLimit() const
const btTransform & getCalculatedTransformB() const
btAlignedObjectArray< btRigidBody * > m_nonStaticRigidBodies
bool isConvex() const
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
virtual void addRigidBody(btRigidBody *body)
btScalar btSin(btScalar x)
Definition: btScalar.h:452
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
const btVector3 & getPivotInB() const
btScalar m_loLimit
limit_parameters
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
virtual void setGravity(const btVector3 &gravity)
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::StaticFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter)
const btTransform & getCenterOfMassTransform() const
Definition: btRigidBody.h:359
btAlignedObjectArray< btTypedConstraint * > m_sortedConstraints
btScalar m_combinedRestitution
virtual void removeCharacter(btActionInterface *character)
obsolete, use removeAction instead
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
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
const btRigidBody & getRigidBodyB() const
virtual void startSerialization()=0
btTranslationalLimitMotor * getTranslationalLimitMotor()
Retrieves the limit informacion.
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...
bool gDisableDeactivation
Definition: btRigidBody.cpp:26
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:306
const btRigidBody & getRigidBodyA() const
SimulationIslandManager creates and handles simulation islands, using btUnionFind.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
btScalar m_appliedImpulse
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
btInternalTickCallback m_internalTickCallback
#define btAssert(x)
Definition: btScalar.h:114
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)
virtual btVector3 getGravity() const
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:129
bool isKinematicObject() const
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:64
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: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.
int getActivationState() const
btDispatcher * m_dispatcher1
class btIDebugDraw * m_debugDraw
Definition: btDispatcher.h:58
virtual btScalar addSingleResult(LocalConvexResult &convexResult, bool normalInWorldSpace)
virtual void updateActivationState(btCollisionWorld *colWorld, btDispatcher *dispatcher)
const btRigidBody & getRigidBodyB() const
const btTransform & getCalculatedTransformA() const
const btTransform & getAFrame() const
#define ISLAND_SLEEPING
bool isStaticOrKinematicObject() const
btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const
hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in lo...
btVector3FloatData m_gravity
btScalar getTwistAngle() const
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:307
int getNumCollisionObjects() const
const btCollisionShape * getCollisionShape() const
Definition: btRigidBody.h:254
const btVector3 & getInterpolationLinearVelocity() const
const btTransform & getCalculatedTransformA() const
Gets the global transform of the offset for body A.
virtual bool needsCollision(btBroadphaseProxy *proxy0) 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.
const btManifoldPoint & getContactPoint(int index) const
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
btVector3 getColumn(int i) const
Get a column of the matrix as a vector.
Definition: btMatrix3x3.h:134
virtual btOverlappingPairCache * getOverlappingPairCache()=0
btCollisionWorld * getCollisionWorld()
#define SIMD_PI
Definition: btScalar.h:477
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
#define SIMD_2_PI
Definition: btScalar.h:478
btVector3 m_positionWorldOnB
btTranslationalLimitMotor2 * getTranslationalLimitMotor()
btInternalTickCallback m_internalPreTickCallback
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...
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:362
btIDebugDraw * m_debugDrawer
const btTransform & getCalculatedTransformB() const
Gets the global transform of the offset for body B.
btAlignedObjectArray< btCollisionObject * > m_bodies
virtual btIDebugDraw * getDebugDrawer()
btScalar getCcdSquareMotionThreshold() const
const btVector3 & getPositionWorldOnB() const
const btCollisionObject * getBody0() const
bool isEnabled() const
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
void addConstraintRef(btTypedConstraint *c)
bool isStaticObject() const
btScalar getInvMass() const
Definition: btRigidBody.h:273
const btBroadphaseProxy * getBroadphaseProxy() const
Definition: btRigidBody.h:460
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
virtual void predictUnconstraintMotion(btScalar timeStep)
const btTransform & getCalculatedTransformB() const
#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
bool hasContactResponse() 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
const btTransform & getInterpolationWorldTransform() const
virtual void flushLines()
Definition: btIDebugDraw.h:472
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
int getFlags() const
Definition: btRigidBody.h:533
void clearForces()
Definition: btRigidBody.h:346
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)=0
static void Reset(void)
virtual int calculateSerializeBufferSize() const
btRotationalLimitMotor2 * getRotationalLimitMotor(int index)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
void proceedToTransform(const btTransform &newTrans)
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
virtual void applyGravity()
apply gravity, call this once per timestep
The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (...
InplaceSolverIslandCallback(btConstraintSolver *solver, btStackAlloc *stackAlloc, btDispatcher *dispatcher)
static btScalar calculateCombinedFriction(const btCollisionObject *body0, const btCollisionObject *body1)
User can override this material combiner by implementing gContactAddedCallback and setting body0->m_c...
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:83
const btTransform & getAFrame() const
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)=0
static void integrateTransform(const btTransform &curTrans, const btVector3 &linvel, const btVector3 &angvel, btScalar timeStep, btTransform &predictedTransform)
int size() const
return the number of elements in the array
virtual void debugDrawConstraint(btTypedConstraint *constraint)
#define BT_PROFILE(name)
Definition: btQuickprof.h:213
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
void btMutexUnlock(btSpinMutex *)
Definition: btThreads.h:70
btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) ...
void serialize(struct btVector3Data &dataOut) const
Definition: btVector3.h:1350
btScalar getCcdMotionThreshold() 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)
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...
int getIslandTag() const
btScalar getAngle(int axis_index) const
btDispatcherInfo & getDispatchInfo()
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btScalar getHitFraction() const
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: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:519
virtual void integrateTransforms(btScalar timeStep)
const btCollisionObject * getBody1() const
btRotationalLimitMotor * getRotationalLimitMotor(int index)
Retrieves the angular limit informacion.
int getInternalType() const
reserved for Bullet internal usage
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:120
virtual void storeIslandActivationState(btCollisionWorld *world)
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1)=0
#define DISABLE_DEACTIVATION
virtual void performDiscreteCollisionDetection()
btScalar m_combinedFriction
InplaceSolverIslandCallback * m_solverIslandCallback
virtual void addCharacter(btActionInterface *character)
obsolete, use addAction instead
#define btAlignedAlloc(size, alignment)
virtual int calculateSerializeBufferSize() const
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ...
btConstraintSolver * m_constraintSolver
btMotionState * getMotionState()
Definition: btRigidBody.h:474
btTypedConstraintType getConstraintType() const
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:334
void serializeRigidBodies(btSerializer *serializer)
virtual void updateActivationState(btScalar timeStep)
btScalar getAngle(int axis_index) const
Get the relative Euler angle.
btAlignedObjectArray< btTypedConstraint * > m_constraints
btScalar m_timeStep
Definition: btDispatcher.h:53
btScalar getCcdSweptSphereRadius() const
Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
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 bool needsCollision(btBroadphaseProxy *proxy0) const
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:75
void removeConstraintRef(btTypedConstraint *c)
const btRigidBody & getRigidBodyA() const
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
btContactSolverInfo & getSolverInfo()
const btBroadphaseInterface * getBroadphase() const
virtual void setWorldTransform(const btTransform &worldTrans)=0
void setActivationState(int newState) const
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
virtual btChunk * allocate(size_t size, int numElements)=0
const btTransform & getBFrame() const
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:279
void quickSort(const L &CompareFunc)
btScalar btCos(btScalar x)
Definition: btScalar.h:451
btAlignedObjectArray< btTypedConstraint * > m_constraints
void setGravity(const btVector3 &acceleration)
btTypedConstraint ** m_sortedConstraints
The btBroadphasePair class contains a pair of aabb-overlapping objects.