Bullet Collision Detection & Physics Library
btDiscreteDynamicsWorld.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16
18
19//collision detection
27
28//rigidbody & constraints
40
41
44
45
49
51
52#if 0
55int startHit=2;
56int 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),
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);
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 {
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 {
158 {
159 numCurConstraints++;
160 }
161 }
162
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]);
176 {
178 } else
179 {
180 //printf("deferred\n");
181 }
182 }
183 }
184 }
186 {
187
188 btCollisionObject** bodies = m_bodies.size()? &m_bodies[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);
195 m_constraints.resize(0);
196
197 }
198
199};
200
201
202
204:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
205m_sortedConstraints (),
206m_solverIslandCallback ( NULL ),
207m_constraintSolver(constraintSolver),
208m_gravity(0,-10,0),
209m_localTime(0),
210m_fixedTimeStep(0),
211m_synchronizeAllMotionStates(false),
212m_applySpeculativeContactRestitution(false),
213m_profileTimings(0),
214m_latencyMotionStateInterpolation(true)
215
216{
218 {
222 } else
223 {
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
401int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
402{
403 startProfiling(timeStep);
404
405
406 int numSimulationSubSteps = 0;
407
408 if (maxSubSteps)
409 {
410 //fixed timestep with interpolation
411 m_fixedTimeStep = fixedTimeStep;
412 m_localTime += timeStep;
413 if (m_localTime >= fixedTimeStep)
414 {
415 numSimulationSubSteps = int( m_localTime / fixedTimeStep);
416 m_localTime -= numSimulationSubSteps * fixedTimeStep;
417 }
418 } else
419 {
420 //variable timestep
421 fixedTimeStep = timeStep;
423 m_fixedTimeStep = 0;
424 if (btFuzzyZero(timeStep))
425 {
426 numSimulationSubSteps = 0;
427 maxSubSteps = 0;
428 } else
429 {
430 numSimulationSubSteps = 1;
431 maxSubSteps = 1;
432 }
433 }
434
435 //process some debugging flags
436 if (getDebugDrawer())
437 {
438 btIDebugDraw* debugDrawer = getDebugDrawer ();
440 }
441 if (numSimulationSubSteps)
442 {
443
444 //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
445 int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
446
447 saveKinematicState(fixedTimeStep*clampedSimulationSteps);
448
449 applyGravity();
450
451
452
453 for (int i=0;i<clampedSimulationSteps;i++)
454 {
455 internalSingleStepSimulation(fixedTimeStep);
457 }
458
459 } else
460 {
462 }
463
464 clearForces();
465
466#ifndef BT_NO_PROFILE
468#endif //BT_NO_PROFILE
469
470 return numSimulationSubSteps;
471}
472
474{
475
476 BT_PROFILE("internalSingleStepSimulation");
477
479 (*m_internalPreTickCallback)(this, timeStep);
480 }
481
484
485 btDispatcherInfo& dispatchInfo = getDispatchInfo();
486
487 dispatchInfo.m_timeStep = timeStep;
488 dispatchInfo.m_stepCount = 0;
489 dispatchInfo.m_debugDraw = getDebugDrawer();
490
491
492 createPredictiveContacts(timeStep);
493
496
498
499
500 getSolverInfo().m_timeStep = timeStep;
501
502
503
506
508
510
511 integrateTransforms(timeStep);
512
514 updateActions(timeStep);
515
516 updateActivationState( timeStep );
517
518 if(0 != m_internalTickCallback) {
519 (*m_internalTickCallback)(this, timeStep);
520 }
521}
522
524{
525 m_gravity = gravity;
526 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
527 {
529 if (body->isActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY))
530 {
531 body->setGravity(gravity);
532 }
533 }
534}
535
537{
538 return m_gravity;
539}
540
541void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
542{
543 btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask);
544}
545
547{
548 btRigidBody* body = btRigidBody::upcast(collisionObject);
549 if (body)
550 removeRigidBody(body);
551 else
553}
554
556{
557 m_nonStaticRigidBodies.remove(body);
559}
560
561
563{
565 {
566 body->setGravity(m_gravity);
567 }
568
569 if (body->getCollisionShape())
570 {
571 if (!body->isStaticObject())
572 {
573 m_nonStaticRigidBodies.push_back(body);
574 } else
575 {
577 }
578
579 bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
580 int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
581 int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
582
583 addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
584 }
585}
586
588{
590 {
591 body->setGravity(m_gravity);
592 }
593
594 if (body->getCollisionShape())
595 {
596 if (!body->isStaticObject())
597 {
598 m_nonStaticRigidBodies.push_back(body);
599 }
600 else
601 {
603 }
604 addCollisionObject(body,group,mask);
605 }
606}
607
608
610{
611 BT_PROFILE("updateActions");
612
613 for ( int i=0;i<m_actions.size();i++)
614 {
615 m_actions[i]->updateAction( this, timeStep);
616 }
617}
618
619
621{
622 BT_PROFILE("updateActivationState");
623
624 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
625 {
627 if (body)
628 {
629 body->updateDeactivation(timeStep);
630
631 if (body->wantsSleeping())
632 {
633 if (body->isStaticOrKinematicObject())
634 {
636 } else
637 {
638 if (body->getActivationState() == ACTIVE_TAG)
640 if (body->getActivationState() == ISLAND_SLEEPING)
641 {
642 body->setAngularVelocity(btVector3(0,0,0));
643 body->setLinearVelocity(btVector3(0,0,0));
644 }
645
646 }
647 } else
648 {
651 }
652 }
653 }
654}
655
656void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
657{
658 m_constraints.push_back(constraint);
659 //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?)
660 btAssert(&constraint->getRigidBodyA()!=&constraint->getRigidBodyB());
661
662 if (disableCollisionsBetweenLinkedBodies)
663 {
664 constraint->getRigidBodyA().addConstraintRef(constraint);
665 constraint->getRigidBodyB().addConstraintRef(constraint);
666 }
667}
668
670{
671 m_constraints.remove(constraint);
672 constraint->getRigidBodyA().removeConstraintRef(constraint);
673 constraint->getRigidBodyB().removeConstraintRef(constraint);
674}
675
677{
678 m_actions.push_back(action);
679}
680
682{
683 m_actions.remove(action);
684}
685
686
688{
689 addAction(vehicle);
690}
691
693{
694 removeAction(vehicle);
695}
696
698{
699 addAction(character);
700}
701
703{
704 removeAction(character);
705}
706
707
708
709
711{
712 BT_PROFILE("solveConstraints");
713
714 m_sortedConstraints.resize( m_constraints.size());
715 int i;
716 for (i=0;i<getNumConstraints();i++)
717 {
719 }
720
721// btAssert(0);
722
723
724
726
727 btTypedConstraint** constraintsPtr = getNumConstraints() ? &m_sortedConstraints[0] : 0;
728
729 m_solverIslandCallback->setup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer());
731
734
736
738}
739
740
742{
743 BT_PROFILE("calculateSimulationIslands");
744
746
747 {
748 //merge islands based on speculative contact manifolds too
749 for (int i=0;i<this->m_predictiveManifolds.size();i++)
750 {
752
753 const btCollisionObject* colObj0 = manifold->getBody0();
754 const btCollisionObject* colObj1 = manifold->getBody1();
755
756 if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
757 ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
758 {
759 getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
760 }
761 }
762 }
763
764 {
765 int i;
766 int numConstraints = int(m_constraints.size());
767 for (i=0;i< numConstraints ; i++ )
768 {
769 btTypedConstraint* constraint = m_constraints[i];
770 if (constraint->isEnabled())
771 {
772 const btRigidBody* colObj0 = &constraint->getRigidBodyA();
773 const btRigidBody* colObj1 = &constraint->getRigidBodyB();
774
775 if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
776 ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
777 {
778 getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag());
779 }
780 }
781 }
782 }
783
784 //Store the island id in each body
786
787
788}
789
790
791
792
794{
795public:
796
801
802public:
805 m_me(me),
807 m_pairCache(pairCache),
808 m_dispatcher(dispatcher)
809 {
810 }
811
812 virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
813 {
814 if (convexResult.m_hitCollisionObject == m_me)
815 return 1.0f;
816
817 //ignore result if there is no contact response
818 if(!convexResult.m_hitCollisionObject->hasContactResponse())
819 return 1.0f;
820
821 btVector3 linVelA,linVelB;
823 linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin();
824
825 btVector3 relativeVelocity = (linVelA-linVelB);
826 //don't report time of impact for motion away from the contact normal (or causes minor penetration)
827 if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration)
828 return 1.f;
829
830 return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
831 }
832
833 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
834 {
835 //don't collide with itself
836 if (proxy0->m_clientObject == m_me)
837 return false;
838
840 if (!ClosestConvexResultCallback::needsCollision(proxy0))
841 return false;
842
844
845 //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
846 if (m_dispatcher->needsResponse(m_me,otherObj))
847 {
848#if 0
851 btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
852 if (collisionPair)
853 {
854 if (collisionPair->m_algorithm)
855 {
856 manifoldArray.resize(0);
857 collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
858 for (int j=0;j<manifoldArray.size();j++)
859 {
860 btPersistentManifold* manifold = manifoldArray[j];
861 if (manifold->getNumContacts()>0)
862 return false;
863 }
864 }
865 }
866#endif
867 return true;
868 }
869
870 return false;
871 }
872
873
874};
875
878
879
881{
882 btTransform predictedTrans;
883 for ( int i=0;i<numBodies;i++)
884 {
885 btRigidBody* body = bodies[i];
886 body->setHitFraction(1.f);
887
888 if (body->isActive() && (!body->isStaticOrKinematicObject()))
889 {
890
891 body->predictIntegratedTransform(timeStep, predictedTrans);
892
893 btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
894
896 {
897 BT_PROFILE("predictive convexSweepTest");
898 if (body->getCollisionShape()->isConvex())
899 {
901#ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
902 class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
903 {
904 public:
905
906 StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
907 btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
908 {
909 }
910
911 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
912 {
914 if (!otherObj->isStaticOrKinematicObject())
915 return false;
917 }
918 };
919
920 StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
921#else
922 btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
923#endif
924 //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
925 btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
926 sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
927
928 sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
929 sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
930 btTransform modifiedPredictedTrans = predictedTrans;
931 modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
932
933 convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
934 if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
935 {
936
937 btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction;
938 btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
939
940
941 btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject);
945
946 btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec;
947 btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB;
948
949 btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance);
950
951 bool isPredictive = true;
952 int index = manifold->addManifoldPoint(newPoint, isPredictive);
953 btManifoldPoint& pt = manifold->getContactPoint(index);
955 pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject);
957 pt.m_positionWorldOnB = worldPointB;
958
959 }
960 }
961 }
962 }
963 }
964}
965
967{
968 BT_PROFILE( "release predictive contact manifolds" );
969
970 for ( int i = 0; i < m_predictiveManifolds.size(); i++ )
971 {
973 this->m_dispatcher1->releaseManifold( manifold );
974 }
976}
977
979{
980 BT_PROFILE("createPredictiveContacts");
982 if (m_nonStaticRigidBodies.size() > 0)
983 {
985 }
986}
987
989{
990 btTransform predictedTrans;
991 for (int i=0;i<numBodies;i++)
992 {
993 btRigidBody* body = bodies[i];
994 body->setHitFraction(1.f);
995
996 if (body->isActive() && (!body->isStaticOrKinematicObject()))
997 {
998
999 body->predictIntegratedTransform(timeStep, predictedTrans);
1000
1001 btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1002
1003
1004
1006 {
1007 BT_PROFILE("CCD motion clamping");
1008 if (body->getCollisionShape()->isConvex())
1009 {
1011#ifdef USE_STATIC_ONLY
1012 class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
1013 {
1014 public:
1015
1016 StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
1017 btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
1018 {
1019 }
1020
1021 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
1022 {
1023 btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
1024 if (!otherObj->isStaticOrKinematicObject())
1025 return false;
1027 }
1028 };
1029
1030 StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
1031#else
1032 btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
1033#endif
1034 //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1035 btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
1036 sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
1037
1038 sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
1039 sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
1040 btTransform modifiedPredictedTrans = predictedTrans;
1041 modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
1042
1043 convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
1044 if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
1045 {
1046
1047 //printf("clamped integration to hit fraction = %f\n",fraction);
1048 body->setHitFraction(sweepResults.m_closestHitFraction);
1049 body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
1050 body->setHitFraction(0.f);
1051 body->proceedToTransform( predictedTrans);
1052
1053#if 0
1054 btVector3 linVel = body->getLinearVelocity();
1055
1057 btScalar maxSpeedSqr = maxSpeed*maxSpeed;
1058 if (linVel.length2()>maxSpeedSqr)
1059 {
1060 linVel.normalize();
1061 linVel*= maxSpeed;
1062 body->setLinearVelocity(linVel);
1063 btScalar ms2 = body->getLinearVelocity().length2();
1064 body->predictIntegratedTransform(timeStep, predictedTrans);
1065
1066 btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1068 printf("sm2=%f\n",sm2);
1069 }
1070#else
1071
1072 //don't apply the collision response right now, it will happen next frame
1073 //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
1074 //btScalar appliedImpulse = 0.f;
1075 //btScalar depth = 0.f;
1076 //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
1077
1078
1079#endif
1080
1081 continue;
1082 }
1083 }
1084 }
1085
1086
1087 body->proceedToTransform( predictedTrans);
1088
1089 }
1090
1091 }
1092
1093}
1094
1096{
1097 BT_PROFILE("integrateTransforms");
1098 if (m_nonStaticRigidBodies.size() > 0)
1099 {
1101 }
1102
1105 {
1106 BT_PROFILE("apply speculative contact restitution");
1107 for (int i=0;i<m_predictiveManifolds.size();i++)
1108 {
1112
1113 for (int p=0;p<manifold->getNumContacts();p++)
1114 {
1115 const btManifoldPoint& pt = manifold->getContactPoint(p);
1116 btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1);
1117
1118 if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1119 //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1120 {
1121 btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution;
1122
1123 const btVector3& pos1 = pt.getPositionWorldOnA();
1124 const btVector3& pos2 = pt.getPositionWorldOnB();
1125
1126 btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
1127 btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
1128
1129 if (body0)
1130 body0->applyImpulse(imp,rel_pos0);
1131 if (body1)
1132 body1->applyImpulse(-imp,rel_pos1);
1133 }
1134 }
1135 }
1136 }
1137}
1138
1139
1140
1141
1142
1144{
1145 BT_PROFILE("predictUnconstraintMotion");
1146 for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
1147 {
1149 if (!body->isStaticOrKinematicObject())
1150 {
1151 //don't integrate/update velocities here, it happens in the constraint solver
1152
1153 body->applyDamping(timeStep);
1154
1156 }
1157 }
1158}
1159
1160
1162{
1163 (void)timeStep;
1164
1165#ifndef BT_NO_PROFILE
1167#endif //BT_NO_PROFILE
1168
1169}
1170
1171
1172
1173
1174
1175
1177{
1178 bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
1180 btScalar dbgDrawSize = constraint->getDbgDrawSize();
1181 if(dbgDrawSize <= btScalar(0.f))
1182 {
1183 return;
1184 }
1185
1186 switch(constraint->getConstraintType())
1187 {
1189 {
1191 btTransform tr;
1192 tr.setIdentity();
1193 btVector3 pivot = p2pC->getPivotInA();
1194 pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1195 tr.setOrigin(pivot);
1196 getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1197 // that ideally should draw the same frame
1198 pivot = p2pC->getPivotInB();
1199 pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1200 tr.setOrigin(pivot);
1201 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1202 }
1203 break;
1205 {
1206 btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
1207 btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1208 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1209 tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1210 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1211 btScalar minAng = pHinge->getLowerLimit();
1212 btScalar maxAng = pHinge->getUpperLimit();
1213 if(minAng == maxAng)
1214 {
1215 break;
1216 }
1217 bool drawSect = true;
1218 if(!pHinge->hasLimit())
1219 {
1220 minAng = btScalar(0.f);
1221 maxAng = SIMD_2_PI;
1222 drawSect = false;
1223 }
1224 if(drawLimits)
1225 {
1226 btVector3& center = tr.getOrigin();
1227 btVector3 normal = tr.getBasis().getColumn(2);
1228 btVector3 axis = tr.getBasis().getColumn(0);
1229 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
1230 }
1231 }
1232 break;
1234 {
1235 btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
1237 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1238 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1239 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1240 if(drawLimits)
1241 {
1242 //const btScalar length = btScalar(5);
1243 const btScalar length = dbgDrawSize;
1244 static int nSegments = 8*4;
1245 btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
1246 btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1247 pPrev = tr * pPrev;
1248 for (int i=0; i<nSegments; i++)
1249 {
1250 fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
1251 btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1252 pCur = tr * pCur;
1253 getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
1254
1255 if (i%(nSegments/8) == 0)
1256 getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
1257
1258 pPrev = pCur;
1259 }
1260 btScalar tws = pCT->getTwistSpan();
1261 btScalar twa = pCT->getTwistAngle();
1262 bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1263 if(useFrameB)
1264 {
1265 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1266 }
1267 else
1268 {
1269 tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1270 }
1271 btVector3 pivot = tr.getOrigin();
1272 btVector3 normal = tr.getBasis().getColumn(0);
1273 btVector3 axis1 = tr.getBasis().getColumn(1);
1274 getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
1275
1276 }
1277 }
1278 break;
1280 case D6_CONSTRAINT_TYPE:
1281 {
1284 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1285 tr = p6DOF->getCalculatedTransformB();
1286 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1287 if(drawLimits)
1288 {
1289 tr = p6DOF->getCalculatedTransformA();
1290 const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1291 btVector3 up = tr.getBasis().getColumn(2);
1292 btVector3 axis = tr.getBasis().getColumn(0);
1293 btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1294 btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1295 btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1296 btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1297 getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
1298 axis = tr.getBasis().getColumn(1);
1299 btScalar ay = p6DOF->getAngle(1);
1300 btScalar az = p6DOF->getAngle(2);
1301 btScalar cy = btCos(ay);
1302 btScalar sy = btSin(ay);
1303 btScalar cz = btCos(az);
1304 btScalar sz = btSin(az);
1305 btVector3 ref;
1306 ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1307 ref[1] = -sz*axis[0] + cz*axis[1];
1308 ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1309 tr = p6DOF->getCalculatedTransformB();
1310 btVector3 normal = -tr.getBasis().getColumn(0);
1311 btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1312 btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1313 if(minFi > maxFi)
1314 {
1315 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
1316 }
1317 else if(minFi < maxFi)
1318 {
1319 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
1320 }
1321 tr = p6DOF->getCalculatedTransformA();
1324 getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
1325 }
1326 }
1327 break;
1330 {
1331 {
1334 if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1335 tr = p6DOF->getCalculatedTransformB();
1336 if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1337 if (drawLimits)
1338 {
1339 tr = p6DOF->getCalculatedTransformA();
1340 const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1341 btVector3 up = tr.getBasis().getColumn(2);
1342 btVector3 axis = tr.getBasis().getColumn(0);
1343 btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1344 btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1345 btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1346 btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1347 getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1348 axis = tr.getBasis().getColumn(1);
1349 btScalar ay = p6DOF->getAngle(1);
1350 btScalar az = p6DOF->getAngle(2);
1351 btScalar cy = btCos(ay);
1352 btScalar sy = btSin(ay);
1353 btScalar cz = btCos(az);
1354 btScalar sz = btSin(az);
1355 btVector3 ref;
1356 ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
1357 ref[1] = -sz*axis[0] + cz*axis[1];
1358 ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
1359 tr = p6DOF->getCalculatedTransformB();
1360 btVector3 normal = -tr.getBasis().getColumn(0);
1361 btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1362 btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1363 if (minFi > maxFi)
1364 {
1365 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1366 }
1367 else if (minFi < maxFi)
1368 {
1369 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1370 }
1371 tr = p6DOF->getCalculatedTransformA();
1374 getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1375 }
1376 }
1377 break;
1378 }
1380 {
1381 btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
1382 btTransform tr = pSlider->getCalculatedTransformA();
1383 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1384 tr = pSlider->getCalculatedTransformB();
1385 if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
1386 if(drawLimits)
1387 {
1389 btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1390 btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1391 getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
1392 btVector3 normal = tr.getBasis().getColumn(0);
1393 btVector3 axis = tr.getBasis().getColumn(1);
1394 btScalar a_min = pSlider->getLowerAngLimit();
1395 btScalar a_max = pSlider->getUpperAngLimit();
1396 const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1397 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
1398 }
1399 }
1400 break;
1401 default :
1402 break;
1403 }
1404 return;
1405}
1406
1407
1408
1409
1410
1412{
1414 {
1416 }
1417 m_ownsConstraintSolver = false;
1418 m_constraintSolver = solver;
1420}
1421
1423{
1424 return m_constraintSolver;
1425}
1426
1427
1429{
1430 return int(m_constraints.size());
1431}
1433{
1434 return m_constraints[index];
1435}
1437{
1438 return m_constraints[index];
1439}
1440
1441
1442
1444{
1445 int i;
1446 //serialize all collision objects
1447 for (i=0;i<m_collisionObjects.size();i++)
1448 {
1451 {
1452 int len = colObj->calculateSerializeBufferSize();
1453 btChunk* chunk = serializer->allocate(len,1);
1454 const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1455 serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj);
1456 }
1457 }
1458
1459 for (i=0;i<m_constraints.size();i++)
1460 {
1461 btTypedConstraint* constraint = m_constraints[i];
1462 int size = constraint->calculateSerializeBufferSize();
1463 btChunk* chunk = serializer->allocate(size,1);
1464 const char* structType = constraint->serialize(chunk->m_oldPtr,serializer);
1465 serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint);
1466 }
1467}
1468
1469
1470
1471
1473{
1474#ifdef BT_USE_DOUBLE_PRECISION
1475 int len = sizeof(btDynamicsWorldDoubleData);
1476 btChunk* chunk = serializer->allocate(len,1);
1478#else//BT_USE_DOUBLE_PRECISION
1479 int len = sizeof(btDynamicsWorldFloatData);
1480 btChunk* chunk = serializer->allocate(len,1);
1482#endif//BT_USE_DOUBLE_PRECISION
1483
1484 memset(worldInfo ,0x00,len);
1485
1486 m_gravity.serialize(worldInfo->m_gravity);
1487 worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
1491
1494 worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
1495 worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
1496
1497 worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
1501
1506
1511
1513
1514 // Fill padding with zeros to appease msan.
1515 memset(worldInfo->m_solverInfo.m_padding, 0, sizeof(worldInfo->m_solverInfo.m_padding));
1516
1517#ifdef BT_USE_DOUBLE_PRECISION
1518 const char* structType = "btDynamicsWorldDoubleData";
1519#else//BT_USE_DOUBLE_PRECISION
1520 const char* structType = "btDynamicsWorldFloatData";
1521#endif//BT_USE_DOUBLE_PRECISION
1522 serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo);
1523}
1524
1526{
1527
1528 serializer->startSerialization();
1529
1530 serializeDynamicsWorldInfo(serializer);
1531
1532 serializeCollisionObjects(serializer);
1533
1534 serializeRigidBodies(serializer);
1535
1536 serializer->finishSerialization();
1537}
1538
#define btAlignedFree(ptr)
#define btAlignedAlloc(size, alignment)
#define ACTIVE_TAG
#define DISABLE_DEACTIVATION
#define WANTS_DEACTIVATION
#define ISLAND_SLEEPING
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
int btGetConstraintIslandId(const btTypedConstraint *lhs)
int gNumClampedCcdMotions
internal debugging variable. this value shouldn't be too high
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:886
#define BT_PROFILE(name)
Definition: btQuickprof.h:215
bool gDisableDeactivation
Definition: btRigidBody.cpp:26
@ BT_DISABLE_WORLD_GRAVITY
Definition: btRigidBody.h:43
#define SIMD_PI
Definition: btScalar.h:504
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:292
btScalar btSin(btScalar x)
Definition: btScalar.h:477
#define SIMD_FORCE_INLINE
Definition: btScalar.h:81
btScalar btCos(btScalar x)
Definition: btScalar.h:476
bool btFuzzyZero(btScalar x)
Definition: btScalar.h:550
#define SIMD_2_PI
Definition: btScalar.h:505
#define btAssert(x)
Definition: btScalar.h:131
#define BT_RIGIDBODY_CODE
Definition: btSerializer.h:120
#define BT_DYNAMICSWORLD_CODE
Definition: btSerializer.h:129
#define BT_CONSTRAINT_CODE
Definition: btSerializer.h:121
void btMutexLock(btSpinMutex *mutex)
Definition: btThreads.h:71
void btMutexUnlock(btSpinMutex *mutex)
Definition: btThreads.h:78
@ SLIDER_CONSTRAINT_TYPE
@ CONETWIST_CONSTRAINT_TYPE
@ POINT2POINT_CONSTRAINT_TYPE
@ D6_SPRING_2_CONSTRAINT_TYPE
@ HINGE_CONSTRAINT_TYPE
@ D6_SPRING_CONSTRAINT_TYPE
@ D6_CONSTRAINT_TYPE
static void Increment_Frame_Counter(void)
static void Reset(void)
Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWor...
int size() const
return the number of elements in the array
void resize(int newsize, const T &fillData=T())
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0),...
void push_back(const T &_Val)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
void * m_oldPtr
Definition: btSerializer.h:56
btClosestNotMeConvexResultCallback(btCollisionObject *me, const btVector3 &fromA, const btVector3 &toA, btOverlappingPairCache *pairCache, btDispatcher *dispatcher)
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace)
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
virtual void getAllContactManifolds(btManifoldArray &manifoldArray)=0
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size,...
btCollisionObject can be used to manage collision detection objects.
bool isStaticOrKinematicObject() const
btScalar getHitFraction() const
virtual const char * serialize(void *dataBuffer, class btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTransform & getWorldTransform()
btBroadphaseProxy * getBroadphaseHandle()
int getInternalType() const
reserved for Bullet internal usage
bool hasContactResponse() const
bool isStaticObject() const
void setActivationState(int newState) const
virtual int calculateSerializeBufferSize() const
bool isKinematicObject() const
const btTransform & getInterpolationWorldTransform() const
int getIslandTag() const
const btVector3 & getInterpolationAngularVelocity() const
btScalar getCcdMotionThreshold() const
void setHitFraction(btScalar hitFraction)
int getActivationState() const
btScalar getCcdSquareMotionThreshold() const
const btVector3 & getInterpolationLinearVelocity() const
btScalar getCcdSweptSphereRadius() const
Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
bool isConvex() const
CollisionWorld is interface and container for the collision detection.
btDispatcher * getDispatcher()
btDispatcherInfo & getDispatchInfo()
virtual void debugDrawWorld()
virtual btIDebugDraw * getDebugDrawer()
virtual void removeCollisionObject(btCollisionObject *collisionObject)
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
int getNumCollisionObjects() const
virtual void performDiscreteCollisionDetection()
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...
btIDebugDraw * m_debugDrawer
btDispatcher * m_dispatcher1
const btBroadphaseInterface * getBroadphase() const
void serializeCollisionObjects(btSerializer *serializer)
btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc)
const btRigidBody & getRigidBodyB() const
const btTransform & getBFrame() const
btScalar getTwistAngle() const
const btRigidBody & getRigidBodyA() const
btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const
const btTransform & getAFrame() const
virtual void allSolved(const btContactSolverInfo &, class btIDebugDraw *)
virtual void prepareSolve(int, int)
virtual btScalar solveGroup(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifold, int numManifolds, btTypedConstraint **constraints, int numConstraints, const btContactSolverInfo &info, class btIDebugDraw *debugDrawer, btDispatcher *dispatcher)=0
solve a group of constraints
void updateActions(btScalar timeStep)
virtual void removeAction(btActionInterface *)
btAlignedObjectArray< btPersistentManifold * > m_predictiveManifolds
void integrateTransformsInternal(btRigidBody **bodies, int numBodies, btScalar timeStep)
virtual void setGravity(const btVector3 &gravity)
virtual void removeConstraint(btTypedConstraint *constraint)
virtual void integrateTransforms(btScalar timeStep)
void synchronizeSingleMotionState(btRigidBody *body)
this can be useful to synchronize a single rigid body -> graphics object
void createPredictiveContactsInternal(btRigidBody **bodies, int numBodies, btScalar timeStep)
virtual void addVehicle(btActionInterface *vehicle)
obsolete, use addAction instead
virtual btConstraintSolver * getConstraintSolver()
virtual void serialize(btSerializer *serializer)
Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see B...
void serializeRigidBodies(btSerializer *serializer)
virtual void internalSingleStepSimulation(btScalar timeStep)
virtual void addRigidBody(btRigidBody *body)
virtual void removeRigidBody(btRigidBody *body)
virtual btTypedConstraint * getConstraint(int index)
void serializeDynamicsWorldInfo(btSerializer *serializer)
virtual void addAction(btActionInterface *)
btAlignedObjectArray< btTypedConstraint * > m_sortedConstraints
btDiscreteDynamicsWorld(btDispatcher *dispatcher, btBroadphaseInterface *pairCache, btConstraintSolver *constraintSolver, btCollisionConfiguration *collisionConfiguration)
this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete thos...
virtual void setConstraintSolver(btConstraintSolver *solver)
virtual int stepSimulation(btScalar timeStep, int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))
if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
virtual void saveKinematicState(btScalar timeStep)
virtual void addConstraint(btTypedConstraint *constraint, bool disableCollisionsBetweenLinkedBodies=false)
virtual void addCharacter(btActionInterface *character)
obsolete, use addAction instead
virtual btVector3 getGravity() const
InplaceSolverIslandCallback * m_solverIslandCallback
virtual void applyGravity()
apply gravity, call this once per timestep
btSimulationIslandManager * m_islandManager
virtual void createPredictiveContacts(btScalar timeStep)
btAlignedObjectArray< btTypedConstraint * > m_constraints
btAlignedObjectArray< btRigidBody * > m_nonStaticRigidBodies
btAlignedObjectArray< btActionInterface * > m_actions
virtual void removeCharacter(btActionInterface *character)
obsolete, use removeAction instead
btSimulationIslandManager * getSimulationIslandManager()
virtual void updateActivationState(btScalar timeStep)
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::StaticFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter)
virtual void removeCollisionObject(btCollisionObject *collisionObject)
removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise ca...
btConstraintSolver * m_constraintSolver
virtual void debugDrawConstraint(btTypedConstraint *constraint)
btCollisionWorld * getCollisionWorld()
virtual void clearForces()
the forces on each rigidbody is accumulating together with gravity. clear this after each timestep.
virtual void solveConstraints(btContactSolverInfo &solverInfo)
virtual void predictUnconstraintMotion(btScalar timeStep)
virtual void removeVehicle(btActionInterface *vehicle)
obsolete, use removeAction instead
void startProfiling(btScalar timeStep)
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
Definition: btDispatcher.h:76
virtual void releaseManifold(btPersistentManifold *manifold)=0
virtual bool needsResponse(const btCollisionObject *body0, const btCollisionObject *body1)=0
virtual btPersistentManifold * getNewManifold(const btCollisionObject *b0, const btCollisionObject *b1)=0
The btDynamicsWorld is the interface class for several dynamics implementation, basic,...
btContactSolverInfo & getSolverInfo()
btInternalTickCallback m_internalTickCallback
btInternalTickCallback m_internalPreTickCallback
btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis locatio...
const btTransform & getCalculatedTransformB() const
Gets the global transform of the offset for body B.
btRotationalLimitMotor * getRotationalLimitMotor(int index)
Retrieves the angular limit informacion.
const btTransform & getCalculatedTransformA() const
Gets the global transform of the offset for body A.
btScalar getAngle(int axis_index) const
Get the relative Euler angle.
btTranslationalLimitMotor * getTranslationalLimitMotor()
Retrieves the limit informacion.
btRotationalLimitMotor2 * getRotationalLimitMotor(int index)
const btTransform & getCalculatedTransformA() const
const btTransform & getCalculatedTransformB() const
btScalar getAngle(int axis_index) const
btTranslationalLimitMotor2 * getTranslationalLimitMotor()
hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in lo...
const btRigidBody & getRigidBodyB() const
const btTransform & getAFrame() const
btScalar getUpperLimit() const
const btTransform & getBFrame() const
btScalar getLowerLimit() const
const btRigidBody & getRigidBodyA() const
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
Definition: btIDebugDraw.h:30
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
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
virtual void flushLines()
Definition: btIDebugDraw.h:476
virtual void drawTransform(const btTransform &transform, btScalar orthoLen)
Definition: btIDebugDraw.h:166
virtual int getDebugMode() const =0
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
Definition: btIDebugDraw.h:306
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
@ DBG_DrawConstraintLimits
Definition: btIDebugDraw.h:71
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar m_combinedRestitution
btVector3 m_positionWorldOnA
m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity
const btVector3 & getPositionWorldOnB() const
const btVector3 & getPositionWorldOnA() const
btScalar m_appliedImpulse
btVector3 m_normalWorldOnB
btScalar m_combinedFriction
btVector3 m_positionWorldOnB
static btScalar calculateCombinedFriction(const btCollisionObject *body0, const btCollisionObject *body1)
User can override this material combiner by implementing gContactAddedCallback and setting body0->m_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
btVector3 getColumn(int i) const
Get a column of the matrix as a vector.
Definition: btMatrix3x3.h:134
virtual void setWorldTransform(const btTransform &worldTrans)=0
The btOverlappingPairCache provides an interface for overlapping pair management (add,...
virtual btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)=0
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
const btManifoldPoint & getContactPoint(int index) const
const btCollisionObject * getBody0() const
const btCollisionObject * getBody1() const
int addManifoldPoint(const btManifoldPoint &newPoint, bool isPredictive=false)
point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocke...
const btVector3 & getPivotInB() const
const btVector3 & getPivotInA() const
The btRigidBody is the main class for rigid body objects.
Definition: btRigidBody.h:63
void applyGravity()
bool wantsSleeping()
Definition: btRigidBody.h:438
void addConstraintRef(btTypedConstraint *c)
void clearForces()
Definition: btRigidBody.h:346
int getFlags() const
Definition: btRigidBody.h:533
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
btScalar getInvMass() const
Definition: btRigidBody.h:273
void updateDeactivation(btScalar timeStep)
Definition: btRigidBody.h:421
void setGravity(const btVector3 &acceleration)
void proceedToTransform(const btTransform &newTrans)
const btTransform & getCenterOfMassTransform() const
Definition: btRigidBody.h:359
const btCollisionShape * getCollisionShape() const
Definition: btRigidBody.h:254
void saveKinematicState(btScalar step)
void applyImpulse(const btVector3 &impulse, const btVector3 &rel_pos)
Definition: btRigidBody.h:334
btMotionState * getMotionState()
Definition: btRigidBody.h:474
void removeConstraintRef(btTypedConstraint *c)
void setAngularVelocity(const btVector3 &ang_vel)
Definition: btRigidBody.h:376
void setLinearVelocity(const btVector3 &lin_vel)
Definition: btRigidBody.h:370
const btBroadphaseProxy * getBroadphaseProxy() const
Definition: btRigidBody.h:460
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:203
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
const btVector3 & getLinearVelocity() const
Definition: btRigidBody.h:362
btScalar m_hiLimit
joint limit
btScalar m_loLimit
limit_parameters
The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (...
virtual btChunk * allocate(size_t size, int numElements)=0
virtual void finishSerialization()=0
virtual void startSerialization()=0
virtual void finalizeChunk(btChunk *chunk, const char *structType, int chunkCode, void *oldPtr)=0
SimulationIslandManager creates and handles simulation islands, using btUnionFind.
virtual void storeIslandActivationState(btCollisionWorld *world)
virtual void updateActivationState(btCollisionWorld *colWorld, btDispatcher *dispatcher)
void buildAndProcessIslands(btDispatcher *dispatcher, btCollisionWorld *collisionWorld, IslandCallback *callback)
const btTransform & getCalculatedTransformB() const
const btTransform & getCalculatedTransformA() const
bool operator()(const btTypedConstraint *lhs, const btTypedConstraint *rhs) const
The btSphereShape implements an implicit sphere, centered around a local origin with radius.
Definition: btSphereShape.h:24
The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out)
Definition: btStackAlloc.h:35
static void integrateTransform(const btTransform &curTrans, const btVector3 &linvel, const btVector3 &angvel, btScalar timeStep, btTransform &predictedTransform)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition: btTransform.h:34
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
Definition: btTransform.h:112
void setIdentity()
Set this transformation to the identity.
Definition: btTransform.h:172
btVector3 & getOrigin()
Return the origin vector translation.
Definition: btTransform.h:117
void setOrigin(const btVector3 &origin)
Set the translational element.
Definition: btTransform.h:150
void setBasis(const btMatrix3x3 &basis)
Set the rotational element by btMatrix3x3.
Definition: btTransform.h:159
btVector3 m_lowerLimit
the constraint lower limits
btVector3 m_upperLimit
the constraint upper limits
TypedConstraint is the baseclass for Bullet constraints and vehicles.
virtual const char * serialize(void *dataBuffer, btSerializer *serializer) const
fills the dataBuffer and returns the struct name (and 0 on failure)
btTypedConstraintType getConstraintType() const
bool isEnabled() const
const btRigidBody & getRigidBodyA() const
const btRigidBody & getRigidBodyB() const
virtual int calculateSerializeBufferSize() const
void unite(int p, int q)
Definition: btUnionFind.h:81
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:84
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:235
btScalar length2() const
Return the length of the vector squared.
Definition: btVector3.h:257
void serialize(struct btVector3Data &dataOut) const
Definition: btVector3.h:1351
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:309
btAlignedObjectArray< btCollisionObject * > m_bodies
InplaceSolverIslandCallback(btConstraintSolver *solver, btStackAlloc *stackAlloc, btDispatcher *dispatcher)
btAlignedObjectArray< btTypedConstraint * > m_constraints
btAlignedObjectArray< btPersistentManifold * > m_manifolds
virtual void processIsland(btCollisionObject **bodies, int numBodies, btPersistentManifold **manifolds, int numManifolds, int islandId)
btTypedConstraint ** m_sortedConstraints
InplaceSolverIslandCallback & operator=(InplaceSolverIslandCallback &other)
void setup(btContactSolverInfo *solverInfo, btTypedConstraint **sortedConstraints, int numConstraints, btIDebugDraw *debugDrawer)
The btBroadphasePair class contains a pair of aabb-overlapping objects.
btCollisionAlgorithm * m_algorithm
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
ClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld)
const btCollisionObject * m_hitCollisionObject
btScalar m_singleAxisRollingFrictionThreshold
double m_singleAxisRollingFrictionThreshold
it is only used for 'explicit' version of gyroscopic force
btScalar m_timeStep
Definition: btDispatcher.h:53
btScalar m_allowedCcdPenetration
Definition: btDispatcher.h:62
class btIDebugDraw * m_debugDraw
Definition: btDispatcher.h:58
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
btContactSolverInfoDoubleData m_solverInfo
btVector3DoubleData m_gravity
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64