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
17
18//collision detection
26
27//rigidbody & constraints
39
42
46
48
49#if 0
52int startHit=2;
54#endif
55
57{
58 int islandId;
59
60 const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
61 const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
62 islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag();
63 return islandId;
64}
65
67{
68public:
70 {
74 return lIslandId0 < rIslandId0;
75 }
76};
77
79{
86
90
92 btConstraintSolver* solver,
96 m_solver(solver),
101 {
102 }
103
105 {
106 btAssert(0);
107 (void)other;
108 return *this;
109 }
110
112 {
116 m_numConstraints = numConstraints;
118 m_bodies.resize(0);
121 }
122
123 virtual void processIsland(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifolds, int numManifolds, int islandId)
124 {
125 if (islandId < 0)
126 {
129 }
130 else
131 {
132 //also add all non-contact constraints/joints for this island
134 int numCurConstraints = 0;
135 int i;
136
137 //find the first constraint for this island
138 for (i = 0; i < m_numConstraints; i++)
139 {
141 {
143 break;
144 }
145 }
146 //count the number of constraints in this island
147 for (; i < m_numConstraints; i++)
148 {
150 {
152 }
153 }
154
156 {
158 }
159 else
160 {
161 for (i = 0; i < numBodies; i++)
162 m_bodies.push_back(bodies[i]);
163 for (i = 0; i < numManifolds; i++)
165 for (i = 0; i < numCurConstraints; i++)
168 {
170 }
171 else
172 {
173 //printf("deferred\n");
174 }
175 }
176 }
177 }
179 {
180 btCollisionObject** bodies = m_bodies.size() ? &m_bodies[0] : 0;
183
185 m_bodies.resize(0);
188 }
189};
190
193 m_sortedConstraints(),
194 m_solverIslandCallback(NULL),
195 m_constraintSolver(constraintSolver),
196 m_gravity(0, -10, 0),
197 m_localTime(0),
198 m_fixedTimeStep(0),
199 m_synchronizeAllMotionStates(false),
200 m_applySpeculativeContactRestitution(false),
201 m_profileTimings(0),
202 m_latencyMotionStateInterpolation(true)
203
204{
206 {
210 }
211 else
212 {
214 }
215
216 {
217 void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager), 16);
219 }
220
221 m_ownsIslandManager = true;
222
223 {
226 }
227}
228
230{
231 //only delete it when we created it
233 {
236 }
238 {
239 m_solverIslandCallback->~InplaceSolverIslandCallback();
241 }
243 {
246 }
247}
248
250{
254 for (int i = 0; i < m_collisionObjects.size(); i++)
255 {
258 if (body && body->getActivationState() != ISLAND_SLEEPING)
259 {
260 if (body->isKinematicObject())
261 {
262 //to calculate velocities next frame
263 body->saveKinematicState(timeStep);
264 }
265 }
266 }
267}
268
270{
271 BT_PROFILE("debugDrawWorld");
272
274
275 bool drawConstraints = false;
276 if (getDebugDrawer())
277 {
280 {
281 drawConstraints = true;
282 }
283 }
284 if (drawConstraints)
285 {
286 for (int i = getNumConstraints() - 1; i >= 0; i--)
287 {
290 }
291 }
292
294 {
295 int i;
296
297 if (getDebugDrawer() && getDebugDrawer()->getDebugMode())
298 {
299 for (i = 0; i < m_actions.size(); i++)
300 {
301 m_actions[i]->debugDraw(m_debugDrawer);
302 }
303 }
304 }
305 if (getDebugDrawer())
307}
308
310{
312 for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
313 {
315 //need to check if next line is ok
316 //it might break backward compatibility (people applying forces on sleeping objects get never cleared and accumulate on wake-up
317 body->clearForces();
318 }
319}
320
323{
325 for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
326 {
328 if (body->isActive())
329 {
330 body->applyGravity();
331 }
332 }
333}
334
336{
337 btAssert(body);
338
339 if (body->getMotionState() && !body->isStaticOrKinematicObject())
340 {
341 //we need to call the update at least once, even for sleeping objects
342 //otherwise the 'graphics' transform never updates properly
344 //if (body->getActivationState() != ISLAND_SLEEPING)
345 {
352 }
353 }
354}
355
357{
358 // BT_PROFILE("synchronizeMotionStates");
360 {
361 //iterate over all collision objects
362 for (int i = 0; i < m_collisionObjects.size(); i++)
363 {
366 if (body)
368 }
369 }
370 else
371 {
372 //iterate over all active rigid bodies
373 for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
374 {
376 if (body->isActive())
378 }
379 }
380}
381
383{
384 startProfiling(timeStep);
385
386 int numSimulationSubSteps = 0;
387
388 if (maxSubSteps)
389 {
390 //fixed timestep with interpolation
392 m_localTime += timeStep;
394 {
397 }
398 }
399 else
400 {
401 //variable timestep
402 fixedTimeStep = timeStep;
404 m_fixedTimeStep = 0;
405 if (btFuzzyZero(timeStep))
406 {
408 maxSubSteps = 0;
409 }
410 else
411 {
413 maxSubSteps = 1;
414 }
415 }
416
417 //process some debugging flags
418 if (getDebugDrawer())
419 {
422 }
424 {
425 //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
427
429
430 applyGravity();
431
432 for (int i = 0; i < clampedSimulationSteps; i++)
433 {
436 }
437 }
438 else
439 {
441 }
442
443 clearForces();
444
445#ifndef BT_NO_PROFILE
446 CProfileManager::Increment_Frame_Counter();
447#endif //BT_NO_PROFILE
448
450}
451
453{
454 BT_PROFILE("internalSingleStepSimulation");
455
457 {
458 (*m_internalPreTickCallback)(this, timeStep);
459 }
460
463
465
466 dispatchInfo.m_timeStep = timeStep;
467 dispatchInfo.m_stepCount = 0;
468 dispatchInfo.m_debugDraw = getDebugDrawer();
469
470 createPredictiveContacts(timeStep);
471
474
476
477 getSolverInfo().m_timeStep = timeStep;
478
481
483
485
486 integrateTransforms(timeStep);
487
489 updateActions(timeStep);
490
491 updateActivationState(timeStep);
492
493 if (0 != m_internalTickCallback)
494 {
495 (*m_internalTickCallback)(this, timeStep);
496 }
497}
498
500{
502 for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
503 {
505 if (body->isActive() && !(body->getFlags() & BT_DISABLE_WORLD_GRAVITY))
506 {
507 body->setGravity(gravity);
508 }
509 }
510}
511
513{
514 return m_gravity;
515}
516
518{
520}
521
523{
525 if (body)
526 removeRigidBody(body);
527 else
529}
530
532{
535}
536
538{
540 {
541 body->setGravity(m_gravity);
542 }
543
544 if (body->getCollisionShape())
545 {
546 if (!body->isStaticObject())
547 {
549 }
550 else
551 {
553 }
554
555 bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
558
560 }
561}
562
564{
566 {
567 body->setGravity(m_gravity);
568 }
569
570 if (body->getCollisionShape())
571 {
572 if (!body->isStaticObject())
573 {
575 }
576 else
577 {
579 }
580 addCollisionObject(body, group, mask);
581 }
582}
583
585{
586 BT_PROFILE("updateActions");
587
588 for (int i = 0; i < m_actions.size(); i++)
589 {
590 m_actions[i]->updateAction(this, timeStep);
591 }
592}
593
595{
596 BT_PROFILE("updateActivationState");
597
598 for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
599 {
601 if (body)
602 {
603 body->updateDeactivation(timeStep);
604
605 if (body->wantsSleeping())
606 {
607 if (body->isStaticOrKinematicObject())
608 {
610 }
611 else
612 {
613 if (body->getActivationState() == ACTIVE_TAG)
615 if (body->getActivationState() == ISLAND_SLEEPING)
616 {
617 body->setAngularVelocity(btVector3(0, 0, 0));
618 body->setLinearVelocity(btVector3(0, 0, 0));
619 }
620 }
621 }
622 else
623 {
626 }
627 }
628 }
629}
630
632{
634 //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?)
635 btAssert(&constraint->getRigidBodyA() != &constraint->getRigidBodyB());
636
638 {
639 constraint->getRigidBodyA().addConstraintRef(constraint);
640 constraint->getRigidBodyB().addConstraintRef(constraint);
641 }
642}
643
645{
647 constraint->getRigidBodyA().removeConstraintRef(constraint);
648 constraint->getRigidBodyB().removeConstraintRef(constraint);
649}
650
652{
654}
655
657{
659}
660
662{
664}
665
667{
669}
670
672{
674}
675
677{
679}
680
682{
683 BT_PROFILE("solveConstraints");
684
686 int i;
687 for (i = 0; i < getNumConstraints(); i++)
688 {
690 }
691
692 // btAssert(0);
693
695
697
700
703
705
707}
708
710{
711 BT_PROFILE("calculateSimulationIslands");
712
714
715 {
716 //merge islands based on speculative contact manifolds too
717 for (int i = 0; i < this->m_predictiveManifolds.size(); i++)
718 {
720
721 const btCollisionObject* colObj0 = manifold->getBody0();
722 const btCollisionObject* colObj1 = manifold->getBody1();
723
724 if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
725 ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
726 {
727 getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag());
728 }
729 }
730 }
731
732 {
733 int i;
734 int numConstraints = int(m_constraints.size());
735 for (i = 0; i < numConstraints; i++)
736 {
738 if (constraint->isEnabled())
739 {
740 const btRigidBody* colObj0 = &constraint->getRigidBodyA();
741 const btRigidBody* colObj1 = &constraint->getRigidBodyB();
742
743 if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
744 ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
745 {
746 getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag());
747 }
748 }
749 }
750 }
751
752 //Store the island id in each body
754}
755
757{
758public:
763
764public:
766 m_me(me),
770 {
771 }
772
774 {
775 if (convexResult.m_hitCollisionObject == m_me)
776 return 1.0f;
777
778 //ignore result if there is no contact response
779 if (!convexResult.m_hitCollisionObject->hasContactResponse())
780 return 1.0f;
781
784 linVelB = btVector3(0, 0, 0); //toB.getOrigin()-fromB.getOrigin();
785
787 //don't report time of impact for motion away from the contact normal (or causes minor penetration)
788 if (convexResult.m_hitNormalLocal.dot(relativeVelocity) >= -m_allowedPenetration)
789 return 1.f;
790
791 return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
792 }
793
795 {
796 //don't collide with itself
797 if (proxy0->m_clientObject == m_me)
798 return false;
799
801 if (!ClosestConvexResultCallback::needsCollision(proxy0))
802 return false;
806 if (!collides)
807 {
808 return false;
809 }
810 }
811
813
815 return false;
816
817 //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
819 {
820#if 0
824 if (collisionPair)
825 {
826 if (collisionPair->m_algorithm)
827 {
828 manifoldArray.resize(0);
829 collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
830 for (int j=0;j<manifoldArray.size();j++)
831 {
832 btPersistentManifold* manifold = manifoldArray[j];
833 if (manifold->getNumContacts()>0)
834 return false;
835 }
836 }
837 }
838#endif
839 return true;
840 }
841
842 return false;
843 }
844};
845
848
850{
852 for (int i = 0; i < numBodies; i++)
853 {
854 btRigidBody* body = bodies[i];
855 body->setHitFraction(1.f);
856
857 if (body->isActive() && (!body->isStaticOrKinematicObject()))
858 {
860
861 btScalar squareMotion = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()).length2();
862
864 {
865 BT_PROFILE("predictive convexSweepTest");
866 if (body->getCollisionShape()->isConvex())
867 {
869#ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
871 {
872 public:
874 {
875 }
876
877 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
878 {
880 if (!otherObj->isStaticOrKinematicObject())
881 return false;
883 }
884 };
885
886 StaticOnlyCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
887#else
888 btClosestNotMeConvexResultCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
889#endif
890 //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
891 btSphereShape tmpSphere(body->getCcdSweptSphereRadius()); //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
893
894 sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
895 sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
898
900 if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
901 {
902 btVector3 distVec = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()) * sweepResults.m_closestHitFraction;
903 btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
904
909
911 btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse() * worldPointB;
912
913 btManifoldPoint newPoint(btVector3(0, 0, 0), localPointB, sweepResults.m_hitNormalWorld, distance);
914
915 bool isPredictive = true;
916 int index = manifold->addManifoldPoint(newPoint, isPredictive);
917 btManifoldPoint& pt = manifold->getContactPoint(index);
919 pt.m_combinedFriction = gCalculateCombinedFrictionCallback(body, sweepResults.m_hitCollisionObject);
920 pt.m_positionWorldOnA = body->getWorldTransform().getOrigin();
921 pt.m_positionWorldOnB = worldPointB;
922 }
923 }
924 }
925 }
926 }
927}
928
930{
931 BT_PROFILE("release predictive contact manifolds");
932
933 for (int i = 0; i < m_predictiveManifolds.size(); i++)
934 {
936 this->m_dispatcher1->releaseManifold(manifold);
937 }
939}
940
942{
943 BT_PROFILE("createPredictiveContacts");
946 {
948 }
949}
950
952{
954 for (int i = 0; i < numBodies; i++)
955 {
956 btRigidBody* body = bodies[i];
957 body->setHitFraction(1.f);
958
959 if (body->isActive() && (!body->isStaticOrKinematicObject()))
960 {
962
963 btScalar squareMotion = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()).length2();
964
966 {
967 BT_PROFILE("CCD motion clamping");
968 if (body->getCollisionShape()->isConvex())
969 {
971#ifdef USE_STATIC_ONLY
973 {
974 public:
976 {
977 }
978
979 virtual bool needsCollision(btBroadphaseProxy* proxy0) const
980 {
982 if (!otherObj->isStaticOrKinematicObject())
983 return false;
985 }
986 };
987
988 StaticOnlyCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
989#else
990 btClosestNotMeConvexResultCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher());
991#endif
992 //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
993 btSphereShape tmpSphere(body->getCcdSweptSphereRadius()); //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
995
996 sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
997 sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
1000
1002 if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
1003 {
1004 //printf("clamped integration to hit fraction = %f\n",fraction);
1005 body->setHitFraction(sweepResults.m_closestHitFraction);
1006 body->predictIntegratedTransform(timeStep * body->getHitFraction(), predictedTrans);
1007 body->setHitFraction(0.f);
1009
1010#if 0
1012
1015 if (linVel.length2()>maxSpeedSqr)
1016 {
1017 linVel.normalize();
1018 linVel*= maxSpeed;
1022
1023 btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
1025 printf("sm2=%f\n",sm2);
1026 }
1027#else
1028
1029 //don't apply the collision response right now, it will happen next frame
1030 //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
1031 //btScalar appliedImpulse = 0.f;
1032 //btScalar depth = 0.f;
1033 //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
1034
1035#endif
1036
1037 continue;
1038 }
1039 }
1040 }
1041
1043 }
1044 }
1045}
1046
1048{
1049 BT_PROFILE("integrateTransforms");
1050 if (m_nonStaticRigidBodies.size() > 0)
1051 {
1053 }
1054
1057 {
1058 BT_PROFILE("apply speculative contact restitution");
1059 for (int i = 0; i < m_predictiveManifolds.size(); i++)
1060 {
1064
1065 for (int p = 0; p < manifold->getNumContacts(); p++)
1066 {
1067 const btManifoldPoint& pt = manifold->getContactPoint(p);
1069
1070 if (combinedRestitution > 0 && pt.m_appliedImpulse != 0.f)
1071 //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
1072 {
1073 btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse * combinedRestitution;
1074
1075 const btVector3& pos1 = pt.getPositionWorldOnA();
1076 const btVector3& pos2 = pt.getPositionWorldOnB();
1077
1078 btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
1079 btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
1080
1081 if (body0)
1082 body0->applyImpulse(imp, rel_pos0);
1083 if (body1)
1084 body1->applyImpulse(-imp, rel_pos1);
1085 }
1086 }
1087 }
1088 }
1089}
1090
1092{
1093 BT_PROFILE("predictUnconstraintMotion");
1094 for (int i = 0; i < m_nonStaticRigidBodies.size(); i++)
1095 {
1097 if (!body->isStaticOrKinematicObject())
1098 {
1099 //don't integrate/update velocities here, it happens in the constraint solver
1100
1101 body->applyDamping(timeStep);
1102
1104 }
1105 }
1106}
1107
1109{
1110 (void)timeStep;
1111
1112#ifndef BT_NO_PROFILE
1113 CProfileManager::Reset();
1114#endif //BT_NO_PROFILE
1115}
1116
1118{
1121 btScalar dbgDrawSize = constraint->getDbgDrawSize();
1122 if (dbgDrawSize <= btScalar(0.f))
1123 {
1124 return;
1125 }
1126
1127 switch (constraint->getConstraintType())
1128 {
1130 {
1133 tr.setIdentity();
1134 btVector3 pivot = p2pC->getPivotInA();
1135 pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot;
1136 tr.setOrigin(pivot);
1138 // that ideally should draw the same frame
1139 pivot = p2pC->getPivotInB();
1140 pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot;
1141 tr.setOrigin(pivot);
1143 }
1144 break;
1146 {
1148 btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
1150 tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
1152 btScalar minAng = pHinge->getLowerLimit();
1153 btScalar maxAng = pHinge->getUpperLimit();
1154 if (minAng == maxAng)
1155 {
1156 break;
1157 }
1158 bool drawSect = true;
1159 if (!pHinge->hasLimit())
1160 {
1161 minAng = btScalar(0.f);
1162 maxAng = SIMD_2_PI;
1163 drawSect = false;
1164 }
1165 if (drawLimits)
1166 {
1167 btVector3& center = tr.getOrigin();
1168 btVector3 normal = tr.getBasis().getColumn(2);
1169 btVector3 axis = tr.getBasis().getColumn(0);
1170 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0, 0, 0), drawSect);
1171 }
1172 }
1173 break;
1175 {
1177 btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1179 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1181 if (drawLimits)
1182 {
1183 //const btScalar length = btScalar(5);
1184 const btScalar length = dbgDrawSize;
1185 static int nSegments = 8 * 4;
1187 btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
1188 pPrev = tr * pPrev;
1189 for (int i = 0; i < nSegments; i++)
1190 {
1191 fAngleInRadians = btScalar(2. * 3.1415926) * (btScalar)i / btScalar(nSegments);
1192 btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
1193 pCur = tr * pCur;
1195
1196 if (i % (nSegments / 8) == 0)
1197 getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0, 0, 0));
1198
1199 pPrev = pCur;
1200 }
1201 btScalar tws = pCT->getTwistSpan();
1202 btScalar twa = pCT->getTwistAngle();
1203 bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
1204 if (useFrameB)
1205 {
1206 tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
1207 }
1208 else
1209 {
1210 tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
1211 }
1212 btVector3 pivot = tr.getOrigin();
1213 btVector3 normal = tr.getBasis().getColumn(0);
1214 btVector3 axis1 = tr.getBasis().getColumn(1);
1215 getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa - tws, -twa + tws, btVector3(0, 0, 0), true);
1216 }
1217 }
1218 break;
1220 case D6_CONSTRAINT_TYPE:
1221 {
1223 btTransform tr = p6DOF->getCalculatedTransformA();
1225 tr = p6DOF->getCalculatedTransformB();
1227 if (drawLimits)
1228 {
1229 tr = p6DOF->getCalculatedTransformA();
1230 const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1231 btVector3 up = tr.getBasis().getColumn(2);
1232 btVector3 axis = tr.getBasis().getColumn(0);
1233 btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1234 btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1235 btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1236 btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1237 getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1238 axis = tr.getBasis().getColumn(1);
1239 btScalar ay = p6DOF->getAngle(1);
1240 btScalar az = p6DOF->getAngle(2);
1241 btScalar cy = btCos(ay);
1242 btScalar sy = btSin(ay);
1243 btScalar cz = btCos(az);
1244 btScalar sz = btSin(az);
1245 btVector3 ref;
1246 ref[0] = cy * cz * axis[0] + cy * sz * axis[1] - sy * axis[2];
1247 ref[1] = -sz * axis[0] + cz * axis[1];
1248 ref[2] = cz * sy * axis[0] + sz * sy * axis[1] + cy * axis[2];
1249 tr = p6DOF->getCalculatedTransformB();
1250 btVector3 normal = -tr.getBasis().getColumn(0);
1251 btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1252 btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1253 if (minFi > maxFi)
1254 {
1255 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1256 }
1257 else if (minFi < maxFi)
1258 {
1259 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1260 }
1261 tr = p6DOF->getCalculatedTransformA();
1262 btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
1263 btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
1264 getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1265 }
1266 }
1267 break;
1270 {
1271 {
1273 btTransform tr = p6DOF->getCalculatedTransformA();
1275 tr = p6DOF->getCalculatedTransformB();
1277 if (drawLimits)
1278 {
1279 tr = p6DOF->getCalculatedTransformA();
1280 const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
1281 btVector3 up = tr.getBasis().getColumn(2);
1282 btVector3 axis = tr.getBasis().getColumn(0);
1283 btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
1284 btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
1285 if (minTh <= maxTh)
1286 {
1287 btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
1288 btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
1289 getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0));
1290 }
1291 axis = tr.getBasis().getColumn(1);
1292 btScalar ay = p6DOF->getAngle(1);
1293 btScalar az = p6DOF->getAngle(2);
1294 btScalar cy = btCos(ay);
1295 btScalar sy = btSin(ay);
1296 btScalar cz = btCos(az);
1297 btScalar sz = btSin(az);
1298 btVector3 ref;
1299 ref[0] = cy * cz * axis[0] + cy * sz * axis[1] - sy * axis[2];
1300 ref[1] = -sz * axis[0] + cz * axis[1];
1301 ref[2] = cz * sy * axis[0] + sz * sy * axis[1] + cy * axis[2];
1302 tr = p6DOF->getCalculatedTransformB();
1303 btVector3 normal = -tr.getBasis().getColumn(0);
1304 btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
1305 btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
1306 if (minFi > maxFi)
1307 {
1308 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false);
1309 }
1310 else if (minFi < maxFi)
1311 {
1312 getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true);
1313 }
1314 tr = p6DOF->getCalculatedTransformA();
1315 btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
1316 btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
1317 getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0));
1318 }
1319 }
1320 break;
1321 }
1323 {
1325 btTransform tr = pSlider->getCalculatedTransformA();
1327 tr = pSlider->getCalculatedTransformB();
1329 if (drawLimits)
1330 {
1331 btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB();
1332 btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
1333 btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
1335 btVector3 normal = tr.getBasis().getColumn(0);
1336 btVector3 axis = tr.getBasis().getColumn(1);
1337 btScalar a_min = pSlider->getLowerAngLimit();
1338 btScalar a_max = pSlider->getUpperAngLimit();
1339 const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
1340 getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0, 0, 0), true);
1341 }
1342 }
1343 break;
1344 default:
1345 break;
1346 }
1347 return;
1348}
1349
1351{
1353 {
1355 }
1356 m_ownsConstraintSolver = false;
1357 m_constraintSolver = solver;
1359}
1360
1362{
1363 return m_constraintSolver;
1364}
1365
1367{
1368 return int(m_constraints.size());
1369}
1371{
1372 return m_constraints[index];
1373}
1375{
1376 return m_constraints[index];
1377}
1378
1380{
1381 int i;
1382 //serialize all collision objects
1383 for (i = 0; i < m_collisionObjects.size(); i++)
1384 {
1386 if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY)
1387 {
1388 int len = colObj->calculateSerializeBufferSize();
1389 btChunk* chunk = serializer->allocate(len, 1);
1390 const char* structType = colObj->serialize(chunk->m_oldPtr, serializer);
1392 }
1393 }
1394
1395 for (i = 0; i < m_constraints.size(); i++)
1396 {
1398 int size = constraint->calculateSerializeBufferSize();
1399 btChunk* chunk = serializer->allocate(size, 1);
1400 const char* structType = constraint->serialize(chunk->m_oldPtr, serializer);
1402 }
1403}
1404
1406{
1407#ifdef BT_USE_DOUBLE_PRECISION
1408 int len = sizeof(btDynamicsWorldDoubleData);
1409 btChunk* chunk = serializer->allocate(len, 1);
1411#else //BT_USE_DOUBLE_PRECISION
1412 int len = sizeof(btDynamicsWorldFloatData);
1413 btChunk* chunk = serializer->allocate(len, 1);
1415#endif //BT_USE_DOUBLE_PRECISION
1416
1417 memset(worldInfo, 0x00, len);
1418
1419 m_gravity.serialize(worldInfo->m_gravity);
1420 worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
1421 worldInfo->m_solverInfo.m_damping = getSolverInfo().m_damping;
1422 worldInfo->m_solverInfo.m_friction = getSolverInfo().m_friction;
1423 worldInfo->m_solverInfo.m_timeStep = getSolverInfo().m_timeStep;
1424
1425 worldInfo->m_solverInfo.m_restitution = getSolverInfo().m_restitution;
1426 worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction;
1427 worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
1428 worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
1429
1430 worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
1431 worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm;
1432 worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold;
1433 worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp;
1434
1435 worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop;
1436 worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor;
1437 worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce;
1438 worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold;
1439
1440 worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations;
1441 worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode;
1442 worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold;
1443 worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize;
1444
1445 worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse;
1446
1447
1448#ifdef BT_USE_DOUBLE_PRECISION
1449 const char* structType = "btDynamicsWorldDoubleData";
1450#else //BT_USE_DOUBLE_PRECISION
1451 const char* structType = "btDynamicsWorldFloatData";
1452#endif //BT_USE_DOUBLE_PRECISION
1454}
1455
1457{
1458 serializer->startSerialization();
1459
1461
1463
1465
1467
1468 serializer->finishSerialization();
1469}
#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
CalculateCombinedCallback gCalculateCombinedFrictionCallback
CalculateCombinedCallback gCalculateCombinedRestitutionCallback
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
#define BT_PROFILE(name)
bool gDisableDeactivation
@ BT_DISABLE_WORLD_GRAVITY
Definition btRigidBody.h:41
#define SIMD_PI
Definition btScalar.h:526
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
btScalar btSin(btScalar x)
Definition btScalar.h:499
#define SIMD_FORCE_INLINE
Definition btScalar.h:98
btScalar btCos(btScalar x)
Definition btScalar.h:498
bool btFuzzyZero(btScalar x)
Definition btScalar.h:572
#define SIMD_2_PI
Definition btScalar.h:527
#define btAssert(x)
Definition btScalar.h:153
#define BT_RIGIDBODY_CODE
#define BT_DYNAMICSWORLD_CODE
#define BT_CONSTRAINT_CODE
void btMutexLock(btSpinMutex *mutex)
Definition btThreads.h:70
void btMutexUnlock(btSpinMutex *mutex)
Definition btThreads.h:79
@ SLIDER_CONSTRAINT_TYPE
@ CONETWIST_CONSTRAINT_TYPE
@ POINT2POINT_CONSTRAINT_TYPE
@ D6_SPRING_2_CONSTRAINT_TYPE
@ HINGE_CONSTRAINT_TYPE
@ D6_SPRING_CONSTRAINT_TYPE
@ D6_CONSTRAINT_TYPE
Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWor...
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
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 remove(const T &key)
void quickSort(const L &CompareFunc)
void push_back(const T &_Val)
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
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
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
btTransform & getWorldTransform()
btBroadphaseProxy * getBroadphaseHandle()
bool isStaticObject() const
void setActivationState(int newState) const
bool isKinematicObject() const
const btTransform & getInterpolationWorldTransform() 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
void serializeContactManifolds(btSerializer *serializer)
const btBroadphaseInterface * getBroadphase() const
void serializeCollisionObjects(btSerializer *serializer)
btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc)
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 ...
virtual void releaseManifold(btPersistentManifold *manifold)=0
virtual bool needsCollision(const btCollisionObject *body0, const btCollisionObject *body1)=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...
hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in lo...
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
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))
virtual void flushLines()
virtual void drawTransform(const btTransform &transform, btScalar orthoLen)
virtual int getDebugMode() const =0
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
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)
@ DBG_DrawConstraintLimits
ManifoldContactPoint collects and maintains persistent contactpoints.
btScalar m_combinedRestitution
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
virtual bool needsBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const =0
virtual btOverlapFilterCallback * getOverlapFilterCallback()=0
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocke...
The btRigidBody is the main class for rigid body objects.
Definition btRigidBody.h:60
void applyGravity()
bool wantsSleeping()
void clearForces()
int getFlags() const
void applyDamping(btScalar timeStep)
applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
void updateDeactivation(btScalar timeStep)
void setGravity(const btVector3 &acceleration)
void proceedToTransform(const btTransform &newTrans)
const btCollisionShape * getCollisionShape() const
void saveKinematicState(btScalar step)
btMotionState * getMotionState()
void setAngularVelocity(const btVector3 &ang_vel)
void setLinearVelocity(const btVector3 &lin_vel)
const btBroadphaseProxy * getBroadphaseProxy() const
static const btRigidBody * upcast(const btCollisionObject *colObj)
to keep collision detection and dynamics separate we don't store a rigidbody pointer but a rigidbody ...
void predictIntegratedTransform(btScalar step, btTransform &predictedTransform)
continuous collision detection needs prediction
const btVector3 & getLinearVelocity() const
The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (...
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)
bool operator()(const btTypedConstraint *lhs, const btTypedConstraint *rhs) const
The btSphereShape implements an implicit sphere, centered around a local origin with radius.
The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out)
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:30
btMatrix3x3 & getBasis()
Return the basis matrix for the rotation.
void setIdentity()
Set this transformation to the identity.
btVector3 & getOrigin()
Return the origin vector translation.
void setBasis(const btMatrix3x3 &basis)
Set the rotational element by btMatrix3x3.
TypedConstraint is the baseclass for Bullet constraints and vehicles.
void unite(int p, int q)
Definition btUnionFind.h:76
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
btScalar length2() const
Return the length of the vector squared.
Definition btVector3.h:251
void serialize(struct btVector3Data &dataOut) const
Definition btVector3.h:1317
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)
InplaceSolverIslandCallback & operator=(InplaceSolverIslandCallback &other)
void setup(btContactSolverInfo *solverInfo, btTypedConstraint **sortedConstraints, int numConstraints, btIDebugDraw *debugDrawer)
The btBroadphasePair class contains a pair of aabb-overlapping objects.
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
ClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld)
btScalar m_allowedCcdPenetration
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64