PhysX 3.2.2 crashes in PxCreateCooking when loading user defined convex mesh.

After initializing PhysX to include the cooking library. Whenever I tried to invoke PxCooking::cookConvexMesh with a convex hull, it crashes. Stack trace leads from the delay load hook to the PxCreateCooking. Note the PxConvexMeshDesc is setup without the eCOMPUTE_CONVEX flags. Allowing PhysX to do the actually cooking works fine. However, there is another issue whenever PxConvexMeshDesc flag e16_BIT_INDICES is set, cooking fails.

Hi,

We’ll need a repro, I’m afraid.
Thanks,
Mike

Pardon me in advance for possibly violation forum rule pertaining to code snippets…

PhysicsObjectId PxPhysicsImpl::createConvexMeshRep( const PhysicsConvexMeshParams& convexMeshParams, const PhysicsMaterialParams& material, const PXform& xform, bool createActive )
{
assert( physicsRep_ != 0 );
assert( physicsRep_->physxPhysicsPtr != 0 );
assert( physicsRep_->physxCookingPtr != 0 );

PhysicsObjectId objectId = INVALID_PHYSICS_OBJECT_ID;

PxMaterialPtr pxMaterial = physicsRep_->physxPhysicsPtr->createMaterial( material.staticFrictionCoefficient,
		                                                                 material.dynamicFrictionCoefficient,
																         material.restitutionCoefficient
																       );

assert( pxMaterial != 0 );

physx::PxQuat rotation( xform.rotation.x, xform.rotation.y, xform.rotation.z, xform.rotation.w );

physx::PxTransform identity = physx::PxTransform::createIdentity();;
physx::PxTransform pxXform = physx::PxTransform::createIdentity();
pxXform.p = physx::PxVec3( static_cast<float32>( xform.position.x ), static_cast<float32>( xform.position.y ), static_cast<float32>( xform.position.z ) );
pxXform.q = rotation;

PxRigidActorPtr actor			= 0;
PxRigidDynamicPtr dynamicActor  = 0;
PxRigidStaticPtr staticActor	= 0;

if( convexMeshParams.flags & PHYSICS_PARAM_FLAG_STATIC )
{
	staticActor = physicsRep_->physxPhysicsPtr->createRigidStatic( pxXform);
	actor = staticActor;
	assert( actor != 0 );
}
else
{
	dynamicActor =  physicsRep_->physxPhysicsPtr->createRigidDynamic( pxXform );
	actor = dynamicActor;

	assert( actor != 0 );

	//check our kinematic flag
	if( convexMeshParams.flags & PHYSICS_PARAM_FLAG_KINEMATIC )
		dynamicActor->setRigidDynamicFlag( physx::PxRigidDynamicFlag::eKINEMATIC, true );
	else
		dynamicActor->setRigidDynamicFlag( physx::PxRigidDynamicFlag::eKINEMATIC, false );

}

if( actor )
{
	std::vector< physx::PxVec3 > vertices( convexMeshParams.numVertices );
	std::vector< physx::PxU32 > indices( convexMeshParams.numIndices );

	for( uint32 i = 0; i < convexMeshParams.numIndices; i+=3 )
	{
		indices[i]		= static_cast<uint32>( convexMeshParams.indices[i] );
		indices[i+1]	= static_cast<uint32>( convexMeshParams.indices[i+1] );
		indices[i+2]	= static_cast<uint32>( convexMeshParams.indices[i+2] );
	}

	physx::PxConvexMeshDesc convexMeshDesc;

	convexMeshDesc.points.data		= convexMeshParams.vertices;
	convexMeshDesc.points.count		= convexMeshParams.numVertices;
	convexMeshDesc.points.stride	= convexMeshParams.vertexStride;
	
	convexMeshDesc.triangles.data	= &( indices[0 ] );//convexMeshParams.indices;
	convexMeshDesc.triangles.count	= convexMeshParams.numIndices;
	convexMeshDesc.triangles.stride	= 3 * sizeof( physx::PxU32 );//convexMeshParams.indexStride;

	//using 16-bit indices..this seems to cause issues..why ???
	//convexMeshDesc.flags = physx::PxConvexFlag::e16_BIT_INDICES;

	if( !convexMeshParams.isConvex )
	{
		convexMeshDesc.flags|= physx::PxConvexFlag::eCOMPUTE_CONVEX;
	}

	uint32 bufferSize = 1024 * 1024;
	std::vector<uint8> tempBuffer( bufferSize );

	PhysxMemoryOutputStream outBuffer( &( tempBuffer[0] ), tempBuffer.size() );

	if( !physicsRep_->physxCookingPtr->cookConvexMesh( convexMeshDesc, outBuffer ) )
	{
		assert( false );
	}

	PhysxMemoryInputStream inputBuffer( outBuffer.getBuffer(), outBuffer.getBufferSize() );

	PxConvexMeshPtr pxConvexMesh = physicsRep_->physxPhysicsPtr->createConvexMesh( inputBuffer );

	assert( pxConvexMesh != 0 );

}

If convexMeshParams.isConvex is true, then the crash occur as indicated in the first post.

Hi,

you can use the “[code” “[/code” (with ] at the end ) tags for your code.
I´m converting your code to test it - but you are using classes which I dont have and thus
we ( and I ) dont know what happend in the background with your variables.
Example:

convexMeshDesc.triangles.count = convexMeshParams.numIndices; // <- IndicesNum / 3 should be here
convexMeshDesc.triangles.data = &( indices[0 ] ); 
// - you know that .data needs a void pointer -> I didnt use a vector for it - I used directly a pointer in my code.

We dont know how you get the information about your meshparams - maybe there is a litte issue.
One other thing:

—> Nice. When I use the code tags it shows the code above. I cant create code tags here :( BUUUG!

convexMeshDesc.triangles.stride = 3 * sizeof( physx::PxU32 );//convexMeshParams.indexStride;
//using 16-bit indices…this seems to cause issues…why ???
//convexMeshDesc.flags = physx::PxConvexFlag::e16_BIT_INDICES;

Maybe you should use PxU16 when you raise the e16_BIT_INDICES flag.

But I didnt test it yet.

Which renderer are you using? I´m using Ogre as my renderer and everything works here.
( Because I feed my cooker with the information of the mesh which I´m going to cook)

Hi.
So I´ve changed almost anything in your code and it works fine. Everything works here.
But my code wont help you because its specific.

You should debug your whole code and look at the variables step by step - to see what happens.
Maybe it helps when you using for your .points.data a PxVec3*
and for your .points.stride sizeof(PxVec3).

You also should know that convex is limited to have 256 polygons.

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

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

This is the way I fill the convexMeshDesc with data.

CMemoryOutputStream buf;
physic->getCooking()->cookConvexMesh(convexMeshDesc, buf);
pxConvexMesh = physic->getSDK()->createConvexMesh(((PxInputStream)&CMemoryInputData(buf.getData(),buf.getSize())));
shape = actor->createShape(PxConvexMeshGeometry(pxConvexMesh),*_material);

->>> HM AGAIN THIS BUG IN THE FORUM: You cant create 2 codeblocks - it generates it wrong. ( and displays everytime the first codeblock…)
-> @ Nvidia: -> Solution: rename your code - tags with a number to indentificate which codeblock is used

I dont know how you create a PxShape of it, but here is the way I did it.
You really need to debug it - to see what data is in your variables.

If I raise the PxConvexFlag::e16_BIT_INDICES flag, it dont create the PxShape and warnings will printed.
Due to the fact that my mIndices is a long* pointer.

So everything works as expectet.

Thanks for the looking into this ScreenOfDeath. I’ve been through the code via the debugger, step by step and line by line. I commented out the 16-bit indices flag, because it would not work. At the time the indices coming in were 16-bit, since only 32-bit indices worked, I convert them in that function. As for renderer, I’m using my custom renderer ( GL + DX9 ). The convex mesh being used has < 256 and was generated with HACD ( very awesome convex decomposition tool ). When stepping through the code in the debugger, the crash happens deep within PhysX.

Hi,

Hm. Maybe there are some vertex or indices generated wrong by HACD ( I didnt know it ).
Could you use a primitive shape like an cube? - directly exported by e.g. Blender.
Did you get an error message or an exception?

// I´ve saw your setup (platforms) in the other thread.
Which libs are you linking against?
The DEBUG libs contains more checks and displays more error messages than CHECKED.

But I guess it doesn´t matter - I guess the meshData is corrupt.
So it crashs while PhysX is trying to cook it. ( You probalby feed the PxConvexMeshDesc wrong )

Any attempt to load any mesh without having the SDK do the cooking causes a crash. I tried with something a simple as a cube and that did not work. What troubling is that the SDK documentation should cover most use cases, but there is no example of using a predefined convex mesh. If anyone has a convex mesh that works I’m more than willing to give it a try. Also, just realized that I’m using the CHECKED version for by debug build instead of the DEBUG versions…will fix that and retry.

Hi
I guess that I understand you wrong with
“Any attempt to load any mesh without having the SDK do the cooking causes a crash.”
-> You are trying to cook a mesh without having the SDK initalized? NOOO That cant be.

Cant you create a simple cube in your renderer and feed it to your convex method?
If you dont have an option like that (or you dont want to code it) I could
create a primitive like a cube, and “non cube shape” in Blender and export it.
Which format can you import in your app?
(Maybe one of these: .obj (wavefront) .collada .mesh (Ogre3D) .x(Microsoft DirectX))

Of course, when you are using OpenGL you could take a look at the examples.

Its easy to create a cube in Blender - (and it is the default mesh in Blender) so you
can export it directly without any need of learning Blender.

But, as I said above, I could export you a primitive shape for testing.

…the Cooking SDK does get initialized ( it would crash for the other case, no convex mesh input )…
The SDK allow usage of an already created convex mesh, as long as the physx::PxConvexFlag::eCOMPUTE_CONVEX flag is not set. The only limitation is that the mesh has <= 256 vertices and triangles. I’m able to load Wavefront files.

Hi.

Uh. So probably we found the solution: You feed the PxConvexMesh with wrong data -
or your PhysxMemoryOutputStream / PhysxMemoryIntputStream wont work correctly.

You could check the bool from convexMeshDesc.isValid(); to show whether you feed the data right or wrong.

If your cooking “works” the cooker->cookConvexMesh(…) returns also a bool.

I “hope” it crashs at sdk->createConvexMesh(…) and the other bools are all true, so there will be the
error ( out/in -putStream wont work correctly )

Here is an cube: http://www.file-upload.net/download-7537720/cube.obj.html ( < 1kb size )
Here is a “non cubed shape”: http://www.file-upload.net/download-7537713/weirdShape.obj.html (< 3 kb Size)

(Tags which you use multiple, generats multiple … BUG)

convexMeshDesc.isValid() return true for the test case.
PhysxMemoryOutputStream / PhysxMemoryIntputStream are the same streams used for the non-convex input case and those seems to work fine. Another thing I noticed after linking to the debug libraries is that it seems to be still using the CHECKED dlls. Makes me wonder if the libraries were built incorrectly…

Hi.
Hm. I answered your other post about the checked dlls. It seems to me that this is desired.

—> So I guess with your last statement we found the problem:
Your mesh data is in a wrong format. Just show us how you get the data for the convexMeshDesc.
I really think (since your said the memoryStream works fine for other cooking things) that
there is the problem. If you dont want to show us the code, we continue to grope in the dark.

Triple checking the code, I found out that the params being passed to the convex mesh descriptor was not valid ( you mentioned this earlier, but I think I needa a break after pouring over the code for a week…lol), specifically the triangle count. I was assuming that num indices was equivalent to num triangles. This was the cause of the crash. Issue has now been resolved. Thanks.

Very good news!