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 http://continuousphysics.com/Bullet/
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
202 for (int i = 0; i < m_collisionObjects.size(); i++)
203 {
205 btAssert(colObj->getWorldArrayIndex() == i);
206
207 //only update aabb of active objects
208 if (m_forceUpdateAllAabbs || colObj->isActive())
209 {
211 }
212 }
213}
214
216{
217 BT_PROFILE("calculateOverlappingPairs");
219}
220
222{
223 BT_PROFILE("performDiscreteCollisionDetection");
224
226
227 updateAabbs();
228
230
232 {
233 BT_PROFILE("dispatchAllCollisionPairs");
234 if (dispatcher)
236 }
237}
238
240{
241 //bool removeFromBroadphase = false;
242
243 {
244 btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
245 if (bp)
246 {
247 //
248 // only clear the cached algorithms
249 //
252 collisionObject->setBroadphaseHandle(0);
253 }
254 }
255
256 int iObj = collisionObject->getWorldArrayIndex();
257 // btAssert(iObj >= 0 && iObj < m_collisionObjects.size()); // trying to remove an object that was never added or already removed previously?
258 if (iObj >= 0 && iObj < m_collisionObjects.size())
259 {
264 {
265 m_collisionObjects[iObj]->setWorldArrayIndex(iObj);
266 }
267 }
268 else
269 {
270 // slow linear search
271 //swapremove
273 }
274 collisionObject->setWorldArrayIndex(-1);
275}
276
282{
285}
286
290{
292 pointShape.setMargin(0.f);
294 const btCollisionShape* collisionShape = collisionObjectWrap->getCollisionShape();
295 const btTransform& colObjWorldTransform = collisionObjectWrap->getWorldTransform();
296
297 if (collisionShape->isConvex())
298 {
299 // BT_PROFILE("rayTestConvex");
301 castResult.m_fraction = resultCallback.m_closestHitFraction;
302
306
308
309 //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
310
312 //use kF_UseSubSimplexConvexCastRaytest by default
315 else
317
319
321 {
322 //add hit
323 if (castResult.m_normal.length2() > btScalar(0.0001))
324 {
325 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
326 {
327 //todo: figure out what this is about. When is rayFromTest.getBasis() not identity?
328#ifdef USE_SUBSIMPLEX_CONVEX_CAST
329 //rotate normal into worldspace
330 castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
331#endif //USE_SUBSIMPLEX_CONVEX_CAST
332
333 castResult.m_normal.normalize();
335 collisionObjectWrap->getCollisionObject(),
336 0,
337 castResult.m_normal,
338 castResult.m_fraction);
339
340 bool normalInWorldSpace = true;
342 }
343 }
344 }
345 }
346 else
347 {
348 if (collisionShape->isConcave())
349 {
350 //ConvexCast::CastResult
352 {
353 btCollisionWorld::RayResultCallback* m_resultCallback;
354 const btCollisionObject* m_collisionObject;
356
358
362 m_resultCallback(resultCallback),
363 m_collisionObject(collisionObject),
366 {
367 }
368
369 virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
370 {
373 shapeInfo.m_triangleIndex = triangleIndex;
374
376
378 &shapeInfo,
381
382 bool normalInWorldSpace = true;
383 return m_resultCallback->addSingleResult(rayResult, normalInWorldSpace);
384 }
385 };
386
390
391 // BT_PROFILE("rayTestConcave");
392 if (collisionShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
393 {
396
398 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
399 triangleMesh->performRaycast(&rcb, rayFromLocal, rayToLocal);
400 }
401 else if (collisionShape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE)
402 {
406
407 //scale the ray positions
408 btVector3 scale = scaledTriangleMesh->getLocalScaling();
411
412 //perform raycast in the underlying btBvhTriangleMeshShape
414 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
416 }
418 && collisionShape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE
419 )
420 {
426
428 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
429 heightField->performRaycast(&rcb, rayFromLocal, rayToLocal);
430 }
431 else
432 {
433 //generic (slower) case
435
437
440
441 //ConvexCast::CastResult
442
444 {
445 btCollisionWorld::RayResultCallback* m_resultCallback;
446 const btCollisionObject* m_collisionObject;
448
450
454 m_resultCallback(resultCallback),
455 m_collisionObject(collisionObject),
458 {
459 }
460
461 virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex)
462 {
465 shapeInfo.m_triangleIndex = triangleIndex;
466
468
470 &shapeInfo,
473
474 bool normalInWorldSpace = true;
475 return m_resultCallback->addSingleResult(rayResult, normalInWorldSpace);
476 }
477 };
478
480 rcb.m_hitFraction = resultCallback.m_closestHitFraction;
481
486
487 concaveShape->processAllTriangles(&rcb, rayAabbMinLocal, rayAabbMaxLocal);
488 }
489 }
490 else
491 {
492 // BT_PROFILE("rayTestCompound");
493 if (collisionShape->isCompound())
494 {
495 struct LocalInfoAdder2 : public RayResultCallback
496 {
498 int m_i;
499
501 : m_userCallback(user), m_i(i)
502 {
503 m_closestHitFraction = m_userCallback->m_closestHitFraction;
504 m_flags = m_userCallback->m_flags;
505 }
506 virtual bool needsCollision(btBroadphaseProxy* p) const
507 {
508 return m_userCallback->needsCollision(p);
509 }
510
511 virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& r, bool b)
512 {
515 shapeInfo.m_triangleIndex = m_i;
516 if (r.m_localShapeInfo == NULL)
518
519 const btScalar result = m_userCallback->addSingleResult(r, b);
520 m_closestHitFraction = m_userCallback->m_closestHitFraction;
521 return result;
522 }
523 };
524
526 {
527 const btCollisionObject* m_collisionObject;
528 const btCompoundShape* m_compoundShape;
530 const btTransform& m_rayFromTrans;
531 const btTransform& m_rayToTrans;
532 RayResultCallback& m_resultCallback;
533
538 const btTransform& rayToTrans,
539 RayResultCallback& resultCallback) : m_collisionObject(collisionObject),
540 m_compoundShape(compoundShape),
542 m_rayFromTrans(rayFromTrans),
543 m_rayToTrans(rayToTrans),
544 m_resultCallback(resultCallback)
545 {
546 }
547
548 void ProcessLeaf(int i)
549 {
550 const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
551 const btTransform& childTrans = m_compoundShape->getChildTransform(i);
553
555 // replace collision shape so that callback can determine the triangle
556
557 LocalInfoAdder2 my_cb(i, &m_resultCallback);
558
559 rayTestSingleInternal(
560 m_rayFromTrans,
561 m_rayToTrans,
562 &tmpOb,
563 my_cb);
564 }
565
566 void Process(const btDbvtNode* leaf)
567 {
568 ProcessLeaf(leaf->dataAsInt);
569 }
570 };
571
572 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
573 const btDbvt* dbvt = compoundShape->getDynamicAabbTree();
574
576 collisionObjectWrap->getCollisionObject(),
582#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
583 if (dbvt)
584 {
585 btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin();
586 btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin();
588 }
589 else
590#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
591 {
592 for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
593 {
594 rayCB.ProcessLeaf(i);
595 }
596 }
597 }
598 }
599 }
600}
601
607{
610}
611
615{
616 const btCollisionShape* collisionShape = colObjWrap->getCollisionShape();
617 const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform();
618
619 if (collisionShape->isConvex())
620 {
621 //BT_PROFILE("convexSweepConvex");
624 castResult.m_fraction = resultCallback.m_closestHitFraction; //btScalar(1.);//??
625
629
631 //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
632 //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
633
635
637 {
638 //add hit
639 if (castResult.m_normal.length2() > btScalar(0.0001))
640 {
641 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
642 {
643 castResult.m_normal.normalize();
645 colObjWrap->getCollisionObject(),
646 0,
647 castResult.m_normal,
648 castResult.m_hitPoint,
649 castResult.m_fraction);
650
651 bool normalInWorldSpace = true;
653 }
654 }
655 }
656 }
657 else
658 {
659 if (collisionShape->isConcave())
660 {
661 if (collisionShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
662 {
663 //BT_PROFILE("convexSweepbtBvhTriangleMesh");
668 // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
670
671 //ConvexCast::CastResult
673 {
675 const btCollisionObject* m_collisionObject;
677
680 m_resultCallback(resultCallback),
681 m_collisionObject(collisionObject),
683 {
684 }
685
687 {
690 shapeInfo.m_triangleIndex = triangleIndex;
691 if (hitFraction <= m_resultCallback->m_closestHitFraction)
692 {
694 &shapeInfo,
698
699 bool normalInWorldSpace = true;
700
701 return m_resultCallback->addSingleResult(convexResult, normalInWorldSpace);
702 }
703 return hitFraction;
704 }
705 };
706
708 tccb.m_hitFraction = resultCallback.m_closestHitFraction;
709 tccb.m_allowedPenetration = allowedPenetration;
713 }
714 else
715 {
716 if (collisionShape->getShapeType() == STATIC_PLANE_PROXYTYPE)
717 {
720 castResult.m_fraction = resultCallback.m_closestHitFraction;
724
726 {
727 //add hit
728 if (castResult.m_normal.length2() > btScalar(0.0001))
729 {
730 if (castResult.m_fraction < resultCallback.m_closestHitFraction)
731 {
732 castResult.m_normal.normalize();
734 colObjWrap->getCollisionObject(),
735 0,
736 castResult.m_normal,
737 castResult.m_hitPoint,
738 castResult.m_fraction);
739
740 bool normalInWorldSpace = true;
742 }
743 }
744 }
745 }
746 else
747 {
748 //BT_PROFILE("convexSweepConcave");
753 // rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
755
756 //ConvexCast::CastResult
758 {
760 const btCollisionObject* m_collisionObject;
762
765 m_resultCallback(resultCallback),
766 m_collisionObject(collisionObject),
768 {
769 }
770
772 {
775 shapeInfo.m_triangleIndex = triangleIndex;
776 if (hitFraction <= m_resultCallback->m_closestHitFraction)
777 {
779 &shapeInfo,
783
784 bool normalInWorldSpace = true;
785
786 return m_resultCallback->addSingleResult(convexResult, normalInWorldSpace);
787 }
788 return hitFraction;
789 }
790 };
791
793 tccb.m_hitFraction = resultCallback.m_closestHitFraction;
794 tccb.m_allowedPenetration = allowedPenetration;
797
804 concaveShape->processAllTriangles(&tccb, rayAabbMinLocal, rayAabbMaxLocal);
805 }
806 }
807 }
808 else
809 {
810 if (collisionShape->isCompound())
811 {
813 {
823 : m_colObjWrap(colObjWrap),
824 m_castShape(castShape),
825 m_convexFromTrans(convexFromTrans),
826 m_convexToTrans(convexToTrans),
827 m_allowedPenetration(allowedPenetration),
828 m_compoundShape(compoundShape),
830 m_resultCallback(resultCallback)
831 {
832 }
833
834 const btCollisionObjectWrapper* m_colObjWrap;
835 const btConvexShape* m_castShape;
836 const btTransform& m_convexFromTrans;
837 const btTransform& m_convexToTrans;
838 btScalar m_allowedPenetration;
839 const btCompoundShape* m_compoundShape;
841 ConvexResultCallback& m_resultCallback;
842
843 public:
845 {
847
849 {
851 int m_i;
852
854 : m_userCallback(user), m_i(i)
855 {
856 m_closestHitFraction = m_userCallback->m_closestHitFraction;
857 }
858 virtual bool needsCollision(btBroadphaseProxy* p) const
859 {
860 return m_userCallback->needsCollision(p);
861 }
862 virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b)
863 {
866 shapeInfo.m_triangleIndex = m_i;
867 if (r.m_localShapeInfo == NULL)
869 const btScalar result = m_userCallback->addSingleResult(r, b);
870 m_closestHitFraction = m_userCallback->m_closestHitFraction;
871 return result;
872 }
873 };
874
875 LocalInfoAdder my_cb(index, &m_resultCallback);
876
878
879 objectQuerySingleInternal(m_castShape, m_convexFromTrans, m_convexToTrans, &tmpObj, my_cb, m_allowedPenetration);
880 }
881
882 void Process(const btDbvtNode* leaf)
883 {
884 // Processing leaf node
885 int index = leaf->dataAsInt;
886
887 btTransform childTrans = m_compoundShape->getChildTransform(index);
888 const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(index);
889
891 }
892 };
893
894 BT_PROFILE("convexSweepCompound");
895 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
896
899
902
905
908
909 const btDbvt* tree = compoundShape->getDynamicAabbTree();
910 if (tree)
911 {
913 tree->collideTV(tree->m_root, bounds, callback);
914 }
915 else
916 {
917 int i;
918 for (i = 0; i < compoundShape->getNumChildShapes(); i++)
919 {
920 const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
921 btTransform childTrans = compoundShape->getChildTransform(i);
922 callback.ProcessChild(i, childTrans, childCollisionShape);
923 }
924 }
925 }
926 }
927 }
928}
929
931{
937
940
944 m_world(world),
946 {
951
952 btVector3 rayDir = (rayToWorld - rayFromWorld);
953
954 rayDir.normalize();
956 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
957 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
958 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
959 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
960 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
961 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
962
964 }
965
966 virtual bool process(const btBroadphaseProxy* proxy)
967 {
970 return false;
971
973
974 //only perform raycast if filterMask matches
975 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
976 {
977 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
978 //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
979#if 0
980#ifdef RECALCULATE_AABB
982 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
983#else
984 //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
985 const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
986 const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
987#endif
988#endif
989 //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
990 //culling already done by broadphase
991 //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
992 {
995 collisionObject->getCollisionShape(),
996 collisionObject->getWorldTransform(),
998 }
999 }
1000 return true;
1001 }
1002};
1003
1005{
1006 //BT_PROFILE("rayTest");
1010
1011#ifndef USE_BRUTEFORCE_RAYBROADPHASE
1013#else
1014 for (int i = 0; i < this->getNumCollisionObjects(); i++)
1015 {
1016 rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
1017 }
1018#endif //USE_BRUTEFORCE_RAYBROADPHASE
1019}
1020
1022{
1030
1034 m_world(world),
1038 {
1042 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0];
1043 m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1];
1044 m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2];
1045 m_signs[0] = m_rayDirectionInverse[0] < 0.0;
1046 m_signs[1] = m_rayDirectionInverse[1] < 0.0;
1047 m_signs[2] = m_rayDirectionInverse[2] < 0.0;
1048
1050 }
1051
1052 virtual bool process(const btBroadphaseProxy* proxy)
1053 {
1056 return false;
1057
1059
1060 //only perform raycast if filterMask matches
1061 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1062 {
1063 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1066 collisionObject->getCollisionShape(),
1067 collisionObject->getWorldTransform(),
1070 }
1071
1072 return true;
1073 }
1074};
1075
1077{
1078 BT_PROFILE("convexSweepTest");
1082
1087 /* Compute AABB that encompasses angular movement */
1088 {
1092 zeroLinVel.setValue(0, 0, 0);
1093 btTransform R;
1094 R.setIdentity();
1095 R.setRotation(convexFromTrans.getRotation());
1096 castShape->calculateTemporalAabb(R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax);
1097 }
1098
1099#ifndef USE_BRUTEFORCE_RAYBROADPHASE
1100
1102
1104
1105#else
1107 // do a ray-shape query using convexCaster (CCD)
1108 int i;
1109 for (i = 0; i < m_collisionObjects.size(); i++)
1110 {
1112 //only perform raycast if filterMask matches
1113 if (resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1114 {
1115 //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
1117 collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(), collisionObjectAabbMin, collisionObjectAabbMax);
1119 btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
1122 {
1125 collisionObject->getCollisionShape(),
1126 collisionObject->getWorldTransform(),
1129 }
1130 }
1131 }
1132#endif //USE_BRUTEFORCE_RAYBROADPHASE
1133}
1134
1136{
1138
1142 {
1143 }
1144
1146 {
1151 if (isSwapped)
1152 {
1155 }
1156 else
1157 {
1160 }
1161
1163 newPt.m_positionWorldOnA = pointA;
1164 newPt.m_positionWorldOnB = pointInWorld;
1165
1166 //BP mod, store contact triangles.
1167 if (isSwapped)
1168 {
1169 newPt.m_partId0 = m_partId1;
1170 newPt.m_partId1 = m_partId0;
1171 newPt.m_index0 = m_index1;
1172 newPt.m_index1 = m_index0;
1173 }
1174 else
1175 {
1176 newPt.m_partId0 = m_partId0;
1177 newPt.m_partId1 = m_partId1;
1178 newPt.m_index0 = m_index0;
1179 newPt.m_index1 = m_index1;
1180 }
1181
1182 //experimental feature info, for per-triangle material etc.
1185 m_resultCallback.addSingleResult(newPt, obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1);
1186 }
1187};
1188
1190{
1194
1197 m_world(world),
1199 {
1200 }
1201
1202 virtual bool process(const btBroadphaseProxy* proxy)
1203 {
1206 return true;
1207
1208 //only perform raycast if filterMask matches
1209 if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
1210 {
1212 btCollisionObjectWrapper ob1(0, collisionObject->getCollisionShape(), collisionObject, collisionObject->getWorldTransform(), -1, -1);
1213
1215 if (algorithm)
1216 {
1218 //discrete collision detection query
1219
1221
1222 algorithm->~btCollisionAlgorithm();
1224 }
1225 }
1226 return true;
1227 }
1228};
1229
1233{
1235 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), aabbMin, aabbMax);
1237
1239}
1240
1244{
1245 btCollisionObjectWrapper obA(0, colObjA->getCollisionShape(), colObjA, colObjA->getWorldTransform(), -1, -1);
1246 btCollisionObjectWrapper obB(0, colObjB->getCollisionShape(), colObjB, colObjB->getWorldTransform(), -1, -1);
1247
1249 if (algorithm)
1250 {
1252 contactPointResult.m_closestPointDistanceThreshold = resultCallback.m_closestDistanceThreshold;
1253 //discrete collision detection query
1255
1256 algorithm->~btCollisionAlgorithm();
1258 }
1259}
1260
1262{
1266
1267public:
1269 m_color(color),
1271 {
1272 }
1273
1275 {
1277 }
1278
1280 {
1281 (void)partId;
1283
1284 btVector3 wv0, wv1, wv2;
1285 wv0 = m_worldTrans * triangle[0];
1286 wv1 = m_worldTrans * triangle[1];
1287 wv2 = m_worldTrans * triangle[2];
1288 btVector3 center = (wv0 + wv1 + wv2) * btScalar(1. / 3.);
1289
1291 {
1292 btVector3 normal = (wv1 - wv0).cross(wv2 - wv0);
1293 normal.normalize();
1294 btVector3 normalColor(1, 1, 0);
1295 m_debugDrawer->drawLine(center, center + normal, normalColor);
1296 }
1300 }
1301};
1302
1304{
1305 // Draw a small simplex at the center of the object
1306 if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawFrames)
1307 {
1309 }
1310
1311 if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE)
1312 {
1313 const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
1314 for (int i = compoundShape->getNumChildShapes() - 1; i >= 0; i--)
1315 {
1316 btTransform childTrans = compoundShape->getChildTransform(i);
1317 const btCollisionShape* colShape = compoundShape->getChildShape(i);
1319 }
1320 }
1321 else
1322 {
1323 switch (shape->getShapeType())
1324 {
1326 {
1327 const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
1328 btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
1330 break;
1331 }
1332
1334 {
1335 const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
1336 btScalar radius = sphereShape->getMargin(); //radius doesn't include the margin, so draw with margin
1337
1339 break;
1340 }
1342 {
1343 const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
1344
1347
1348 for (int i = multiSphereShape->getSphereCount() - 1; i >= 0; i--)
1349 {
1350 childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
1352 }
1353
1354 break;
1355 }
1357 {
1358 const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
1359
1361 btScalar halfHeight = capsuleShape->getHalfHeight();
1362
1363 int upAxis = capsuleShape->getUpAxis();
1365 break;
1366 }
1368 {
1369 const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
1370 btScalar radius = coneShape->getRadius(); //+coneShape->getMargin();
1371 btScalar height = coneShape->getHeight(); //+coneShape->getMargin();
1372
1373 int upAxis = coneShape->getConeUpIndex();
1375 break;
1376 }
1378 {
1379 const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
1380 int upAxis = cylinder->getUpAxis();
1381 btScalar radius = cylinder->getRadius();
1382 btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
1384 break;
1385 }
1386
1388 {
1389 const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
1391 const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
1393 break;
1394 }
1395 default:
1396 {
1398 if (shape->isPolyhedral())
1399 {
1401
1402 int i;
1403 if (polyshape->getConvexPolyhedron())
1404 {
1405 const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
1406 for (i = 0; i < poly->m_faces.size(); i++)
1407 {
1408 btVector3 centroid(0, 0, 0);
1409 int numVerts = poly->m_faces[i].m_indices.size();
1410 if (numVerts)
1411 {
1412 int lastV = poly->m_faces[i].m_indices[numVerts - 1];
1413 for (int v = 0; v < poly->m_faces[i].m_indices.size(); v++)
1414 {
1415 int curVert = poly->m_faces[i].m_indices[v];
1416 centroid += poly->m_vertices[curVert];
1417 getDebugDrawer()->drawLine(worldTransform * poly->m_vertices[lastV], worldTransform * poly->m_vertices[curVert], color);
1418 lastV = curVert;
1419 }
1420 }
1422 if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
1423 {
1424 btVector3 normalColor(1, 1, 0);
1425 btVector3 faceNormal(poly->m_faces[i].m_plane[0], poly->m_faces[i].m_plane[1], poly->m_faces[i].m_plane[2]);
1427 }
1428 }
1429 }
1430 else
1431 {
1432 for (i = 0; i < polyshape->getNumEdges(); i++)
1433 {
1434 btVector3 a, b;
1435 polyshape->getEdge(i, a, b);
1439 }
1440 }
1441 }
1442
1443 if (shape->isConcave())
1444 {
1446
1450
1452 concaveMesh->processAllTriangles(&drawCallback, aabbMin, aabbMax);
1453 }
1454
1456 {
1458 //todo: pass camera for some culling
1461 //DebugDrawcallback drawCallback;
1463 convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback, aabbMin, aabbMax);
1464 }
1465 }
1466 }
1467 }
1468}
1469
1471{
1472 if (getDebugDrawer())
1473 {
1475
1477
1479 {
1480 if (getDispatcher())
1481 {
1483
1484 for (int i = 0; i < numManifolds; i++)
1485 {
1487 //btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
1488 //btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
1489
1491 for (int j = 0; j < numContacts; j++)
1492 {
1493 btManifoldPoint& cp = contactManifold->getContactPoint(j);
1494 getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB, cp.m_normalWorldOnB, cp.getDistance(), cp.getLifeTime(), defaultColors.m_contactPoint);
1495 }
1496 }
1497 }
1498 }
1499
1501 {
1502 int i;
1503
1504 for (i = 0; i < m_collisionObjects.size(); i++)
1505 {
1507 if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT) == 0)
1508 {
1509 if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe))
1510 {
1511 btVector3 color(btScalar(0.4), btScalar(0.4), btScalar(0.4));
1512
1513 switch (colObj->getActivationState())
1514 {
1515 case ACTIVE_TAG:
1516 color = defaultColors.m_activeObject;
1517 break;
1518 case ISLAND_SLEEPING:
1519 color = defaultColors.m_deactivatedObject;
1520 break;
1521 case WANTS_DEACTIVATION:
1522 color = defaultColors.m_wantsDeactivationObject;
1523 break;
1525 color = defaultColors.m_disabledDeactivationObject;
1526 break;
1527 case DISABLE_SIMULATION:
1528 color = defaultColors.m_disabledSimulationObject;
1529 break;
1530 default:
1531 {
1532 color = btVector3(btScalar(.3), btScalar(0.3), btScalar(0.3));
1533 }
1534 };
1535
1536 colObj->getCustomDebugColor(color);
1537
1538 debugDrawObject(colObj->getWorldTransform(), colObj->getCollisionShape(), color);
1539 }
1541 {
1544 colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb, maxAabb);
1548
1550
1551 if (getDispatchInfo().m_useContinuous && colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject())
1552 {
1553 colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(), minAabb2, maxAabb2);
1557 maxAabb.setMax(maxAabb2);
1558 }
1559
1561 }
1562 }
1563 }
1564 }
1565 }
1566}
1567
1569{
1570 int i;
1571
1574
1575 for (i = 0; i < m_collisionObjects.size(); i++)
1576 {
1578 btCollisionShape* shape = colObj->getCollisionShape();
1579
1580 if (!serializedShapes.find(shape))
1581 {
1582 serializedShapes.insert(shape, shape);
1584 }
1585 }
1586
1587 //serialize all collision objects
1588 for (i = 0; i < m_collisionObjects.size(); i++)
1589 {
1591 if (colObj->getInternalType() == btCollisionObject::CO_COLLISION_OBJECT)
1592 {
1593 colObj->serializeSingleObject(serializer);
1594 }
1595 }
1596}
1597
1599{
1600 if (serializer->getSerializationFlags() & BT_SERIALIZE_CONTACT_MANIFOLDS)
1601 {
1603 for (int i = 0; i < numManifolds; i++)
1604 {
1606 //don't serialize empty manifolds, they just take space
1607 //(may have to do it anyway if it destroys determinism)
1608 if (manifold->getNumContacts() == 0)
1609 continue;
1610
1611 btChunk* chunk = serializer->allocate(manifold->calculateSerializeBufferSize(), 1);
1612 const char* structType = manifold->serialize(manifold, chunk->m_oldPtr, serializer);
1614 }
1615 }
1616}
1617
1619{
1620 serializer->startSerialization();
1621
1623
1625
1626 serializer->finishSerialization();
1627}
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 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
btVector3 normalized() const
Return a normalized version of this vector.
Definition btVector3.h:949
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)