A PhysX but not NxOgre related question

calsmurf2904

21-02-2009 12:57:06

Hi,
Since you guys are the PhysX experts with Ogre I wanted to ask you some stuff.
I'm using plain PhysX code...so no NxOgre code (srry).
I have a question about how you did it.
I'm trying to convert a OgreMesh to NxTriangleMesh by using this code:

void PhysicsObject::addOgreSceneNode(Ogre::SceneNode* mNode,float Mass)
{
NxActorDesc mActorBase;
for(int i = 0;i<mNode->numChildren();i++)
{
Ogre::SceneNode* mSceneNode = static_cast<Ogre::SceneNode*>(mNode->getChild(i));
Ogre::Entity* mEntity = static_cast<Ogre::Entity*>(mSceneNode->getAttachedObject(0));
Ogre::Mesh* mMesh = mEntity->getMesh().getPointer();
size_t mVerticesCount,mIndicesCount;
Ogre::Vector3* mVertices;
unsigned long* mIndices;
getMeshInformation(mMesh,mVerticesCount,mVertices,mIndicesCount,mIndices,Ogre::Vector3::ZERO,Ogre::Quaternion::IDENTITY,Ogre::Vector3::UNIT_SCALE);
NxTriangleMeshDesc mMeshDesc;
mMeshDesc.setToDefault();
mMeshDesc.numTriangles = mIndicesCount/3;
mMeshDesc.numVertices = mVerticesCount;
mMeshDesc.points = mVertices;
mMeshDesc.pointStrideBytes = sizeof(Ogre::Vector3);
mMeshDesc.triangles = mIndices;
mMeshDesc.triangleStrideBytes = sizeof(unsigned long)*3;
NxBuffer mBuffer;
NxGetCookingLib(NX_PHYSICS_SDK_VERSION)->NxCookTriangleMesh(mMeshDesc,mBuffer);
NxTriangleMesh* mTriangleMesh = mSDK->createTriangleMesh(mBuffer);
NxTriangleMeshShapeDesc mShapeDesc;
mShapeDesc.meshData = mTriangleMesh;
mShapeDesc.localPose.t = NxVec3(mSceneNode->getPosition().x,mSceneNode->getPosition().y,mSceneNode->getPosition().z);
mActorBase.shapes.push_back(&mShapeDesc);
};
NxBodyDesc mBodyDesc;
mActorBase.body = &mBodyDesc;
NxActor* mActor = mScene->createActor(mActorBase);
if(mActor == NULL)
{
throw Ogre::Exception(0,"Failed to create NxActor.",__FUNCTION__);
};
mActors[mNode->getName().c_str()] = std::pair< std::pair< Ogre::Vector3, Ogre::SceneNode*>, std::pair< NxVec3, NxActor*>>(std::pair< Ogre::Vector3, Ogre::SceneNode*>(mNode->getPosition(),mNode),std::pair< NxVec3, NxActor*>(mActorBase.globalPose.t,mActor));
};

It does create the NxTriangleMesh without errors but it gives a error when using it.
I don't know whats causing it....when I use a NxBoxShapeDesc it works correctly.
Could someone help me please?
(BTW:If this is not allowed in this forum then please delete this topic.)

betajaen

21-02-2009 14:57:47

Couple of suggestions.

- Make the mass of the body 0 when using TriangleShapes, PhysX will moan otherwise.
- I doubt it's the reason why it's crashing though. I wouldn't use longs for indicies, unsigned ints are good enough.

As for your cooking code. I would suggest you let "flour" to pre-cook them for you, then write a simple reader/writer class based of NxStream to load it in directly. It would gain a faster creation time, and it would work all of the time.

calsmurf2904

21-02-2009 15:25:51

ok...I converted the ogre mesh to nxs mesh with flour.
my current code is :

NxActorDesc mActorBase;
mActorBase.setToDefault();
NxTriangleMesh* mTriangleMesh = mSDK->createTriangleMesh(UserStream(mMeshName.c_str(),true));
NxTriangleMeshShapeDesc mShapeDesc;
mShapeDesc.setToDefault();
mShapeDesc.meshData = mTriangleMesh;
mShapeDesc.localPose.t = NxVec3(mNode->getPosition().x,mNode->getPosition().y,mNode->getPosition().z);
if(!mShapeDesc.isValid())
throw Ogre::Exception(0,"ShapeDescription is invalid.",__FUNCTION__);
mActorBase.shapes.push_back(&mShapeDesc);
NxBodyDesc mBodyDesc;
mBodyDesc.setToDefault();
mBodyDesc.mass = 0.0f;
mBodyDesc.massSpaceInertia = NxVec3(0.1f,0.1f,0.1f);
mBodyDesc.massLocalPose.t = mBodyDesc.massSpaceInertia;
mActorBase.density = 1.0f;
mActorBase.body = &mBodyDesc;
if(!mBodyDesc.isValid())
throw Ogre::Exception(0,"BodyDescription is invalid.",__FUNCTION__);
if(!mActorBase.isValid())
throw Ogre::Exception(0,"ActorDescription is invalid.",__FUNCTION__);
NxActor* mActor = mScene->createActor(mActorBase);
if(mActor == NULL)
{
throw Ogre::Exception(0,"Failed to create NxActor.",__FUNCTION__);
};
mActors[mNode->getName().c_str()] = std::pair< std::pair< Ogre::Vector3, Ogre::SceneNode*>, std::pair< NxVec3, NxActor*>>(std::pair< Ogre::Vector3, Ogre::SceneNode*>(mNode->getPosition(),mNode),std::pair< NxVec3, NxActor*>(mActorBase.globalPose.t,mActor));

Exception is ActorDescription is invalid.
I can't seem to get it to work :(

betajaen

21-02-2009 19:51:29

Alright, Can you get the PhysX error?

calsmurf2904

22-02-2009 09:26:24

PhysX only reports that my graphics card doesn't support CUDA.....and that
the ActorDescription is invalid...

betajaen

22-02-2009 10:03:35

Then the actor description is wrong.

- Set that density to 0.
- And take out that mass space inertia. I have no idea why you have that in there.

calsmurf2904

22-02-2009 16:51:19

ok...figured out the problem is related to the NxBodyDesc.
When I comment out the line :

mActorBase.body = &mBodyDesc;

it works correctly...only the actor is static...which I don't want.
My code also doesn't report that the BodyDescription is invalid....so there might be something
that isn't in the bodydescription which is needed by the ActorDescription.
I can't figure out what though.

My current code is :

void PhysicsObject::addOgreSceneNode(Ogre::SceneNode* mNode,Ogre::String mMeshName)
{
NxActorDesc mActorBase;
mActorBase.setToDefault();
NxTriangleMesh* mTriangleMesh = mSDK->createTriangleMesh(UserStream(mMeshName.c_str(),true));
NxTriangleMeshShapeDesc mShapeDesc;
mShapeDesc.setToDefault();
mShapeDesc.meshData = mTriangleMesh;
mShapeDesc.mass = 0.0f;
if(!mShapeDesc.isValid())
throw Ogre::Exception(0,"ShapeDescription is invalid.",__FUNCTION__);
mActorBase.shapes.push_back(&mShapeDesc);
NxBodyDesc mBodyDesc;
mBodyDesc.setToDefault();
mBodyDesc.mass = 0.0f;
mActorBase.density = 0.0f;
mActorBase.body = &mBodyDesc;
if(!mBodyDesc.isValid())
throw Ogre::Exception(0,"BodyDescription is invalid.",__FUNCTION__);
if(!mActorBase.isValid())
throw Ogre::Exception(0,"ActorDescription is invalid.",__FUNCTION__);
NxActor* mActor = mScene->createActor(mActorBase);
if(mActor == NULL)
{
throw Ogre::Exception(0,"Failed to create NxActor.",__FUNCTION__);
};
mActors[mNode->getName().c_str()] = std::pair< std::pair< Ogre::Vector3, Ogre::SceneNode*>, std::pair< NxVec3, NxActor*>>(std::pair< Ogre::Vector3, Ogre::SceneNode*>(mNode->getPosition(),mNode),std::pair< NxVec3, NxActor*>(mActorBase.globalPose.t,mActor));
};

betajaen

22-02-2009 18:04:07

Are you seriously wanting a dynamic actor that has a triangle mesh shape? Because that won't happen. PhysX won't allow it, and it won't behave in the scene as you want it to be.

calsmurf2904

22-02-2009 19:36:24

ok...My understanding is that a static actor isn't affected by any force...I want it to be affected by gravity etc.
If that isn't possible with a trianglemeshshape then which shape should I use to convert a ogre model to PhysX as Dynamic actor?

betajaen

22-02-2009 20:08:39

PhysX optimises the scene and expects the triangle mesh not to be moved.

You need to place over your model convexes and primitives that make up the features of your mesh; i.e. a table would be 5 cubes. 4 legs and a top.

calsmurf2904

22-02-2009 22:42:51

ok...maybe i need to add a vector as argument for the function containing the convex shapes + positions relative to the actor.
so the function prototype will be :

void PhysicsObject::addOgreSceneNode(Ogre::SceneNode* mNode,std::vector<NxConvexShapeDesc> mShapes); //Dynamic Actor
//And
void PhysicsObject::addOgreSceneNode(Ogre::SceneNode* mNode,std::string mMeshName); //Static Actor