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
	{
Пример #3
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
	{