aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ode-0.9/contrib/GeomTransformGroup
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ode-0.9/contrib/GeomTransformGroup')
-rw-r--r--libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.cpp218
-rw-r--r--libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.h29
-rw-r--r--libraries/ode-0.9/contrib/GeomTransformGroup/README.txt148
3 files changed, 395 insertions, 0 deletions
diff --git a/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.cpp b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.cpp
new file mode 100644
index 0000000..26b77b0
--- /dev/null
+++ b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.cpp
@@ -0,0 +1,218 @@
1
2/* ************************************************************************ */
3/*
4 grouped and transformed geometry functions
5 author: Tim Schmidt tisch@uni-paderborn.de
6*/
7
8
9#include <ode/common.h>
10#include <ode/geom.h>
11#include <ode/rotation.h>
12#include <ode/odemath.h>
13#include <ode/memory.h>
14#include <ode/misc.h>
15#include <ode/objects.h>
16#include <ode/matrix.h>
17#include <ode/GeomTransformGroup.h>
18#include "objects.h"
19#include "array.h"
20#include "geom_internal.h"
21
22// given a pointer `p' to a dContactGeom, return the dContactGeom at
23// p + skip bytes.
24
25#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip)))
26
27
28// ############################################################################
29
30int dGeomTransformGroupClass = -1;
31// ############################################################################
32
33struct dxGeomTransformGroup {
34 dArray<dxGeom*> parts; // all the geoms that make up the group
35 dVector3 relativePosition;
36 dMatrix3 relativeRotation;
37};
38// ############################################################################
39
40void dGeomTransformGroupSetRelativePosition (dxGeom *g, dReal x, dReal y, dReal z)
41{
42 dAASSERT (g);
43 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
44 transformGroup->relativePosition[0] = x;
45 transformGroup->relativePosition[1] = y;
46 transformGroup->relativePosition[2] = z;
47}
48// ############################################################################
49
50void dGeomTransformGroupSetRelativeRotation (dxGeom *g, const dMatrix3 R)
51{
52 dAASSERT (g);
53 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
54 memcpy (transformGroup->relativeRotation,R,sizeof(dMatrix3));
55}
56// ############################################################################
57
58const dReal * dGeomTransformGroupGetRelativePosition (dxGeom *g)
59{
60 dAASSERT (g);
61 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
62 return transformGroup->relativePosition;
63}
64// ############################################################################
65
66const dReal * dGeomTransformGroupGetRelativeRotation (dxGeom *g)
67{
68 dAASSERT (g);
69 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
70 return transformGroup->relativeRotation;
71}
72// ############################################################################
73
74static void computeFinalTransformation (const dxGeom *tg, const dxGeom *part)
75{
76 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(tg);
77 dMULTIPLY0_331 (part->pos,tg->R,transformGroup->relativePosition);
78 part->pos[0] += tg->pos[0];
79 part->pos[1] += tg->pos[1];
80 part->pos[2] += tg->pos[2];
81 dMULTIPLY0_333 (part->R,tg->R,transformGroup->relativeRotation);
82}
83// ############################################################################
84
85int dCollideTransformGroup (const dxGeom *o1, const dxGeom *o2, int flags,
86 dContactGeom *contact, int skip)
87{
88 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(o1);
89 if (transformGroup->parts.size() == 0)
90 {
91 return 0;
92 }
93 int numleft = flags & NUMC_MASK;
94 if (numleft == 0) numleft = 1;
95 flags &= ~NUMC_MASK;
96 int num=0, i=0;
97 while (i < transformGroup->parts.size() && numleft > 0)
98 {
99 dUASSERT (transformGroup->parts[i]->spaceid==0,
100 "GeomTransformGroup encapsulated object must not be in a space");
101 dUASSERT (transformGroup->parts[i]->body==0,
102 "GeomTransformGroup encapsulated object must not be attached to a body");
103 if (!o1->space_aabb)
104 {
105 computeFinalTransformation (o1, transformGroup->parts[i]);
106 }
107 dxBody *bodyBackup = transformGroup->parts[i]->body;
108 transformGroup->parts[i]->body = o1->body;
109 int n = dCollide (transformGroup->parts[i],const_cast<dxGeom*>(o2),
110 flags | numleft,contact,skip);
111 transformGroup->parts[i]->body = bodyBackup;
112 contact = CONTACT (contact,skip*n);
113 numleft -= n;
114 num += n;
115 i++;
116 }
117 return num;
118}
119// ############################################################################
120
121static dColliderFn * dGeomTransformGroupColliderFn (int num)
122{
123 return (dColliderFn *) &dCollideTransformGroup;
124}
125// ############################################################################
126
127static void dGeomTransformGroupAABB (dxGeom *geom, dReal aabb[6])
128{
129 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(geom);
130 aabb[0] = dInfinity;
131 aabb[1] = -dInfinity;
132 aabb[2] = dInfinity;
133 aabb[3] = -dInfinity;
134 aabb[4] = dInfinity;
135 aabb[5] = -dInfinity;
136 int i,j;
137 for (i=0; i < transformGroup->parts.size(); i++)
138 {
139 computeFinalTransformation (geom, transformGroup->parts[i]);
140 dReal aabb2[6];
141 transformGroup->parts[i]->_class->aabb (transformGroup->parts[i],aabb2);
142 for (j=0; j<6; j += 2) if (aabb2[j] < aabb[j]) aabb[j] = aabb2[j];
143 for (j=1; j<6; j += 2) if (aabb2[j] > aabb[j]) aabb[j] = aabb2[j];
144 }
145}
146// ############################################################################
147
148static void dGeomTransformGroupDtor (dxGeom *geom)
149{
150 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(geom);
151 transformGroup->parts.~dArray();
152}
153// ############################################################################
154
155dxGeom *dCreateGeomTransformGroup (dSpaceID space)
156{
157 if (dGeomTransformGroupClass == -1) {
158 dGeomClass c;
159 c.bytes = sizeof (dxGeomTransformGroup);
160 c.collider = &dGeomTransformGroupColliderFn;
161 c.aabb = &dGeomTransformGroupAABB;
162 c.aabb_test = 0;
163 c.dtor = dGeomTransformGroupDtor;
164 dGeomTransformGroupClass = dCreateGeomClass (&c);
165 }
166 dxGeom *g = dCreateGeom (dGeomTransformGroupClass);
167 if (space)
168 {
169 dSpaceAdd (space,g);
170 }
171 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
172 transformGroup->parts.constructor();
173 dSetZero (transformGroup->relativePosition,4);
174 dRSetIdentity (transformGroup->relativeRotation);
175 return g;
176}
177// ############################################################################
178
179void dGeomTransformGroupAddGeom (dxGeom *g, dxGeom *obj)
180{
181 dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
182 "argument not a geom TransformGroup");
183 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
184 transformGroup->parts.push (obj);
185}
186// ############################################################################
187
188void dGeomTransformGroupRemoveGeom (dxGeom *g, dxGeom *obj)
189{
190 dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
191 "argument not a geom TransformGroup");
192 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
193 for (int i=0; i < transformGroup->parts.size(); i++) {
194 if (transformGroup->parts[i] == obj) {
195 transformGroup->parts.remove (i);
196 return;
197 }
198 }
199}
200// ############################################################################
201
202dxGeom * dGeomTransformGroupGetGeom (dxGeom *g, int i)
203{
204 dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
205 "argument not a geom TransformGroup");
206 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
207 dAASSERT (i >= 0 && i < transformGroup->parts.size());
208 return transformGroup->parts[i];
209}
210// ############################################################################
211
212int dGeomTransformGroupGetNumGeoms (dxGeom *g)
213{
214 dUASSERT (g && g->_class->num == dGeomTransformGroupClass,
215 "argument not a geom TransformGroup");
216 dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g);
217 return transformGroup->parts.size();
218}
diff --git a/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.h b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.h
new file mode 100644
index 0000000..705fdb9
--- /dev/null
+++ b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.h
@@ -0,0 +1,29 @@
1
2/* ************************************************************************ */
3/*
4 grouped and transformed geometry functions
5 author: Tim Schmidt tisch@uni-paderborn.de
6*/
7
8
9#ifdef __cplusplus
10extern "C" {
11#endif
12
13
14extern int dGeomTransformGroupClass;
15
16void dGeomTransformGroupSetRelativePosition (dGeomID g, dReal x, dReal y, dReal z);
17void dGeomTransformGroupSetRelativeRotation (dGeomID g, const dMatrix3 R);
18const dReal * dGeomTransformGroupGetRelativePosition (dxGeom *g);
19const dReal * dGeomTransformGroupGetRelativeRotation (dxGeom *g);
20dGeomID dCreateGeomTransformGroup (dSpaceID space);
21void dGeomTransformGroupAddGeom (dGeomID tg, dGeomID obj);
22void dGeomTransformGroupRemoveGeom (dGeomID tg, dGeomID obj);
23dGeomID dGeomTransformGroupGetGeom (dGeomID tg, int i);
24int dGeomTransformGroupGetNumGeoms (dGeomID tg);
25
26
27#ifdef __cplusplus
28}
29#endif
diff --git a/libraries/ode-0.9/contrib/GeomTransformGroup/README.txt b/libraries/ode-0.9/contrib/GeomTransformGroup/README.txt
new file mode 100644
index 0000000..bca0e66
--- /dev/null
+++ b/libraries/ode-0.9/contrib/GeomTransformGroup/README.txt
@@ -0,0 +1,148 @@
1README for GeomTransformGroup by Tim Schmidt.
2---------------------------------------------
3
4This is a patch to add the dGeomTransformGroup object to the list of geometry
5objects.
6
7It should work with the cvs version of the ode library from 07/24/2002.
8
9++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
10
11comment by russ smith: this code is easy to use with the rest of ODE.
12simply copy GeomTransformGroup.cpp to ode/src and copy GeomTransformGroup.h
13to include/ode. then add GeomTransformGroup.cpp to the ODE_SRC variable
14in the makefile. rebuild, and you're done! of course i could have done all
15this for you, but i prefer to keep GeomTransformGroup separated from the
16rest of ODE for now while other issues with the collision system are
17resolved.
18
19++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20
21
22Description:
23
24The dGeomTransformGroup is an adaption of the TransformGroup known from
25Java3D (and maybe other libraries with a similar scene graph representation).
26It can be used to build an arbitrarily structured tree of objects that are
27each positioned relative to the particular parent node.
28
29If you have a plane for example, there is one root node associated with the
30plane's body and another three transformgroups placed 'under' this node. One
31with the fuselage (cappedcylinder) under it and two with the underlying wings
32(flat boxes). And if you want to add engines, simply put them 'next to' the
33wings under another two transformgroups.
34
35bodyTG ---> associated with dBody
36 |
37 +--fuselageTG
38 | |
39 | +--fuselageCylinder
40 |
41 +--leftwingTG
42 | |
43 | +--wingBox
44 | |
45 | +--leftengineTG
46 | |
47 | +--leftengineCylinder
48 |
49 +--rightwingTG
50 |
51 +--wingBox
52 |
53 +--rightengineTG
54 |
55 +--rightengineCylinder
56
57This is a method to easily compose objects without the necessity of always
58calculating global coordinates. But apart from this there is something else
59that makes dGeomTransformGroups very valuable.
60
61Maybe you remember that some users reported the problem of acquiring the
62correct bodies to be attached by a contactjoint in the nearCallback when
63using dGeomGroups and dGeomTransforms at the same time. This results from the
64fact that dGeomGroups are not associated with bodies while all other
65geometries are.
66
67So, as you can see in the nearCallback of the the test_buggy demo you have to
68attach the contactjoint with the bodies that you get from the geometries that
69are stored in the contact struct (-> dGeomGetBody(contacts[i].geom.g1)).
70Normally you would do this by asking o1 and o2 directly with dGeomGetBody(o1)
71and dGeomGetBody(o2) respectively.
72
73As a first approach you can overcome that problem by testing o1 and o2 if
74they are groups or not to find out how to get the corresponding bodies.
75
76However this will fail if you want grouped transforms that are constructed
77out of dGeomTransforms encapsulated in a dGeomGroup. According to the test
78you use contacts[i].geom.g1 to get the right body. Unfortunately g1 is
79encapsulated in a transform and therefore not attached to any body. In this
80case the dGeomTransform 'in the middle' would have been the right object to
81be asked for the body.
82
83You may now conclude that it is a good idea to unwrap the group encapsulated
84geoms at the beginning of the nearcallback and use dGeomGetBody(o1)
85consistently. But keep in mind that this also means not to invoke
86dCollide(..) on groups at all and therefore not to expoit the capability of
87dGeomGroups to speed up collision detection by the creation of bounding boxes
88around the encapsulated geometry.
89
90Everything becomes even worse if you create a dGeomTransform that contains a
91dGeomGroup of geoms. The function that cares about the collision of
92transforms with other objects uses the position and rotation of the
93respective encapsulated object to compute its final position and orientation.
94Unfortunately dGeomGroups do not have a position and rotation, so the result
95will not be what you have expected.
96
97Here the dGeomTransformGroups comes into operation, because it combines the
98advantages and capabilities of the dGeomGroup and the dGeomTransform.
99And as an effect of synergy it is now even possible to set the position of a
100group of geoms with one single command.
101Even nested encapsulations of dGeomTransformGroups in dGeomTransformGroups
102should be possible (to be honest, I have not tried that so far ;-) ).
103
104++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
105
106API:
107
108dGeomID dCreateGeomTransformGroup (dSpaceID space);
109 - create a GeomTransformGroup
110
111void dGeomTransformGroupAddGeom (dGeomID tg, dGeomID obj);
112 - Comparable to dGeomTransformSetGeom or dGeomGroupAdd
113 - add objects to this group
114
115void dGeomTransformGroupRemoveGeom (dGeomID tg, dGeomID obj);
116 - remove objects from this group
117
118void dGeomTransformGroupSetRelativePosition
119 (dGeomID g, dReal x, dReal y, dReal z);
120void dGeomTransformGroupSetRelativeRotation
121 (dGeomID g, const dMatrix3 R);
122 - Comparable to setting the position and rotation of all the
123 dGeomTransform encapsulated geometry. The difference
124 is that it is global with respect to this group and therefore
125 affects all geoms in this group.
126 - The relative position and rotation are attributes of the
127 transformgroup, so the position and rotation of the individual
128 geoms are not changed
129
130const dReal * dGeomTransformGroupGetRelativePosition (dGeomID g);
131const dReal * dGeomTransformGroupGetRelativeRotation (dGeomID g);
132 - get the relative position and rotation
133
134dGeomID dGeomTransformGroupGetGeom (dGeomID tg, int i);
135 - Comparable to dGeomGroupGetGeom
136 - get a specific geom of the group
137
138int dGeomTransformGroupGetNumGeoms (dGeomID tg);
139 - Comparable to dGeomGroupGetNumGeoms
140 - get the number of geoms in the group
141
142
143++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
144
145Tim Schmidt
146student of computer science
147University of Paderborn, Germany
148tisch@uni-paderborn.de