Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ode/ode-0.9/contrib/TerrainAndCone/readme.txt @ 238

Last change on this file since 238 was 216, checked in by mathiask, 18 years ago

[Physik] add ode-0.9

File size: 10.1 KB
Line 
1Benoit CHAPEROT 2003-2004 www.jstarlab.com
2Support for terrain and cones, collision and drawing.
3
4Terrains can be with z up (dTerrainZ) or y up (dTerrainY).
5Terrains are defined by a height field.
6Terrains are now placeable.
7Terrains can now be finite or infinite (repeat themselve in the x and (y or z) directions).
8
9Terrains can potentially collide with everything that collides with planes and rays;
10see the switch statement.
11
12Cones currently collides only with terrain and planes and rays.
13Cones, with high radius to height ratios are perfect to simulate vehicle wheels on terrains.
14
15
16
17There was an error in the depths returned by dCollideTerrain.
18Plus now contacts are not sorted according to their depths.
19Contact sorting is now supposed to be done externally.
20Not all dCollide functions seem to sort contacts according to depth.
21Requesting a high number of contacts, sorting them and then considering only the most significant contacts
22is a good way I think to improve stability.
23* Cones Collisions with spheres, boxes, ccylinder and trimesh are now roughly approximated using sphere collisions.
24
25You will need to complete the following operations (with ODE 0.039):
26
27*** add to folder ode\src:
28
29dCone.cpp       
30dTerrainY.cpp
31dTerrainZ.cpp
32collision_std_internal.h
33
34On linux => edit each .cpp file and comment out     #include "windows.h"    &    #include "ode\ode.h"
35
36
37*** add to drawstuff\src\drawstuff.cpp:
38
39static void drawCone(float l, float r)
40{
41  int i;
42  float tmp,ny,nz,a,ca,sa;
43  const int n = 24;     // number of sides to the cone (divisible by 4)
44
45  a = float(M_PI*2.0)/float(n);
46  sa = (float) sin(a);
47  ca = (float) cos(a);
48
49  // draw top
50  glShadeModel (GL_FLAT);
51  ny=1; nz=0;             // normal vector = (0,ny,nz)
52  glBegin (GL_TRIANGLE_FAN);
53  glNormal3d (0,0,1);
54  glVertex3d (0,0,l);
55  for (i=0; i<=n; i++) {
56    if (i==1 || i==n/2+1)
57      setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]);
58    glNormal3d (ny*r,nz*r,0);
59    glVertex3d (ny*r,nz*r,0);
60    if (i==1 || i==n/2+1)
61      setColor (color[0],color[1],color[2],color[3]);
62
63    // rotate ny,nz
64    tmp = ca*ny - sa*nz;
65    nz = sa*ny + ca*nz;
66    ny = tmp;
67  }
68  glEnd();
69
70  // draw bottom
71  ny=1; nz=0;             // normal vector = (0,ny,nz)
72  glBegin (GL_TRIANGLE_FAN);
73  glNormal3d (0,0,-1);
74  glVertex3d (0,0,0);
75  for (i=0; i<=n; i++) {
76    if (i==1 || i==n/2+1)
77      setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]);
78    glNormal3d (0,0,-1);
79    glVertex3d (ny*r,nz*r,0);
80    if (i==1 || i==n/2+1)
81      setColor (color[0],color[1],color[2],color[3]);
82
83    // rotate ny,nz
84    tmp = ca*ny + sa*nz;
85    nz = -sa*ny + ca*nz;
86    ny = tmp;
87  }
88  glEnd();
89}
90
91void dsDrawCone (const float pos[3], const float R[12], float length, float radius)
92{
93        if (current_state != 2) dsError ("drawing function called outside simulation loop");
94        setupDrawingMode();
95        glShadeModel (GL_SMOOTH);
96        setTransform (pos,R);
97        drawCone (length,radius);
98        glPopMatrix();
99       
100        if (use_shadows) {
101                setShadowDrawingMode();
102                setShadowTransform();
103                setTransform (pos,R);
104                drawCone (length,radius);
105                glPopMatrix();
106                glPopMatrix();
107                glDepthRange (0,1);
108        }
109}
110
111void dsDrawConeD (const double pos[3], const double R[12], float length, float radius)
112{
113  int i;
114  float pos2[3],R2[12];
115  for (i=0; i<3; i++) pos2[i]=(float)pos[i];
116  for (i=0; i<12; i++) R2[i]=(float)R[i];
117  dsDrawCone(pos2,R2,length,radius);
118}
119
120static float GetHeight(int x,int y,int nNumNodesPerSide,float *pHeights)
121{
122        int nNumNodesPerSideMask = nNumNodesPerSide - 1;
123        return pHeights[        (((unsigned int)(y) & nNumNodesPerSideMask) * nNumNodesPerSide)
124                                        +        ((unsigned int)(x) & nNumNodesPerSideMask)];
125}
126
127void dsDrawTerrainY(int x,int z,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos)
128{
129        float A[3],B[3],C[3],D[3];
130        float R[12];
131        float pos[3];
132        if (pR)
133                memcpy(R,pR,sizeof(R));
134        else
135        {
136                memset(R,0,sizeof(R));
137                R[0] = 1.f;
138                R[5] = 1.f;
139                R[10] = 1.f;
140        }
141       
142        if (ppos)
143                memcpy(pos,ppos,sizeof(pos));
144        else
145                memset(pos,0,sizeof(pos));
146       
147        float vx,vz;
148        vx = vLength * x;
149        vz = vLength * z;
150       
151        int i;
152        for (i=0;i<nNumNodesPerSide;i++)
153        {
154                for (int j=0;j<nNumNodesPerSide;j++)
155                {
156                        A[0] = i * vNodeLength + vx;
157                        A[2] = j * vNodeLength + vz;
158                        A[1] = GetHeight(i,j,nNumNodesPerSide,pHeights);
159                        B[0] = (i+1) * vNodeLength + vx;
160                        B[2] = j * vNodeLength + vz;
161                        B[1] = GetHeight(i+1,j,nNumNodesPerSide,pHeights);
162                        C[0] = i * vNodeLength + vx;
163                        C[2] = (j+1) * vNodeLength + vz;
164                        C[1] = GetHeight(i,j+1,nNumNodesPerSide,pHeights);
165                        D[0] = (i+1) * vNodeLength + vx;
166                        D[2] = (j+1) * vNodeLength + vz;
167                        D[1] = GetHeight(i+1,j+1,nNumNodesPerSide,pHeights);
168                        dsDrawTriangle(pos,R,C,B,A,1);
169                        dsDrawTriangle(pos,R,D,B,C,1);
170                }
171        }
172}
173
174void dsDrawTerrainZ(int x,int z,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos)
175{
176        float A[3],B[3],C[3],D[3];
177        float R[12];
178        float pos[3];
179        if (pR)
180                memcpy(R,pR,sizeof(R));
181        else
182        {
183                memset(R,0,sizeof(R));
184                R[0] = 1.f;
185                R[5] = 1.f;
186                R[10] = 1.f;
187        }
188       
189        if (ppos)
190                memcpy(pos,ppos,sizeof(pos));
191        else
192                memset(pos,0,sizeof(pos));
193       
194        float vx,vz;
195        vx = vLength * x;
196        vz = vLength * z;
197       
198        int i;
199        for (i=0;i<nNumNodesPerSide;i++)
200        {
201                for (int j=0;j<nNumNodesPerSide;j++)
202                {
203                        A[0] = i * vNodeLength + vx;
204                        A[1] = j * vNodeLength + vz;
205                        A[2] = GetHeight(i,j,nNumNodesPerSide,pHeights);
206                        B[0] = (i+1) * vNodeLength + vx;
207                        B[1] = j * vNodeLength + vz;
208                        B[2] = GetHeight(i+1,j,nNumNodesPerSide,pHeights);
209                        C[0] = i * vNodeLength + vx;
210                        C[1] = (j+1) * vNodeLength + vz;
211                        C[2] = GetHeight(i,j+1,nNumNodesPerSide,pHeights);
212                        D[0] = (i+1) * vNodeLength + vx;
213                        D[1] = (j+1) * vNodeLength + vz;
214                        D[2] = GetHeight(i+1,j+1,nNumNodesPerSide,pHeights);
215                        dsDrawTriangle(pos,R,C,A,B,1);
216                        dsDrawTriangle(pos,R,D,C,B,1);
217                }
218        }
219}
220
221*** add to include\drawstuff\drawstuff.h:
222void dsDrawCone (const float pos[3], const float R[12], float length, float radius);
223void dsDrawConeD (const double pos[3], const double R[12], float length, float radius);
224void dsDrawTerrainY(int x,int y,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos);
225void dsDrawTerrainZ(int x,int y,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos);
226
227*** add in include\ode\collision.h line 77:
228/* class numbers - each geometry object needs a unique number */
229enum {
230  dSphereClass = 0,
231  dBoxClass,
232  dCCylinderClass,
233  dCylinderClass,
234  dPlaneClass,
235  dRayClass,
236  dGeomTransformClass,
237  dTriMeshClass,
238
239  dTerrainYClass,       //here
240  dTerrainZClass,       //here
241  dConeClass,           //here
242
243  dFirstSpaceClass,
244  dSimpleSpaceClass = dFirstSpaceClass,
245  dHashSpaceClass,
246  dQuadTreeSpaceClass,
247
248  dLastSpaceClass = dQuadTreeSpaceClass,
249
250  dFirstUserClass,
251  dLastUserClass = dFirstUserClass + dMaxUserClasses - 1,
252  dGeomNumClasses
253};
254
255dGeomID dCreateTerrainY (dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable);
256dReal dGeomTerrainYPointDepth (dGeomID g, dReal x, dReal y, dReal z);
257dGeomID dCreateTerrainZ (dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable);
258dReal dGeomTerrainZPointDepth (dGeomID g, dReal x, dReal y, dReal z);
259
260dGeomID dCreateCone(dSpaceID space, dReal radius, dReal length);
261void dGeomConeSetParams (dGeomID cone, dReal radius, dReal length);
262void dGeomConeGetParams (dGeomID cone, dReal *radius, dReal *length);
263dReal dGeomConePointDepth(dGeomID g, dReal x, dReal y, dReal z);
264
265*** add in include\ode\odemath.h:
266#define dOP(a,op,b,c) \
267  (a)[0] = ((b)[0]) op ((c)[0]); \
268  (a)[1] = ((b)[1]) op ((c)[1]); \
269  (a)[2] = ((b)[2]) op ((c)[2]);
270#define dOPC(a,op,b,c) \
271  (a)[0] = ((b)[0]) op (c); \
272  (a)[1] = ((b)[1]) op (c); \
273  (a)[2] = ((b)[2]) op (c);
274#define dOPE(a,op,b) \
275  (a)[0] op ((b)[0]); \
276  (a)[1] op ((b)[1]); \
277  (a)[2] op ((b)[2]);
278#define dOPEC(a,op,c) \
279  (a)[0] op (c); \
280  (a)[1] op (c); \
281  (a)[2] op (c);
282#define dLENGTH(a) \
283        (dSqrt( ((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]) ));
284#define dLENGTHSQUARED(a) \
285        (((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]));
286
287*** add in ode\src\collision_kernel.cpp function  'static void initColliders()'  next to other 'setCollider' calls:
288  setCollider (dTerrainYClass,dSphereClass,&dCollideTerrainY);
289  setCollider (dTerrainYClass,dBoxClass,&dCollideTerrainY);
290  setCollider (dTerrainYClass,dCCylinderClass,&dCollideTerrainY);
291  setCollider (dTerrainYClass,dRayClass,&dCollideTerrainY);
292  setCollider (dTerrainYClass,dConeClass,&dCollideTerrainY);
293
294  setCollider (dTerrainZClass,dSphereClass,&dCollideTerrainZ);
295  setCollider (dTerrainZClass,dBoxClass,&dCollideTerrainZ);
296  setCollider (dTerrainZClass,dCCylinderClass,&dCollideTerrainZ);
297  setCollider (dTerrainZClass,dRayClass,&dCollideTerrainZ);
298  setCollider (dTerrainZClass,dConeClass,&dCollideTerrainZ);
299
300  setCollider (dRayClass,dConeClass,&dCollideRayCone);
301  setCollider (dConeClass,dPlaneClass,&dCollideConePlane);
302  setCollider (dConeClass,dSphereClass,&dCollideConeSphere);
303  setCollider (dConeClass,dBoxClass,&dCollideConeBox);
304  setCollider (dCCylinderClass,dConeClass,&dCollideCCylinderCone);
305  setCollider (dTriMeshClass,dConeClass,&dCollideTriMeshCone);
306
307*** add in ode\src\collision_std.h:
308int dCollideTerrainY(dxGeom *o1, dxGeom *o2, int flags,dContactGeom *contact, int skip);
309int dCollideTerrainZ(dxGeom *o1, dxGeom *o2, int flags,dContactGeom *contact, int skip);
310
311int dCollideConePlane (dxGeom *o1, dxGeom *o2, int flags,dContactGeom *contact, int skip);
312int dCollideRayCone (dxGeom *o1, dxGeom *o2, int flags,dContactGeom *contact, int skip);
313int dCollideConeSphere(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
314int dCollideConeBox(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
315int dCollideCCylinderCone(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
316int dCollideTriMeshCone(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip);
317
318*** add dCone.cpp, dTerrainY.cpp and dTerrainZ.cpp to the the ODE_SRC variable in the makefile
319On Linux => add dCone.cpp, dTerrainY.cpp and dTerrainZ.cpp to the the libode_a_SOURCES variable in the ode/src/Makefile.am file.
320
321*** now you can now test using file test_boxstackb.cpp (to add in folder ode\test).
322
Note: See TracBrowser for help on using the repository browser.