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();
	}

}
Пример #5
0
void btCompoundCollisionAlgorithm::nihilize(btDispatcher* dispatcher)
{
	removeChildAlgorithms(dispatcher);
	btActivatingCollisionAlgorithm::nihilize(dispatcher);
}
Пример #6
0
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
	{