PhsyX Actor From X

Started by
10 comments, last by of_ownage 16 years, 2 months ago
hi, i have a problem. I have added some static objects to my scene with ageia and now i want to create a sphere and move it around. This is the code to add the static stuff: NxTriangleMeshDesc TriMeshDesc; TriMeshDesc.numVertices = NumVerticies; TriMeshDesc.numTriangles = NumTriangles; TriMeshDesc.pointStrideBytes = sizeof(NxVec3); TriMeshDesc.triangleStrideBytes = 3*sizeof(short); TriMeshDesc.points = &verts[0].x; TriMeshDesc.triangles = &tris[0]; TriMeshDesc.flags = NX_MF_16_BIT_INDICES; MemoryWriteBuffer buf; bool status = NxCookTriangleMesh(TriMeshDesc, buf); ShapeDesc.meshData = g_CAgeia->m_PhysicsSDK->createTriangleMesh(MemoryReadBuffer(buf.data)); i do not add a bodydesc and then create the actor. Now if i use the ageia code:: NxBodyDesc SphereBodyDesc; SphereBodyDesc.angularDamping = 0.5f; SphereBodyDesc.linearVelocity = NxVec3(0.0f, 0.0f, 0.0f); NxSphereShapeDesc SphereDesc; SphereDesc.radius = 1.0f; NxActorDesc SphereActorDesc; SphereActorDesc.shapes.pushBack(&SphereDesc); SphereActorDesc.body = &SphereBodyDesc SphereActorDesc.density = 10.0f; SphereActorDesc.globalPose.t = NxVec3(-70.0f, 32.0f, -190.0f); and create a sphere with a bodydesc so it can move it works perfect it collides with the scene. But if i want to create a NxActor from a ID3DXMesh* and move around with it i have no idea what to do. if i do it like in step1 and add a body desc it falls down but it never collides with anything it just falls invinite. So do i need another MeshDesc? I tryed NxConvexMeshDesc convexDesc; convexDesc.numVertices = NumVerticies; convexDesc.pointStrideBytes = sizeof(NxVec3); convexDesc.points = &verts[0].x; convexDesc.numTriangles = NumTriangles; convexDesc.triangles = &tris[0]; convexDesc.triangleStrideBytes = 3*sizeof(short); convexDesc.flags = NX_CF_COMPUTE_CONVEX | NX_CF_16_BIT_INDICES; but if i do this with:: NxInitCooking(); MemoryWriteBuffer buf2; bool status2 = NxCookConvexMesh(convexDesc, buf2); convexShapeDesc.meshData = g_CAgeia->m_PhysicsSDK->createConvexMesh(MemoryReadBuffer(buf2.data)); NxCookConvexMesh returns false and createConvexMesh fails. Any idea? thx
Advertisement
I'm assuming, since you had success with the static triangle meshes, that the data structure types that you are passing into NxConvexMeshDesc are correct. I would recommend doing the following:

convexDesc.points = verts;


instead of

convexDesc.points = &verts[0].x


Since the latter makes an assumption about the internal implementation of NxVec3, and you cannot be 100% certain that the implementation will be the same in the future, or that the member 'x' will always remain public. That's just a general coding comment. (Oh, and if you happen to be using pointers to DirectX data structures here instead of copying to Ageia data structures...it might work fine, but be aware that you are getting lucky in a way. No guarantee that DX and Ageia will always define their vectors in a way that you can cast between them like this, e.g., what if Ageia's vector class goes double precision even while keeping .xyz in the same order?)

So, I see two possible things that might be causing NxCookConvexMesh to fail.

First, you are using the flag NX_CF_COMPUTE_CONVEX and also passing in triangles via convexDesc.triangles and convexDesc.triangleStrideBytes. The flag
tells the API to generate triangles by using a convex hull algorithm on a point cloud. If you tell it to do this but you are already giving it triangles---suggesting that you want it to use your triangles, it may be failing because you are giving it conflicting instructions.

Second, it might be failing because your triangles don't make up a convex mesh...maybe it is in reality concave.

Here's what I'd try, in this order:

1) Remove the NX_CF_COMPUTE_CONVEX flag and see what happens. If no failure, go with that. Your own triangles are a good, convex mesh.

2) If (1) fails, add back the NX_CF_COMPUTE_CONVEX flag and assign ConvexDesc.triangles = 0 and ConvexDesc.triangleStrideBytes = 0. See what happens.

My guess, assuming all else is good, is that one of these things will fix it.

A third option would be to treat your movable object using NxCookTriangleMesh, as you did with the static objects, just adding a body also to make it dynamic. But I would not do this at all unless you really have a concave mesh and need it to collide as concave. This will be your most expensive option.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
1) am i right that i cannot create a actor
with a NxTriangleMeshDesc that performs dynamic collision detection?
If i create one with such a struct and a body struct it falls throught
everything and never collides with anything :S

2) no NX_CF_COMPUTE_CONVEX flag is still failure


3) now i set it like this::

NxConvexMeshDesc convexDesc;
convexDesc.numVertices = NumVerticies;
convexDesc.pointStrideBytes = sizeof(NxVec3);
convexDesc.points = verts;
convexDesc.numTriangles = 0; //NumTriangles;
convexDesc.triangles = 0; //&tris[0];
convexDesc.triangleStrideBytes = 0; //3*sizeof(short);
convexDesc.flags = NX_CF_COMPUTE_CONVEX |NX_CF_16_BIT_INDICES;

NxConvexShapeDesc convexShapeDesc;
convexShapeDesc.localPose.t = NxVec3(0,0,0);

NxInitCooking();

after this the NxCookConvexMesh still fails



4) if i use a TriangleMesh and assign a body NxCookTriangleMesh it does not
fail but the mesh never collides

5) i dont really get what you mean with convace and convex but i can send
you the file if you want ;)

thank you
Look in the SDK docs, under collisions, there is a matrix that shows what works and doesn't considering the type of mesh you setup with. IIRC forget the triangle mesh, it was almost useless to me for almost everything of than a static object, and it will not work with terrain mesh.

BTW you set to short? should be unsigned short, shouldn't matter since they should be both 16bit, but isn't correct.

TriMeshDesc.triangleStrideBytes = 3*sizeof(short);
of_ownage,

I would agree with MARS_999...actually, regardless of whether technically would work for you, if you can avoid them, I would. They are going to be more expensive than the standard collision shapes. General triangle meshes are worse than convex meshes. The standard collision shapes use highly optimized, shape-specific code and can be very fast.

Now...you said something in your PM to me that gave me another clue about what might be going wrong. You said that your shapes had around 600 triangles. That is a problem! Ageia supports convex meshes only up to 256 triangles! Look at the NxConvexMesh documentation. It clearly states this triangle/polygon limit.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
Quote:Original post by MARS_999
Look in the SDK docs, under collisions, there is a matrix that shows what works and doesn't considering the type of mesh you setup with. IIRC forget the triangle mesh, it was almost useless to me for almost everything of than a static object, and it will not work with terrain mesh.

BTW you set to short? should be unsigned short, shouldn't matter since they should be both 16bit, but isn't correct.

TriMeshDesc.triangleStrideBytes = 3*sizeof(short);



The size of a short is the same as the size of an unsigned short, so this line isn't a proble...though for clarity I personally would have made it sizeof(unsigned short).

The bigger issue is, of course, that of_ownage neds to make sure that the "tris" array is an array of unsigned shorts.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
Quote:Original post by grhodes_at_work
Quote:Original post by MARS_999
Look in the SDK docs, under collisions, there is a matrix that shows what works and doesn't considering the type of mesh you setup with. IIRC forget the triangle mesh, it was almost useless to me for almost everything of than a static object, and it will not work with terrain mesh.

BTW you set to short? should be unsigned short, shouldn't matter since they should be both 16bit, but isn't correct.

TriMeshDesc.triangleStrideBytes = 3*sizeof(short);



The size of a short is the same as the size of an unsigned short, so this line isn't a proble...though for clarity I personally would have made it sizeof(unsigned short).

The bigger issue is, of course, that of_ownage neds to make sure that the "tris" array is an array of unsigned shorts.


I agree as it's not an issue, like I stated before both are 2 bytes, but for obvious reasons its sloppy coding practices.

On the topic of 256 triangles I know that is in the SDK also, but not sure if that relfects 2.7.3 SDK, as I have a mesh with 2000k polygons and it works fine with it... I have more issues with the mesh being concave and not convex enough, then cooking it blows up.

If you're using concave meshes break up the mesh into chunks and try to make each one a NxConvexMeshDesc type.

MARS*, your 2000 polygon meshes are being cooked as convex? Interesting.

I'll also point to John Ratcliff's CreateDynamics source code, built to work with PhysX (and partly while he was employed by Ageia), which can do the convex decomposition for you, if you have a concave mesh to begin with. It is SLOW so more a preprocess than a runtime thing.

John Ratcliff's Source Code (Look for "CreateDynamics")
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
ok i use boxes now they work ok for me. But sometimes the behavior of them is really strange. Very small boxes stay above the ground while other fall onto it.
Maybe im confusing something with the creation of a Ageia Actor as far as
i know i need two things. the dimension and the world pos.

I have a ID3DXMesh* with a translate a rotate and a scale matrix
i have a local box with a min and a max point

so first i compute length/height/width of the new box which is::

D3DXVECTOR3 newStats;
newStats.x = box.maxPoint.x - box.centerPoint.x
newStats.y = box.maxPoint.y - box.centerPoint.y
newStats.z = box.maxPoint.z - box.centerPoint.z

now i have a vector with the half length half height half width and ageia
wants that.

Now since my mesh is scaled and rotated i need to do that with my local
box too so i do this:

D3DXMATRIX combined = rotate * scale;
D3DXVec3TransformCoord(&newStats, &newStats, &combined);

now i have a scaled rotated new local box and pash it to ageia
boxDesc.dimensions.set(NxVec3(newStats.x, newStats.y, newStats.z);

after this i set the actorDesc.globalPose.t to pos which is the position of
my ID3DXMesh* in worldSpace.

Is this correct or am i doing something wrong?
Quote:ok i use boxes now they work ok for me. But sometimes the behavior of them is really strange. Very small boxes stay above the ground while other fall onto it.


Not sure if you're already doing this but using the PhysX remote visual debugger is VERY helpful as it shows you exactly what your actors are doing. to use it just add this line to your program after you create your physX SDK instance:

gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost");


n.b. you can replace localhost with the IP address of another machine for remote debugging.

Then open the remote debugger tool at:

Start->All Programs->AGEIA PhysX SDK 2.7.3->Tools->Remote Debugger

It will run concurantly with your program and show you exactly what's going on in the PhysX simulation. This has gotten me out of a few scrapes in the past so I hope you find it as usefull.

This topic is closed to new replies.

Advertisement