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
39 
40 
43 
44 
46 #include "LinearMath/btQuickprof.h"
48 
50 
51 #if 0
54 int startHit=2;
55 int firstHit=startHit;
56 #endif
57 
59 {
60  int islandId;
61 
62  const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
63  const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
64  islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag();
65  return islandId;
66 
67 }
68 
69 
71 {
72  public:
73 
74  bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) const
75  {
76  int rIslandId0,lIslandId0;
77  rIslandId0 = btGetConstraintIslandId(rhs);
78  lIslandId0 = btGetConstraintIslandId(lhs);
79  return lIslandId0 < rIslandId0;
80  }
81 };
82 
84 {
91 
95 
96 
98  btConstraintSolver* solver,
99  btStackAlloc* stackAlloc,
100  btDispatcher* dispatcher)
101  :m_solverInfo(NULL),
102  m_solver(solver),
103  m_sortedConstraints(NULL),
104  m_numConstraints(0),
105  m_debugDrawer(NULL),
106  m_dispatcher(dispatcher)
107  {
108 
109  }
110 
112  {
113  btAssert(0);
114  (void)other;
115  return *this;
116  }
117 
118  SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer)
119  {
120  btAssert(solverInfo);
121  m_solverInfo = solverInfo;
122  m_sortedConstraints = sortedConstraints;
123  m_numConstraints = numConstraints;
124  m_debugDrawer = debugDrawer;
125  m_bodies.resize (0);
126  m_manifolds.resize (0);
127  m_constraints.resize (0);
128  }
129 
130 
131  virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId)
132  {
133  if (islandId<0)
134  {
136  m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
137  } else
138  {
139  //also add all non-contact constraints/joints for this island
140  btTypedConstraint** startConstraint = 0;
141  int numCurConstraints = 0;
142  int i;
143 
144  //find the first constraint for this island
145  for (i=0;i<m_numConstraints;i++)
146  {
147  if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
148  {
149  startConstraint = &m_sortedConstraints[i];
150  break;
151  }
152  }
153  //count the number of constraints in this island
154  for (;i<m_numConstraints;i++)
155  {
156  if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
157  {
158  numCurConstraints++;
159  }
160  }
161 
163  {
164  m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher);
165  } else
166  {
167 
168  for (i=0;i<numBodies;i++)
169  m_bodies.push_back(bodies[i]);
170  for (i=0;i<numManifolds;i++)
171  m_manifolds.push_back(manifolds[i]);
172  for (i=0;i<numCurConstraints;i++)
173  m_constraints.push_back(startConstraint[i]);
175  {
177  } else
178  {
179  //printf("deferred\n");
180  }
181  }
182  }
183  }
185  {
186 
187  btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0;
188  btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0;
189  btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0;
190 
192  m_bodies.resize(0);
193  m_manifolds.resize(0);
195 
196  }
197 
198 };
199 
200 
201 
203 :btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
204 m_sortedConstraints (),
205 m_solverIslandCallback ( NULL ),
206 m_constraintSolver(constraintSolver),
207 m_gravity(0,-10,0),
208 m_localTime(0),
209 m_synchronizeAllMotionStates(false),
210 m_applySpeculativeContactRestitution(false),
211 m_profileTimings(0),
212 m_fixedTimeStep(0),
213 m_latencyMotionStateInterpolation(true)
214 
215 {
216  if (!m_constraintSolver)
217  {
218  void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16);
220  m_ownsConstraintSolver = true;
221  } else
222  {
223  m_ownsConstraintSolver = false;
224  }
225 
226  {
227  void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16);
229  }
230 
231  m_ownsIslandManager = true;
232 
233  {
234  void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback),16);
236  }
237 }
238 
239 
241 {
242  //only delete it when we created it
244  {
247  }
249  {
250  m_solverIslandCallback->~InplaceSolverIslandCallback();
252  }
254  {
255 
258  }
259 }
260 
262 {
266  for (int i=0;i<m_collisionObjects.size();i++)
267  {
269  btRigidBody* body = btRigidBody::upcast(colObj);
270  if (body && body->getActivationState() != ISLAND_SLEEPING)
271  {
272  if (body->isKinematicObject())
273  {
274  //to calculate velocities next frame
275  body->saveKinematicState(timeStep);
276  }
277  }
278  }
279 
280 }
281 
283 {
284  BT_PROFILE("debugDrawWorld");
285 
287 
288  bool drawConstraints = false;
289  if (getDebugDrawer())
290  {
291  int mode = getDebugDrawer()->getDebugMode();
293  {
294  drawConstraints = true;
295  }
296  }
297  if(drawConstraints)
298  {
299  for(int i = getNumConstraints()-1; i>=0 ;i--)
300  {
301  btTypedConstraint* constraint = getConstraint(i);
302  debugDrawConstraint(constraint);
303  }
304  }
305 
306 
307 
309  {
310  int i;
311 
312  if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
313  {
314  for (i=0;i<m_actions.size();i++)
315  {
316  m_actions[i]->debugDraw(m_debugDrawer);
317  }
318  }
319  }
320 }
321 
323 {
325  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
326  {
328  //need to check if next line is ok
329  //it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up
330  body->clearForces();
331  }
332 }
333 
336 {
338  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
339  {
341  if (body->isActive())
342  {
343  body->applyGravity();
344  }
345  }
346 }
347 
348 
350 {
351  btAssert(body);
352 
353  if (body->getMotionState() && !body->isStaticOrKinematicObject())
354  {
355  //we need to call the update at least once, even for sleeping objects
356  //otherwise the 'graphics' transform never updates properly
358  //if (body->getActivationState() != ISLAND_SLEEPING)
359  {
360  btTransform interpolatedTransform;
364  interpolatedTransform);
365  body->getMotionState()->setWorldTransform(interpolatedTransform);
366  }
367  }
368 }
369 
370 
372 {
373  BT_PROFILE("synchronizeMotionStates");
375  {
376  //iterate over all collision objects
377  for ( int i=0;i<m_collisionObjects.size();i++)
378  {
380  btRigidBody* body = btRigidBody::upcast(colObj);
381  if (body)
383  }
384  } else
385  {
386  //iterate over all active rigid bodies
387  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
388  {
390  if (body->isActive())
392  }
393  }
394 }
395 
396 
397 int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
398 {
399  startProfiling(timeStep);
400 
401  BT_PROFILE("stepSimulation");
402 
403  int numSimulationSubSteps = 0;
404 
405  if (maxSubSteps)
406  {
407  //fixed timestep with interpolation
408  m_fixedTimeStep = fixedTimeStep;
409  m_localTime += timeStep;
410  if (m_localTime >= fixedTimeStep)
411  {
412  numSimulationSubSteps = int( m_localTime / fixedTimeStep);
413  m_localTime -= numSimulationSubSteps * fixedTimeStep;
414  }
415  } else
416  {
417  //variable timestep
418  fixedTimeStep = timeStep;
420  m_fixedTimeStep = 0;
421  if (btFuzzyZero(timeStep))
422  {
423  numSimulationSubSteps = 0;
424  maxSubSteps = 0;
425  } else
426  {
427  numSimulationSubSteps = 1;
428  maxSubSteps = 1;
429  }
430  }
431 
432  //process some debugging flags
433  if (getDebugDrawer())
434  {
435  btIDebugDraw* debugDrawer = getDebugDrawer ();
437  }
438  if (numSimulationSubSteps)
439  {
440 
441  //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
442  int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
443 
444  saveKinematicState(fixedTimeStep*clampedSimulationSteps);
445 
446  applyGravity();
447 
448 
449 
450  for (int i=0;i<clampedSimulationSteps;i++)
451  {
452  internalSingleStepSimulation(fixedTimeStep);
454  }
455 
456  } else
457  {
459  }
460 
461  clearForces();
462 
463 #ifndef BT_NO_PROFILE
465 #endif //BT_NO_PROFILE
466 
467  return numSimulationSubSteps;
468 }
469 
471 {
472 
473  BT_PROFILE("internalSingleStepSimulation");
474 
475  if(0 != m_internalPreTickCallback) {
476  (*m_internalPreTickCallback)(this, timeStep);
477  }
478 
480  predictUnconstraintMotion(timeStep);
481 
482  btDispatcherInfo& dispatchInfo = getDispatchInfo();
483 
484  dispatchInfo.m_timeStep = timeStep;
485  dispatchInfo.m_stepCount = 0;
486  dispatchInfo.m_debugDraw = getDebugDrawer();
487 
488 
489  createPredictiveContacts(timeStep);
490 
493 
495 
496 
497  getSolverInfo().m_timeStep = timeStep;
498 
499 
500 
503 
505 
507 
508  integrateTransforms(timeStep);
509 
511  updateActions(timeStep);
512 
513  updateActivationState( timeStep );
514 
515  if(0 != m_internalTickCallback) {
516  (*m_internalTickCallback)(this, timeStep);
517  }
518 }
519 
521 {
522  m_gravity = gravity;
523  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
524  {
526  if (body->isActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
527  {
528  body->setGravity(gravity);
529  }
530  }
531 }
532 
534 {
535  return m_gravity;
536 }
537 
538 void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
539 {
540  btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask);
541 }
542 
544 {
545  btRigidBody* body = btRigidBody::upcast(collisionObject);
546  if (body)
547  removeRigidBody(body);
548  else
550 }
551 
553 {
556 }
557 
558 
560 {
561  if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
562  {
563  body->setGravity(m_gravity);
564  }
565 
566  if (body->getCollisionShape())
567  {
568  if (!body->isStaticObject())
569  {
571  } else
572  {
574  }
575 
576  bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
577  short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
578  short collisionFilterMask = isDynamic? short(btBroadphaseProxy::AllFilter) : short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
579 
580  addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
581  }
582 }
583 
584 void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
585 {
586  if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
587  {
588  body->setGravity(m_gravity);
589  }
590 
591  if (body->getCollisionShape())
592  {
593  if (!body->isStaticObject())
594  {
596  }
597  else
598  {
600  }
601  addCollisionObject(body,group,mask);
602  }
603 }
604 
605 
607 {
608  BT_PROFILE("updateActions");
609 
610  for ( int i=0;i<m_actions.size();i++)
611  {
612  m_actions[i]->updateAction( this, timeStep);
613  }
614 }
615 
616 
618 {
619  BT_PROFILE("updateActivationState");
620 
621  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
622  {
624  if (body)
625  {
626  body->updateDeactivation(timeStep);
627 
628  if (body->wantsSleeping())
629  {
630  if (body->isStaticOrKinematicObject())
631  {
633  } else
634  {
635  if (body->getActivationState() == ACTIVE_TAG)
637  if (body->getActivationState() == ISLAND_SLEEPING)
638  {
639  body->setAngularVelocity(btVector3(0,0,0));
640  body->setLinearVelocity(btVector3(0,0,0));
641  }
642 
643  }
644  } else
645  {
648  }
649  }
650  }
651 }
652 
653 void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
654 {
655  m_constraints.push_back(constraint);
656  if (disableCollisionsBetweenLinkedBodies)
657  {
658  constraint->getRigidBodyA().addConstraintRef(constraint);
659  constraint->getRigidBodyB().addConstraintRef(constraint);
660  }
661 }
662 
664 {
665  m_constraints.remove(constraint);
666  constraint->getRigidBodyA().removeConstraintRef(constraint);
667  constraint->getRigidBodyB().removeConstraintRef(constraint);
668 }
669 
671 {
672  m_actions.push_back(action);
673 }
674 
676 {
677  m_actions.remove(action);
678 }
679 
680 
682 {
683  addAction(vehicle);
684 }
685 
687 {
688  removeAction(vehicle);
689 }
690 
692 {
693  addAction(character);
694 }
695 
697 {
698  removeAction(character);
699 }
700 
701 
702 
703 
705 {
706  BT_PROFILE("solveConstraints");
707 
709  int i;
710  for (i=0;i<getNumConstraints();i++)
711  {
713  }
714 
715 // btAssert(0);
716 
717 
718 
720 
721  btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0;
722 
723  m_solverIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer());
725 
728 
730 
732 }
733 
734 
736 {
737  BT_PROFILE("calculateSimulationIslands");
738 
740 
741  {
742  //merge islands based on speculative contact manifolds too
743  for (int i=0;i<this->m_predictiveManifolds.size();i++)
744  {
746 
747  const btCollisionObject* colObj0 = manifold->getBody0();
748  const btCollisionObject* colObj1 = manifold->getBody1();
749 
750  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
751  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
752  {
753  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
754  }
755  }
756  }
757 
758  {
759  int i;
760  int numConstraints = int(m_constraints.size());
761  for (i=0;i< numConstraints ; i++ )
762  {
763  btTypedConstraint* constraint = m_constraints[i];
764  if (constraint->isEnabled())
765  {
766  const btRigidBody* colObj0 = &constraint->getRigidBodyA();
767  const btRigidBody* colObj1 = &constraint->getRigidBodyB();
768 
769  if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
770  ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
771  {
772  getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
773  }
774  }
775  }
776  }
777 
778  //Store the island id in each body
780 
781 
782 }
783 
784 
785 
786 
788 {
789 public:
790 
795 
796 public:
799  m_me(me),
800  m_allowedPenetration(0.0f),
801  m_pairCache(pairCache),
802  m_dispatcher(dispatcher)
803  {
804  }
805 
806  virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
807  {
808  if (convexResult.m_hitCollisionObject == m_me)
809  return 1.0f;
810 
811  //ignore result if there is no contact response
812  if(!convexResult.m_hitCollisionObject->hasContactResponse())
813  return 1.0f;
814 
815  btVector3 linVelA,linVelB;
817  linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin();
818 
819  btVector3 relativeVelocity = (linVelA-linVelB);
820  //don't report time of impact for motion away from the contact normal (or causes minor penetration)
821  if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration)
822  return 1.f;
823 
824  return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
825  }
826 
827  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
828  {
829  //don't collide with itself
830  if (proxy0->m_clientObject == m_me)
831  return false;
832 
834  if (!ClosestConvexResultCallback::needsCollision(proxy0))
835  return false;
836 
837  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
838 
839  //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
840  if (m_dispatcher->needsResponse(m_me,otherObj))
841  {
842 #if 0
845  btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
846  if (collisionPair)
847  {
848  if (collisionPair->m_algorithm)
849  {
850  manifoldArray.resize(0);
851  collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
852  for (int j=0;j<manifoldArray.size();j++)
853  {
854  btPersistentManifold* manifold = manifoldArray[j];
855  if (manifold->getNumContacts()>0)
856  return false;
857  }
858  }
859  }
860 #endif
861  return true;
862  }
863 
864  return false;
865  }
866 
867 
868 };
869 
872 
873 
875 {
876  BT_PROFILE("createPredictiveContacts");
877 
878  {
879  BT_PROFILE("release predictive contact manifolds");
880 
881  for (int i=0;i<m_predictiveManifolds.size();i++)
882  {
884  this->m_dispatcher1->releaseManifold(manifold);
885  }
887  }
888 
889  btTransform predictedTrans;
890  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
891  {
893  body->setHitFraction(1.f);
894 
895  if (body->isActive() && (!body->isStaticOrKinematicObject()))
896  {
897 
898  body->predictIntegratedTransform(timeStep, predictedTrans);
899 
900  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
901 
903  {
904  BT_PROFILE("predictive convexSweepTest");
905  if (body->getCollisionShape()->isConvex())
906  {
908 #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
909  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
910  {
911  public:
912 
913  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
914  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
915  {
916  }
917 
918  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
919  {
920  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
921  if (!otherObj->isStaticOrKinematicObject())
922  return false;
924  }
925  };
926 
927  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
928 #else
930 #endif
931  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
932  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
933  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
934 
935  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
936  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
937  btTransform modifiedPredictedTrans = predictedTrans;
938  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
939 
940  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
941  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
942  {
943 
944  btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction;
945  btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
946 
947 
948  btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject);
950 
951  btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec;
952  btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB;
953 
954  btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance);
955 
956  bool isPredictive = true;
957  int index = manifold->addManifoldPoint(newPoint, isPredictive);
958  btManifoldPoint& pt = manifold->getContactPoint(index);
959  pt.m_combinedRestitution = 0;
960  pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject);
962  pt.m_positionWorldOnB = worldPointB;
963 
964  }
965  }
966  }
967  }
968  }
969 }
971 {
972  BT_PROFILE("integrateTransforms");
973  btTransform predictedTrans;
974  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
975  {
977  body->setHitFraction(1.f);
978 
979  if (body->isActive() && (!body->isStaticOrKinematicObject()))
980  {
981 
982  body->predictIntegratedTransform(timeStep, predictedTrans);
983 
984  btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
985 
986 
987 
989  {
990  BT_PROFILE("CCD motion clamping");
991  if (body->getCollisionShape()->isConvex())
992  {
994 #ifdef USE_STATIC_ONLY
995  class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
996  {
997  public:
998 
999  StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
1000  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
1001  {
1002  }
1003 
1004  virtual bool needsCollision(btBroadphaseProxy* proxy0) const
1005  {
1006  btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
1007  if (!otherObj->isStaticOrKinematicObject())
1008  return false;
1010  }
1011  };
1012 
1013  StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
1014 #else
1016 #endif
1017  //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1018  btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1019  sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
1020 
1021  sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
1022  sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
1023  btTransform modifiedPredictedTrans = predictedTrans;
1024  modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
1025 
1026  convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
1027  if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
1028  {
1029 
1030  //printf("clamped integration to hit fraction = %f\n",fraction);
1031  body->setHitFraction(sweepResults.m_closestHitFraction);
1032  body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
1033  body->setHitFraction(0.f);
1034  body->proceedToTransform( predictedTrans);
1035 
1036 #if 0
1037  btVector3 linVel = body->getLinearVelocity();
1038 
1040  btScalar maxSpeedSqr = maxSpeed*maxSpeed;
1041  if (linVel.length2()>maxSpeedSqr)
1042  {
1043  linVel.normalize();
1044  linVel*= maxSpeed;
1045  body->setLinearVelocity(linVel);
1046  btScalar ms2 = body->getLinearVelocity().length2();
1047  body->predictIntegratedTransform(timeStep, predictedTrans);
1048 
1049  btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1050  btScalar smt = body->getCcdSquareMotionThreshold();
1051  printf("sm2=%f\n",sm2);
1052  }
1053 #else
1054 
1055  //don't apply the collision response right now, it will happen next frame
1056  //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
1057  //btScalar appliedImpulse = 0.f;
1058  //btScalar depth = 0.f;
1059  //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
1060 
1061 
1062 #endif
1063 
1064  continue;
1065  }
1066  }
1067  }
1068 
1069 
1070  body->proceedToTransform( predictedTrans);
1071 
1072  }
1073 
1074  }
1075 
1078  {
1079  BT_PROFILE("apply speculative contact restitution");
1080  for (int i=0;i<m_predictiveManifolds.size();i++)
1081  {
1085 
1086  for (int p=0;p<manifold->getNumContacts();p++)
1087  {
1088  const btManifoldPoint& pt = manifold->getContactPoint(p);
1089  btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1);
1090 
1091  if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1092  //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1093  {
1094  btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution;
1095 
1096  const btVector3& pos1 = pt.getPositionWorldOnA();
1097  const btVector3& pos2 = pt.getPositionWorldOnB();
1098 
1099  btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
1100  btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
1101 
1102  if (body0)
1103  body0->applyImpulse(imp,rel_pos0);
1104  if (body1)
1105  body1->applyImpulse(-imp,rel_pos1);
1106  }
1107  }
1108  }
1109  }
1110 
1111 }
1112 
1113 
1114 
1115 
1116 
1117 
1119 {
1120  BT_PROFILE("predictUnconstraintMotion");
1121  for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
1122  {
1124  if (!body->isStaticOrKinematicObject())
1125  {
1126  //don't integrate/update velocities here, it happens in the constraint solver
1127 
1128  body->applyDamping(timeStep);
1129 
1131  }
1132  }
1133 }
1134 
1135 
1137 {
1138  (void)timeStep;
1139 
1140 #ifndef BT_NO_PROFILE
1142 #endif //BT_NO_PROFILE
1143 
1144 }
1145 
1146 
1147 
1148 
1149 
1150 
1152 {
1153  bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
1154  bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
1155  btScalar dbgDrawSize = constraint->getDbgDrawSize();
1156  if(dbgDrawSize <= btScalar(0.f))
1157  {
1158  return;
1159  }
1160 
1161  switch(constraint->getConstraintType())
1162  {
1164  {
1165  btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
1166  btTransform tr;
1167  tr.setIdentity();
1168  btVector3 pivot = p2pC->getPivotInA();
1169  pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1170  tr.setOrigin(pivot);
1171  getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1172  // that ideally should draw the same frame
1173  pivot = p2pC->getPivotInB();
1174  pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1175  tr.setOrigin(pivot);
1176  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1177  }
1178  break;
1179  case HINGE_CONSTRAINT_TYPE:
1180  {
1181  btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
1182  btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1183  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1184  tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1185  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1186  btScalar minAng = pHinge->getLowerLimit();
1187  btScalar maxAng = pHinge->getUpperLimit();
1188  if(minAng == maxAng)
1189  {
1190  break;
1191  }
1192  bool drawSect = true;
1193  if(minAng > maxAng)
1194  {
1195  minAng = btScalar(0.f);
1196  maxAng = SIMD_2_PI;
1197  drawSect = false;
1198  }
1199  if(drawLimits)
1200  {
1201  btVector3& center = tr.getOrigin();
1202  btVector3 normal = tr.getBasis().getColumn(2);
1203  btVector3 axis = tr.getBasis().getColumn(0);
1204  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
1205  }
1206  }
1207  break;
1209  {
1210  btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
1212  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1213  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1214  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1215  if(drawLimits)
1216  {
1217  //const btScalar length = btScalar(5);
1218  const btScalar length = dbgDrawSize;
1219  static int nSegments = 8*4;
1220  btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
1221  btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1222  pPrev = tr * pPrev;
1223  for (int i=0; i<nSegments; i++)
1224  {
1225  fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
1226  btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1227  pCur = tr * pCur;
1228  getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
1229 
1230  if (i%(nSegments/8) == 0)
1231  getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
1232 
1233  pPrev = pCur;
1234  }
1235  btScalar tws = pCT->getTwistSpan();
1236  btScalar twa = pCT->getTwistAngle();
1237  bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1238  if(useFrameB)
1239  {
1240  tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1241  }
1242  else
1243  {
1244  tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1245  }
1246  btVector3 pivot = tr.getOrigin();
1247  btVector3 normal = tr.getBasis().getColumn(0);
1248  btVector3 axis1 = tr.getBasis().getColumn(1);
1249  getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
1250 
1251  }
1252  }
1253  break;
1255  case D6_CONSTRAINT_TYPE:
1256  {
1257  btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
1258  btTransform tr = p6DOF->getCalculatedTransformA();
1259  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1260  tr = p6DOF->getCalculatedTransformB();
1261  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1262  if(drawLimits)
1263  {
1264  tr = p6DOF->getCalculatedTransformA();
1265  const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1266  btVector3 up = tr.getBasis().getColumn(2);
1267  btVector3 axis = tr.getBasis().getColumn(0);
1268  btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1269  btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1270  btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1271  btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1272  getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
1273  axis = tr.getBasis().getColumn(1);
1274  btScalar ay = p6DOF->getAngle(1);
1275  btScalar az = p6DOF->getAngle(2);
1276  btScalar cy = btCos(ay);
1277  btScalar sy = btSin(ay);
1278  btScalar cz = btCos(az);
1279  btScalar sz = btSin(az);
1280  btVector3 ref;
1281  ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1282  ref[1] = -sz*axis[0] + cz*axis[1];
1283  ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1284  tr = p6DOF->getCalculatedTransformB();
1285  btVector3 normal = -tr.getBasis().getColumn(0);
1286  btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1287  btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1288  if(minFi > maxFi)
1289  {
1290  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
1291  }
1292  else if(minFi < maxFi)
1293  {
1294  getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
1295  }
1296  tr = p6DOF->getCalculatedTransformA();
1299  getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
1300  }
1301  }
1302  break;
1304  {
1305  btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
1306  btTransform tr = pSlider->getCalculatedTransformA();
1307  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1308  tr = pSlider->getCalculatedTransformB();
1309  if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1310  if(drawLimits)
1311  {
1313  btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1314  btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1315  getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
1316  btVector3 normal = tr.getBasis().getColumn(0);
1317  btVector3 axis = tr.getBasis().getColumn(1);
1318  btScalar a_min = pSlider->getLowerAngLimit();
1319  btScalar a_max = pSlider->getUpperAngLimit();
1320  const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1321  getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
1322  }
1323  }
1324  break;
1325  default :
1326  break;
1327  }
1328  return;
1329 }
1330 
1331 
1332 
1333 
1334 
1336 {
1338  {
1340  }
1341  m_ownsConstraintSolver = false;
1342  m_constraintSolver = solver;
1343  m_solverIslandCallback->m_solver = solver;
1344 }
1345 
1347 {
1348  return m_constraintSolver;
1349 }
1350 
1351 
1353 {
1354  return int(m_constraints.size());
1355 }
1357 {
1358  return m_constraints[index];
1359 }
1361 {
1362  return m_constraints[index];
1363 }
1364 
1365 
1366 
1368 {
1369  int i;
1370  //serialize all collision objects
1371  for (i=0;i<m_collisionObjects.size();i++)
1372  {
1375  {
1376  int len = colObj->calculateSerializeBufferSize();
1377  btChunk* chunk = serializer->allocate(len,1);
1378  const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1379  serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
1380  }
1381  }
1382 
1383  for (i=0;i<m_constraints.size();i++)
1384  {
1385  btTypedConstraint* constraint = m_constraints[i];
1386  int size = constraint->calculateSerializeBufferSize();
1387  btChunk* chunk = serializer->allocate(size,1);
1388  const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
1389  serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
1390  }
1391 }
1392 
1393 
1394 
1395 
1397 {
1398 #ifdef BT_USE_DOUBLE_PRECISION
1399  int len = sizeof(btDynamicsWorldDoubleData);
1400  btChunk* chunk = serializer->allocate(len,1);
1402 #else//BT_USE_DOUBLE_PRECISION
1403  int len = sizeof(btDynamicsWorldFloatData);
1404  btChunk* chunk = serializer->allocate(len,1);
1406 #endif//BT_USE_DOUBLE_PRECISION
1407 
1408  memset(worldInfo ,0x00,len);
1409 
1410  m_gravity.serialize(worldInfo->m_gravity);
1411  worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
1415 
1418  worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
1419  worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
1420 
1421  worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
1425 
1430 
1435 
1437 
1438 #ifdef BT_USE_DOUBLE_PRECISION
1439  const char* structType = "btDynamicsWorldDoubleData";
1440 #else//BT_USE_DOUBLE_PRECISION
1441  const char* structType = "btDynamicsWorldFloatData";
1442 #endif//BT_USE_DOUBLE_PRECISION
1443  serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo);
1444 }
1445 
1447 {
1448 
1449  serializer->startSerialization();
1450 
1451  serializeDynamicsWorldInfo(serializer);
1452 
1453  serializeRigidBodies(serializer);
1454 
1455  serializeCollisionObjects(serializer);
1456 
1457  serializer->finishSerialization();
1458 }
1459 
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
btScalar getInvMass() const
Definition: btRigidBody.h:267
virtual void setConstraintSolver(btConstraintSolver *solver)
const btCollisionShape * getCollisionShape() const
Definition: btRigidBody.h:248
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't store a rigidbody pointer but a rigidbody ...
Definition: btRigidBody.h:197
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 '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:116
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:409
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:432
btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis locatio...
virtual int calculateSerializeBufferSize() const
bool gDisableDeactivation
Definition: btRigidBody.cpp:26
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:276
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:51
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:101
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:124
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:58
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:144
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 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:415
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:169
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:434
void setActivationState(int newState) const
btTransform & getWorldTransform()
btVector3 m_normalWorldOnB
#define SIMD_2_PI
Definition: btScalar.h:435
btVector3 m_positionWorldOnB
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...
btScalar getUpperLimit() const
btIDebugDraw * m_debugDrawer
btAlignedObjectArray< btCollisionObject * > m_bodies
virtual btIDebugDraw * getDebugDrawer()
const btTransform & getCenterOfMassTransform() const
Definition: btRigidBody.h:353
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.
ClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld)
virtual void predictUnconstraintMotion(btScalar timeStep)
bool isStaticOrKinematicObject() const
void serialize(struct btVector3Data &dataOut) const
Definition: btVector3.h:1339
#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:364
btAlignedObjectArray< btPersistentManifold * > m_predictiveManifolds
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:59
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:340
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)=0
static void Reset(void)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs...
void proceedToTransform(const btTransform &newTrans)
const btManifoldPoint & getContactPoint(int index) const
btDispatcher * getDispatcher()
virtual btConstraintSolver * getConstraintSolver()
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
int gNumClampedCcdMotions
internal debugging variable. this value shouldn'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's
void createPredictiveContacts(btScalar timeStep)
btCollisionAlgorithm * m_algorithm
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
void debugDrawConstraint(btTypedConstraint *constraint)
const btBroadphaseInterface * getBroadphase() const
#define BT_PROFILE(name)
Definition: btQuickprof.h:191
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 & 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:136
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:468
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:370
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:115
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:454
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:468
const btRigidBody & getRigidBodyA() const
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:356
const btVector3 & getPivotInB() const
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:328
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:266
bool isActive() const
void quickSort(const L &CompareFunc)
int getFlags() const
Definition: btRigidBody.h:529
btScalar btCos(btScalar x)
Definition: btScalar.h:408
btAlignedObjectArray< btTypedConstraint * > m_constraints
void setGravity(const btVector3 &acceleration)
btTypedConstraint ** m_sortedConstraints
The btBroadphasePair class contains a pair of aabb-overlapping objects.