First, great work ! bravo !
Like the idea, the code (well most of it, see below) and the fact you released it. Thanks.
If the community involves in it, perhaps we'll get an optimised physics engine, well tested, octree/islands compatible, with lots of feature and ease that can load to tools, file based configuration/serialization, lots of samples and so on.
That's why I'm considering switching my ode code (threaded, unreadable, but functionnal and fast) for OgreOde (and contributing if possible)
So question : as you added vehicle, could/would/shall we go to toward adding helicopter, firstperson, tank, turret, grenade, mine, bomb, rockets, bullet, colliding camera, etc... objects to OgreOde or does it seems to much application oriented ?
Is there an official todo, planning ?
Now some notes and thoughts.
in ContactMapCollisionListener::getContactPtr there is a suspicious second
i = _map.find(A);
that should surely be in the first if block ?
Do you know that the MaintainedList::findItem() used by Geometry::getBody() is the major bottleneck here when having lots of objects?
so I added a _body member in geom that is updated when addbody and that is returned on getbody (at each collision*numberofstep)
I also prefer to tag each body/geoms of his object type to apply treatments to avoid using map.find() to know his type. for example, rocket a body->gettype() == rocket) where rocket is a use defined int. Got significant fps boost with that. STL map::find is somewhat costly, specially when called numberofstep*numberofcollision*numberofboxthatarenotatallarocketforsure)
(using find when knowing it's not in the container is the algo worst case...)
So an utility function to tag objects would be great ?
More generally I'm more convinced by a Object linking approach (each geom, body and Object like vehicle or wheel can have direct or indirect reference to each other.) than a general approach that would need to find() (costly operation.). The problem of find() is that complexity grows very fast as we're adding objects...
The point is to avoid the most possible calculation in all functions called by the collision callbacks, because of its huge number of calling by frame.
for example :
Code: Select all
const int num_contacts = dCollide(_geom,geometry->getGeometryID(),_max_contacts,&(_contacts[0].geom),sizeof(dContact));
if (num_contacts)
{
_contact_high_water_mark = std::max(_contact_high_water_mark,num_contacts);
const dWorldID wid = World::getSingleton().getWorldID();
const dJointGroupID cid = World::getSingleton().getContactGroupID();
const dBodyID b1 = dGeomGetBody(_geom);
const dBodyID b2 = dGeomGetBody(geometry->getGeometryID());
if(!listener)
{
for(int i = 0;i < num_contacts;i++)
{
Contact contact;
contact = &(_contacts[i]);
dJointID c = dJointCreateContact(wid,cid,&_contacts[i]);
dJointAttach(c,b1,b2);
}
}
else
{
for(int i = 0;i < num_contacts;i++)
{
Contact contact;
contact = &(_contacts[i]);
if(listener->collision(&contact))
{
dJointID c = dJointCreateContact(wid,cid,&_contacts[i]);
dJointAttach(c,b1,b2);
}
}
}
}
return num_contacts;
avoid some calculation, some branch misprediction and unused assigmenent, etc...
ps: you should really read effective stl, it enlightened me a lt on stl container and use. I've read since our map iterator story, and I don't regret it at all. (I rewrote all STL pre-reading code and speeded it successfully. (and I nearly fell in all traps the writer describes in his book... like the "container indepedent" code))