OgreOde::Body* SimpleScenes::createRandomObject(OgreOde::Geometry::Class objectClass)
{
if(_key_delay < SimpleScenes::KEY_DELAY) return 0;
String typeName="robot";
String name = typeName + StringConverter::toString((unsigned int)_bodies.size());
Entity* entity = _mgr->createEntity(name, "robot.mesh");
SceneNode* node = _mgr->getRootSceneNode()->createChildSceneNode(name);
node->attachObject(entity);
entity->setNormaliseNormals(true);
entity->setCastShadows(true);
node->showBoundingBox(true);
// Pick a size
AxisAlignedBox box=entity->getBoundingBox();
box.scale(Vector3(0.1,0.1,0.1));
Vector3 size=box.getMaximum()-box.getMinimum();
// Create a body associated with the node we created
OgreOde::Body* body = new OgreOde::Body();
node->attachObject(body);
// Set the mass and geometry to match the visual representation
OgreOde::Geometry* geom = 0;
OgreOde::BoxMass mass(1.0,size);
geom = (OgreOde::Geometry*)new OgreOde::BoxGeometry(size,_space);
node->setScale(0.1 ,0.1, 0.1 );
body->setMass(mass);
geom->setBody(body);
// Keep track of the body
_bodies.push_back(body);
_geoms.push_back(geom);
_key_delay = 0.0;
// If we created something position and orient it randomly
if(body)
{
//body->setOrientation(Quaternion(Radian(OgreOde::Utility::randomReal() * 10.0 - 5.0),Vector3(OgreOde::Utility::randomReal() * 2.0 - 1.0,OgreOde::Utility::randomReal() * 2.0 - 1.0,OgreOde::Utility::randomReal() * 2.0 - 1.0)));
body->setPosition(Vector3((OgreOde::Utility::randomReal() * 10.0) - 5.0,OgreOde::Utility::randomReal() + 5,(OgreOde::Utility::randomReal() * 10.0) - 5.0));
// Set the last body we created to be looked at
_last_node = static_cast<SceneNode*>(body->getParentNode());
}
return body;
}
The OgreODE Box is centered on the origin of the model. The origin of the robot mesh is between the feet of the robot. You will have to use a TransformGeometry to encapsulate your BoxGeometry to recenter the ogreode box.
You can find how to set up a transform geometry in the ogreode examples (look at the apache helicopter setup)
AxisAlignedBox box = entity->getBoundingBox();
// Set the mass and geometry to match the visual representation
OgreOde::Geometry* geom = NULL;
Vector3 min, max;
min = box.getMinimum();
max = box.getMaximum();
Vector3 size(Math::Abs(max.x-min.x),Math::Abs(max.y-min.y),Math::Abs(max.z-min.z));
// Main body
OgreOde::TransformGeometry* trans = new OgreOde::TransformGeometry(_space);
geom = (OgreOde::Geometry*)new OgreOde::BoxGeometry(size);
trans->setEncapsulatedGeometry(geom);
geom->setPosition(node->getPosition()+Vector3(0,size.y/2,0));
_geoms.push_back(geom);
_geoms.push_back(trans);
In this code, ontity is the robot, node is the parent scenenode of the robot.
Sorry to revive an old thread, but I have a question about this.
Is there any detriment to having each object reside in the default space of the world (IE passing World->getDefaultSpace() to the TransformGeometry constructor) or should each object have its own space?
You should try to combine bodies that reside geographically close to each other in the same space. The bounding box of the space will then be used to do early rejection for collsion proxies.
For example, if a car has four wheels and a body, combine those into one space.