[ODE] transformed groups - dGeomTransformGroup

Tim Schmidt tisch at uni-paderborn.de
Wed Jul 24 17:33:01 2002


This is a multi-part message in MIME format.
--------------010104030507030102060002
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hello list!

Yes, there was this GeomTransform thread some time ago.

The necessity of getting the corresponding bodies of dGeomGroups and 
other geoms in the nearCallback in different ways ...

    dGeomGetBody(contacts[i].geom.g1) <-> dGeomGetBody(o1)

... seem to be always confusing for people who are new to ODE.
Additionally there may be people who try to encapsulate transforms in 
groups and the other way round and wonder why the results are not as 
expected.

At that time I suggested a combination of the dGeomTransform and 
dGeomGroup but did not get much response.
Now I have remembered Russ' request for 'diff -C 2'-patches, if anybody 
wants to contribute code to the cvs.

So, here is what I have suggested. Please feel free to send any 
comments, if this is useful to you or not or what could be improved.

bye
	Tim

----------------------------------------------

This is the README that comes with the patch:
----------------------------------------------

This is a patch to add the dGeomTransformGroup object to the list of
geometry objects.

It should work with the cvs version of the ode library from
07/24/2002.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Description:

The dGeomTransformGroup is an adaption of the TransformGroup known
from Java3D (and maybe other libraries with a similar scene graph
representation).
It can be used to build an arbitrarily structured tree of objects
that are each positioned relative to the particular parent node.

If you have a plane for example, there is one root node associated
with the plane's body and another three transformgroups placed
'under' this node. One with the fuselage (cappedcylinder) under it
and two with the underlying wings (flat boxes). And if you want to
add engines, simply put them 'next to' the wings under another two
transformgroups.

bodyTG ---> associated with dBody
     |
     +--fuselageTG
     |   |
     |   +--fuselageCylinder
     |
     +--leftwingTG
     |   |
     |   +--wingBox
     |   |
     |   +--leftengineTG
     |         |
     |         +--leftengineCylinder
     |
     +--rightwingTG
         |
         +--wingBox
         |
         +--rightengineTG
               |
               +--rightengineCylinder

This is a method to easily compose objects without the necessity of
always calculating global coordinates. But apart from this there is
something else that makes dGeomTransformGroups very valuable.

Maybe you remember that some users reported the problem of acquiring
the correct bodies to be attached by a contactjoint in the
nearCallback when using dGeomGroups and dGeomTransforms at the same
time. This results from the fact that dGeomGroups are not associated
with bodies while all other geometries are.

So, as you can see in the nearCallback of the the test_buggy demo you
have to attach the contactjoint with the bodies that you get from the
geometries that are stored in the contact struct (->
dGeomGetBody(contacts[i].geom.g1)). Normally you would do this by
asking o1 and o2 directly with dGeomGetBody(o1) and dGeomGetBody(o2)
respectively.

As a first approach you can overcome that problem by testing o1 and
o2 if they are groups or not to find out how to get the corresponding
bodies.

However this will fail if you want grouped transforms that are
constructed out of dGeomTransforms encapsulated in a dGeomGroup.
According to the test you use contacts[i].geom.g1 to get the right
body. Unfortunately g1 is encapsulated in a transform and therefore
not attached to any body. In this case the dGeomTransform 'in the
middle' would have been the right object to be asked for the body.

You may now conclude that it is a good idea to unwrap the group
encapsulated geoms at the beginning of the nearcallback and use
dGeomGetBody(o1) consistently. But keep in mind that this also means
not to invoke dCollide(..) on groups at all and therefore not to
expoit the capability of dGeomGroups to speed up collision detection
by the creation of bounding boxes around the encapsulated geometry.

Everything becomes even worse if you create a dGeomTransform that
contains a dGeomGroup of geoms. The function that cares about the
collision of transforms with other objects uses the position and
rotation of the respective encapsulated object to compute its final
position and orientation. Unfortunately dGeomGroups do not have a
position and rotation, so the result will not be what you have
expected.

Here the dGeomTransformGroups comes into operation, because it
combines the advantages and capabilities of the dGeomGroup and the
dGeomTransform.
And as an effect of synergy it is now even possible to set the
position of a group of geoms with one single command.
Even nested encapsulations of dGeomTransformGroups in
dGeomTransformGroups should be possible (to be honest, I have not
tried that so far ;-) ).

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

API:

dGeomID dCreateGeomTransformGroup (dSpaceID space);
   - create a GeomTransformGroup

void dGeomTransformGroupAddGeom    (dGeomID tg, dGeomID obj);
   - Comparable to dGeomTransformSetGeom or dGeomGroupAdd
   - add objects to this group

void dGeomTransformGroupRemoveGeom (dGeomID tg, dGeomID obj);
   - remove objects from this group

void dGeomTransformGroupSetRelativePosition
             (dGeomID g, dReal x, dReal y, dReal z);
void dGeomTransformGroupSetRelativeRotation
             (dGeomID g, const dMatrix3 R);
   - Comparable to setting the position and rotation of all the
     dGeomTransform encapsulated geometry. The difference
     is that it is global with respect to this group and therefore
     affects all geoms in this group.
   - The relative position and rotation are attributes of the
     transformgroup, so the position and rotation of the individual
     geoms are not changed

const dReal * dGeomTransformGroupGetRelativePosition (dGeomID g);
const dReal * dGeomTransformGroupGetRelativeRotation (dGeomID g);
   - get the relative position and rotation

dGeomID dGeomTransformGroupGetGeom (dGeomID tg, int i);
   - Comparable to dGeomGroupGetGeom
   - get a specific geom of the group

int dGeomTransformGroupGetNumGeoms (dGeomID tg);
   - Comparable to dGeomGroupGetNumGeoms
   - get the number of geoms in the group


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

How to apply this patch:

if you are unsure, first call:

   patch --dry-run --verbose -p1 -d path_to_ODE_root_directory/ \
   < path_to_patch_file/addTransformGroupsToODE.patch

The output should be:

   Hmm...  Looks like a new-style context diff to me...
   The text leading up to this was:
   --------------------------
   |diff -C 5 -rN ode_original/include/ode/geom.h
                  ode_modified/include/ode/geom.h
   |*** ode_original/include/ode/geom.h	Wed Jun 26 01:46:15 2002
   |--- ode_modified/include/ode/geom.h	Wed Jul 24 20:39:28 2002
   --------------------------
   Patching file include/ode/geom.h using Plan A...
   Hunk #1 succeeded at 137.
   Hmm...  The next patch looks like a new-style context diff to me...
   The text leading up to this was:
   --------------------------
   |diff -C 5 -rN ode_original/ode/src/geom.cpp
                  ode_modified/ode/src/geom.cpp
   |*** ode_original/ode/src/geom.cpp	Wed Jun 26 01:46:18 2002
   |--- ode_modified/ode/src/geom.cpp	Wed Jul 24 20:35:33 2002
   --------------------------
   Patching file ode/src/geom.cpp using Plan A...
   Hunk #1 succeeded at 1847.
   done

If this works fine, invoke the same command without "--dry-run"

   patch -p1 -d path_to_ODE_root_directory/ \
   < path_to_patch_file/addTransformGroupsToODE.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Tim Schmidt
student of computer science
University of Paderborn, Germany
tisch@uni-paderborn.de

--------------010104030507030102060002
Content-Type: application/x-gzip;
 name="odePatch_addTransformGroups_2002-07-24.tgz"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
 filename="odePatch_addTransformGroups_2002-07-24.tgz"

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
--------------010104030507030102060002--