Esempio n. 1
0
	virtual void processNode(int nodeSubPart, int nodeShapeIndex)
	{
		const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(m_compoundCollider.getCollisionShape());
		const btCollisionShape* childShape = compoundShape->getChildShape(nodeShapeIndex);

		//backup
		btTransform	orgTrans = m_compoundCollider.getWorldTransform();
		const btTransform& childTrans = compoundShape->getChildTransform(nodeShapeIndex);
		btTransform	newChildWorldTrans = orgTrans*childTrans ;

		//the contactpoint is still projected back using the original inverted worldtrans
		btCollider childCollider(&m_compoundCollider, childShape,m_compoundCollider.getCollisionObject(), newChildWorldTrans);

		if (!m_childCollisionAlgorithms[nodeShapeIndex])
			m_childCollisionAlgorithms[nodeShapeIndex] = m_dispatcher->findAlgorithm(&childCollider,&m_collidingObj,m_sharedManifold);

		///detect swapping case
		if (m_resultOut->getBody0Internal() == m_compoundCollider.getCollisionObject())
		{
			m_resultOut->setShapeIdentifiersA(-1,nodeShapeIndex);
		} else
		{
			m_resultOut->setShapeIdentifiersB(-1,nodeShapeIndex);
		}
		btCollisionProcessInfo processInfo(childCollider, m_collidingObj, m_dispatchInfo, m_resultOut, m_dispatcher);
		m_childCollisionAlgorithms[nodeShapeIndex]->processCollision(processInfo);
	}
	void	ProcessChildShape(btCollisionShape* childShape,int index)
	{
		
		btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());


		//backup
		btTransform	orgTrans = m_compoundColObj->getWorldTransform();
		btTransform	orgInterpolationTrans = m_compoundColObj->getInterpolationWorldTransform();
		const btTransform& childTrans = compoundShape->getChildTransform(index);
		btTransform	newChildWorldTrans = orgTrans*childTrans ;

		//perform an AABB check first
		btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
		childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
		m_otherObj->getCollisionShape()->getAabb(m_otherObj->getWorldTransform(),aabbMin1,aabbMax1);

		if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
		{

			m_compoundColObj->setWorldTransform( newChildWorldTrans);
			m_compoundColObj->setInterpolationWorldTransform(newChildWorldTrans);

			//the contactpoint is still projected back using the original inverted worldtrans
			btCollisionShape* tmpShape = m_compoundColObj->getCollisionShape();
			m_compoundColObj->internalSetTemporaryCollisionShape( childShape );

			if (!m_childCollisionAlgorithms[index])
				m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);

			///detect swapping case
			if (m_resultOut->getBody0Internal() == m_compoundColObj)
			{
				m_resultOut->setShapeIdentifiersA(-1,index);
			} else
			{
				m_resultOut->setShapeIdentifiersB(-1,index);
			}

			m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
			if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
			{
				btVector3 worldAabbMin,worldAabbMax;
				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
			}
			
			//revert back transform
			m_compoundColObj->internalSetTemporaryCollisionShape( tmpShape);
			m_compoundColObj->setWorldTransform(  orgTrans );
			m_compoundColObj->setInterpolationWorldTransform(orgInterpolationTrans);
		}
	}
	virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar orgDepth)
	{
		btVector3 endPt, startPt;
		btScalar newDepth;
		btVector3 newNormal;

		if (m_perturbA)
		{
			btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth;
			endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg);
			newDepth = (endPt -  pointInWorld).dot(normalOnBInWorld);
			startPt = endPt+normalOnBInWorld*newDepth;
		} else
		{
			endPt = pointInWorld + normalOnBInWorld*orgDepth;
			startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld);
			newDepth = (endPt -  startPt).dot(normalOnBInWorld);
			
		}

#ifdef DEBUG_CONTACTS
		m_debugDrawer->drawLine(startPt, endPt, btVector3(1,0,0));
		m_debugDrawer->drawSphere(startPt,0.05, btVector3(0,1,0));
		m_debugDrawer->drawSphere(endPt,0.05, btVector3(0,0,1));
#endif //DEBUG_CONTACTS

		
		m_originalManifoldResult->addContactPoint(normalOnBInWorld, startPt, newDepth);
	}
Esempio n. 4
0
	void	ProcessChildShape(const btCollisionShape* childShape,int index)
	{
		btAssert(index>=0);
		const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(m_compoundColObj->getCollisionShape());
		btAssert(index<compoundShape->getNumChildShapes());


		//backup
		btTransform	orgTrans = m_compoundColObj->getWorldTransform();
		const btTransform& childTrans = compoundShape->getChildTransform(index);
		btTransform	newChildWorldTrans = orgTrans*childTrans ;

		//perform an AABB check first
		btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
		childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
		m_otherObj->getCollisionShape()->getAabb(m_otherObj->getWorldTransform(),aabbMin1,aabbMax1);

		if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
		{
			//the contactpoint is still projected back using the original inverted worldtrans
			btCollider childCollider(m_compoundColObj, childShape, m_compoundColObj->getCollisionObject(), newChildWorldTrans);

			if (!m_childCollisionAlgorithms[index])
				m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(&childCollider,m_otherObj,m_sharedManifold);

			///detect swapping case
			if (m_resultOut->getBody0Internal() == m_compoundColObj->getCollisionObject())
			{
				m_resultOut->setShapeIdentifiersA(-1,index);
			} else
			{
				m_resultOut->setShapeIdentifiersB(-1,index);
			}
			btCollisionProcessInfo processInfo(childCollider, *m_otherObj, m_dispatchInfo, m_resultOut, m_dispatcher);
			m_childCollisionAlgorithms[index]->processCollision(processInfo);

			if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
			{
				btVector3 worldAabbMin,worldAabbMax;
				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
			}
		}
	}
	void	ProcessChildShape(const btCollisionShape* childShape,int index)
	{
		btAssert(index>=0);
		const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(m_compoundColObjWrap->getCollisionShape());
		btAssert(index<compoundShape->getNumChildShapes());


		//backup
		btTransform	orgTrans = m_compoundColObjWrap->getWorldTransform();
		
		const btTransform& childTrans = compoundShape->getChildTransform(index);
		btTransform	newChildWorldTrans = orgTrans*childTrans ;

		//perform an AABB check first
		btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
		childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
		m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1);

		if (gCompoundChildShapePairCallback)
		{
			if (!gCompoundChildShapePairCallback(m_otherObjWrap->getCollisionShape(), childShape))
				return;
		}

		if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
		{

			btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap,childShape,m_compoundColObjWrap->getCollisionObject(),newChildWorldTrans,-1,index);


			//the contactpoint is still projected back using the original inverted worldtrans
			if (!m_childCollisionAlgorithms[index])
				m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(&compoundWrap,m_otherObjWrap,m_sharedManifold);

			
			const btCollisionObjectWrapper* tmpWrap = 0;

			///detect swapping case
			if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject())
			{
				tmpWrap = m_resultOut->getBody0Wrap();
				m_resultOut->setBody0Wrap(&compoundWrap);
				m_resultOut->setShapeIdentifiersA(-1,index);
			} else
			{
				tmpWrap = m_resultOut->getBody1Wrap();
				m_resultOut->setBody1Wrap(&compoundWrap);
				m_resultOut->setShapeIdentifiersB(-1,index);
			}


			m_childCollisionAlgorithms[index]->processCollision(&compoundWrap,m_otherObjWrap,m_dispatchInfo,m_resultOut);

#if 0
			if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
			{
				btVector3 worldAabbMin,worldAabbMax;
				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
			}
#endif

			if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject())
			{
				m_resultOut->setBody0Wrap(tmpWrap);
			} else
			{
				m_resultOut->setBody1Wrap(tmpWrap);
			}
			
		}
	}
	void		Process(const btDbvtNode* leaf0,const btDbvtNode* leaf1)
	{
		m_numOverlapPairs++;


		int childIndex0 = leaf0->dataAsInt;
		int childIndex1 = leaf1->dataAsInt;
		

		btAssert(childIndex0>=0);
		btAssert(childIndex1>=0);


		const btCompoundShape* compoundShape0 = static_cast<const btCompoundShape*>(m_compound0ColObjWrap->getCollisionShape());
		btAssert(childIndex0<compoundShape0->getNumChildShapes());

		const btCompoundShape* compoundShape1 = static_cast<const btCompoundShape*>(m_compound1ColObjWrap->getCollisionShape());
		btAssert(childIndex1<compoundShape1->getNumChildShapes());

		const btCollisionShape* childShape0 = compoundShape0->getChildShape(childIndex0);
		const btCollisionShape* childShape1 = compoundShape1->getChildShape(childIndex1);

		//backup
		btTransform	orgTrans0 = m_compound0ColObjWrap->getWorldTransform();
		const btTransform& childTrans0 = compoundShape0->getChildTransform(childIndex0);
		btTransform	newChildWorldTrans0 = orgTrans0*childTrans0 ;
		
		btTransform	orgTrans1 = m_compound1ColObjWrap->getWorldTransform();
		const btTransform& childTrans1 = compoundShape1->getChildTransform(childIndex1);
		btTransform	newChildWorldTrans1 = orgTrans1*childTrans1 ;
		

		//perform an AABB check first
		btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
		childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0);
		childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1);
		
		if (gCompoundCompoundChildShapePairCallback)
		{
			if (!gCompoundCompoundChildShapePairCallback(childShape0,childShape1))
				return;
		}

		if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
		{
			btCollisionObjectWrapper compoundWrap0(this->m_compound0ColObjWrap,childShape0, m_compound0ColObjWrap->getCollisionObject(),newChildWorldTrans0,-1,childIndex0);
			btCollisionObjectWrapper compoundWrap1(this->m_compound1ColObjWrap,childShape1,m_compound1ColObjWrap->getCollisionObject(),newChildWorldTrans1,-1,childIndex1);
			

			btSimplePair* pair = m_childCollisionAlgorithmCache->findPair(childIndex0,childIndex1);

			btCollisionAlgorithm* colAlgo = 0;

			if (pair)
			{
				colAlgo = (btCollisionAlgorithm*)pair->m_userPointer;
				
			} else
			{
				colAlgo = m_dispatcher->findAlgorithm(&compoundWrap0,&compoundWrap1,m_sharedManifold);
				pair = m_childCollisionAlgorithmCache->addOverlappingPair(childIndex0,childIndex1);
				btAssert(pair);
				pair->m_userPointer = colAlgo;
			}

			btAssert(colAlgo);
						
			const btCollisionObjectWrapper* tmpWrap0 = 0;
			const btCollisionObjectWrapper* tmpWrap1 = 0;

			tmpWrap0 = m_resultOut->getBody0Wrap();
			tmpWrap1 = m_resultOut->getBody1Wrap();

			m_resultOut->setBody0Wrap(&compoundWrap0);
			m_resultOut->setBody1Wrap(&compoundWrap1);

			m_resultOut->setShapeIdentifiersA(-1,childIndex0);
			m_resultOut->setShapeIdentifiersB(-1,childIndex1);


			colAlgo->processCollision(&compoundWrap0,&compoundWrap1,m_dispatchInfo,m_resultOut);
			
			m_resultOut->setBody0Wrap(tmpWrap0);
			m_resultOut->setBody1Wrap(tmpWrap1);
			


		}
	}