22 #include <LinearMath/btQuickprof.h>
23 #include <BulletCollision/CollisionDispatch/btCollisionObject.h>
24 #include <BulletCollision/CollisionShapes/btCompoundShape.h>
25 #include <BulletCollision/CollisionShapes/btCollisionShape.h>
26 #include <BulletCollision/BroadphaseCollision/btDbvt.h>
27 #include <BulletCollision/NarrowPhaseCollision/btPersistentManifold.h>
28 #include <LinearMath/btIDebugDraw.h>
29 #include <LinearMath/btAabbUtil2.h>
30 #include <BulletCollision/CollisionDispatch/btManifoldResult.h>
31 #include <BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h>
36 #define USE_LOCAL_STACK 1
47 const btCollisionAlgorithmConstructionInfo& ci,
48 const btCollisionObjectWrapper* body0Wrap,
49 const btCollisionObjectWrapper* body1Wrap,
53 void* ptr = btAlignedAlloc(
sizeof(btHashedSimplePairCache), 16);
56 const btCollisionObjectWrapper* col0ObjWrap = body0Wrap;
57 btAssert(col0ObjWrap->getCollisionShape()->isCompound());
59 const btCollisionObjectWrapper* col1ObjWrap = body1Wrap;
60 btAssert(col1ObjWrap->getCollisionShape()->isCompound());
62 const auto* compoundShape0 =
static_cast<const btCompoundShape*
>(col0ObjWrap->getCollisionShape());
65 const auto* compoundShape1 =
static_cast<const btCompoundShape*
>(col1ObjWrap->getCollisionShape());
79 for (
int i = 0; i < pairs.size(); i++)
81 if (pairs[i].m_userPointer !=
nullptr)
83 ((btCollisionAlgorithm*)pairs[i].m_userPointer)->getAllContactManifolds(
manifoldArray);
92 int numChildren = pairs.size();
93 for (
int i = 0; i < numChildren; i++)
95 if (pairs[i].m_userPointer !=
nullptr)
97 auto* algo = (btCollisionAlgorithm*)pairs[i].m_userPointer;
98 algo->~btCollisionAlgorithm();
99 m_dispatcher->freeCollisionAlgorithm(algo);
122 const btCollisionObjectWrapper* compound0ObjWrap,
123 btDispatcher* dispatcher,
124 const btDispatcherInfo& dispatchInfo,
125 btManifoldResult* resultOut,
126 btHashedSimplePairCache* childAlgorithmsCache,
127 btPersistentManifold* sharedManifold)
139 void Process(
const btDbvtNode* leaf0,
const btDbvtNode* leaf1)
141 BT_PROFILE(
"TesseractCompoundCompoundLeafCallback::Process");
144 int childIndex0 = leaf0->dataAsInt;
145 int childIndex1 = leaf1->dataAsInt;
147 btAssert(childIndex0 >= 0);
148 btAssert(childIndex1 >= 0);
150 const auto* compoundShape0 =
static_cast<const btCompoundShape*
>(
m_compound0ColObjWrap->getCollisionShape());
151 btAssert(childIndex0 < compoundShape0->getNumChildShapes());
153 const auto* compoundShape1 =
static_cast<const btCompoundShape*
>(
m_compound1ColObjWrap->getCollisionShape());
154 btAssert(childIndex1 < compoundShape1->getNumChildShapes());
156 const btCollisionShape* childShape0 = compoundShape0->getChildShape(childIndex0);
157 const btCollisionShape* childShape1 = compoundShape1->getChildShape(childIndex1);
161 const btTransform& childTrans0 = compoundShape0->getChildTransform(childIndex0);
162 btTransform newChildWorldTrans0 = orgTrans0 * childTrans0;
165 const btTransform& childTrans1 = compoundShape1->getChildTransform(childIndex1);
166 btTransform newChildWorldTrans1 = orgTrans1 * childTrans1;
169 btVector3 aabbMin0, aabbMax0, aabbMin1, aabbMax1;
170 childShape0->getAabb(newChildWorldTrans0, aabbMin0, aabbMax0);
171 childShape1->getAabb(newChildWorldTrans1, aabbMin1, aabbMax1);
173 btVector3 thresholdVec(
m_resultOut->m_closestPointDistanceThreshold,
177 aabbMin0 -= thresholdVec;
178 aabbMax0 += thresholdVec;
183 if (TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1))
185 btCollisionObjectWrapper compoundWrap0(this->m_compound0ColObjWrap,
191 btCollisionObjectWrapper compoundWrap1(this->m_compound1ColObjWrap,
199 bool removePair =
false;
200 btCollisionAlgorithm* colAlgo =
nullptr;
201 if (
m_resultOut->m_closestPointDistanceThreshold > 0)
203 colAlgo =
m_dispatcher->findAlgorithm(&compoundWrap0, &compoundWrap1,
nullptr, BT_CLOSEST_POINT_ALGORITHMS);
210 colAlgo = (btCollisionAlgorithm*)pair->m_userPointer;
215 &compoundWrap0, &compoundWrap1,
m_sharedManifold, BT_CONTACT_POINT_ALGORITHMS);
218 pair->m_userPointer = colAlgo;
224 const btCollisionObjectWrapper* tmpWrap0 =
nullptr;
225 const btCollisionObjectWrapper* tmpWrap1 =
nullptr;
233 m_resultOut->setShapeIdentifiersA(-1, childIndex0);
234 m_resultOut->setShapeIdentifiersB(-1, childIndex1);
243 colAlgo->~btCollisionAlgorithm();
250 static DBVT_INLINE
bool
251 MyIntersect(
const btDbvtAabbMm& a,
const btDbvtAabbMm& b,
const btTransform& xform, btScalar distanceThreshold)
253 btVector3 newmin, newmax;
254 btTransformAabb(b.Mins(), b.Maxs(), btScalar(0), xform, newmin, newmax);
255 newmin -= btVector3(distanceThreshold, distanceThreshold, distanceThreshold);
256 newmax += btVector3(distanceThreshold, distanceThreshold, distanceThreshold);
257 btDbvtAabbMm newb = btDbvtAabbMm::FromMM(newmin, newmax);
258 return Intersect(a, newb);
262 const btDbvtNode* root1,
263 const btTransform& xform,
265 btScalar distanceThreshold)
267 if (root0 !=
nullptr && root1 !=
nullptr)
270 int treshold = btDbvt::DOUBLE_STACKSIZE - 4;
271 btAlignedObjectArray<btDbvt::sStkNN> stkStack;
272 #ifdef USE_LOCAL_STACK
273 ATTRIBUTE_ALIGNED16(btDbvt::sStkNN localStack[btDbvt::DOUBLE_STACKSIZE]);
274 stkStack.initializeFromBuffer(&localStack, btDbvt::DOUBLE_STACKSIZE, btDbvt::DOUBLE_STACKSIZE);
276 stkStack.resize(btDbvt::DOUBLE_STACKSIZE);
278 stkStack[0] = btDbvt::sStkNN(root0, root1);
281 btDbvt::sStkNN p = stkStack[--depth];
282 if (
MyIntersect(p.a->volume, p.b->volume, xform, distanceThreshold))
284 if (depth > treshold)
286 stkStack.resize(stkStack.size() * 2);
287 treshold = stkStack.size() - 4;
289 if (p.a->isinternal())
291 if (p.b->isinternal())
293 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b->childs[0]);
294 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b->childs[0]);
295 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b->childs[1]);
296 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b->childs[1]);
300 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b);
301 stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b);
306 if (p.b->isinternal())
308 stkStack[depth++] = btDbvt::sStkNN(p.a, p.b->childs[0]);
309 stkStack[depth++] = btDbvt::sStkNN(p.a, p.b->childs[1]);
317 }
while (depth != 0);
322 const btCollisionObjectWrapper* body1Wrap,
323 const btDispatcherInfo& dispatchInfo,
324 btManifoldResult* resultOut)
326 const btCollisionObjectWrapper* col0ObjWrap = body0Wrap;
327 const btCollisionObjectWrapper* col1ObjWrap = body1Wrap;
329 btAssert(col0ObjWrap->getCollisionShape()->isCompound());
330 btAssert(col1ObjWrap->getCollisionShape()->isCompound());
331 const auto* compoundShape0 =
static_cast<const btCompoundShape*
>(col0ObjWrap->getCollisionShape());
332 const auto* compoundShape1 =
static_cast<const btCompoundShape*
>(col1ObjWrap->getCollisionShape());
334 const btDbvt* tree0 = compoundShape0->getDynamicAabbTree();
335 const btDbvt* tree1 = compoundShape1->getDynamicAabbTree();
336 if (tree0 ==
nullptr || tree1 ==
nullptr)
357 #ifdef USE_LOCAL_STACK
358 btPersistentManifold localManifolds[4];
362 for (
int i = 0; i < pairs.size(); i++)
364 if (pairs[i].m_userPointer !=
nullptr)
366 auto* algo = (btCollisionAlgorithm*)pairs[i].m_userPointer;
373 resultOut->refreshContactPoints();
374 resultOut->setPersistentManifold(
nullptr);
390 const btTransform xform = col0ObjWrap->getWorldTransform().inverse() * col1ObjWrap->getWorldTransform();
391 MycollideTT(tree0->m_root, tree1->m_root, xform, &callback, resultOut->m_closestPointDistanceThreshold);
405 btVector3 aabbMin0, aabbMax0, aabbMin1, aabbMax1;
407 for (
int i = 0; i < pairs.size(); i++)
409 if (pairs[i].m_userPointer !=
nullptr)
411 auto* algo = (btCollisionAlgorithm*)pairs[i].m_userPointer;
414 const btCollisionShape* childShape0 =
nullptr;
416 btTransform newChildWorldTrans0;
417 childShape0 = compoundShape0->getChildShape(pairs[i].m_indexA);
418 const btTransform& childTrans0 = compoundShape0->getChildTransform(pairs[i].m_indexA);
419 newChildWorldTrans0 = col0ObjWrap->getWorldTransform() * childTrans0;
420 childShape0->getAabb(newChildWorldTrans0, aabbMin0, aabbMax0);
422 btVector3 thresholdVec(resultOut->m_closestPointDistanceThreshold,
423 resultOut->m_closestPointDistanceThreshold,
424 resultOut->m_closestPointDistanceThreshold);
425 aabbMin0 -= thresholdVec;
426 aabbMax0 += thresholdVec;
428 const btCollisionShape* childShape1 =
nullptr;
429 btTransform newChildWorldTrans1;
431 childShape1 = compoundShape1->getChildShape(pairs[i].m_indexB);
432 const btTransform& childTrans1 = compoundShape1->getChildTransform(pairs[i].m_indexB);
433 newChildWorldTrans1 = col1ObjWrap->getWorldTransform() * childTrans1;
434 childShape1->getAabb(newChildWorldTrans1, aabbMin1, aabbMax1);
437 aabbMin1 -= thresholdVec;
438 aabbMax1 += thresholdVec;
440 if (!TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1))
442 algo->~btCollisionAlgorithm();
443 m_dispatcher->freeCollisionAlgorithm(algo);
444 m_removePairs.push_back(btSimplePair(pairs[i].m_indexA, pairs[i].m_indexB));
458 const btDispatcherInfo& ,