btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm() { removeChildAlgorithms(); }
void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) { const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap; const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap; btAssert (colObjWrap->getCollisionShape()->isCompound()); const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObjWrap->getCollisionShape()); ///btCompoundShape might have changed: ////make sure the internal child collision algorithm caches are still valid if (compoundShape->getUpdateRevision() != m_compoundShapeRevision) { ///clear and update all removeChildAlgorithms(); preallocateChildAlgorithms(body0Wrap,body1Wrap); m_compoundShapeRevision = compoundShape->getUpdateRevision(); } if (m_childCollisionAlgorithms.size()==0) return; const btDbvt* tree = compoundShape->getDynamicAabbTree(); //use a dynamic aabb tree to cull potential child-overlaps btCompoundLeafCallback callback(colObjWrap,otherObjWrap,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold); ///we need to refresh all contact manifolds ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm { int i; manifoldArray.resize(0); for (i=0;i<m_childCollisionAlgorithms.size();i++) { if (m_childCollisionAlgorithms[i]) { m_childCollisionAlgorithms[i]->getAllContactManifolds(manifoldArray); for (int m=0;m<manifoldArray.size();m++) { if (manifoldArray[m]->getNumContacts()) { resultOut->setPersistentManifold(manifoldArray[m]); resultOut->refreshContactPoints(); resultOut->setPersistentManifold(0);//??necessary? } } manifoldArray.resize(0); } } } if (tree) { btVector3 localAabbMin,localAabbMax; btTransform otherInCompoundSpace; otherInCompoundSpace = colObjWrap->getWorldTransform().inverse() * otherObjWrap->getWorldTransform(); otherObjWrap->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax); const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); //process all children, that overlap with the given AABB bounds tree->collideTVNoStackAlloc(tree->m_root,bounds,stack2,callback); } else {
btCompoundCompoundCollisionAlgorithm::~btCompoundCompoundCollisionAlgorithm() { removeChildAlgorithms(); m_childCollisionAlgorithmCache->~btHashedSimplePairCache(); btAlignedFree(m_childCollisionAlgorithmCache); }
void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) { const btCollisionObjectWrapper* col0ObjWrap = body0Wrap; const btCollisionObjectWrapper* col1ObjWrap= body1Wrap; btAssert (col0ObjWrap->getCollisionShape()->isCompound()); btAssert (col1ObjWrap->getCollisionShape()->isCompound()); const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(col0ObjWrap->getCollisionShape()); const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(col1ObjWrap->getCollisionShape()); const btDbvt* tree0 = compoundShape0->getDynamicAabbTree(); const btDbvt* tree1 = compoundShape1->getDynamicAabbTree(); if (!tree0 || !tree1) { return btCompoundCollisionAlgorithm::processCollision(body0Wrap,body1Wrap,dispatchInfo,resultOut); } ///btCompoundShape might have changed: ////make sure the internal child collision algorithm caches are still valid if ((compoundShape0->getUpdateRevision() != m_compoundShapeRevision0) || (compoundShape1->getUpdateRevision() != m_compoundShapeRevision1)) { ///clear all removeChildAlgorithms(); m_compoundShapeRevision0 = compoundShape0->getUpdateRevision(); m_compoundShapeRevision1 = compoundShape1->getUpdateRevision(); } ///we need to refresh all contact manifolds ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm { int i; btManifoldArray manifoldArray; btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray(); for (i=0;i<pairs.size();i++) { if (pairs[i].m_userPointer) { btCollisionAlgorithm* algo = (btCollisionAlgorithm*) pairs[i].m_userPointer; algo->getAllContactManifolds(manifoldArray); for (int m=0;m<manifoldArray.size();m++) { if (manifoldArray[m]->getNumContacts()) { resultOut->setPersistentManifold(manifoldArray[m]); resultOut->refreshContactPoints(); resultOut->setPersistentManifold(0); } } manifoldArray.resize(0); } } } btCompoundCompoundLeafCallback callback(col0ObjWrap,col1ObjWrap,this->m_dispatcher,dispatchInfo,resultOut,this->m_childCollisionAlgorithmCache,m_sharedManifold); const btTransform xform=col0ObjWrap->getWorldTransform().inverse()*col1ObjWrap->getWorldTransform(); MycollideTT(tree0->m_root,tree1->m_root,xform,&callback); //printf("#compound-compound child/leaf overlap =%d \r",callback.m_numOverlapPairs); //remove non-overlapping child pairs { btAssert(m_removePairs.size()==0); //iterate over all children, perform an AABB check inside ProcessChildShape btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray(); int i; btManifoldArray manifoldArray; btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1; for (i=0;i<pairs.size();i++) { if (pairs[i].m_userPointer) { btCollisionAlgorithm* algo = (btCollisionAlgorithm*)pairs[i].m_userPointer; { btTransform orgTrans0; const btCollisionShape* childShape0 = 0; btTransform newChildWorldTrans0; btTransform orgInterpolationTrans0; childShape0 = compoundShape0->getChildShape(pairs[i].m_indexA); orgTrans0 = col0ObjWrap->getWorldTransform(); orgInterpolationTrans0 = col0ObjWrap->getWorldTransform(); const btTransform& childTrans0 = compoundShape0->getChildTransform(pairs[i].m_indexA); newChildWorldTrans0 = orgTrans0*childTrans0 ; childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0); } { btTransform orgInterpolationTrans1; const btCollisionShape* childShape1 = 0; btTransform orgTrans1; btTransform newChildWorldTrans1; childShape1 = compoundShape1->getChildShape(pairs[i].m_indexB); orgTrans1 = col1ObjWrap->getWorldTransform(); orgInterpolationTrans1 = col1ObjWrap->getWorldTransform(); const btTransform& childTrans1 = compoundShape1->getChildTransform(pairs[i].m_indexB); newChildWorldTrans1 = orgTrans1*childTrans1 ; childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1); } if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1)) { algo->~btCollisionAlgorithm(); m_dispatcher->freeCollisionAlgorithm(algo); m_removePairs.push_back(btSimplePair(pairs[i].m_indexA,pairs[i].m_indexB)); } } } for (int i=0;i<m_removePairs.size();i++) { m_childCollisionAlgorithmCache->removeOverlappingPair(m_removePairs[i].m_indexA,m_removePairs[i].m_indexB); } m_removePairs.clear(); } }
void btCompoundCollisionAlgorithm::nihilize(btDispatcher* dispatcher) { removeChildAlgorithms(dispatcher); btActivatingCollisionAlgorithm::nihilize(dispatcher); }
void btCompoundCollisionAlgorithm::processCollision (const btCollisionProcessInfo& processInfo) { const btCollider& colObj = m_isSwapped ? processInfo.m_body1 : processInfo.m_body0; const btCollider& otherObj = m_isSwapped ? processInfo.m_body0 : processInfo.m_body1; const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObj.getCollisionShape()); ///btCompoundShape might have changed: ////make sure the internal child collision algorithm caches are still valid if (compoundShape->getUpdateRevision() != m_compoundShapeRevision && !compoundShape->getBvhTree()) { ///clear and update all removeChildAlgorithms(processInfo.m_dispatcher); preallocateChildAlgorithms(processInfo.m_dispatcher, processInfo.m_body0, processInfo.m_body1); } ///we need to refresh all contact manifolds ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm { for (int i=0; i < m_childCollisionAlgorithms.size(); i++) { if (m_childCollisionAlgorithms[i]) { m_childCollisionAlgorithms[i]->getAllContactManifolds(m_manifoldArray); for (int m = 0; m < m_manifoldArray.size(); m++) { if (m_manifoldArray[m]->getNumContacts()) { processInfo.m_result->setPersistentManifold(m_manifoldArray[m]); processInfo.m_result->refreshContactPoints(); processInfo.m_result->setPersistentManifold(0);//??necessary? } } m_manifoldArray.resize(0); } } } const btDbvt* tree = compoundShape->getDynamicAabbTree(); const btQuantizedBvh* obvh = compoundShape->getBvhTree(); if (obvh) { btVector3 aabbMin, aabbMax; MyCompoundNodeOverlapCallback myCallback(colObj, otherObj, processInfo.m_dispatcher, processInfo.m_dispatchInfo, processInfo.m_result, &m_childCollisionAlgorithms[0], m_manifoldPtr); btTransform collidingInCompoundSpace = colObj.getWorldTransform().inverse() * otherObj.getWorldTransform(); otherObj.getCollisionShape()->getAabb(collidingInCompoundSpace, aabbMin, aabbMax); // Query bvh-tree here. obvh->reportAabbOverlappingNodex(&myCallback,aabbMin,aabbMax); } else if (tree) { //use a dynamic aabb tree to cull potential child-overlaps btCompoundLeafCallback callback( &colObj, &otherObj, processInfo.m_dispatcher, processInfo.m_dispatchInfo, processInfo.m_result, &m_childCollisionAlgorithms[0], m_manifoldPtr ); btVector3 localAabbMin,localAabbMax; btTransform otherInCompoundSpace; otherInCompoundSpace = colObj.getWorldTransform().inverse() * otherObj.getWorldTransform(); otherObj.getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax); const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); //process all children, that overlap with the given AABB bounds tree->collideTV(tree->m_root,bounds,callback); } else {