예제 #1
0
	void GLUTGame::RenderGeometry(PxGeometryHolder h, bool textured)
	{
		switch (h.getType())
		{
		case PxGeometryType::eBOX:
			glScalef(h.box().halfExtents.x, h.box().halfExtents.y, h.box().halfExtents.z);
			if (textured)
				RenderTexturedCube(2.0f);
			else
				glutSolidCube(2.0f);
			break;
		case PxGeometryType::eSPHERE:
			glutSolidSphere(h.sphere().radius, RENDER_DETAIL, RENDER_DETAIL);
			break;
		case PxGeometryType::eCONVEXMESH:
			PxConvexMesh* mesh = h.convexMesh().convexMesh;
			const PxU32 nbPolys = mesh->getNbPolygons();
			const PxU8* polygons = mesh->getIndexBuffer();
			const PxVec3* verts = mesh->getVertices();
			PxU32 numTotalTriangles = 0;

			for (PxU32 i = 0; i < nbPolys; i++)
			{
				PxHullPolygon data;
				mesh->getPolygonData(i, data);

				const PxU32 nbTris = data.mNbVerts - 2;
				const PxU8 vref0 = polygons[data.mIndexBase + 0];
				for (PxU32 j = 0; j < nbTris; j++)
				{
					const PxU32 vref1 = polygons[data.mIndexBase + 0 + j + 1];
					const PxU32 vref2 = polygons[data.mIndexBase + 0 + j + 2];
					if (numTotalTriangles < MAX_NUM_CONVEXMESH_TRIANGLES)
					{
						gConvexMeshTriIndices[3 * numTotalTriangles + 0] = vref0;
						gConvexMeshTriIndices[3 * numTotalTriangles + 1] = vref1;
						gConvexMeshTriIndices[3 * numTotalTriangles + 2] = vref2;
						numTotalTriangles++;
					}
				}
			}

			if (numTotalTriangles < MAX_NUM_CONVEXMESH_TRIANGLES)
			{
				glEnableClientState(GL_VERTEX_ARRAY);
				glVertexPointer(3, GL_FLOAT, 0, verts);
				glDrawElements(GL_TRIANGLES, numTotalTriangles * 3, GL_UNSIGNED_INT, gConvexMeshTriIndices);
				glDisableClientState(GL_VERTEX_ARRAY);
			}
		}
	}
예제 #2
0
/** 
*	Perform any cleanup of physics engine resources. 
*	This is deferred because when closing down the game, you want to make sure you are not destroying a mesh after the physics SDK has been shut down.
*/
void DeferredPhysResourceCleanup()
{
#if WITH_PHYSX
	// Release all tri meshes and reset array
	for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillTriMesh.Num(); MeshIdx++)
	{
		PxTriangleMesh* PTriMesh = GPhysXPendingKillTriMesh[MeshIdx];
		check(PTriMesh);
		PTriMesh->release();
		GPhysXPendingKillTriMesh[MeshIdx] = NULL;
	}
	GPhysXPendingKillTriMesh.Reset();

	// Release all convex meshes and reset array
	for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillConvex.Num(); MeshIdx++)
	{
		PxConvexMesh* PConvexMesh = GPhysXPendingKillConvex[MeshIdx];
		check(PConvexMesh);
		PConvexMesh->release();
		GPhysXPendingKillConvex[MeshIdx] = NULL;
	}
	GPhysXPendingKillConvex.Reset();

	// Release all heightfields and reset array
	for(int32 HfIdx=0; HfIdx<GPhysXPendingKillHeightfield.Num(); HfIdx++)
	{
		PxHeightField* PHeightfield = GPhysXPendingKillHeightfield[HfIdx];
		check(PHeightfield);
		PHeightfield->release();
		GPhysXPendingKillHeightfield[HfIdx] = NULL;
	}
	GPhysXPendingKillHeightfield.Reset();

	// Release all materials and reset array
	for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillMaterial.Num(); MeshIdx++)
	{
		PxMaterial* PMaterial = GPhysXPendingKillMaterial[MeshIdx];
		check(PMaterial);
		PMaterial->release();
		GPhysXPendingKillMaterial[MeshIdx] = NULL;
	}
	GPhysXPendingKillMaterial.Reset();
#endif
}
예제 #3
0
// NB: ElemTM is assumed to have no scaling in it!
void FKConvexElem::DrawElemWire(FPrimitiveDrawInterface* PDI, const FTransform& ElemTM, const FVector& Scale3D, const FColor Color)
{
#if WITH_PHYSX

	FTransform LocalToWorld = ElemTM;
	LocalToWorld.SetScale3D(Scale3D);

	PxConvexMesh* Mesh = ConvexMesh;

	if(Mesh)
	{
		// Draw each triangle that makes up the convex hull
		PxU32 NbVerts = Mesh->getNbVertices();
		const PxVec3* Vertices = Mesh->getVertices();
		
		TArray<FVector> TransformedVerts;
		TransformedVerts.AddUninitialized(NbVerts);
		for(PxU32 i=0; i<NbVerts; i++)
		{
			TransformedVerts[i] = LocalToWorld.TransformPosition( P2UVector(Vertices[i]) );
		}
						
		const PxU8* PIndexBuffer = Mesh->getIndexBuffer();
		PxU32 NbPolygons = Mesh->getNbPolygons();

		for(PxU32 i=0;i<NbPolygons;i++)
		{
			PxHullPolygon Data;
			bool bStatus = Mesh->getPolygonData(i, Data);
			check(bStatus);

			const PxU8* PIndices = PIndexBuffer + Data.mIndexBase;
		
			for(PxU16 j=0;j<Data.mNbVerts;j++)
			{
				// Get the verts that make up this line.
				int32 I0 = PIndices[j];
				int32 I1 = PIndices[j+1];

				// Loop back last and first vertices
				if(j==Data.mNbVerts - 1)
				{
					I1 = PIndices[0];
				}

				PDI->DrawLine( TransformedVerts[I0], TransformedVerts[I1], Color, SDPG_World );
			}
		}
	}
	else
	{
		UE_LOG(LogPhysics, Log, TEXT("FKConvexElem::DrawElemWire : No ConvexMesh, so unable to draw."));
	}
#endif // WITH_PHYSX
}
예제 #4
0
Mesh* ConvexHull::newMesh(Array<Vector3> points, VertexDescriptor& descriptor,
		GraphicsSystem& graphicsSystem, PhysicsSystem& physicsSystem) {
	GraphicsAPI& graphicsAPI = graphicsSystem.getAPI();

	PxConvexMesh* pxMesh = compute(points, physicsSystem);

	FDUint vertexCount = pxMesh->getNbVertices();
	FDUint byteSize = vertexCount * descriptor.getVertexSize();
	FDUint polygonCount = pxMesh->getNbPolygons();

	GeometryAuthor author(descriptor, graphicsAPI.getDynamicAllocator());

	const PxU8* indices = pxMesh->getIndexBuffer();
	for (FDUint i = 0; i < polygonCount; i++) {
		PxHullPolygon polygon;
		FDbool success = pxMesh->getPolygonData(i, polygon);
		if (!success) {
			FD_THROW(GenericException("Failed to get polygon data.\n"));
		}

		FDUint firstIndex = 0;
		for (FDUint j = 0; j < polygon.mNbVerts; j++) {

			PxU8 cIndex = *(indices + polygon.mIndexBase + j);
			FDUint myIndex = author.newPoint(pxMesh->getVertices()[cIndex]);
			if (j == 0) {
				firstIndex = myIndex;
			}
		}

		for (FDUint j = 2; j < polygon.mNbVerts; j++) {
			FDUint i1 = firstIndex;
			FDUint i2 = firstIndex + j - 1;
			FDUint i3 = firstIndex + j;

			author.newTriangle(i1, i2, i3);
		}
	}

	author.postProcess();

	Mesh* mesh = graphicsSystem.getAPI().newMesh(author);
	return mesh;
}
예제 #5
0
/** 
*	Perform any cleanup of physics engine resources. 
*	This is deferred because when closing down the game, you want to make sure you are not destroying a mesh after the physics SDK has been shut down.
*/
void DeferredPhysResourceCleanup()
{
#if WITH_PHYSX

	// Release all tri meshes and reset array
	for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillTriMesh.Num(); MeshIdx++)
	{
		PxTriangleMesh* PTriMesh = GPhysXPendingKillTriMesh[MeshIdx];

		// Check this as it shouldn't be null, but then gate on it so we can
		// avoid a crash if we end up in this state in shipping
		check(PTriMesh);
		if(PTriMesh)
		{
			PTriMesh->release();

			if(GPhysXPendingKillTriMesh.IsValidIndex(MeshIdx))
			{
				GPhysXPendingKillTriMesh[MeshIdx] = NULL;
			}
			else
			{
				UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillTriMesh, another thread may have modified the array."), MeshIdx);
			}
		}
		else
		{
			UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxTriangleMesh in pending kill array, another thread may have modified the array."), MeshIdx);
		}
	}
	GPhysXPendingKillTriMesh.Reset();

	// Release all convex meshes and reset array
	for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillConvex.Num(); MeshIdx++)
	{
		PxConvexMesh* PConvexMesh = GPhysXPendingKillConvex[MeshIdx];

		// Check this as it shouldn't be null, but then gate on it so we can
		// avoid a crash if we end up in this state in shipping
		check(PConvexMesh);
		if(PConvexMesh)
		{
			PConvexMesh->release();

			if(GPhysXPendingKillConvex.IsValidIndex(MeshIdx))
			{
				GPhysXPendingKillConvex[MeshIdx] = NULL;
			}
			else
			{
				UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillConvex (%d), another thread may have modified the array."), MeshIdx);
			}
		}
		else
		{
			UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxConvexMesh in pending kill array (at %d), another thread may have modified the array."), MeshIdx);
		}
	}
	GPhysXPendingKillConvex.Reset();

	// Release all heightfields and reset array
	for(int32 HfIdx=0; HfIdx<GPhysXPendingKillHeightfield.Num(); HfIdx++)
	{
		PxHeightField* PHeightfield = GPhysXPendingKillHeightfield[HfIdx];

		// Check this as it shouldn't be null, but then gate on it so we can
		// avoid a crash if we end up in this state in shipping
		check(PHeightfield);
		if(PHeightfield)
		{
			PHeightfield->release();

			if(GPhysXPendingKillHeightfield.IsValidIndex(HfIdx))
			{
				GPhysXPendingKillHeightfield[HfIdx] = NULL;
			}
			else
			{
				UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillHeightfield (%d), another thread may have modified the array."), HfIdx);
			}
		}
		else
		{
			UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxHeightField in pending kill array (at %d), another thread may have modified the array."), HfIdx);
		}
	}
	GPhysXPendingKillHeightfield.Reset();

	// Release all materials and reset array
	for(int32 MeshIdx=0; MeshIdx<GPhysXPendingKillMaterial.Num(); MeshIdx++)
	{
		PxMaterial* PMaterial = GPhysXPendingKillMaterial[MeshIdx];

		// Check this as it shouldn't be null, but then gate on it so we can
		// avoid a crash if we end up in this state in shipping
		check(PMaterial);
		if(PMaterial)
		{
			PMaterial->release();
			if(GPhysXPendingKillMaterial.IsValidIndex(MeshIdx))
			{
				GPhysXPendingKillMaterial[MeshIdx] = NULL;
			}
			else
			{
				UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found invalid index into GPhysXPendingKillMaterial(%d), another thread may have modified the array."), MeshIdx);
			}
		}
		else
		{
			UE_LOG(LogPhysics, Warning, TEXT("DeferredPhysResourceCleanup found null PxMaterial in pending kill array (at %d), another thread may have modified the array."), MeshIdx);
		}
	}
	GPhysXPendingKillMaterial.Reset();
#endif
}