3.3.0 Cooking TriangleMesh

First off I’d like to state that the PhysX documentation is severely lacking any explanation on how to cook meshes, actually, it’s lacking in everything.

Ok so now my problem… I’ve tried alot of ways of filling the TriangleMeshDesc but IsValid is always false, looking into source it is like this due to the MaterialIndices not being filled (NULL) , so it seems it’s a required field to fill, But as I said… Due to lack of any documentation, What am I supposed to put in there?

In the case that it’s not required, which seems more likely when looking at PxToolkit and other rare cases I managed to find mesh cooking code on google, I can’t figure out why PxCooking->CookTriangleMesh() always returns false as I can’t look into the source to see what checks it does.

I use DirectX 9.0 and DirectX meshes (.x file)

Here’s my code:

bool PhysXEngine::BakeMesh(LPD3DXMESH mesh)
{
	PxTriangleMeshDesc* description=new PxTriangleMeshDesc();
	
	description->setToDefault();
	description->points.count= mesh->GetNumVertices();
	description->triangles.count=mesh->GetNumFaces()*3;

	PxVec3* vertices = new PxVec3[mesh->GetNumVertices()];
	PxU32* indices = new PxU32[mesh->GetNumFaces()*3];

	BYTE* vPtr = NULL;
	DWORD numVerts=mesh->GetNumVertices();
	DWORD fvf=mesh->GetFVF();
	DWORD vertSize=D3DXGetFVFVertexSize(fvf);
	mesh->LockVertexBuffer(0,(LPVOID*)&vPtr);

	for (DWORD i=0;i<numVerts;i++) 
	{
		D3DXVECTOR3 *ptr=(D3DXVECTOR3 *) vPtr;
		vertices[i] =PxVec3(ptr->x,ptr->y,ptr->z);
		vPtr+=vertSize;
	}
	mesh->UnlockVertexBuffer();

	description->points.count = mesh->GetNumVertices();
	description->points.stride = sizeof(PxVec3);
	description->points.data = vertices;
	
	LPDIRECT3DINDEXBUFFER9 pIndBuf;
	mesh->GetIndexBuffer(&pIndBuf);

	void* pInd = NULL;
	DWORD numFaces=mesh->GetNumFaces();
	pIndBuf->Lock(0,numFaces*3*sizeof(WORD),(void**) &pInd,D3DLOCK_DISCARD);
	DWORD* iptr=(DWORD*) pInd;
	for (int i=0;i<numFaces;i++)
	{
		for (int j=0;j<3;j++) 
		{
			indices[i] =iptr[i*3+j];
		}
	}
	pIndBuf->Unlock();
	pIndBuf->Release();

	description->triangles.data = indices;
	description->triangles.count = mesh->GetNumFaces()*3;
	description->triangles.stride = sizeof(PxU32);

	PxDefaultMemoryOutputStream stream;
	if(cooking->cookTriangleMesh(*description,stream))
	{
		std::cout << "Mesh has been baked successfully" << std::endl;
	}
	else
	{
		std::cout << "Mesh failed baking." << std::endl;
		return false;
	}

//code never comes here due to cookTriangleMesh always failing

//code handling the final cooked mesh

for the sake of other googles

I fixed it…

HOW TO BAKE COLLISION MESH FROM TRIANGLEMESH

Heres the final code:

bool PhysXEngine::BakeMesh(LPD3DXMESH mesh,PxVec3 scale)
{
	PxTriangleMeshDesc* description=new PxTriangleMeshDesc();
	
	description->setToDefault();
	description->points.count= mesh->GetNumVertices();
	description->triangles.count=mesh->GetNumFaces()*3;

	PxVec3* vertices = new PxVec3[mesh->GetNumVertices()];
	PxU32* indices = new PxU32[mesh->GetNumFaces()*3];

	BYTE* vPtr = NULL;
	DWORD numVerts=mesh->GetNumVertices();
	DWORD fvf=mesh->GetFVF();
	DWORD vertSize=D3DXGetFVFVertexSize(fvf);
	mesh->LockVertexBuffer(0,(LPVOID*)&vPtr);

	for (DWORD i=0;i<numVerts;i++) 
	{
		D3DXVECTOR3 *ptr=(D3DXVECTOR3 *) vPtr;
		vertices[i] =PxVec3(ptr->x*scale.x,ptr->y*scale.y,ptr->z*scale.z);
		vPtr+=vertSize;
	}
	mesh->UnlockVertexBuffer();

	description->points.count = mesh->GetNumVertices();
	description->points.stride = sizeof(PxVec3);
	description->points.data = vertices;
	
	LPDIRECT3DINDEXBUFFER9 pIndBuf;
	mesh->GetIndexBuffer(&pIndBuf);

	void* pInd = NULL;
	DWORD numFaces=mesh->GetNumFaces();
	pIndBuf->Lock(0,numFaces*3*sizeof(WORD),(void**) &pInd,D3DLOCK_READONLY);
	DWORD* iptr=(DWORD*) pInd;
	for (int i=0;i<numFaces;i++)
	{
		for (int j=0;j<3;j++) 
		{
			indices[i] =iptr[i*3+j];
		}
	}
	pIndBuf->Unlock();
	pIndBuf->Release();

	description->triangles.data = indices;
	description->triangles.count = mesh->GetNumFaces()*3;
	description->triangles.stride = 3*sizeof(PxU32);

	PxDefaultMemoryOutputStream stream;
	if(cooking->cookTriangleMesh(*description,stream))
	{
		std::cout << "Mesh has been baked successfully" << std::endl;
	}
	else
	{
		std::cout << "Mesh failed baking." << std::endl;
		return false;
	}

	
	PxTransform pose;
	pose.p = PxVec3(0,-20,0);
	pose.q= PxQuat(0,PxVec3(0,0,0));

	PxDefaultMemoryInputData istream(stream.getData(),stream.getSize());
	PxTriangleMesh *triangleMesh = gPhysicsSDK->createTriangleMesh(istream);

	PxRigidStatic* triangleMeshActor = gPhysicsSDK->createRigidStatic(pose);

	PxTriangleMeshGeometry geom = PxTriangleMeshGeometry(triangleMesh,PxMeshScale());

	PxShape *triangleMeshShape = triangleMeshActor->createShape(geom,*defaultMaterial,pose);

	gScene->addActor(*triangleMeshActor);
	statics.push_back(triangleMeshActor);
	return true;
}

Hello,I also faced this problem.I still don’t understand the solution by looking over your code.Can you recommend the solution? Thanks so much.

The samples included with the sdk show you how to do this stuff.

What is the exact problem you are having?