NxOgre + oFusion

s0lidnuts

10-07-2007 17:04:55

oK, I was doing the following until now
Loading the oFusion scene
and then parsing a XML I've made by hand for the physics
I got the name on the XML, and got the oFusion node by it, then got the orientation/rotation/position from it and creating the NxOgre bodies. Then I would setVisible(false) on the oFusion nodes.
But, that's a horrible way of setting up the NxWorld dinamically and I'm if there's anyway onto attach the physics to existing oFusion created nodes =/

betajaen

10-07-2007 17:15:26

Not out of the box no.

The oFusion scene format is great, but it's not suitable for a physics scene; no support of shapes, mass, etc. So you'd have to come up with your own. Or at least base yours on the oFusion and add physics specific information in.

I have a plan to address serialization of the scene, but it's not going to be around for a while.

s0lidnuts

10-07-2007 17:23:53

I did my own XML and parser, but I don't know what to do with the NxOgre Ogre::SceneManager.. There's 2 of every object of my scene, one from oFusion original scene loader, and another from NxOgre, wich has physics and collision. With the creepy OgreNewt I could attach the physics to the existing node/entity, so that OgreNewt would only create the physics, not the visible mesh.

betajaen

10-07-2007 17:30:40

You can do that as well:-

mBody->setNode(node);

Backov

10-07-2007 19:36:21

With the pro version of OFusion you can modify the scene file exporter to include physics animation. I haven't done it yet, so I have no idea what limitations there might be, but I do plan to.

s0lidnuts

11-07-2007 04:26:31

Well.. I did this and it's working, of course there are joints, etc.. but it's a start.. (and cubes/capsules are not ready xD)

bool class::parseBodies(Ogre::SceneManager *_sceneMgr)
{
mXMLElement = mXMLRoot->FirstChildElement("Body");
Ogre::SceneNode *node = 0;
NxOgre::Body *nxBody = 0;
NxOgre::Actor *nxActor = 0;
SimpleBody *body = new SimpleBody();

//mWorld->getPhysXDriver()->setTimeModifier(0);

while (mXMLElement)
{
body->bName = mXMLElement->Attribute("name");
body->bType = mXMLElement->Attribute("type");
body->bShape = mXMLElement->Attribute("shape");
body->bMesh = mXMLElement->Attribute("mesh");
node = _sceneMgr->getSceneNode(body->bName);
if (body->bType == "dynamic")
body->bMass = mXMLElement->Attribute("mass");

if (body->bType == "Static")
{
if (body->bShape == "Cube")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh),
NxOgre::Pose(node->getPosition(), node->getOrientation()), "static: true");
else if (body->bShape == "Sphere")
{
body->bRadius = Ogre::StringConverter::parseReal(mXMLElement->Attribute("radius"));
nxBody = mNxScene->createBody(body->bName, new NxOgre::SphereShape(body->bRadius),
NxOgre::Pose(node->getPosition(), node->getOrientation()), "static: true");
}
else if (body->bShape == "Capsule")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh),
NxOgre::Pose(node->getPosition(), node->getOrientation()), "static: true");
else if (body->bShape == "Convex")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh),
NxOgre::Pose(node->getPosition(), node->getOrientation()), "static: true");
}
else if (body->bType == "Dynamic")
{
body->bMass = mXMLElement->Attribute("mass");
NxOgre::NxString params;
params.append("mass: ");
params.append(body->bMass);
if (body->bShape == "Cube")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh),
NxOgre::Pose(node->getPosition(), node->getOrientation()), params);
else if (body->bShape == "Sphere")
{
body->bRadius = Ogre::StringConverter::parseReal(mXMLElement->Attribute("radius"));
nxBody = mNxScene->createBody(body->bName, new NxOgre::SphereShape(body->bRadius),
NxOgre::Pose(node->getPosition(), node->getOrientation()), params);
}
else if (body->bShape == "Capsule")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh),
NxOgre::Pose(node->getPosition(), node->getOrientation()), params);
else if (body->bShape == "Convex")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh),
NxOgre::Pose(node->getPosition(), node->getOrientation()), params);
}
if (nxBody)
nxBody->setNode(node);
mXMLElement = mXMLElement->NextSiblingElement("Body");
}


But once I do nxBody->setNode(node); shouldn't I clear something ? I mean, it seems to me that there's 2 scene's running, the one NxOgre did, and the other oFusion did.. any help is appreciated.

betajaen

11-07-2007 10:18:53

Do you mean two SceneManagers or two Scenes?

s0lidnuts

11-07-2007 16:45:01

Well.. I'm still loading all the data in the normal way, except I'm executing (nxSceneNode->setNode(originalSceneNode))
That makes me think the NxOgre scene is still up, running, and consuming some resources or processing.

Anyway, some code update for those who may like.
bool Physics::parseBodies(Ogre::SceneManager *_sceneMgr)
{
mXMLElement = mXMLRoot->FirstChildElement("Body");
Ogre::SceneNode *node = 0;
NxOgre::Body *nxBody = 0;
NxOgre::Actor *nxActor = 0;
SimpleBody *body = new SimpleBody();

//mWorld->getPhysXDriver()->setTimeModifier(0.2);

while (mXMLElement)
{
body->bName = mXMLElement->Attribute("name");
body->bType = mXMLElement->Attribute("type");
body->bShape = mXMLElement->Attribute("shape");
body->bMesh = mXMLElement->Attribute("mesh");
node = _sceneMgr->getSceneNode(body->bName);
if (body->bType == "Dynamic")
body->bMass = mXMLElement->Attribute("mass");

NxOgre::NxString nodeParams(""), meshParams("mesh-scale: " + Ogre::StringConverter::toString(node->getScale()));
if (body->bType == "Static")
nodeParams.append("static: true");
else if (body->bType == "Dynamic")
nodeParams.append("mass: " + body->bMass);

if (body->bShape == "Cube")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);
else if (body->bShape == "Sphere")
{
body->bRadius = Ogre::StringConverter::parseReal(mXMLElement->Attribute("radius"));
nxBody = mNxScene->createBody(body->bName, new NxOgre::SphereShape(body->bRadius, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);
}
else if (body->bShape == "Capsule")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);
else if (body->bShape == "Convex")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);
else if (body->bShape == "Mesh")
nxBody = mNxScene->createBody(body->bName, new NxOgre::TriangleMeshShape(body->bMesh, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);
if (nxBody)
nxBody->setNode(node);
mXMLElement = mXMLElement->NextSiblingElement("Body");
}

//mWorld->getPhysXDriver()->setTimeModifier(1);

return true;
}


The code isn't documented but it's very self-explanatory and short so..
the body class is made of many Ogre::String except for bRadius wich is Ogre::Real and bSize wich is currently Ogre::Vector3 (I'm not using it yet because I really don't know how to get the size of a node or entity from ogre.

betajaen

11-07-2007 16:57:03

I think you'll be quite suprised and happy as I'm currently working on the ActorBlueprint and SceneBlueprints now.

s0lidnuts

11-07-2007 17:01:57

And you'll be surprised when I say I don't know what blueprints are..
But, if I remember well, in 3D modeling, blueprints are pictures you use as a guide to do the modeling.. and seeing the context in the forum, would the blueprints be something like a shape of the model ? Wich would give their size ? :D

betajaen

11-07-2007 17:12:05

That's it. It's a blueprint on of a Scene or more like; the instructions on how a scene should be and what should be in it.

s0lidnuts

11-07-2007 18:49:26

Well.. I guess that parseBodies function is just OK by now, just not sure about that 'double-scene' thing, but..
bool PhysicsManager::parseBodies(Ogre::SceneManager *_sceneMgr)
{
mXMLElement = mXMLRoot->FirstChildElement("Body");
Ogre::SceneNode *node = 0;
NxOgre::Body *nxBody = 0;
NxOgre::Actor *nxActor = 0;
SimpleBody *body = new SimpleBody();

mWorld->getPhysXDriver()->setTimeModifier(0);

while (mXMLElement)
{
body->bName = mXMLElement->Attribute("name");
body->bType = mXMLElement->Attribute("type");
body->bShape = mXMLElement->Attribute("shape");
body->bMesh = mXMLElement->Attribute("mesh");
if (body->bShape == "Cube" || body->bShape == "Capsule")
body->bSize = Ogre::StringConverter::parseVector3(mXMLElement->Attribute("Size"));
if (body->bShape == "Sphere" || body->bShape == "Capsule")
body->bRadius = Ogre::StringConverter::parseReal(mXMLElement->Attribute("radius"));
if (body->bType == "Dynamic")
body->bMass = mXMLElement->Attribute("mass");

node = _sceneMgr->getSceneNode(body->bName);
NxOgre::NxString nodeParams(""), meshParams("mesh-scale: " + Ogre::StringConverter::toString(node->getScale()));

if (body->bType == "Static")
nodeParams.append("static: true");
else if (body->bType == "Dynamic")
nodeParams.append("mass: " + body->bMass);

if (body->bShape == "Cube")
{
nxBody = mNxScene->createBody(body->bName, new NxOgre::CubeShape(body->bSize.x, body->bSize.y, body->bSize.z, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);
}
else if (body->bShape == "Sphere")
{
nxBody = mNxScene->createBody(body->bName, new NxOgre::SphereShape(body->bRadius, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);
}
else if (body->bShape == "Capsule")
nxBody = mNxScene->createBody(body->bName, new NxOgre::CapsuleShape(body->bRadius, body->bSize.y, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);

else if (body->bShape == "Convex")
nxBody = mNxScene->createBody(body->bName, new NxOgre::ConvexShape(body->bMesh, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);

else if (body->bShape == "Mesh")
nxBody = mNxScene->createBody(body->bName, new NxOgre::TriangleMeshShape(body->bMesh, meshParams),
NxOgre::Pose(node->getPosition(), node->getOrientation()), nodeParams);

if (nxBody)
nxBody->setNode(node);
mXMLElement = mXMLElement->NextSiblingElement("Body");
}

mWorld->getPhysXDriver()->setTimeModifier(1);

return true;
}


Example XML:
<World>
<Body name = "Ground" type = "Static" shape = "Mesh" mesh = "Ground.mesh"/>
<Body name = "House" type = "Static" shape = "Convex" mesh = "House.mesh"/>
<Body name = "Sphere" type = "Dynamic" shape = "Sphere" radius = "2.431" mass = "40" mesh = "Sphere.mesh"/>
<Body name = "Box" type = "Dynamic" shape = "Cube" size = "2 2 2" mass = "40" mesh = "Box.mesh"/>
<Body name = "Capsule" type = "Dynamic" shape = "Capsule" size = "4 4 4" radius = "1" mass = "100" mesh = "Capsule.mesh"/>
</World>


The loadScene function wich will call parseBodies() and parseJoints/etc in the future..
bool PhysicsManager::loadScene(Ogre::String _sceneFile, Ogre::SceneManager *_sceneMgr)
{
mNxScene = mWorld->createScene("scene", _sceneMgr, "gravity: yes, floor: yes");
mXMLDoc.LoadFile(_sceneFile.c_str());
mXMLRoot = mXMLDoc.RootElement();

if (!parseBodies(_sceneMgr))
return false;

return true;
}


I guess this serves as a base.. or for ideas ^^
Thanks NxOgre ^^

jams

19-07-2007 23:37:22

Hi s0lidnuts, I have the same need as you, adding physics to a scene loaded from oFusion library. If I understand well, you're copying your entire oFusion scene into NxOgre by creating a body for each entity ... which actually duplicates everything. I wonder if Actors could not just make it ? They are bodies without mesh. So if you create an actor for each oFusion entity and attach it to the entity's parent scene node, it could work ? Though I tried to do it, but I can't make it work, I'm still missing something ...

betajaen

19-07-2007 23:42:17

Problem is; Actors don't have SceneNodes. Bodies are a better choice.

jams

20-07-2007 00:03:16

Ok, so doing bodies with no mesh could just make it ? I still don't understand what Actors are for ??

Aiursrage2k

20-07-2007 02:35:12

Ok, so doing bodies with no mesh could just make it ? I still don't understand what Actors are for ??

Actors only have the physics representation, where bodies have both physical and graphical.

For example if you wanted to use the sphere shape for the camera collision, but you didnt want to give it a graphical representation you would use an actor.

jams

20-07-2007 09:28:40

Ok, that's how I understand it, but then how the actor and camera positions are synchronized ?