Bullet Collision Detection & Physics Library
btCollisionWorld.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans https://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#include "btCollisionWorld.h"
39
40//#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
41
42//#define USE_BRUTEFORCE_RAYBROADPHASE 1
43//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest
44//#define RECALCULATE_AABB_RAYCAST 1
45
46//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
50
52
53//for debug rendering
66
68 : m_dispatcher1(dispatcher),
69 m_broadphasePairCache(pairCache),
70 m_debugDrawer(0),
71 m_forceUpdateAllAabbs(true)
72{
73}
74
76{
77 //clean up remaining objects
78 int i;
79 for (i = 0; i < m_collisionObjects.size(); i++)
80 {
82
83 btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
84 if (bp)
85 {
86 //
87 // only clear the cached algorithms
88 //
91 collisionObject->setBroadphaseHandle(0);
92 }
93 }
94}
95
97{
98 if (collisionObject->getBroadphaseHandle())
99 {
100 int collisionFilterGroup = collisionObject->getBroadphaseHandle()->m_collisionFilterGroup;
101 int collisionFilterMask = collisionObject->getBroadphaseHandle()->m_collisionFilterMask;
102
103 getBroadphase()->destroyProxy(collisionObject->getBroadphaseHandle(), getDispatcher());
104
105 //calculate new AABB
106 btTransform trans = collisionObject->getWorldTransform();
107
110 collisionObject->getCollisionShape()->getAabb(trans, minAabb, maxAabb);
111
112 int type = collisionObject->getCollisionShape()->getShapeType();
113 collisionObject->setBroadphaseHandle(getBroadphase()->createProxy(
114 minAabb,
115 maxAabb,
116 type,
121 }
122}
123
125{
127
128 //check that the object isn't already added
130 btAssert(collisionObject->getWorldArrayIndex() == -1); // do not add the same object to more than one collision world
131
132 collisionObject->setWorldArrayIndex(m_collisionObjects.size());
134
135 //calculate new AABB
136 btTransform trans = collisionObject->getWorldTransform();
137
140 collisionObject->getCollisionShape()->getAabb(trans, minAabb, maxAabb);
141
142 int type = collisionObject->getCollisionShape()->getShapeType();
143 collisionObject->setBroadphaseHandle(getBroadphase()->createProxy(
144 minAabb,
145 maxAabb,
146 type,
151}
152
154{
156 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb, maxAabb);
157 //need to increase the aabb for contact thresholds
161
162 if (getDispatchInfo().m_useContinuous && colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
163 {
165 colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(), minAabb2, maxAabb2);
169 maxAabb.setMax(maxAabb2);
170 }
171
173
174 //moving objects should be moderately sized, probably something wrong if not
175 if (colObj->isStaticObject() || ((maxAabb - minAabb).length2() < btScalar(1e12)))
176 {
177 bp->setAabb(colObj->getBroadphaseHandle(), minAabb, maxAabb, m_dispatcher1);
178 }
179 else
180 {
181 //something went wrong, investigate
182 //this assert is unwanted in 3D modelers (danger of loosing work)
183 colObj->setActivationState(DISABLE_SIMULATION);
184
185 static bool reportMe = true;
186 if (reportMe && m_debugDrawer)
187 {
188 reportMe = false;
189 m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
190 m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
191 m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
192 m_debugDrawer->reportErrorWarning("Thanks.\n");
193 }
194 }
195}
196
198{
199 BT_PROFILE("updateAabbs");
200
201 for (int i = 0; i < m_collisionObjects.size(); i++)
202 {
204 btAssert(colObj->getWorldArrayIndex() == i);
205
206 //only update aabb of active objects
207 if (m_forceUpdateAllAabbs || colObj->isActive())
208 {
210 }
211 }
212}
213
215{
216 BT_PROFILE("calculateOverlappingPairs");
218}
219
221{
222 BT_PROFILE("performDiscreteCollisionDetection");
223
225
226 updateAabbs();
227
229
231 {
232 BT_PROFILE("dispatchAllCollisionPairs");
233 if (dispatcher)
235 }
236}
237
239{
240 //bool removeFromBroadphase = false;
241
242 {
243 btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
244 if (bp)
245 {
246 //
247 // only clear the cached algorithms
248 //
251 collisionObject->setBroadphaseHandle(0);
252 }
253 }
254
255 int iObj = collisionObject->getWorldArrayIndex();
256 // btAssert(iObj >= 0 && iObj < m_collisionObjects.size()); // trying to remove an object that was never added or already removed previously?
257 if (iObj >= 0 && iObj < m_collisionObjects.size())
258 {
263 {
264 m_collisionObjects[iObj]->setWorldArrayIndex(iObj);
265 }
266 }
267 else
268 {
269 // slow linear search
270 //swapremove
272 }
273 collisionObject->setWorldArrayIndex(-1);
274}
275
281{
284}
285
289{
291 pointShape.setMargin(0.f);
293 const btCollisionShape* collisionShape = collisionObjectWrap->getCollisionShape();
294 const btTransform& colObjWorldTransform = collisionObjectWrap->getWorldTransform();
295
296 if (collisionShape->isConvex())
297 {
298 // BT_PROFILE("rayTestConvex");
300 castResult.m_fraction = resultCallback.m_closestHitFraction;
301
305
307
308 //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
309
311 //use kF_UseSubSimplexConvexCastRaytest by default
314 else
316
318
320 {
321 //add hit
322 if (castResult.m_normal.length2() > btScalar(0.0001))
323 {
324 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
325 {
326 //todo: figure out what this is about. When is rayFromTest.getBasis() not identity?
327#ifdef USE_SUBSIMPLEX_CONVEX_CAST
328 //rotate normal into worldspace
329 castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
330#endif //USE_SUBSIMPLEX_CONVEX_CAST
331
332 castResult.m_normal.normalize();
334 collisionObjectWrap->getCollisionObject(),
335 0,
336 castResult.m_normal,
337 castResult.m_fraction);
338
339 bool normalInWorldSpace = true;
341 }
342 }
343 }
344 }
345 else
346 {
347 if (collisionShape->isConcave())
348 {
349 //ConvexCast::CastResult
351 {
352 btCollisionWorld::RayResultCallback* m_resultCallback;
353 const btCollisionObject* m_collisionObject;
355
357
361 m_resultCallback(resultCallback),
362 m_collisionObject(collisionObject),
365 {
366 }
367
368 virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
369 {
372 shapeInfo.m_triangleIndex = triangleIndex;
373
375
377 &shapeInfo,
380
381 bool normalInWorldSpace = true;
382 return m_resultCallback->addSingleResult(rayResult, normalInWorldSpace);
383 }
384 };
385
389
390 // BT_PROFILE("rayTestConcave");
391 if (collisionShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
392 {
395
397 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
398 triangleMesh->performRaycast(&rcb, rayFromLocal, rayToLocal);
399 }
400 else if (collisionShape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
401 {
405
406 //scale the ray positions
407 btVector3 scale = scaledTriangleMesh->getLocalScaling();
410
411 //perform raycast in the underlying btBvhTriangleMeshShape
413 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
415 }
417 && collisionShape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE
418 )
419 {
425
427 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
428 heightField->performRaycast(&rcb, rayFromLocal, rayToLocal);
429 }
430 else
431 {
432 //generic (slower) case
434
436
439
440 //ConvexCast::CastResult
441
443 {
444 btCollisionWorld::RayResultCallback* m_resultCallback;
445 const btCollisionObject* m_collisionObject;
447
449
453 m_resultCallback(resultCallback),
454 m_collisionObject(collisionObject),
457 {
458 }
459
460 virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
461 {
464 shapeInfo.m_triangleIndex = triangleIndex;
465
467
469 &shapeInfo,
472
473 bool normalInWorldSpace = true;
474 return m_resultCallback->addSingleResult(rayResult, normalInWorldSpace);
475 }
476 };
477
479 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
480
485
486 concaveShape->processAllTriangles(&rcb, rayAabbMinLocal, rayAabbMaxLocal);
487 }
488 }
489 else
490 {
491 // BT_PROFILE("rayTestCompound");
492 if (collisionShape->isCompound())
493 {
494 struct LocalInfoAdder2 : public RayResultCallback
495 {
497 int m_i;
498
500 : m_userCallback(user), m_i(i)
501 {
502 m_closestHitFraction = m_userCallback->m_closestHitFraction;
503 m_flags = m_userCallback->m_flags;
504 }
505 virtual bool needsCollision(btBroadphaseProxy* p) const
506 {
507 return m_userCallback->needsCollision(p);
508 }
509
510 virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& r, bool b)
511 {
514 shapeInfo.m_triangleIndex = m_i;
515 if (r.m_localShapeInfo == NULL)
517
518 const btScalar result = m_userCallback->addSingleResult(r, b);
519 m_closestHitFraction = m_userCallback->m_closestHitFraction;
520 return result;
521 }
522 };
523
525 {
526 const btCollisionObject* m_collisionObject;
527 const btCompoundShape* m_compoundShape;
529 const btTransform& m_rayFromTrans;
530 const btTransform& m_rayToTrans;
531 RayResultCallback& m_resultCallback;
532
537 const btTransform& rayToTrans,
538 RayResultCallback& resultCallback) : m_collisionObject(collisionObject),
539 m_compoundShape(compoundShape),
541 m_rayFromTrans(rayFromTrans),
542 m_rayToTrans(rayToTrans),
543 m_resultCallback(resultCallback)
544 {
545 }
546
547 void ProcessLeaf(int i)
548 {
549 const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
550 const btTransform& childTrans = m_compoundShape->getChildTransform(i);
552
554 // replace collision shape so that callback can determine the triangle
555
556 LocalInfoAdder2 my_cb(i, &m_resultCallback);
557
558 rayTestSingleInternal(
559 m_rayFromTrans,
560 m_rayToTrans,
561 &tmpOb,
562 my_cb);
563 }
564
565 void Process(const btDbvtNode* leaf)
566 {
567 ProcessLeaf(leaf->dataAsInt);
568 }
569 };
570
571 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
572 const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
573
575 collisionObjectWrap->getCollisionObject(),
581#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
582 if (dbvt)
583 {
584 btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
585 btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
587 }
588 else
589#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
590 {
591 for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
592 {
593 rayCB.ProcessLeaf(i);
594 }
595 }
596 }
597 }
598 }
599}
600
606{
609}
610
614{
615 const btCollisionShape* collisionShape = colObjWrap->getCollisionShape();
616 const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform();
617
618 if (collisionShape->isConvex())
619 {
620 //BT_PROFILE("convexSweepConvex");
623 castResult.m_fraction = resultCallback.m_closestHitFraction; //btScalar(1.);//??
624
628
630 //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
631 //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
632
634
636 {
637 //add hit
638 if (castResult.m_normal.length2() > btScalar(0.0001))
639 {
640 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
641 {
642 castResult.m_normal.normalize();
644 colObjWrap->getCollisionObject(),
645 0,
646 castResult.m_normal,
647 castResult.m_hitPoint,
648 castResult.m_fraction);
649
650 bool normalInWorldSpace = true;
652 }
653 }
654 }
655 }
656 else
657 {
658 if (collisionShape->isConcave())
659 {
660 if (collisionShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
661 {
662 //BT_PROFILE("convexSweepbtBvhTriangleMesh");
667 // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
669
670 //ConvexCast::CastResult
672 {
674 const btCollisionObject* m_collisionObject;
676
679 m_resultCallback(resultCallback),
680 m_collisionObject(collisionObject),
682 {
683 }
684
686 {
689 shapeInfo.m_triangleIndex = triangleIndex;
690 if (hitFraction <= m_resultCallback->m_closestHitFraction)
691 {
693 &shapeInfo,
697
698 bool normalInWorldSpace = true;
699
700 return m_resultCallback->addSingleResult(convexResult, normalInWorldSpace);
701 }
702 return hitFraction;
703 }
704 };
705
707 tccb.m_hitFraction = resultCallback.m_closestHitFraction;
708 tccb.m_allowedPenetration = allowedPenetration;
712 }
713 else
714 {
715 if (collisionShape->getShapeType() == STATIC_PLANE_PROXYTYPE)
716 {
719 castResult.m_fraction = resultCallback.m_closestHitFraction;
723
725 {
726 //add hit
727 if (castResult.m_normal.length2() > btScalar(0.0001))
728 {
729 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
730 {
731 castResult.m_normal.normalize();
733 colObjWrap->getCollisionObject(),
734 0,
735 castResult.m_normal,
736 castResult.m_hitPoint,
737 castResult.m_fraction);
738
739 bool normalInWorldSpace = true;
741 }
742 }
743 }
744 }
745 else
746 {
747 //BT_PROFILE("convexSweepConcave");
752 // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
754
755 //ConvexCast::CastResult
757 {
759 const btCollisionObject* m_collisionObject;
761
764 m_resultCallback(resultCallback),
765 m_collisionObject(collisionObject),
767 {
768 }
769
771 {
774 shapeInfo.m_triangleIndex = triangleIndex;
775 if (hitFraction <= m_resultCallback->m_closestHitFraction)
776 {
778 &shapeInfo,
782
783 bool normalInWorldSpace = true;
784
785 return m_resultCallback->addSingleResult(convexResult, normalInWorldSpace);
786 }
787 return hitFraction;
788 }
789 };
790
792 tccb.m_hitFraction = resultCallback.m_closestHitFraction;
793 tccb.m_allowedPenetration = allowedPenetration;
796
803 concaveShape->processAllTriangles(&tccb, rayAabbMinLocal, rayAabbMaxLocal);
804 }
805 }
806 }
807 else
808 {
809 if (collisionShape->isCompound())
810 {
812 {
822 : m_colObjWrap(colObjWrap),
823 m_castShape(castShape),
824 m_convexFromTrans(convexFromTrans),
825 m_convexToTrans(convexToTrans),
826 m_allowedPenetration(allowedPenetration),
827 m_compoundShape(compoundShape),
829 m_resultCallback(resultCallback)
830 {
831 }
832
833 const btCollisionObjectWrapper* m_colObjWrap;
834 const btConvexShape* m_castShape;
835 const btTransform& m_convexFromTrans;
836 const btTransform& m_convexToTrans;
837 btScalar m_allowedPenetration;
838 const btCompoundShape* m_compoundShape;
840 ConvexResultCallback& m_resultCallback;
841
842 public:
844 {
846
848 {
850 int m_i;
851
853 : m_userCallback(user), m_i(i)
854 {
855 m_closestHitFraction = m_userCallback->m_closestHitFraction;
856 }
857 virtual bool needsCollision(btBroadphaseProxy* p) const
858 {
859 return m_userCallback->needsCollision(p);
860 }
861 virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b)
862 {
865 shapeInfo.m_triangleIndex = m_i;
866 if (r.m_localShapeInfo == NULL)
868 const btScalar result = m_userCallback->addSingleResult(r, b);
869 m_closestHitFraction = m_userCallback->m_closestHitFraction;
870 return result;
871 }
872 };
873
874 LocalInfoAdder my_cb(index, &m_resultCallback);
875
877
878 objectQuerySingleInternal(m_castShape, m_convexFromTrans, m_convexToTrans, &tmpObj, my_cb, m_allowedPenetration);
879 }
880
881 void Process(const btDbvtNode* leaf)
882 {
883 // Processing leaf node
884 int index = leaf->dataAsInt;
885
886 btTransform childTrans = m_compoundShape->getChildTransform(index);
887 const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(index);
888
890 }
891 };
892
893 BT_PROFILE("convexSweepCompound");
894 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
895
898
901
904
907
908 const btDbvt* tree = compoundShape->getDynamicAabbTree();
909 if (tree)
910 {
912 tree->collideTV(tree->m_root, bounds, callback);
913 }
914 else
915 {
916 int i;
917 for (i = 0; i < compoundShape->getNumChildShapes(); i++)
918 {
919 const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
920 btTransform childTrans = compoundShape->getChildTransform(i);
921 callback.ProcessChild(i, childTrans, childCollisionShape);
922 }
923 }
924 }
925 }
926 }
927}
928
930{
936
939
943 m_world(world),
945 {
950
951 btVector3 rayDir = (rayToWorld - rayFromWorld);
952
953 rayDir.normalize();
955 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
956 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
957 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
958 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
959 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
960 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
961
963 }
964
965 virtual bool process(const btBroadphaseProxy* proxy)
966 {
969 return false;
970
972
973 //only perform raycast if filterMask matches
974 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
975 {
976 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
977 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
978#if 0
979#ifdef RECALCULATE_AABB
981 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
982#else
983 //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
984 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
985 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
986#endif
987#endif
988 //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
989 //culling already done by broadphase
990 //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
991 {
994 collisionObject->getCollisionShape(),
995 collisionObject->getWorldTransform(),
997 }
998 }
999 return true;
1000 }
1001};
1002
1004{
1005 //BT_PROFILE("rayTest");
1009
1010#ifndef USE_BRUTEFORCE_RAYBROADPHASE
1012#else
1013 for (int i = 0; i < this->getNumCollisionObjects(); i++)
1014 {
1015 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
1016 }
1017#endif //USE_BRUTEFORCE_RAYBROADPHASE
1018}
1019
1021{
1029
1033 m_world(world),
1037 {
1039 btVector3 rayDir = unnormalizedRayDir.fuzzyZero() ? btVector3(btScalar(0.0), btScalar(0.0), btScalar(0.0)) : unnormalizedRayDir.normalized();
1041 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
1042 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
1043 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
1044 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
1045 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
1046 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
1047
1049 }
1050
1051 virtual bool process(const btBroadphaseProxy* proxy)
1052 {
1055 return false;
1056
1058
1059 //only perform raycast if filterMask matches
1060 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1061 {
1062 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1065 collisionObject->getCollisionShape(),
1066 collisionObject->getWorldTransform(),
1069 }
1070
1071 return true;
1072 }
1073};
1074
1076{
1077 BT_PROFILE("convexSweepTest");
1081
1086 /* Compute AABB that encompasses angular movement */
1087 {
1091 zeroLinVel.setValue(0, 0, 0);
1092 btTransform R;
1093 R.setIdentity();
1094 R.setRotation(convexFromTrans.getRotation());
1095 castShape->calculateTemporalAabb(R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax);
1096 }
1097
1098#ifndef USE_BRUTEFORCE_RAYBROADPHASE
1099
1101
1103
1104#else
1106 // do a ray-shape query using convexCaster (CCD)
1107 int i;
1108 for (i = 0; i < m_collisionObjects.size(); i++)
1109 {
1111 //only perform raycast if filterMask matches
1112 if (resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1113 {
1114 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1116 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(), collisionObjectAabbMin, collisionObjectAabbMax);
1118 btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
1121 {
1124 collisionObject->getCollisionShape(),
1125 collisionObject->getWorldTransform(),
1128 }
1129 }
1130 }
1131#endif //USE_BRUTEFORCE_RAYBROADPHASE
1132}
1133
1135{
1137
1141 {
1142 }
1143
1145 {
1150 if (isSwapped)
1151 {
1154 }
1155 else
1156 {
1159 }
1160
1162 newPt.m_positionWorldOnA = pointA;
1163 newPt.m_positionWorldOnB = pointInWorld;
1164
1165 //BP mod, store contact triangles.
1166 if (isSwapped)
1167 {
1168 newPt.m_partId0 = m_partId1;
1169 newPt.m_partId1 = m_partId0;
1170 newPt.m_index0 = m_index1;
1171 newPt.m_index1 = m_index0;
1172 }
1173 else
1174 {
1175 newPt.m_partId0 = m_partId0;
1176 newPt.m_partId1 = m_partId1;
1177 newPt.m_index0 = m_index0;
1178 newPt.m_index1 = m_index1;
1179 }
1180
1181 //experimental feature info, for per-triangle material etc.
1184 m_resultCallback.addSingleResult(newPt, obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1);
1185 }
1186};
1187
1189{
1193
1196 m_world(world),
1198 {
1199 }
1200
1201 virtual bool process(const btBroadphaseProxy* proxy)
1202 {
1205 return true;
1206
1207 //only perform raycast if filterMask matches
1208 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1209 {
1211 btCollisionObjectWrapper ob1(0, collisionObject->getCollisionShape(), collisionObject, collisionObject->getWorldTransform(), -1, -1);
1212
1214 if (algorithm)
1215 {
1217 //discrete collision detection query
1218
1220
1221 algorithm->~btCollisionAlgorithm();
1223 }
1224 }
1225 return true;
1226 }
1227};
1228
1232{
1234 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), aabbMin, aabbMax);
1236
1238}
1239
1243{
1244 btCollisionObjectWrapper obA(0, colObjA->getCollisionShape(), colObjA, colObjA->getWorldTransform(), -1, -1);
1245 btCollisionObjectWrapper obB(0, colObjB->getCollisionShape(), colObjB, colObjB->getWorldTransform(), -1, -1);
1246
1248 if (algorithm)
1249 {
1251 contactPointResult.m_closestPointDistanceThreshold = resultCallback.m_closestDistanceThreshold;
1252 //discrete collision detection query
1254
1255 algorithm->~btCollisionAlgorithm();
1257 }
1258}
1259
1261{
1265
1266public:
1268 m_color(color),
1270 {
1271 }
1272
1274 {
1276 }
1277
1279 {
1280 (void)partId;
1282
1283 btVector3 wv0, wv1, wv2;
1284 wv0 = m_worldTrans * triangle[0];
1285 wv1 = m_worldTrans * triangle[1];
1286 wv2 = m_worldTrans * triangle[2];
1287 btVector3 center = (wv0 + wv1 + wv2) * btScalar(1. / 3.);
1288
1290 {
1291 btVector3 normal = (wv1 - wv0).cross(wv2 - wv0);
1292 normal.normalize();
1293 btVector3 normalColor(1, 1, 0);
1294 m_debugDrawer->drawLine(center, center + normal, normalColor);
1295 }
1297 }
1298};
1299
1301{
1302 // Draw a small simplex at the center of the object
1303 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawFrames)
1304 {
1306 }
1307
1308 if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
1309 {
1310 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
1311 for (int i = compoundShape->getNumChildShapes() - 1; i >= 0; i--)
1312 {
1313 btTransform childTrans = compoundShape->getChildTransform(i);
1314 const btCollisionShape* colShape = compoundShape->getChildShape(i);
1316 }
1317 }
1318 else
1319 {
1320 switch (shape->getShapeType())
1321 {
1323 {
1324 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
1325 btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
1327 break;
1328 }
1329
1331 {
1332 const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
1333 btScalar radius = sphereShape->getMargin(); //radius doesn't include the margin, so draw with margin
1334
1336 break;
1337 }
1339 {
1340 const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
1341
1344
1345 for (int i = multiSphereShape->getSphereCount() - 1; i >= 0; i--)
1346 {
1347 childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
1349 }
1350
1351 break;
1352 }
1354 {
1355 const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
1356
1358 btScalar halfHeight = capsuleShape->getHalfHeight();
1359
1360 int upAxis = capsuleShape->getUpAxis();
1362 break;
1363 }
1365 {
1366 const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
1367 btScalar radius = coneShape->getRadius(); //+coneShape->getMargin();
1368 btScalar height = coneShape->getHeight(); //+coneShape->getMargin();
1369
1370 int upAxis = coneShape->getConeUpIndex();
1372 break;
1373 }
1375 {
1376 const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
1377 int upAxis = cylinder->getUpAxis();
1378 btScalar radius = cylinder->getRadius();
1379 btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
1381 break;
1382 }
1383
1385 {
1386 const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
1388 const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
1390 break;
1391 }
1392 default:
1393 {
1395 if (shape->isPolyhedral())
1396 {
1398
1399 int i;
1400 if (polyshape->getConvexPolyhedron())
1401 {
1402 const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
1403 for (i = 0; i < poly->m_faces.size(); i++)
1404 {
1405 btVector3 centroid(0, 0, 0);
1406 int numVerts = poly->m_faces[i].m_indices.size();
1407 if (numVerts)
1408 {
1409 int lastV = poly->m_faces[i].m_indices[numVerts - 1];
1410 for (int v = 0; v < poly->m_faces[i].m_indices.size(); v++)
1411 {
1412 int curVert = poly->m_faces[i].m_indices[v];
1413 centroid += poly->m_vertices[curVert];
1414 getDebugDrawer()->drawLine(worldTransform * poly->m_vertices[lastV], worldTransform * poly->m_vertices[curVert], color);
1415 lastV = curVert;
1416 }
1417 }
1419 if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
1420 {
1421 btVector3 normalColor(1, 1, 0);
1422 btVector3 faceNormal(poly->m_faces[i].m_plane[0], poly->m_faces[i].m_plane[1], poly->m_faces[i].m_plane[2]);
1424 }
1425 }
1426 }
1427 else
1428 {
1429 for (i = 0; i < polyshape->getNumEdges(); i++)
1430 {
1431 btVector3 a, b;
1432 polyshape->getEdge(i, a, b);
1436 }
1437 }
1438 }
1439
1440 if (shape->isConcave())
1441 {
1443
1447
1449 concaveMesh->processAllTriangles(&drawCallback, aabbMin, aabbMax);
1450 }
1451
1453 {
1455 //todo: pass camera for some culling
1458 //DebugDrawcallback drawCallback;
1460 convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback, aabbMin, aabbMax);
1461 }
1462 }
1463 }
1464 }
1465}
1466
1468{
1469 if (getDebugDrawer())
1470 {
1472
1474
1476 {
1477 if (getDispatcher())
1478 {
1480
1481 for (int i = 0; i < numManifolds; i++)
1482 {
1484 //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
1485 //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
1486
1488 for (int j = 0; j < numContacts; j++)
1489 {
1490 btManifoldPoint& cp = contactManifold->getContactPoint(j);
1491 getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB, cp.m_normalWorldOnB, cp.getDistance(), cp.getLifeTime(), defaultColors.m_contactPoint);
1492 }
1493 }
1494 }
1495 }
1496
1498 {
1499 int i;
1500
1501 for (i = 0; i < m_collisionObjects.size(); i++)
1502 {
1504 if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT) == 0)
1505 {
1506 if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
1507 {
1508 btVector3 color(btScalar(0.4), btScalar(0.4), btScalar(0.4));
1509
1510 switch (colObj->getActivationState())
1511 {
1512 case ACTIVE_TAG:
1513 color = defaultColors.m_activeObject;
1514 break;
1515 case ISLAND_SLEEPING:
1516 color = defaultColors.m_deactivatedObject;
1517 break;
1518 case WANTS_DEACTIVATION:
1519 color = defaultColors.m_wantsDeactivationObject;
1520 break;
1522 color = defaultColors.m_disabledDeactivationObject;
1523 break;
1524 case DISABLE_SIMULATION:
1525 color = defaultColors.m_disabledSimulationObject;
1526 break;
1527 default:
1528 {
1529 color = btVector3(btScalar(.3), btScalar(0.3), btScalar(0.3));
1530 }
1531 };
1532
1533 colObj->getCustomDebugColor(color);
1534
1535 debugDrawObject(colObj->getWorldTransform(), colObj->getCollisionShape(), color);
1536 }
1538 {
1541 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb, maxAabb);
1545
1547
1548 if (getDispatchInfo().m_useContinuous && colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
1549 {
1550 colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(), minAabb2, maxAabb2);
1554 maxAabb.setMax(maxAabb2);
1555 }
1556
1558 }
1559 }
1560 }
1561 }
1562 }
1563}
1564
1566{
1567 int i;
1568
1571
1572 for (i = 0; i < m_collisionObjects.size(); i++)
1573 {
1575 btCollisionShape* shape = colObj->getCollisionShape();
1576
1577 if (!serializedShapes.find(shape))
1578 {
1579 serializedShapes.insert(shape, shape);
1581 }
1582 }
1583
1584 //serialize all collision objects
1585 for (i = 0; i < m_collisionObjects.size(); i++)
1586 {
1588 if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
1589 {
1590 colObj->serializeSingleObject(serializer);
1591 }
1592 }
1593}
1594
1596{
1597 if (serializer->getSerializationFlags() & BT_SERIALIZE_CONTACT_MANIFOLDS)
1598 {
1600 for (int i = 0; i < numManifolds; i++)
1601 {
1603 //don't serialize empty manifolds, they just take space
1604 //(may have to do it anyway if it destroys determinism)
1605 if (manifold->getNumContacts() == 0)
1606 continue;
1607
1608 btChunk* chunk = serializer->allocate(manifold->calculateSerializeBufferSize(), 1);
1609 const char* structType = manifold->serialize(manifold, chunk->m_oldPtr, serializer);
1611 }
1612 }
1613}
1614
1616{
1617 serializer->startSerialization();
1618
1620
1622
1623 serializer->finishSerialization();
1624}
bool btRayAabb(const btVector3 &rayFrom, const btVector3 &rayTo, const btVector3 &aabbMin, const btVector3 &aabbMax, btScalar &param, btVector3 &normal)
void AabbExpand(btVector3 &aabbMin, btVector3 &aabbMax, const btVector3 &expansionMin, const btVector3 &expansionMax)
Definition btAabbUtil2.h:22
@ CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE
@ COMPOUND_SHAPE_PROXYTYPE
@ SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE
@ TRIANGLE_MESH_SHAPE_PROXYTYPE
@ TERRAIN_SHAPE_PROXYTYPE
@ STATIC_PLANE_PROXYTYPE
@ SPHERE_SHAPE_PROXYTYPE
@ BOX_SHAPE_PROXYTYPE
@ MULTI_SPHERE_SHAPE_PROXYTYPE
@ CYLINDER_SHAPE_PROXYTYPE
@ CONE_SHAPE_PROXYTYPE
@ CAPSULE_SHAPE_PROXYTYPE
#define ACTIVE_TAG
#define DISABLE_DEACTIVATION
#define WANTS_DEACTIVATION
#define ISLAND_SLEEPING
#define DISABLE_SIMULATION
btScalar gContactBreakingThreshold
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
@ BT_CLOSEST_POINT_ALGORITHMS
const T & btMax(const T &a, const T &b)
Definition btMinMax.h:27
#define BT_PROFILE(name)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
#define ATTRIBUTE_ALIGNED16(a)
Definition btScalar.h:99
#define BT_LARGE_FLOAT
Definition btScalar.h:316
#define btAssert(x)
Definition btScalar.h:153
@ BT_SERIALIZE_CONTACT_MANIFOLDS
#define BT_CONTACTMANIFOLD_CODE
virtual void internalProcessTriangleIndex(btVector3 *triangle, int partId, int triangleIndex)
virtual void processTriangle(btVector3 *triangle, int partId, int triangleIndex)
DebugDrawcallback(btIDebugDraw *debugDrawer, const btTransform &worldTrans, const btVector3 &color)
btIDebugDraw * m_debugDrawer
int size() const
return the number of elements in the array
int findLinearSearch(const T &key) const
void swap(int index0, int index1)
void remove(const T &key)
void push_back(const T &_Val)
The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by ...
Definition btBoxShape.h:28
The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
virtual void aabbTest(const btVector3 &aabbMin, const btVector3 &aabbMax, btBroadphaseAabbCallback &callback)=0
virtual void calculateOverlappingPairs(btDispatcher *dispatcher)=0
calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during th...
virtual void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btBroadphaseRayCallback &rayCallback, const btVector3 &aabbMin=btVector3(0, 0, 0), const btVector3 &aabbMax=btVector3(0, 0, 0))=0
virtual void setAabb(btBroadphaseProxy *proxy, const btVector3 &aabbMin, const btVector3 &aabbMax, btDispatcher *dispatcher)=0
virtual void destroyProxy(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
virtual btOverlappingPairCache * getOverlappingPairCache()=0
The btBvhTriangleMeshShape is a static-triangle mesh shape, it can only be used for fixed/non-moving ...
The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned ...
btScalar getRadius() const
btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatche...
virtual void processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut)=0
btCollisionConfiguration allows to configure Bullet collision detection stack allocator size,...
btCollisionObject can be used to manage collision detection objects.
btTransform & getWorldTransform()
const btCollisionShape * getCollisionShape() const
The btCollisionShape class provides an interface for collision shapes that can be shared among btColl...
int getShapeType() const
bool isConcave() const
virtual void serializeSingleShape(btSerializer *serializer) const
bool isPolyhedral() const
CollisionWorld is interface and container for the collision detection.
virtual void rayTest(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, RayResultCallback &resultCallback) const
rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback This ...
virtual void updateAabbs()
btDispatcher * getDispatcher()
btDispatcherInfo & getDispatchInfo()
virtual void serialize(btSerializer *serializer)
Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bulle...
virtual void debugDrawWorld()
static void objectQuerySingleInternal(const btConvexShape *castShape, const btTransform &convexFromTrans, const btTransform &convexToTrans, const btCollisionObjectWrapper *colObjWrap, ConvexResultCallback &resultCallback, btScalar allowedPenetration)
virtual btIDebugDraw * getDebugDrawer()
virtual void refreshBroadphaseProxy(btCollisionObject *collisionObject)
btBroadphaseInterface * m_broadphasePairCache
void updateSingleAabb(btCollisionObject *colObj)
virtual void removeCollisionObject(btCollisionObject *collisionObject)
virtual void addCollisionObject(btCollisionObject *collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter)
btAlignedObjectArray< btCollisionObject * > m_collisionObjects
btCollisionWorld(btDispatcher *dispatcher, btBroadphaseInterface *broadphasePairCache, btCollisionConfiguration *collisionConfiguration)
for debug drawing
int getNumCollisionObjects() const
virtual void performDiscreteCollisionDetection()
static void rayTestSingleInternal(const btTransform &rayFromTrans, const btTransform &rayToTrans, const btCollisionObjectWrapper *collisionObjectWrap, RayResultCallback &resultCallback)
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...
bool m_forceUpdateAllAabbs
m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs it is...
btIDebugDraw * m_debugDrawer
static void objectQuerySingle(const btConvexShape *castShape, const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, ConvexResultCallback &resultCallback, btScalar allowedPenetration)
objectQuerySingle performs a collision detection query and calls the resultCallback....
btDispatcher * m_dispatcher1
void contactPairTest(btCollisionObject *colObjA, btCollisionObject *colObjB, ContactResultCallback &resultCallback)
contactTest performs a discrete collision test between two collision objects and calls the resultCall...
void serializeContactManifolds(btSerializer *serializer)
virtual void debugDrawObject(const btTransform &worldTransform, const btCollisionShape *shape, const btVector3 &color)
static void rayTestSingle(const btTransform &rayFromTrans, const btTransform &rayToTrans, btCollisionObject *collisionObject, const btCollisionShape *collisionShape, const btTransform &colObjWorldTransform, RayResultCallback &resultCallback)
rayTestSingle performs a raycast call and calls the resultCallback.
const btBroadphaseInterface * getBroadphase() const
void contactTest(btCollisionObject *colObj, ContactResultCallback &resultCallback)
contactTest performs a discrete collision test between colObj against all objects in the btCollisionW...
void serializeCollisionObjects(btSerializer *serializer)
virtual void computeOverlappingPairs()
the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSi...
The btCompoundShape allows to store multiple other btCollisionShapes This allows for moving concave c...
btCollisionShape * getChildShape(int index)
btTransform & getChildTransform(int index)
The btConcaveShape class provides an interface for non-moving (static) concave shapes.
The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y ...
Definition btConeShape.h:26
btScalar getRadius() const
Definition btConeShape.h:42
btContinuousConvexCollision implements angular and linear time of impact for convex objects.
Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degene...
The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape...
The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good...
The btCylinderShape class implements a cylinder shape primitive, centered around the origin....
int getUpAxis() const
The btDispatcher interface class can be used in combination with broadphase to dispatch calculations ...
virtual int getNumManifolds() const =0
virtual btPersistentManifold * getManifoldByIndexInternal(int index)=0
virtual void freeCollisionAlgorithm(void *ptr)=0
virtual btCollisionAlgorithm * findAlgorithm(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, btPersistentManifold *sharedManifold, ebtDispatcherQueryType queryType)=0
virtual btPersistentManifold ** getInternalManifoldPointer()=0
GjkConvexCast performs a raycast on a convex object using support mapping.
EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to calculate the penetration depth be...
The btHashMap template class implements a generic and lightweight hashmap.
Definition btHashMap.h:220
btHeightfieldTerrainShape simulates a 2D heightfield terrain
The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform &transform, const btVector3 &color)
virtual void drawPlane(const btVector3 &planeNormal, btScalar planeConst, const btTransform &transform, const btVector3 &color)
virtual void drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)=0
virtual void drawSphere(btScalar radius, const btTransform &transform, const btVector3 &color)
virtual void drawTriangle(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2, const btVector3 &, const btVector3 &, const btVector3 &, const btVector3 &color, btScalar alpha)
virtual void reportErrorWarning(const char *warningString)=0
virtual void clearLines()
virtual void drawTransform(const btTransform &transform, btScalar orthoLen)
virtual void drawContactPoint(const btVector3 &PointOnB, const btVector3 &normalOnB, btScalar distance, int lifeTime, const btVector3 &color)=0
virtual int getDebugMode() const =0
virtual void drawBox(const btVector3 &bbMin, const btVector3 &bbMax, const btVector3 &color)
virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform &transform, const btVector3 &color)
virtual DefaultColors getDefaultColors() const
virtual void drawAabb(const btVector3 &from, const btVector3 &to, const btVector3 &color)
virtual void drawCapsule(btScalar radius, btScalar halfHeight, int upAxis, const btTransform &transform, const btVector3 &color)
ManifoldContactPoint collects and maintains persistent contactpoints.
btManifoldResult is a helper class to manage contact results.
const btCollisionObjectWrapper * m_body0Wrap
const btCollisionObjectWrapper * m_body1Wrap
btPersistentManifold * m_manifoldPtr
The btMultiSphereShape represents the convex hull of a collection of spheres.
virtual void cleanProxyFromPairs(btBroadphaseProxy *proxy, btDispatcher *dispatcher)=0
btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping...
const btCollisionObject * getBody0() const
The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes.
The btScaledBvhTriangleMeshShape allows to instance a scaled version of an existing btBvhTriangleMesh...
The btSphereShape implements an implicit sphere, centered around a local origin with radius.
virtual btScalar getMargin() const
The btStaticPlaneShape simulates an infinite non-moving (static) collision plane.
const btScalar & getPlaneConstant() const
btSubsimplexConvexCast implements Gino van den Bergens' paper "Ray Casting against bteral Convex Obje...
static void calculateVelocity(const btTransform &transform0, const btTransform &transform1, btScalar timeStep, btVector3 &linVel, btVector3 &angVel)
The btTransform class supports rigid transforms with only translation and rotation and no scaling/she...
Definition btTransform.h:30
btTransform inverse() const
Return the inverse of this transform.
btVector3 invXform(const btVector3 &inVec) const
void setIdentity()
Set this transformation to the identity.
btVector3 & getOrigin()
Return the origin vector translation.
void setOrigin(const btVector3 &origin)
Set the translational element.
The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTrian...
The btTriangleMeshShape is an internal concave triangle mesh interface. Don't use this class directly...
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition btVector3.h:609
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition btVector3.h:229
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Definition btVector3.h:640
bool fuzzyZero() const
Definition btVector3.h:688
void setMin(const btVector3 &other)
Set each element to the min of the current values and the values of another btVector3.
Definition btVector3.h:626
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition btVector3.h:303
btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points...
btCollisionWorld::ContactResultCallback & m_resultCallback
virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth)
btBridgedManifoldResult(const btCollisionObjectWrapper *obj0Wrap, const btCollisionObjectWrapper *obj1Wrap, btCollisionWorld::ContactResultCallback &resultCallback)
The btBroadphaseProxy is the main class that can be used with the Bullet broadphases.
btVector3 m_rayDirectionInverse
added some cached data to accelerate ray-AABB tests
const btCollisionObject * getCollisionObject() const
ContactResultCallback is used to report contact points.
virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1)=0
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
RayResultCallback is used to report new raycast results.
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
virtual btScalar addSingleResult(LocalConvexResult &convexResult, bool normalInWorldSpace)=0
LocalShapeInfo gives extra information for complex shapes Currently, only btTriangleMeshShape is avai...
RayResultCallback is used to report new raycast results.
virtual bool needsCollision(btBroadphaseProxy *proxy0) const
virtual btScalar addSingleResult(LocalRayResult &rayResult, bool normalInWorldSpace)=0
RayResult stores the closest result alternatively, add a callback method to decide about closest/all ...
static btDbvtAabbMm FromMM(const btVector3 &mi, const btVector3 &mx)
Definition btDbvt.h:479
int dataAsInt
Definition btDbvt.h:189
The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes ...
Definition btDbvt.h:229
static DBVT_PREFIX void rayTest(const btDbvtNode *root, const btVector3 &rayFrom, const btVector3 &rayTo, DBVT_IPOLICY)
rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thre...
Definition btDbvt.h:1276
btCollisionObject * m_collisionObject
btCollisionWorld::ContactResultCallback & m_resultCallback
btSingleContactCallback(btCollisionObject *collisionObject, btCollisionWorld *world, btCollisionWorld::ContactResultCallback &resultCallback)
virtual bool process(const btBroadphaseProxy *proxy)
const btCollisionWorld * m_world
virtual bool process(const btBroadphaseProxy *proxy)
btSingleRayCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const btCollisionWorld *world, btCollisionWorld::RayResultCallback &resultCallback)
btCollisionWorld::RayResultCallback & m_resultCallback
const btConvexShape * m_castShape
virtual bool process(const btBroadphaseProxy *proxy)
const btCollisionWorld * m_world
btCollisionWorld::ConvexResultCallback & m_resultCallback
btSingleSweepCallback(const btConvexShape *castShape, const btTransform &convexFromTrans, const btTransform &convexToTrans, const btCollisionWorld *world, btCollisionWorld::ConvexResultCallback &resultCallback, btScalar allowedPenetration)