PhysX 3.3 Creating PxShape error

Hi, I’m new in PhysX and I’m trying to create static rigidbody with triangle mesh geometry. And on the line:

PxShape* shape = actor->createShape(PxTriangleMeshGeometry(Mesh),*material);

It crash in PxRigidActor on this line:

return createShape(geometry, &materialPtr, 1, shapeFlags);

with:
Unhandled exception at 0x00DD436C in Infinity-Engine.exe: 0xC0000005: Access violation reading location 0x00000000.

This is part of my code:

PxMaterial * material	= gPhysicsSDK->createMaterial(0.5f,0.5f,0.1f);
PxTransform planePos	= PxTransform(PxVec3(Position.m128_f32[0],Position.m128_f32[1],Position.m128_f32[2]),PxQuat(PxHalfPi, PxVec3(Rotation.x, Rotation.y, Rotation.z)));
PxRigidStatic* actor = gPhysicsSDK->createRigidStatic(planePos);
	PX_ASSERT( actor );
	PxMeshScale meshScale = PxMeshScale(*new PxVec3(PxReal(1)), PxQuat(PxIdentity));

	PxTriangleMesh *Mesh = NULL;

	Mesh = GetTriangleMesh(Verticles,Indices,IndicesCount);
	PX_ASSERT( Mesh );

	<b>PxShape* shape = actor->createShape(PxTriangleMeshGeometry(Mesh),*material);</b> //Here it all crash
		PX_ASSERT( shape );

Here is method GetTriangleMesh:

PxTriangleMesh* PhysX::GetTriangleMesh(vector<Vertex> Verticles,vector<int> Indices,int IndicesCount)
{
PxTriangleMeshDesc meshDesc;
	meshDesc.points.count           = Verticles.capacity();
meshDesc.points.stride          = sizeof(PxVec3);
meshDesc.points.data            = ConvertFromVectorToPxVec(Verticles);

meshDesc.triangles.count        = IndicesCount;
meshDesc.triangles.stride       = 3*sizeof(int);
meshDesc.triangles.data         = &Indices[0];

PxToolkit::PxDefaultMemoryOutputStream writeBuffer;
bool status = mCooking->cookTriangleMesh(meshDesc, writeBuffer);
if(!status)
    return NULL;

PxToolkit::PxDefaultMemoryInputData readBuffer(writeBuffer.getData(), writeBuffer.getSize());
PxTriangleMesh * c = gPhysicsSDK->createTriangleMesh(readBuffer);

return c;}

And I have included this:

#include "PxPhysicsAPI.h"
#include "PxToolkit.h"

#ifdef _DEBUG //If in 'Debug' load libraries for debug mode 
#pragma comment(lib, "PhysX3DEBUG_x86.lib")				//Always be needed  
#pragma comment(lib, "PhysX3CommonDEBUG_x86.lib")		//Always be needed
#pragma comment(lib, "PhysX3ExtensionsDEBUG.lib")		//PhysX extended library 
#pragma comment(lib, "PhysXVisualDebuggerSDKDEBUG.lib") //For PVD only 
#pragma comment(lib, "PhysX3CookingDEBUG_x86.lib")		//For Cooking

#else //Else load libraries for 'Release' mode
#pragma comment(lib, "PhysX3_x86.lib")	
#pragma comment(lib, "PhysX3Common_x86.lib") 
#pragma comment(lib, "PhysX3Extensions.lib")
#pragma comment(lib, "PhysXVisualDebuggerSDK.lib")
#pragma comment(lib, "PhysX3Cooking_x86.lib")	
#endif

Please help. I’m trying to get this work for all this holidays and I realy don’t know why. I think I did some terrible mistache.

Thanks all of you.

Problem with mesh, when use PxTriangleMeshGeometry() instead of PxTriangleMeshGeometry(Mesh), program try take access to memory which is not or dont have access and in result you got error Unhandled exception at 0x00DD436C… etc.

Ok, but I have some values in Mesh variable. In fact, method GetTriangleMesh looks working.

Try in header

extern PxTriangleMesh* Mesh;

next where you “part of my code”, outside any function

PxTriangleMesh *Mesh;

and in function or something else

Mesh = GetTriangleMesh(Verticles,Indices,IndicesCount);

Sorry for misunderstanding, but that “part of my code” is part of function

void PhysX::AddStaticObject(XMVECTOR Position, XMFLOAT3 Rotation,vector<Vertex> Verticles,vector<int> Indices,int IndicesCount )
{

“outside any function”

Ok, ok. I tried it. But no change.

Check your PxTriangleMeshGeometry by .isValid() function.
And what it returns ?

I think the problem might be in the material, because when I stepped it into PhysX header files, the material has some pointer to address 0x00000000.

It return true;

This material?

PxMaterial * material = gPhysicsSDK->createMaterial(0.5f,0.5f,0.1f);

No, its fine.

Can you check PxTriangleMeshGeometry ?

Yeah, I thought so too. But the address on the material in UserData is realy suspected.

Hi,

please use the Debugger of your IDE for testing the values, simply set a breakpoint on the first line
of your method to step thru each line.

Do you forget to call PxInitExtensions(*mSDK) ??
or PxCreateCooking(PX_PHYSICS_VERSION,*getFoundation(),PxCookingParams(toleranceScale)) ?

But I guess your meshDesc is wrong -
Here is how I cook my trianglemesh:

You need to change “data” to your type.

PxTriangleMeshDesc meshDesc;

	meshDesc.points.count            = data.mVertexCount;
	meshDesc.points.stride           = sizeof(Vector3); 
	meshDesc.points.data	         = data.mVertices; //THIS IS A POINTER - of Vector3

	meshDesc.triangles.stride        = 3*sizeof(int);
	meshDesc.triangles.data          = data.mIndices;  //THIS IS A POINTER - of unsigned long    
	meshDesc.triangles.count         = data.mIndexCount / 3;

You see, you should use .data as a pointer to your data - not a single value.
[What ever ConvertFromVectorToPxVec does…]

And I hope you call everything in the right order - or use them on the heap instead on the stack,
(I hope you know the difference)

This line is also interesting:
PxMeshScale meshScale = PxMeshScale(*new PxVec3(PxReal(1)), PxQuat(PxIdentity));
OMG. You have a memory leak here!

Please change it to :
PxMeshScale meshScale = PxMeshScale(PxVec3(PxReal(1)), PxQuat(PxIdentity));

Please read again about pointers and how to delete them, or use boost for smart pointer or what ever, but you should read about them again.

Other thing:
PxTriangleMesh *Mesh = NULL;
Mesh = …;
You could write it in the same line.

And if you are using C11 [comes with Visual Studio 13 or some gcc version etc] you should
set pointer to “nullptr” if they are invalid.

Ok. So you have right. I forget to call PxInitExtensions. So I completly rewrite Initialization and nothing changed.

I don’t know what do you think what is wrong on meshDesc. I think the pointers are right.

This is ConvertFromVectorToPxVec

PxVec3* PhysX::ConvertFromVectorToPxVec(vector<Vertex> Verticles)
{
	const int VerticlesCount = Verticles.size();

	PxVec3 * convexVerts = new PxVec3[VerticlesCount] ;

for (int i = 0; i < Verticles.size(); i++) 
	{
		convexVerts[i].x = Verticles[i].Position.x;
		convexVerts[i].y = Verticles[i].Position.y;
		convexVerts[i].z = Verticles[i].Position.z;
	}

return convexVerts;
}

And yes, I know. My C++ skill isn’t very high. I’m 17 and I’m migrating from C# and Java to C++. And I have a lot of books waiting for their time.

Thanks

Hi,

good that you found the first error, but here are some “hidden” hints:

WRONG LINE meshDesc.triangles.count = IndicesCount;

I guess you didnt saw that I wrote:
meshDesc.triangles.count = data.mIndexCount / 3;

→ It seems you are using your IndicesCount as triangles.count - but its wrong.
You always have to divide by 3 of your IndicesCount, the reason is that a triangle have 3 vertices.

NOT WRONG BUT NOT NECESSARY meshDesc.triangles.data = &Indices[0];
Here another hit: → “Better way:” meshDesc.triangles.data = Indices;
You dont need to dereference (Indecies[0]) and then get the memoryadress (&Indecies) of that pointer,
just pass the pointer to meshDesc.triangles.data - its already the pointer.
(Its “almost” the same, but its maybe faster to compile and in runtime - depended on your compiler)

Its nice to see that other “freaky people” :D is also learning how to code in their “early” years,
I began with 14 with C++ - now I am 24 and studying IT in Germany,
(Assembler, some C#, some C, some C++, sadly most of it is in Java) but I have 10 years experience with C++ (and had done some own gaming projects…) :)
Of course, I have Java and some C# experience too.

You should really learn about the pointers - its the most important part
(of course OO, templates … too) in C++.

And dont forget to delete them all :D

Oh and dont forget to learn how to use the Debugger of your IDE, its absolutly important to know how it works - for bug hunting like this …

Hi,
I changed that line with IndicesCount, but that change nothing.

But interesting is pointer to Indicies. When I change it like you said, isValid() function on PxTriangleMeshGeometry return false.

And don’t worry. I’m using debugger. But this PhysX variables return only address in memory and message about missing debuging symbols for PhysX3CHECKED_x86.dll

I found one thing. With some reason this line

PxRigidStatic* actor = gPhysicsSDK->createRigidStatic(planePos);

return address 0x00000000.

I’m Czech and here is little harder to work on myself. Here is punished activity. I’m lucky, because I have active father and he helped me on the begining. So I have lot of references to my age.

Hi,

oh okay, I dont know what you get with IndicesCount - I guessed it was the count of it.
[I get also the Indices, and I have to divide them by 3 to get the trianglecount - maybe its depended on your 3D renderer engine which returns the correct triangle count (and the variablename is inconvienent).]

Hm, when you get a null pointer of this method, maybe the planePos is invalid.
Maybe its the rotation which is invalid.
Just remove the rotation of it and test if it works.

It seems to me its really the rotation quaternion - its depended on the rotation vector which you passed, if that PxQuat is invalid, the actor cant be created.

I guess you are using the Euler rotation system - (you have x,y,z values for rotation).
You should google how to convert them to a quaternion system. (x,y,z,w values for rotation)
[You have in your code a fixed .x part, which is incorrect—(PxHalfPi)]

This is how I convert Euler rotations to a Quaternion rotation system.
I dont use it anymore, its only a code leftup … But I think it works correctly :)
[Google for gimbal lock if you have some weird rotation at some point…]

PxQuat toPxQuat(Vector3 angles) //angles are in degree
{
	angles *= Math::fDeg2Rad*0.5f; // *fDeg2Rad only needed if angles are in degree [PI/180]
      //angles *= PI / 360 is also possible if you dont want a constant [delete line over this];
	PxReal cos_x = cosf(angles.x);
	PxReal cos_y = cosf(angles.y);
	PxReal cos_z = cosf(angles.z);

	PxReal sin_x = sinf(angles.x);
	PxReal sin_y = sinf(angles.y);
	PxReal sin_z = sinf(angles.z);

	PxQuat quad = PxQuat();

	quad.w = cos_x*cos_y*cos_z + sin_x*sin_y*sin_z;
	quad.x = sin_x*cos_y*cos_z - cos_x*sin_y*sin_z;
	quad.y = cos_x*sin_y*cos_z + sin_x*cos_y*sin_z;
	quad.z = cos_x*cos_y*sin_z - sin_x*sin_y*cos_z;

	return quad;
}

[UPDATE: Modified for easy usage]
Just replace Vector3 to your “own” Vector3 and test if it works correctly.

Cool, I´ve learn all by my own, and didnt have any sources how could help me but books.
Of course, now I´m studing, but it doesent help me anymore - I already know almost everything of it :D

Really thanks. It works now. Problem was in rotation, just like you said. I change angle from halfPi to 0 and now it works.
It was really bad mistake.
Thanks for your time.

Schools aren’t for informations, but for contacts. I had one workshop I remember. It was windows 8 Hands On Lab. That was the day I finally move all nonwindows work to linux.

So Happy New Year

Hi,

you are welcome.
Just use the snippet for rotation convertion to PxQuat if needed.
[0 works only if the rotation values are correct, with the snippet it should alwas return valid values]

:D Nice one

Happy New Year!