Ptoblems with cooking TriangleMesh from .x

Hi, I have some troubles with cooking TriangleMesh. I have 3Ds max 2014 and two plugins to convert model in .x.
When I cook TriangleMesh from my file I get break break geometry. I think this problem because FVF. I have another model from example and this model doesn’t have any troubles.
Left - 3ds Max 2014, Right - Visual Debugger.
External Media

Thanks.

Hi.
Could you export your geometry to a .3ds file and import it in Blender? After that you could export it to .x format and test it again.

Maybe is your .x exporter broken or optimize the mesh in a bad way.

There are also different .x formats avaiable. I guess some errors happend while you converting the mesh.

Or you are cooking the mesh wrong.

Yes! You was right, I used wrong function to create Triangle Mesh!

void Mesh::CreateTriMesh()
{

	typedef struct {
		D3DXVECTOR3 VertexPos;
		D3DXVECTOR3 Normal;
		D3DXVECTOR2 TexCoord;
	} Mesh_FVF;

	//Used to copy indices
	typedef struct {
		short IBNumber[3];
	} IndexBufferStruct;

	int NumVerticies = Model->GetNumVertices();
	int NumTriangles = Model->GetNumFaces();
	DWORD FVFSize = D3DXGetFVFVertexSize(Model->GetFVF());

	//Create pointer for vertices
	NxVec3* verts = new NxVec3[NumVerticies];

	char *DXMeshPtr;
	Model->LockVertexBuffer(D3DLOCK_READONLY, (void**)&DXMeshPtr);
	for(int i = 0; i < NumVerticies; i++)
	{
		Mesh_FVF *DXMeshFVF = (Mesh_FVF*)DXMeshPtr;
		verts[i] = NxVec3(DXMeshFVF->VertexPos.x, DXMeshFVF->VertexPos.y, DXMeshFVF->VertexPos.z);
		DXMeshPtr += FVFSize;
	}
	Model->UnlockVertexBuffer();

	//Create pointer for indices
	IndexBufferStruct *tris = new IndexBufferStruct[NumTriangles];

	IndexBufferStruct *DXMeshIBPtr;
	Model->LockIndexBuffer(D3DLOCK_READONLY, (void**)&DXMeshIBPtr);
	for(int NumInd = 0; NumInd < NumTriangles; NumInd++)
	{
		tris[NumInd].IBNumber[0] = DXMeshIBPtr[NumInd].IBNumber[0];
		tris[NumInd].IBNumber[1] = DXMeshIBPtr[NumInd].IBNumber[1];
		tris[NumInd].IBNumber[2] = DXMeshIBPtr[NumInd].IBNumber[2];
	}

	Model->UnlockIndexBuffer();

	// Build physical model
	NxTriangleMeshDesc TriMeshDesc;
	TriMeshDesc.numVertices = NumVerticies;
	TriMeshDesc.numTriangles = NumTriangles;
	TriMeshDesc.pointStrideBytes = sizeof(NxVec3);
	TriMeshDesc.triangleStrideBytes = 3*sizeof(NxU16);
	TriMeshDesc.points = verts;
	TriMeshDesc.triangles = tris;
	TriMeshDesc.flags = NX_MF_16_BIT_INDICES;

	NxTriangleMeshShapeDesc ShapeDesc;
	if(0)
	{
		// Cooking from file
		bool status = NxCookTriangleMesh(TriMeshDesc, UserStream("c:\tmp.bin", false));
		ShapeDesc.meshData = g_pPhysicsSDK->createTriangleMesh(UserStream("c:\tmp.bin", true));
	}
	else
	{
		// Cooking from memory
		MemoryWriteBuffer buf;
		bool status = NxCookTriangleMesh(TriMeshDesc, buf);
		ShapeDesc.meshData = g_pPhysicsSDK->createTriangleMesh(MemoryReadBuffer(buf.data));
	}

	NxActorDesc actorDesc;
	actorDesc.shapes.pushBack(&ShapeDesc);
	actorDesc.globalPose.t = NxVec3(0,0,0);
	Actor = g_pScene->createActor(actorDesc);
	Actor->userData = (void*)1;

	delete[] verts;
	delete[] tris;
}

Hi

Im not familiar with PhysX 2.x code - so I cant help you here.
You could remove the TriMeshDesc.flags = NX_MF_16_BIT_INDICES; line - maybe this is the problem.
(And change to TriMeshDesc.triangleStrideBytes = 3*sizeof(int);)

This flag wont work for int indices - (32bit) and I guess your model have int indices.
But I´m not sure about it. But I had a similiar issue. For optimizing reasons I´ve tested
it with the flag - and with a test level. But I forgot to change it back - with a larger mesh
and it wont cooked the mesh (well:)).

I dont know if you are receiving the right model information about
indices, vertex count - you should google for it.

Here is the way how I feed the meshDesc with information.
Maybe it help you. (PhysX 3.2.4 Code!)

    meshDesc.points.count     = data.mVertexCount;
meshDesc.points.stride    = sizeof(Vector3); 
meshDesc.points.data	  = data.mVertices;

meshDesc.triangles.stride        = 3*sizeof(int);
meshDesc.triangles.data          = data.mIndices;       
meshDesc.triangles.count         = data.mIndexCount / 3; 

Hm I dont like this piece of code:
int NumTriangles = Model->GetNumFaces();

Is it possible that you use quads instead of triangles?
And directx count it wrong here?
Is there maybe a function like GetNumIndices()?

I dont know the specs about the DirectX .x mesh format (there are different versions of it)
but maybe the .x mesh format save partially polygons instead of triangles.

Faces could also be quads or even polygons - so maybe the error is in this code (or in the mesh file).
(Triangle count != face count)?

The best way I think is to get the index count and divide it by 3.

The PhysX cooker want to cook triangles of the information - if they are wrong or incompleted, you
get strange results like yours.

Just looked at your picture again -
the cooked mesh seems to be horizontally mirrored.
The mesh information could maybe in the wrong order, too.
Its maybe only a small error here - I guess you have to swap XY values.
Of course, its possible that your optimized mesh have faces which have the wrong clock rotation.

Is it possible to count the triangle and indices of your cooked mesh?

Compare the values - when they are the same, we are a step further.