예제 #1
0
//------------------------------------------------------------------------
//	NodeyBSPTree::ProcessAllTriangles_R
//------------------------------------------------------------------------
//
void NodeyBSPTree::ProcessAllTriangles_R( const Node* pNode, const AABB& aabb, btTriangleCallback* callback ) const
{
	if ( pNode->IsInternal() )
	{
		const E_PlaneSide  eRelation = pNode->GetPlane().ClassifyVolumeRelation( aabb );

		if ( eRelation == SIDE_FRONT ) {
			ProcessAllTriangles_R( pNode->FrontChild, aabb, callback );
		}
		else if ( eRelation == SIDE_BACK ) {
			ProcessAllTriangles_R( pNode->BackChild, aabb, callback );
		}
		else // SIDE_CROSS
		{
#if 0
			// Process all triangles in this node.
			for ( TIndex  iTriIndex = 0; iTriIndex <= pNode->Data.NumTriangles; ++iTriIndex )
			{
				const IndexTriple & rTri = m_pRenderMesh->Triangles[ iTriIndex + pNode->Data.FirstTriangle ];

				btVector3  triangle[3];
				for ( u32 i = 0; i < 3; i++ ) {
					Assign( triangle[i], m_pRenderMesh->GetPos( rTri[i] ) );
				}

				if ( TestTriangleAgainstAabb2( triangle, Convert(aabb.MinEdge), Convert(aabb.MaxEdge) ) )
				{
					callback->processTriangle( triangle, 0, (int)iTriIndex );
				}
			}
#else
			const Polygon * polygon = pNode->Faces;
			while ( polygon != NULL )
			{
				const u32 numTriangles = polygon->NumVertices() - 2;

				const Vec3D & basePoint = polygon->Vertices[ 0 ].Pos;

				btVector3  triangle[3];
				Assign( triangle[0], basePoint );

				for ( u32 i = 1; i < numTriangles + 1; i++ )
				{
					Assign( triangle[ 1 ], polygon->Vertices[ i ].Pos );
					Assign( triangle[ 2 ], polygon->Vertices[ i+1 ].Pos );

					//if ( TestTriangleAgainstAabb2( triangle, Convert(aabb.MinEdge), Convert(aabb.MaxEdge) ) )
					{
						callback->processTriangle( triangle, 0, i );
					}
				}

				polygon = polygon->GetNext();
			}
#endif
			ProcessAllTriangles_R( pNode->FrontChild, aabb, callback );
			ProcessAllTriangles_R( pNode->BackChild, aabb, callback );
		}
	}//End If Node Is Internal
}
		virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
		{
			if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax))
			{
				//check aabb in triangle-space, before doing this
				m_callback->processTriangle(triangle,partId,triangleIndex);
			}
			
		}
void btConvexTriangleCallback::processTriangle(btVector3* triangle,int
partId, int triangleIndex)
{

	if (!TestTriangleAgainstAabb2(triangle, m_aabbMin, m_aabbMax))
	{
		return;
	}

        //just for debugging purposes
        //printf("triangle %d",m_triangleCount++);

        const btCollisionObject* ob = const_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());

	btCollisionAlgorithmConstructionInfo ci;
	ci.m_dispatcher1 = m_dispatcher;

	//const btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());

	


#if 0	
	///debug drawing of the overlapping triangles
	if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
	{
		btVector3 color(1,1,0);
		btTransform& tr = ob->getWorldTransform();
		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
	}
#endif
	
	if (m_convexBodyWrap->getCollisionShape()->isConvex())
	{
		btTriangleShape tm(triangle[0],triangle[1],triangle[2]);	
		tm.setMargin(m_collisionMarginTriangle);
		
		
		btCollisionObjectWrapper triObWrap(m_triBodyWrap,&tm,m_triBodyWrap->getCollisionObject(),m_triBodyWrap->getWorldTransform(),partId,triangleIndex);//correct transform?
		btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap,&triObWrap,m_manifoldPtr);

		const btCollisionObjectWrapper* tmpWrap = 0;

		if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
		{
			tmpWrap = m_resultOut->getBody0Wrap();
			m_resultOut->setBody0Wrap(&triObWrap);
			m_resultOut->setShapeIdentifiersA(partId,triangleIndex);
		}
		else
		{
			tmpWrap = m_resultOut->getBody1Wrap();
			m_resultOut->setBody1Wrap(&triObWrap);
			m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
		}
	
		colAlgo->processCollision(m_convexBodyWrap,&triObWrap,*m_dispatchInfoPtr,m_resultOut);

		if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
		{
			m_resultOut->setBody0Wrap(tmpWrap);
		} else
		{
			m_resultOut->setBody1Wrap(tmpWrap);
		}
		


		colAlgo->~btCollisionAlgorithm();
		ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
	}

}
void btConvexTriangleCallback::processTriangle(btVector3* triangle, int partId, int triangleIndex)
{
	if (!TestTriangleAgainstAabb2(triangle, m_aabbMin, m_aabbMax))
	{
		return;
	}
 
	//just for debugging purposes
	//printf("triangle %d", m_triangleCount++);

	const btCollisionObject* ob = const_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());

	btCollisionAlgorithmConstructionInfo ci;
	ci.m_dispatcher1 = m_dispatcher;

	//const btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());


#if 1
	///debug drawing of the overlapping triangles
	if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
	{
		btVector3 color(1,1,0);
		const btTransform& tr = ob->getWorldTransform();
		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]), tr(triangle[1]), color);
		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]), tr(triangle[2]), color);
		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]), tr(triangle[0]), color);
	}
#endif
	
	if (m_convexBodyWrap->getCollisionShape()->isConvex())
	{
		btTriangleShape tm(triangle[0], triangle[1], triangle[2]);	
		tm.setMargin(m_collisionMarginTriangle);
		
		btCollisionObjectWrapper triObWrap(m_triBodyWrap, &tm, m_triBodyWrap->getCollisionObject(), m_triBodyWrap->getWorldTransform(), partId, triangleIndex);//correct transform?
		btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap, &triObWrap, m_manifoldPtr);

		const btCollisionObjectWrapper* tmpWrap = 0;

		if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
		{
			tmpWrap = m_resultOut->getBody0Wrap();
			m_resultOut->setBody0Wrap(&triObWrap);
			m_resultOut->setShapeIdentifiersA(partId, triangleIndex);
		}
		else
		{
			tmpWrap = m_resultOut->getBody1Wrap();
			m_resultOut->setBody1Wrap(&triObWrap);
			m_resultOut->setShapeIdentifiersB(partId, triangleIndex);
		}
	
		colAlgo->processCollision(m_convexBodyWrap, &triObWrap, *m_dispatchInfoPtr, m_resultOut);

		btIDebugDraw *drawer = NULL;
		if (m_dispatchInfoPtr) {
			drawer = m_dispatchInfoPtr->m_debugDraw;
		}

		// Compensate for any internal edge contact points
		btPersistentManifold *manifold = m_resultOut->getPersistentManifold();
		for (int i = 0; i < manifold->getNumContacts(); i++)
		{
			btManifoldPoint &pt = manifold->getContactPoint(i);
			btAdjustInternalEdgeContacts(pt, &triObWrap, m_convexBodyWrap, partId, triangleIndex, BT_TRIANGLE_CONVEX_DOUBLE_SIDED | BT_TRIANGLE_CONCAVE_DOUBLE_SIDED, drawer);
		}

		if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
		{
			m_resultOut->setBody0Wrap(tmpWrap);
		} else
		{
			m_resultOut->setBody1Wrap(tmpWrap);
		}

		colAlgo->~btCollisionAlgorithm();
		ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
	}
}