PhysX Implementation Questions
by Ronald J Nelson · in Torque Game Engine Advanced · 10/19/2008 (11:03 pm) · 66 replies
I have implemented PhysX into my code. With that I have some questions about some things since I have noticed no one has been updating the stuff on TDN.
1. Has anyone gotten it to work with Polysoup, since Polysoup is stock with TGEA 1.7.1 I figured someone might have by now.
2. Has anyone gotten vehicle collisions to work properly with it yet?
3. Has anyone gotten a working example of using links that they are willing to share?
Thanks in advance.
1. Has anyone gotten it to work with Polysoup, since Polysoup is stock with TGEA 1.7.1 I figured someone might have by now.
2. Has anyone gotten vehicle collisions to work properly with it yet?
3. Has anyone gotten a working example of using links that they are willing to share?
Thanks in advance.
#22
Look at the original code, maybe you can figure it out based on the loops they do there to collect the verts.
You might also try looking into this flag (triangleDesc.flags = NX_MF_HARDWARE_MESH) and checking what other possible flags it takes, because hardware is probably not what you want.
10/25/2008 (8:23 pm)
Well, it's probably the order of the verts that is messed up. I don't remember the proper order, but the original code in TSStatic where it collected the verts should be the right way to do it. I don't have a Windows box at home to actually look at the code, but either tomorrow or Monday I can take a look when I'm at work. In any case, you're close, I can tell you that much.Look at the original code, maybe you can figure it out based on the loops they do there to collect the verts.
You might also try looking into this flag (triangleDesc.flags = NX_MF_HARDWARE_MESH) and checking what other possible flags it takes, because hardware is probably not what you want.
#23
10/25/2008 (9:28 pm)
Well, what you have actually won't work from what I looked at in our code. Instead of trying to do a buildpolylist on the TSStatic, you need to grab its TSShapeInstance, then loop through each of its MeshObjectInstances, then do getMesh( 0 ) on each to get the highest detail TSMesh. After that you need to loop through the TSDrawPrimitives of the TSMesh in order to 1) get the triangle count for that mesh, and 2) collect the verts for that mesh. You'll want to create a NxTriangleMesh for each TSMesh, basically. To figure out how to count the tris and collect the verts right when you're going through each TSDrawPrimitive, you can basically just search for anywhere in the code (i.e., search the whole project) it uses TSDrawPrimitive::Triangles. Check to see what's going on there and you should find somewhere that does the right thing to account for what type of TSDrawPrimitives you can get.
#24
10/26/2008 (12:27 am)
Well Ross I updated my code to what I think you meant. I still can't get it to work. It doesn't crash or anything but it is still wrong somehow.
#25
10/26/2008 (1:08 am)
Hrm, that's not really what I mentioned above now is it? :P I'm taking a poke at the code now, I'll post back here when I'm finished.
#26
Edit: Also, just FYI, you'll need to hold a list of trianglemesh actors, because statics can have more than one mesh (which is why you have to loop through all the MeshObjectInstances).
10/26/2008 (1:27 am)
Alright Ron, check this out. I didn't do all the work for you, but I think this should make things clearer.Edit: Also, just FYI, you'll need to hold a list of trianglemesh actors, because statics can have more than one mesh (which is why you have to loop through all the MeshObjectInstances).
void PhysXTSStatic::SetupTriangleCollision(bool server, TSStatic &tsstatic)
{
Con::errorf(ConsoleLogEntry::General, "SetupTriangleCollision called");
mServer = server;
PhysXWorld *PxWorld = PhysXWorld::getWorld(server);
// RLP: Don't wrap this whole big block
// if we don't have a PhysXWorld, just return.
if ( !PxWorld )
return; // Something really wrong here if this hits.
//////////// I'm leaving this stuff alone /////////
const Box3F &box = tsstatic.getObjBox();
VectorF scale = tsstatic.getScale()*10.0; // RLP: Why are you scaling this up by 10?
box.min.convolve(scale);
box.max.convolve(scale);
// ConcretePolyList polyList;
NxActorDesc actorDesc;
///////////////////////////////////////////////////
TSShapeInstance *shapeInst = tsstatic.mShapeInstance; // RLP: Let's pull this out.
if ( !shapeInst )
return;
// RLP: We're not building a poly list,
// don't need any of this stuff.
// polyList.setTransform(&tsstatic.mObjToWorld, tsstatic.mObjScale);
// polyList.setObject(&tsstatic);
// RLP: This only needs to happen once!
NxInitCooking();
// Loop through each *MeshObjectInstance* in the TSShapeInstance.
for( U32 i = 0; i < shapeInst->mMeshObjects.size(); i++ )
{
// Grab out the MeshObjectInstance.
TSShapeInstance::MeshObjectInstance *meshInst = &shapeInst->mMeshObjects[i];
// Grab out the TSMesh for that MeshObjectInstance.
TSMesh *mesh = meshInst->getMesh( 0 );
if ( !mesh )
continue; // Nothing left to do if no mesh.
// Figure out how many triangles we have...
U32 triCount = 0;
const U32 base = 0;
// Loop through the TSDrawPrimitives.
for ( U32 j = 0; j < mesh->primitives.size(); j++ )
{
// Pull out the TSDrawPrimitive.
TSDrawPrimitive &draw = mesh->primitives[j];
// Here you need to check what sort of primitive it is.
// The easy case is
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
triCount += draw.numElements / 3;
else
{
// Go find somewhere in the code
// that does this stuff, there
// there should be at least one.
// Try searching for "numElements"
// with match case ON.
}
}
// This can go outside, but
// for the sake of illustration
// I'm putting it here.
Vector<U32> indicesList;
// Now we got a triCount,
// so we can collect the verts indices.
for ( U32 j = 0; j < mesh->primitives.size(); j++ )
{
// Similar deal, pull this out.
TSDrawPrimitive &draw = mesh->primitives[j];
U32 start = draw.start;
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
for ( S32 k = 0; k < draw.numElements; )
{
indicesList.push_back( base + mesh->indices[start + k + 2] );
indicesList.push_back( base + mesh->indices[start + k + 1] );
indicesList.push_back( base + mesh->indices[start + k + 0] );
k += 3;
}
}
else
{
// Again you'll have to go find where it deals with the tristrip case.
}
}
// Here you can loop through your
// indicesList and index mesh->verts
// to collect them all.
// Here set up your NxTriangleMeshDesc.
// Set up your MemoryWriteBuffer and cooking params.
// You can just leave the .flags part unset (don't do anything with it).
// Call NxCookTriangleMesh with your desc and buf
// then set up your MemoryReadBuffer and call
// createTriangleMesh on the PhysXSDK object
// passing it the MemoryReadBuffer.
// It will return your actor.
}
}
#27
10/26/2008 (2:05 am)
WOW I was really off, thanks Ross.
#28
By the way thanks again for all of your help Ross.
10/26/2008 (3:07 pm)
OK I thought I had it right, by the way I changed a few things you had shown above because I found the same thing like it in TSMesh, but other than that I have probably assigned an incorrect value somewhere because it still just laughs at me and calls me a bonehead.void PhysXTSStatic::SetupTriangleCollision(bool server, TSStatic &tsstatic)
{
mServer = server;
PhysXWorld *PxWorld = PhysXWorld::getWorld(server);
// if we don't have a PhysXWorld, just return.
if ( !PxWorld )
{
return;
}
Box3F box = tsstatic.getObjBox();
VectorF scale = tsstatic.getScale()*10.0;
box.min.convolve(scale);
box.max.convolve(scale);
NxActorDesc actorDesc;
Vector<U32> indicesList;
TSShapeInstance *shapeInst = tsstatic.mShapeInstance;
if ( !shapeInst )
{
return;
}
NxInitCooking();
// Loop through each *MeshObjectInstance* in the TSShapeInstance.
for( U32 i = 0; i < shapeInst->mMeshObjects.size(); i++ )
{
// Grab out the MeshObjectInstance.
TSShapeInstance::MeshObjectInstance *meshInst = &shapeInst->mMeshObjects[i];
// Grab out the TSMesh for that MeshObjectInstance.
TSMesh *mesh = meshInst->getMesh( 0 );
if ( !mesh )
{
continue; // Nothing left to do if no mesh.
}
// Figure out how many triangles we have...
U32 numTriangles = 0;
const U32 base = 0;
// Loop through the TSDrawPrimitives.
for ( U32 j = 0; j < mesh->primitives.size(); j++ )
{
// Pull out the TSDrawPrimitive.
TSDrawPrimitive &draw = mesh->primitives[j];
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
numTriangles += draw.numElements / 3;
}
else
{
numTriangles += draw.numElements - 2;
}
}
for ( U32 j = 0; j < mesh->primitives.size(); j++ )
{
TSDrawPrimitive &draw = mesh->primitives[j];
U32 start = draw.start;
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
for ( S32 j = 0; j < draw.numElements; )
{
U32 idx0 = base + mesh->indices[start + j + 0];
U32 idx1 = base + mesh->indices[start + j + 1];
U32 idx2 = base + mesh->indices[start + j + 2];
indicesList.push_back( idx0 );
indicesList.push_back( idx1 );
indicesList.push_back( idx2 );
j += 3;
}
}
else
{
U32 idx0 = base + mesh->indices[start + 0];
U32 idx1;
U32 idx2 = base + mesh->indices[start + 1];
U32 * nextIdx = &idx1;
for (S32 j=2; j<draw.numElements; j++)
{
*nextIdx = idx2;
nextIdx = (U32*) ( (dsize_t)nextIdx ^ (dsize_t)&idx0 ^ (dsize_t)&idx1);
idx2 = base + mesh->indices[start + j];
if (idx0 == idx1 || idx0 == idx2 || idx1 == idx2)
continue;
indicesList.push_back( idx0 );
indicesList.push_back( idx1 );
indicesList.push_back( idx2 );
}
}
}
// Here you can loop through your
// indicesList and index mesh->verts
// to collect them all.
int numVertices = indicesList.size();
if (numVertices == 0)
{
return;
}
NxVec3 * points = new NxVec3[numVertices];
NxArray<NxU32> * triangles = new NxArray<NxU32>[numTriangles*3];
// Load vertices
for(U32 i=0; i < numVertices; i++)
{
points[i].x = mesh->verts[i].x;
points[i].y = mesh->verts[i].y;
points[i].z = mesh->verts[i].z;
}
// Load triangles
S16 numE = mesh->primitives.size();
NxU32 k = 0;
for(int j = 0; j < numE; j++)
{
triangles[j] = mesh->indices[k];
triangles[j] = mesh->indices[k++];
triangles[j] = mesh->indices[k++];
k++;
}
NxTriangleMeshDesc triangleDesc;
triangleDesc.numVertices = numVertices;
triangleDesc.numTriangles = numTriangles;
triangleDesc.pointStrideBytes = sizeof(NxVec3);
triangleDesc.triangleStrideBytes = 3*sizeof(NxU32);
triangleDesc.points = points;
triangleDesc.triangles = &triangles[0];
//triangleDesc.flags = 0;
// cook it
MemoryWriteBuffer buf;
NxCookingParams params;
params.targetPlatform = PLATFORM_PC;
params.skinWidth=0.0f;
params.hintCollisionSpeed = false;
NxSetCookingParams(params);
bool status = NxCookTriangleMesh(triangleDesc, buf);
NxCloseCooking();
if (status)
{
MemoryReadBuffer readBuffer(buf.data);
NxTriangleMesh* staticMesh = PxWorld->createTriangleMesh(readBuffer);
NxTriangleMeshShapeDesc staticMeshDesc;
staticMeshDesc.meshData = staticMesh;
actorDesc.shapes.push_back(&staticMeshDesc);
}
actorDesc.body = NULL;
gTSStatic = PxWorld->AddActor(actorDesc);
if(gTSStatic->active)
{
Con::errorf(ConsoleLogEntry::General, "gTSStatic->active");
gTSStatic->actor->userData = (void*) static_cast<SimObject*>( this );
}
//clean up
for(U32 i=0; i<triangleMeshDesc.size(); i++)
{
if (triangleMeshDesc[i])
triangleMeshDesc[i]->~NxTriangleMeshDesc();
}
triangleMeshDesc.clear();
}
}By the way thanks again for all of your help Ross.
#29
You're using indicesList there as just a count. What does the comment say to do with it? *Index* the mesh->verts array by the elements of indicesList.
This code:
Is very odd... Why are you saving the description here? The actor is what you care about. I'm also not sure why you're doing "AddActor" there with the base ActorDesc. If it succeeded in cooking the mesh, it returns the actor, which is what you want to store.
The else for this part (above) should look more like this:
You're getting closer.
10/26/2008 (3:39 pm)
@Ron, read this comment again:// Here you can loop through your
// indicesList and index mesh->verts
// to collect them all.You're using indicesList there as just a count. What does the comment say to do with it? *Index* the mesh->verts array by the elements of indicesList.
This code:
if (status)
{
MemoryReadBuffer readBuffer(buf.data);
NxTriangleMesh* staticMesh = PxWorld->createTriangleMesh(readBuffer);
NxTriangleMeshShapeDesc staticMeshDesc;
staticMeshDesc.meshData = staticMesh;
actorDesc.shapes.push_back(&staticMeshDesc);
}
actorDesc.body = NULL;
gTSStatic = PxWorld->AddActor(actorDesc);
if(gTSStatic->active)
{
Con::errorf(ConsoleLogEntry::General, "gTSStatic->active");
gTSStatic->actor->userData = (void*) static_cast<SimObject*>( this );
}Is very odd... Why are you saving the description here? The actor is what you care about. I'm also not sure why you're doing "AddActor" there with the base ActorDesc. If it succeeded in cooking the mesh, it returns the actor, which is what you want to store.
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
numTriangles += draw.numElements / 3;
}
else
{
numTriangles += draw.numElements - 2;
}The else for this part (above) should look more like this:
U32 idx0 = base + mesh->indices[start + 0];
U32 idx1;
U32 idx2 = base + mesh->indices[start + 1];
U32 * nextIdx = &idx1;
for ( S32 k = 2; k < draw.numElements; k++ )
{
*nextIdx = idx2;
// nextIdx = (j%2)==0 ? &idx0 : &idx1;
nextIdx = (U32*) ( (dsize_t)nextIdx ^ (dsize_t)&idx0 ^ (dsize_t)&idx1);
idx2 = base + mesh->indices[start + k];
if (idx0 == idx1 || idx0 == idx2 || idx1 == idx2)
continue;
triCount++;
}You're getting closer.
#30
First, is this more like what you mean in actually using the indiceList?
Next do you mean I do not need any of what I have commented out here?
Next, I based
off an almost identical piece of code to what you had in the if statement. I added the indentical version of what the code listed in the else statement. It is in TSMesh::getNumPolys(). If I am wrong in that one I am really confused because it seemed like whay you were going for.
10/26/2008 (4:27 pm)
OK let me go through each of these because I am not sure I understand on a couple of points.First, is this more like what you mean in actually using the indiceList?
// Here you can loop through your
// indicesList and index mesh->verts
// to collect them all.
int numVertices = indicesList.size();
if (numVertices == 0)
{
return;
}
NxVec3 * points = new NxVec3[numVertices];
NxArray<NxU32> * triangles = new NxArray<NxU32>[numTriangles*3];
// Load vertices
for(U32 i=0; i < numVertices; i++)
{
points[i].x = mesh->verts[i].x;
points[i].y = mesh->verts[i].y;
points[i].z = mesh->verts[i].z;
}
// Load triangles
S16 numE = mesh->primitives.size();
NxU32 k = 0;
for(int j = 0; j < numE; j++)
{
triangles[j] = indicesList[k];
triangles[j] = indicesList[k++];
triangles[j] = indicesList[k++];
k++;
}I was sure that was the area I screwwed up on the most, but wasn't sure why.Next do you mean I do not need any of what I have commented out here?
if (status)
{
MemoryReadBuffer readBuffer(buf.data);
NxTriangleMesh* staticMesh = PxWorld->createTriangleMesh(readBuffer);
/*
NxTriangleMeshShapeDesc staticMeshDesc;
staticMeshDesc.meshData = staticMesh;
actorDesc.shapes.push_back(&staticMeshDesc);
}
actorDesc.body = NULL;
gTSStatic = PxWorld->AddActor(actorDesc);
if(gTSStatic->active)
{
Con::errorf(ConsoleLogEntry::General, "gTSStatic->active");
gTSStatic->actor->userData = (void*) static_cast<SimObject*>( this );
*/
}Next, I based
numTriangles += draw.numElements - 2;
off an almost identical piece of code to what you had in the if statement. I added the indentical version of what the code listed in the else statement. It is in TSMesh::getNumPolys(). If I am wrong in that one I am really confused because it seemed like whay you were going for.
#31
PS: You don't need brackets ( { and } ) when you have a statement (for, if, while etc.) that would only have one line inside it.
Instead of
do this
Also, you're going to use the indicesList directly.
So you don't need this part
at all (it's wrong anyway).
Instead you'll do
And thus you also don't need to make the NxArray of NxU32s.
You're correct about the stuff you have commented in your post above, it's not necessary.
And as to the last bit, I'm sure there was somewhere that did what you have there, but it was probably doing something different. Use the code I gave you instead.
So the bottom part of your loop should look more like this (this should start from where you currently have "numVertices = indicesList.size()". Make sure to also change your "numTriangles += draw.numElements - 2;" line to what I posted above.
10/26/2008 (5:28 pm)
@Ron, first, read through this entire post carefully before going off to change things! I'm giving a little explanation before the end of my post which shows an updated example of the code. And actually, my bad regarding the first part of what I was saying. But you still want to do things a little differently.PS: You don't need brackets ( { and } ) when you have a statement (for, if, while etc.) that would only have one line inside it.
Instead of
for(U32 i=0; i < numVertices; i++)
{
points[i].x = mesh->verts[i].x;
points[i].y = mesh->verts[i].y;
points[i].z = mesh->verts[i].z;
}do this
for(U32 i=0; i < mesh->verts.size(); i++)
{
points[i].x = mesh->verts[i].x;
points[i].y = mesh->verts[i].y;
points[i].z = mesh->verts[i].z;
}Also, you're going to use the indicesList directly.
So you don't need this part
// Load triangles
S16 numE = mesh->primitives.size();
NxU32 k = 0;
for(int j = 0; j < numE; j++)
{
triangles[j] = mesh->indices[k];
triangles[j] = mesh->indices[k++];
triangles[j] = mesh->indices[k++];
k++;
}at all (it's wrong anyway).
Instead you'll do
triangleDesc.triangles = indicesList.address();
And thus you also don't need to make the NxArray of NxU32s.
You're correct about the stuff you have commented in your post above, it's not necessary.
And as to the last bit, I'm sure there was somewhere that did what you have there, but it was probably doing something different. Use the code I gave you instead.
So the bottom part of your loop should look more like this (this should start from where you currently have "numVertices = indicesList.size()". Make sure to also change your "numTriangles += draw.numElements - 2;" line to what I posted above.
U32 numVertices = mesh->verts.size();
NxVec3 * points = new NxVec3[numVertices];
// Load vertices
for(U32 i=0; i < numVertices; i++)
{
points[i].x = mesh->verts[i].x;
points[i].y = mesh->verts[i].y;
points[i].z = mesh->verts[i].z;
}
NxTriangleMeshDesc triangleDesc;
triangleDesc.numVertices = numVertices;
triangleDesc.numTriangles = numTriangles;
triangleDesc.pointStrideBytes = sizeof(NxVec3);
triangleDesc.triangleStrideBytes = 3*sizeof(NxU32);
triangleDesc.points = points;
triangleDesc.triangles = indicesList.address();
//triangleDesc.flags = 0;
// cook it
MemoryWriteBuffer buf;
NxCookingParams params;
params.targetPlatform = PLATFORM_PC;
params.skinWidth=0.0f;
params.hintCollisionSpeed = false;
NxSetCookingParams(params);
bool status = NxCookTriangleMesh(triangleDesc, buf);
if (status)
{
MemoryReadBuffer readBuffer(buf.data);
NxTriangleMesh* staticMesh = PxWorld->createTriangleMesh(readBuffer);
// Push this actor back into our actor list.
mTriangleMeshActors.push_back( staticMesh );
}
}
// We init cooking outside the loop!
// Don't close it inside the loop.
NxCloseCooking();
}
#32
I have one thing that was in your code I have to find, mTriangleMeshActors. Its not in my project so I am assuming it is in the PhysX code.
10/26/2008 (5:40 pm)
Ross, Thanks again, and you were right I was much closer than I thought. Amazing how such a small change here and there will make such a huge difference. However,I have one thing that was in your code I have to find, mTriangleMeshActors. Its not in my project so I am assuming it is in the PhysX code.
#33
10/26/2008 (5:53 pm)
OK it turns out that doesn't exist at all. Can you enlighten me on what mTriangleMeshActors is?
#34
10/26/2008 (5:59 pm)
@Ron, did you read the comment right above that line? Remember I pointed out that you'll need to keep a list of your actors and push them back into the list if the cooking succeeded. The "m" denotes it's a member variable as well. That is to say, nope, it doesn't exist, but you should be able to figure out what it is and where it's supposed to be (i.e., it's a member variable which is a Vector<> of TriangleMeshes held in your PhysXTSStatic.).
#35
I'm gonna go out on a limb here and say I have done this wrong and that the SetupCollision function is probably always supposed to be run so it adds the actor. Am I right in this guess?
However debug shows the crash occurs at the actual cooking stage. I am going to post the entire function to see if you see my mistake.
10/26/2008 (6:28 pm)
I did everything you said, but it crashes now. Here is a thought, because its not adding an actor, is the fact that I have the following choosing only to do one or the other.void PhysXWorld::SetupTSStatic(TSStatic &tsstatic)
{
if (mRemoteClient || isServerObject())
{
PhysXTSStatic *pxTSStatic = new PhysXTSStatic();
pxTSStatic->registerObject();
mTSStaticList.push_front(pxTSStatic);
if(tsstatic.usesTriangleCook())
{
pxTSStatic->SetupTriangleCollision(isServerObject(),tsstatic);
}
else
{
pxTSStatic->SetupCollision(isServerObject(),tsstatic);
}
}
}I'm gonna go out on a limb here and say I have done this wrong and that the SetupCollision function is probably always supposed to be run so it adds the actor. Am I right in this guess?
However debug shows the crash occurs at the actual cooking stage. I am going to post the entire function to see if you see my mistake.
#36
10/26/2008 (6:31 pm)
void PhysXTSStatic::SetupTriangleCollision(bool server, TSStatic &tsstatic)
{
mServer = server;
PhysXWorld *PxWorld = PhysXWorld::getWorld(server);
// if we don't have a PhysXWorld, just return.
if ( !PxWorld )
{
return;
}
Box3F box = tsstatic.getObjBox();
VectorF scale = tsstatic.getScale()*10.0;
box.min.convolve(scale);
box.max.convolve(scale);
NxActorDesc actorDesc;
Vector<U32> indicesList;
TSShapeInstance *shapeInst = tsstatic.mShapeInstance;
if ( !shapeInst )
{
return;
}
NxInitCooking();
// Loop through each *MeshObjectInstance* in the TSShapeInstance.
for( U32 i = 0; i < shapeInst->mMeshObjects.size(); i++ )
{
// Grab out the MeshObjectInstance.
TSShapeInstance::MeshObjectInstance *meshInst = &shapeInst->mMeshObjects[i];
// Grab out the TSMesh for that MeshObjectInstance.
TSMesh *mesh = meshInst->getMesh( 0 );
if ( !mesh )
{
continue; // Nothing left to do if no mesh.
}
// Figure out how many triangles we have...
U32 numTriangles = 0;
const U32 base = 0;
// Loop through the TSDrawPrimitives.
for ( U32 j = 0; j < mesh->primitives.size(); j++ )
{
// Pull out the TSDrawPrimitive.
TSDrawPrimitive &draw = mesh->primitives[j];
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
numTriangles += draw.numElements / 3;
}
else
{
numTriangles += draw.numElements - 2;
}
}
for ( U32 j = 0; j < mesh->primitives.size(); j++ )
{
TSDrawPrimitive &draw = mesh->primitives[j];
U32 start = draw.start;
if ( (draw.matIndex & TSDrawPrimitive::TypeMask) == TSDrawPrimitive::Triangles)
{
for ( S32 j = 0; j < draw.numElements; )
{
U32 idx0 = base + mesh->indices[start + j + 0];
U32 idx1 = base + mesh->indices[start + j + 1];
U32 idx2 = base + mesh->indices[start + j + 2];
indicesList.push_back( idx0 );
indicesList.push_back( idx1 );
indicesList.push_back( idx2 );
j += 3;
}
}
else
{
U32 idx0 = base + mesh->indices[start + 0];
U32 idx1;
U32 idx2 = base + mesh->indices[start + 1];
U32 * nextIdx = &idx1;
for (S32 j=2; j<draw.numElements; j++)
{
*nextIdx = idx2;
nextIdx = (U32*) ( (dsize_t)nextIdx ^ (dsize_t)&idx0 ^ (dsize_t)&idx1);
idx2 = base + mesh->indices[start + j];
if (idx0 == idx1 || idx0 == idx2 || idx1 == idx2)
continue;
indicesList.push_back( idx0 );
indicesList.push_back( idx1 );
indicesList.push_back( idx2 );
}
}
}
// Here you can loop through your
// indicesList and index mesh->verts
// to collect them all.
int numVertices = mesh->verts.size();
NxVec3 * points = new NxVec3[numVertices];
// Load vertices
for(U32 i=0; i < numVertices; i++)
{
points[i].x = mesh->verts[i].x;
points[i].y = mesh->verts[i].y;
points[i].z = mesh->verts[i].z;
}
NxTriangleMeshDesc triangleDesc;
triangleDesc.numVertices = numVertices;
triangleDesc.numTriangles = numTriangles;
triangleDesc.pointStrideBytes = sizeof(NxVec3);
triangleDesc.triangleStrideBytes = 3*sizeof(NxU32);
triangleDesc.points = points;
triangleDesc.triangles = indicesList.address();
//triangleDesc.flags = 0;
// cook it
MemoryWriteBuffer buf;
NxCookingParams params;
params.targetPlatform = PLATFORM_PC;
params.skinWidth=0.0f;
params.hintCollisionSpeed = false;
NxSetCookingParams(params);
bool status = NxCookTriangleMesh(triangleDesc, buf);
if (status)
{
MemoryReadBuffer readBuffer(buf.data);
NxTriangleMesh* staticMesh = PxWorld->createTriangleMesh(readBuffer);
// Push this actor back into our actor list.
mTriangleMeshActors.push_back( staticMesh );
}
}
NxCloseCooking();
}
#37
You didn't replace this:
with this:
It probably isn't the cause of your crash, but it still needs to be changed. You say it's crashing at the actual cooking stage? Does that mean it's a crash inside the PhysX DLL or inside your app itself? In any case, make the change above and see if that helps.
10/26/2008 (7:29 pm)
@Ron,You didn't replace this:
{
numTriangles += draw.numElements - 2;
}with this:
U32 idx0 = base + mesh->indices[start + 0];
U32 idx1;
U32 idx2 = base + mesh->indices[start + 1];
U32 * nextIdx = &idx1;
for ( S32 k = 2; k < draw.numElements; k++ )
{
*nextIdx = idx2;
// nextIdx = (j%2)==0 ? &idx0 : &idx1;
nextIdx = (U32*) ( (dsize_t)nextIdx ^ (dsize_t)&idx0 ^ (dsize_t)&idx1);
idx2 = base + mesh->indices[start + k];
if (idx0 == idx1 || idx0 == idx2 || idx1 == idx2)
continue;
triCount++;
}It probably isn't the cause of your crash, but it still needs to be changed. You say it's crashing at the actual cooking stage? Does that mean it's a crash inside the PhysX DLL or inside your app itself? In any case, make the change above and see if that helps.
#38
10/26/2008 (8:10 pm)
No crash anymore, but still no collision. But yeah good catch, thanks.
#39
10/26/2008 (8:23 pm)
Have you stepped through the code to see if it's actually succeeding the cook? Also make sure to change "triCount" in the snippet I posted to "numTriangles" as you have it in your code.
#40
10/26/2008 (8:32 pm)
Yes I did that and I added a quick ConsoleLogEntry to verify it passed, it did. So now I must admit I am pretty confused.
Torque Owner Ronald J Nelson
Code Hammer Games
It is my method for putting together triangleDesc.triangles. It is all wrong from what I have seen in other examples. PErhaps you can give me a little help with this one?