[ODE] Trimesh/trimesh collision code

Jeffrey Smith jeffreys at Softimage.com
Mon Feb 9 16:44:04 MST 2004


A few months ago, I wrote some servicable Trimesh/Trimesh collision
code.  I've tested it extensively, and it appears to perform quite
well.  There are three minor caveats:

1) The stepsize you use will, in general, have to be reduced for
   accurate collision resolution.  Non-convex shape collision is much
   more dependent on the collision geometry than primitive collisions.
   Further, the local contact geometry will change more rapidly (and
   in a more complex fashion) for non-convex polytopes than it does
   for simple, convex polytopes such as spheres and cubes.

2) I have changed dGeomTriMeshDataBuildSingle to accept (but not
   require) a new argument: the normals of the faces of each trimesh
   object, e.g.

         dTriMeshDataID TriMeshData;
         TriMeshData = dGeomTriMeshGetTriMeshDataID( Bodies[ BodyIndex ].GeomID );

         // as long as dReal == floats
         dGeomTriMeshDataBuildSingle(TriMeshData,
                                     // Vertices
                                     Bodies[BodyIndex].VertexPositions,
                                     3*sizeof(dReal), (int) numVertices,
                                     // Faces
                                     Bodies[BodyIndex].TriangleIndices, 
                                     (int) NumTriangles, 3*sizeof(unsigned int),
                                     // Normals
                                     Bodies[BodyIndex].FaceNormals);

   This pre-calculation saves some time during evaulation of the
   conacts, but isn't necessary.  If you don't want to calculate
   the face normals before construction (or if you have enormous
   trimeshes and know that only very few faces will be touching
   and want to save time), just pass a "NULL" for the last argument,
   and dCollideTTL will take care of the normal calcuations itself.

3) In order to efficiently resolve collisions, dCollideTTL needs
   the positions of the colliding trimeshes in the previous timestep.
   I use this to calculate an estimated velocity of each colliding
   triangle, which is used to find the direction of impact, contact
   normals, etc.  This requires changes to a few files, as well as
   requiring the user to update these variables at every timestep.
   Personally, I do this update outside of ODE, so it is not included
   in ODE itself.  The code to do this looks something like this:

           const double *DoubleArrayPtr =  Bodies[BodyIndex].TransformationMatrix->GetArray();
           dGeomTriMeshDataSet( TriMeshData,
                                TRIMESH_LAST_TRANSFORMATION,
                                (void *) DoubleArrayPtr );

   The transformation matrix is the standard 4x4 homogenous transform
   matrix, and the "DoubleArray" is the standard flattened array of 
   the 16 matrix values. 


I've sent the files that this new feature affects:

 collision_kernel.cpp
 collision_trimesh.cpp
 collision_trimesh_internal.h
 collision_trimesh_trimesh.cpp
 collision_trimesh.h
 Makefile

to Martin Martin for testing, etc.  

I haven't merged these with the latest CVS drop, so there will need
to be some minor merging by the ODE maintainers.  Please let me know
if there are conflicts that you need me to resolve.  (I also added
some code to the Makefile to make a shared object version of libode;
feel free to remove this if it's unwanted).

Finally, I also have new Trimesh/Bbox collision code which fixes the
(significant) bugs I've mentioned in other emails.  However, I'm not
as happy with the quality of this code so I'll hold back on
contributing it until I've fixed it up a bit.  If the ODE community
really wants this (working, but ugly) implementation, let me know and
I'll contribute it.


-Jeff



More information about the ODE mailing list