[ODE] Re: Copying/Cloning Composite Objects
john rieffel
jrieffel at gmail.com
Sat Aug 20 13:34:25 MST 2005
Hi Again,
Here is my updated code for copying/cloning bodies and their
associated geoms, including geom transforms. The MyObject class is
the same used in the dropstuff example (which my entire code base grew
out of, if you hadn't noticed). The biggest "catch" was making sure
that every geom E that is encapsulated by a transform T is removed
from the space. (I don't know how to *create* geoms without inserting
them into the space-- if there's such a way then maybe the code could
be more elegant). I'm rather happy with the result, and would welcome
any comments and critique:
Again, my code only cares about box geoms now - but it's pretty
obvious how you'd insert code to copy any other kind of geom. Enjoy.
MyObject ODEWorld::copyObject(MyObject inobj)
{
MyObject newobj;
memset (&newobj,0,sizeof(MyObject));
newobj.rc = inobj.rc;
newobj.gc = inobj.gc;
newobj.bc = inobj.bc;
//create it
newobj.body = dBodyCreate(world);
//copy the mass accordingly
dMass fromMass;
dBodyGetMass(inobj.body,&fromMass);
dMass newmass;
dMassSetZero(&newmass);
dMassAdd(&newmass,&fromMass);
dBodySetMass(newobj.body,&newmass);
// set the position and rotation accordingly
const dReal *inpos = dBodyGetPosition (inobj.body);
const dReal *r2 = dBodyGetRotation(inobj.body);
dBodySetPosition(newobj.body,inpos[0],inpos[1],inpos[2]);
dBodySetRotation(newobj.body,r2);
for (int i = 0; i < GPB; i++)
{
if (inobj.geom[i] != NULL)
{
//copy each associated geom
newobj.geom[i] = copyGeom(inobj.geom[i]);
//set its body
dGeomSetBody(newobj.geom[i],newobj.body);
}
else
newobj.geom[i] = NULL;
}
return newobj;
}
dGeomID ODEWorld::copyGeom(dGeomID ingeom)
{
dGeomID copiedGeom = NULL;
if (dGeomGetClass(ingeom) == dGeomTransformClass)
{
copiedGeom = dCreateGeomTransform(space);
dGeomTransformSetCleanup (copiedGeom,1);
dGeomID subGeom = copyGeom(dGeomTransformGetGeom(ingeom));
dGeomTransformSetGeom (copiedGeom, subGeom);
// the manual says that if T is a transform encapsulating geom E
// then E should NOT be inserted into the space.
// we fix this by removing it after copying
// indeed - this resolves most weird problems i had
dSpaceRemove(space,subGeom);
}
else if (dGeomGetClass(ingeom) == dBoxClass)
{
dVector3 sides;
dGeomBoxGetLengths(ingeom, sides);
copiedGeom = dCreateBox(space,sides[0],sides[1],sides[2]);
const dReal *r2 = dGeomGetRotation(ingeom);
dGeomSetRotation(copiedGeom,r2);
const dReal *inpos = dGeomGetPosition (ingeom);
dGeomSetPosition(copiedGeom,inpos[0],inpos[1],inpos[2]);
}
else
{
printf("ODEWorld::copyGeom - I don't know how to copy geom class
%d\n",dGeomGetClass(ingeom));
}
return copiedGeom;
}
More information about the ODE
mailing list