Benoit CHAPEROT 2003-2004 www.jstarlab.com Support for terrain and cones, collision and drawing. Terrains can be with z up (dTerrainZ) or y up (dTerrainY). Terrains are defined by a height field. Terrains are now placeable. Terrains can now be finite or infinite (repeat themselve in the x and (y or z) directions). Terrains can potentially collide with everything that collides with planes and rays; see the switch statement. Cones currently collides only with terrain and planes and rays. Cones, with high radius to height ratios are perfect to simulate vehicle wheels on terrains. There was an error in the depths returned by dCollideTerrain. Plus now contacts are not sorted according to their depths. Contact sorting is now supposed to be done externally. Not all dCollide functions seem to sort contacts according to depth. Requesting a high number of contacts, sorting them and then considering only the most significant contacts is a good way I think to improve stability. * Cones Collisions with spheres, boxes, ccylinder and trimesh are now roughly approximated using sphere collisions. You will need to complete the following operations (with ODE 0.039): *** add to folder ode\src: dCone.cpp dTerrainY.cpp dTerrainZ.cpp collision_std_internal.h On linux => edit each .cpp file and comment out #include "windows.h" & #include "ode\ode.h" *** add to drawstuff\src\drawstuff.cpp: static void drawCone(float l, float r) { int i; float tmp,ny,nz,a,ca,sa; const int n = 24; // number of sides to the cone (divisible by 4) a = float(M_PI*2.0)/float(n); sa = (float) sin(a); ca = (float) cos(a); // draw top glShadeModel (GL_FLAT); ny=1; nz=0; // normal vector = (0,ny,nz) glBegin (GL_TRIANGLE_FAN); glNormal3d (0,0,1); glVertex3d (0,0,l); for (i=0; i<=n; i++) { if (i==1 || i==n/2+1) setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); glNormal3d (ny*r,nz*r,0); glVertex3d (ny*r,nz*r,0); if (i==1 || i==n/2+1) setColor (color[0],color[1],color[2],color[3]); // rotate ny,nz tmp = ca*ny - sa*nz; nz = sa*ny + ca*nz; ny = tmp; } glEnd(); // draw bottom ny=1; nz=0; // normal vector = (0,ny,nz) glBegin (GL_TRIANGLE_FAN); glNormal3d (0,0,-1); glVertex3d (0,0,0); for (i=0; i<=n; i++) { if (i==1 || i==n/2+1) setColor (color[0]*0.75f,color[1]*0.75f,color[2]*0.75f,color[3]); glNormal3d (0,0,-1); glVertex3d (ny*r,nz*r,0); if (i==1 || i==n/2+1) setColor (color[0],color[1],color[2],color[3]); // rotate ny,nz tmp = ca*ny + sa*nz; nz = -sa*ny + ca*nz; ny = tmp; } glEnd(); } void dsDrawCone (const float pos[3], const float R[12], float length, float radius) { if (current_state != 2) dsError ("drawing function called outside simulation loop"); setupDrawingMode(); glShadeModel (GL_SMOOTH); setTransform (pos,R); drawCone (length,radius); glPopMatrix(); if (use_shadows) { setShadowDrawingMode(); setShadowTransform(); setTransform (pos,R); drawCone (length,radius); glPopMatrix(); glPopMatrix(); glDepthRange (0,1); } } void dsDrawConeD (const double pos[3], const double R[12], float length, float radius) { int i; float pos2[3],R2[12]; for (i=0; i<3; i++) pos2[i]=(float)pos[i]; for (i=0; i<12; i++) R2[i]=(float)R[i]; dsDrawCone(pos2,R2,length,radius); } static float GetHeight(int x,int y,int nNumNodesPerSide,float *pHeights) { int nNumNodesPerSideMask = nNumNodesPerSide - 1; return pHeights[ (((unsigned int)(y) & nNumNodesPerSideMask) * nNumNodesPerSide) + ((unsigned int)(x) & nNumNodesPerSideMask)]; } void dsDrawTerrainY(int x,int z,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos) { float A[3],B[3],C[3],D[3]; float R[12]; float pos[3]; if (pR) memcpy(R,pR,sizeof(R)); else { memset(R,0,sizeof(R)); R[0] = 1.f; R[5] = 1.f; R[10] = 1.f; } if (ppos) memcpy(pos,ppos,sizeof(pos)); else memset(pos,0,sizeof(pos)); float vx,vz; vx = vLength * x; vz = vLength * z; int i; for (i=0;i add dCone.cpp, dTerrainY.cpp and dTerrainZ.cpp to the the libode_a_SOURCES variable in the ode/src/Makefile.am file. *** now you can now test using file test_boxstackb.cpp (to add in folder ode\test).