Creating a triangle mesh with 16 bit indices

Hi, I am trying to create a triangle mesh but I am having trouble. I am using Irrlicht for rendering, which uses 16 bit indices. The PhysX API says the triangle mesh descriptor can use 16 or 32 bit indices but when I pass the size of the 16 bit indices PhysX passes an error saying the mesh descriptor is invalid (if I pass the size of 32 bit indices it doesn’t give the error but it obviously doesn’t work). Here is my code for creating the trimesh:

PxTriangleMeshDesc desc;

desc.points.count = nbVerts;
desc.points.stride = sizeof(irr::video::S3DVertex);
desc.points.data = verts;

desc.triangles.count = triCount;
desc.triangles.stride = 3 * sizeof(irr::u16);
desc.triangles.data = indices;
	
PxDefaultMemoryOutputStream writeBuffer;
bool status = m_cooking->cookTriangleMesh(desc, writeBuffer);
if (!status)
    return;

PxDefaultMemoryInputData readBuffer(writeBuffer.getData(), writeBuffer.getSize());

PxTriangleMesh* triMesh = m_physics->createTriangleMesh(readBuffer);
PxRigidDynamic* triMeshActor = m_physics->createRigidDynamic(PxTransform(0, 0, 0));

PxShape* aTriMeshShape;
if (triMeshActor)
{
	triMeshActor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);

	PxTriangleMeshGeometry triGeom;
	triGeom.triangleMesh = triMesh;

	aTriMeshShape = triMeshActor->createShape(triGeom, *m_material);
	m_scene->addActor(*triMeshActor);
}

The S3DVertex structure contains:

S3DVertex { f32 x, f32 y, f32 z, f32 nx, f32 ny, f32 nz, SColor c, f32 tu, f32 tv }

Also, does PhysX know how to use the values in that structure to create the mesh? I pass a void pointer to the vertex array but I wonder how it knows which values to use in each vertex.

The layout description is quite simple. Imagine you have embedded your vertices in an array of structs so that you have an array with repeating layout as follows

int PxVec3 float int int float char[8] int PxVec3 float int int float char[8] int PxVec3 float int int float char[8] ......

In the above the start of your array is an int. Note that the vertex is stored 4 bytes after the start of the array. Also note that the next vertex is stored 24 bytes after the first vertex . If your array starts at address p then you have the following

desc.points.count = nbVerts;
desc.points.stride = sizeof(float) + sizeof(int) + sizeof(int) + sizeof(char)*8 + sizeof(int)
desc.points.data = p + sizeof(int);

In your example, the stride is sizeof(float)*3 + sizeof(SColor) + sizeof(f32)*2. The first vertex is the start of the array so you will have the following:

desc.points.count = nbVerts;
desc.points.stride = sizeof(float)*3 + sizeof(SColor) + sizeof(f32)*2;
desc.points.data = p;

For the indices follow the same rule for the stride. If you have an array that only contains triangle indices (a0 a1 a2 b0 b1 b2 c0 c1 c2 …) and you have 16-bit indices then the stride is 3sizeof(unsigned short). If you have 32-bit indices then the stride is 3sizeof(unsigned int).

It looks like you set the stride incorrectly for vertices and indices in the code you posted. Note that the stride of the indices depends on whether you use 16-bit or 32-bit indices.

Cheers,

Gordon