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