btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped) :btActivatingCollisionAlgorithm(ci,body0,body1), m_isSwapped(isSwapped), m_sharedManifold(ci.m_manifold) { m_ownsManifold = false; btCollisionObject* colObj = m_isSwapped? body1 : body0; btAssert (colObj->getCollisionShape()->isCompound()); btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape()); m_compoundShapeRevision = compoundShape->getUpdateRevision(); preallocateChildAlgorithms(body0,body1); }
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 {
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 {