[ODE] Four little things

Martin C. Martin martin at metahuman.org
Thu Apr 15 08:08:26 MST 2004


The idea is to give dJoint "object semantics" rather than "pointer 
semantics."  In "object semantics," when you create a dJoint, the 
semantics are that you're creating a joint, and when you destroy a 
dJoint, you're destroying a dJoint.  The fact that there's a dJointID 
behind the scenes is a pure implementation detail.  As a result, each 
dJointID should be inside at most one dJoint.

So you can't just have dBody::getJoint() create a dJoint every time it 
was called.  Among other things, that would mean different calls to 
dBody::getJoint() would return different dJoint objects, even for the 
same dBody.

There are a couple ways to fix this:

- Just as dBodyIDs remember their dJointIDs, so dBodys should remember 
dJoints.  This means you can't mix the C++ and C APIs any more.  Which 
is ok, except I suspect many people would not see any warnings, no 
matter how prominent we make them, and mix them any way.  To get around 
that, we could have the compiler enforce that dFoos can't be converted 
to dFooIDs.  That makes a lot more work for whoever writes the C++ 
wrapper, and makes for more problems when the C and C++ APIs get out of 
sync.

- Add a field to the class that dJointID points to, so it can remember 
it's dJoint, if any.  But then people using the C API have to pay a 
memory cost for something they don't use.  We could use the User Data 
field for this (do Joints have them, or just geoms?), but then the user 
can't use that field.

So there doesn't appear to be a perfect solution where people using the 
C++ wrapper never need to handle dFooIDs; where a dJoint has object 
semantics; where the wrapper is small (= easy to write & maintain); that 
degrades gracefully as the C API evolves under the C++ wrapper; and that 
has no cost for people who don't use C++.  Since we had to break one of 
them, I broke the first one.

As for dMass, it's a "transparent class," in that you really want to be 
able to read and set the "total mass" and "inertia matrix" fields 
separately, and you don't want any other fields.  So it's better as a 
struct than a class.  The dSetMassXXX() functions are just convenience 
wrappers, they don't belong as member functions.  So I'm not sure what 
member functions the struct would have.

- Martin




More information about the ODE mailing list