I am trying to create a cylinder PxConvexMesh from 64 vertices (32 side faces and 2 faces top/bottom) “from hand” meaning the PxConvexMeshDesc.flags is 0. I’m providing vertices, polygons and indices to the cooking.
Somewhere in validateConvexMesh it checks for vertex-polygon plane distance (which must be near zero) which fails (“Gu::ConvexMesh::checkHullPolygons: Some hull vertices seems to be too far from hull planes” is printed). It looks like it checks every vertex against every polygon. But why? Shouldn’t only the vertices which belong to the polygon lie on it’s plane?
Anyhow, I think I am misunderstanding something, here’s the pretty simple code which just creates the cylinder geometry and passes it to the cooking
(The cylinders “height axis” is aligned with the x axis, so the “circle” of it is on the y-z plane.
const int VertexCount = 64;
PxVec3 verts[VertexCount];
const int PolyCount = 34; // 32 circle points + lids
PxHullPolygon polys[PolyCount];
const int IndexCount = 192; // 4 verts * 32 faces + 32 verts * 2 faces (lids)
uint32_t indices[IndexCount];
const int NumCirclePoints = 32;
const float xLeft = wheelWidth / 2; // x coord of left lid
const float xRight = -xLeft; // x coord of right lid
float angle = 0;
for (int i = 0; i < NumCirclePoints; ++i)
{
float z = cos(angle) * wheelRadius;
float y = sin(angle) * wheelRadius;
PxVec3 normal{ 0, sin(angle + Float::Pi / NumCirclePoints), cos(angle + Float::Pi / NumCirclePoints) };
polys[i].mPlane[0] = normal.x;
polys[i].mPlane[1] = normal.y;
polys[i].mPlane[2] = normal.z;
polys[i].mPlane[3] = normal.y * y + normal.z * z;
polys[i].mNbVerts = 4;
polys[i].mIndexBase = i * 4;
verts[i * 2].x = xLeft;
verts[i * 2].y = y;
verts[i * 2].z = z;
verts[i * 2 + 1].x = xRight;
verts[i * 2 + 1].y = y;
verts[i * 2 + 1].z = z;
uint32_t index = i * 2;
indices[i * 4] = index;
indices[i * 4 + 1] = index + 1;
indices[i * 4 + 2] = (index + 3) % (NumCirclePoints * 2);
indices[i * 4 + 3] = (index + 2) % (NumCirclePoints * 2);
angle += 2 * Float::Pi / NumCirclePoints;
}
//left lid
for (int i = 0; i < NumCirclePoints; ++i)
indices[NumCirclePoints * 4 + i] = i * 2;
//right lid
for (int i = 0; i < NumCirclePoints; ++i)
// indices in reverse order so that the winding order matches the other polys
indices[NumCirclePoints * 5 + i] = (NumCirclePoints - i - 1) * 2 + 1;
polys[NumCirclePoints].mPlane[0] = 1;
polys[NumCirclePoints].mPlane[1] = 0;
polys[NumCirclePoints].mPlane[2] = 0;
polys[NumCirclePoints].mPlane[3] = xLeft;
polys[NumCirclePoints].mNbVerts = 32;
polys[NumCirclePoints].mIndexBase = IndexCount - 2 * NumCirclePoints;
polys[NumCirclePoints + 1].mPlane[0] = -1;
polys[NumCirclePoints + 1].mPlane[1] = 0;
polys[NumCirclePoints + 1].mPlane[2] = 0;
polys[NumCirclePoints + 1].mPlane[3] = -xRight;
polys[NumCirclePoints + 1].mNbVerts = 32;
polys[NumCirclePoints + 1].mIndexBase = IndexCount - NumCirclePoints;
PxConvexMeshDesc convexMeshDesc;
convexMeshDesc.points.count = VertexCount;
convexMeshDesc.points.data = verts;
convexMeshDesc.points.stride = sizeof(PxVec3);
convexMeshDesc.polygons.count = PolyCount;
convexMeshDesc.polygons.data = polys;
convexMeshDesc.polygons.stride = sizeof(PxHullPolygon);
convexMeshDesc.indices.count = IndexCount;
convexMeshDesc.indices.data = indices;
convexMeshDesc.indices.stride = sizeof(uint32_t);
bool res = physics->cooking->validateConvexMesh(convexMeshDesc); // false