Read Me
==========================================================================
1. INTRODUCTION
==========================================================================
Ricochet is a fast, robust library for continuous collision detection with
polygon soup geometries. It is geared toward generating contacts for
rigid body and multibody dynamics libraries.
Ricochet has been built and tested on Linux and Mac OS X. It should be
possible to port it to Windows, but we haven't done so.
==========================================================================
2. INSTALLATION
==========================================================================
Unpack the archive and, from its root directory, run:
$ python scons/scons.py
If all goes well, the library and demos will build. If not, you will
likely need to modify paths. Here are the options that the scons builder
takes from the command line:
OPTION DESCRIPTION
------------------------------------------------------
BOOST_INCLUDE_PATH The root path to where the Boost includes are located
[default=/usr/include]
BUILD_DEMOS If set to true, builds the demos in the demos subdirectory
[default=true]
DEBUG If set to true, builds Ricochet for debugging and with
logging enabled; if set to false, builds optimized code
[default=false]
DOUBLE If set to true, builds Ricochet with type double; if set
to false, builds Ricochet with type float. [default=true]
LAPACK_LIB_PATH The root path to where the LAPACK libraries are located
[default=/usr/lib]
PROFILE If set to true, builds Ricochet for profiling
[default=false]
QHULL_INCLUDE_PATH The root path to where the Qhull includes are located
[default=/usr/include]
QHULL_LIB_PATH The root path to where the Qhull libraries are located
[default=/usr/lib]
SHARED_LIBRARY If set to true, builds Ricochet as a dynamic (rather than
static) library [default=false]
Here is an example build command:
$ python scons/scons.py SHARED_LIBRARY=true DEBUG=false BOOST_INCLUDE_PATH=/opt/local/include/boost-1_35
You can generate documentation using Doxygen by running doxygen from the root
directory:
$ doxygen
==========================================================================
3. RUNNING THE DEMOS
==========================================================================
==========================================================================
4. USING RICOCHET
==========================================================================
Ricochet is very simple to use. Just create a 'Scene' object:
#include <ricochet/Scene.h>
using namespace ricochet;
...
Scene s;
...
Now, add some rigid bodies to the scene with indexed triangles:
#include <ricochet/Scene.h>
using namespace ricochet;
...
const unsigned nverts1 = 4, nverts2 = 8, ntris1 = 2, ntris2 = 12;
Real verts1[] = { -1e-6, 0, 1e6,
1e6, 0, 1e6,
1e6, 0, -1e6,
-1e6, 0, -1e6 };
Real verts2[] = { -.5, -.5, -.5,
-.5, .5, .5,
-.5, .5, -.5,
-.5, .5, .5,
.5, -.5, -.5,
.5, .5, .5,
.5, .5, -.5,
.5, .5, .5 };
const unsigned tris_plane[] = { 0, 1, 2,
2, 3, 0 };
const unsigned tris_box[] = { 0, 5, 1,
5, 0, 4,
2, 6, 7,
7, 3, 2,
5, 4, 6,
6, 7, 5,
1, 2, 7,
1, 3, 2,
1, 5, 7,
7, 3, 1,
0, 6, 4,
0, 2, 6 };
...
Scene s;
unsigned body1 = s.add_rigid_body(nverts1, verts1, ntris1, tris1);
unsigned body2 = s.add_rigid_body(nverts2, verts2, ntris2, tris2);
...
You can disable some pairs of bodies for collision checking if you wish, or
even (temporarily, one would expect) disable bodies for collision checking
with all other bodies:
...
Scene s;
unsigned body1 = s.add_rigid_body(nverts1, verts1, ntris1, tris1);
unsigned body2 = s.add_rigid_body(nverts2, verts2, ntris2, tris2);
...
s.disable_pair(body3, body4); // disable pair 3 and 4 for checking
s.disable(body7); // disable checking 7 against all other bodies
Now set the transforms for all bodies. Transforms are set non-OpenGL style
(i.e., translation is in the fourth column).
...
Scene s;
unsigned body1 = s.add_rigid_body(nverts1, verts1, ntris1, tris1);
unsigned body2 = s.add_rigid_body(nverts2, verts2, ntris2, tris2);
...
s.disable_pair(body3, body4); // disable pair 3 and 4 for checking
s.disable(body7); // disable checking 7 against all other bodies
...
s.set_transform(body1, T1);
s.set_transform(body2, T2);
...
s.set_transform(bodyN, TN);
...
Then, set the linear and angular velocities for all bodies:
...
Scene s;
unsigned body1 = s.add_rigid_body(nverts1, verts1, ntris1, tris1);
unsigned body2 = s.add_rigid_body(nverts2, verts2, ntris2, tris2);
...
s.disable_pair(body3, body4); // disable pair 3 and 4 for checking
s.disable(body7); // disable checking 7 against all other bodies
...
s.set_transform(body1, T1);
s.set_transform(body2, T2);
...
s.set_transform(bodyN, TN);
...
s.set_lvel(body1, ZEROS_3); // body 1 is stationary
s.set_avel(body1, ZEROS_3);
s.set_lvel(body2, Vector3(10,0,0));
s.set_avel(body2, ZEROS_3);
...
You can now check for contact:
...
Scene s;
unsigned body1 = s.add_rigid_body(nverts1, verts1, ntris1, tris1);
unsigned body2 = s.add_rigid_body(nverts2, verts2, ntris2, tris2);
...
s.disable_pair(body3, body4); // disable pair 3 and 4 for checking
s.disable(body7); // disable checking 7 against all other bodies
...
s.set_transform(body1, T1);
s.set_transform(body2, T2);
...
s.set_transform(bodyN, TN);
...
s.set_lvel(body1, ZEROS_3); // body 1 is stationary
s.set_avel(body1, ZEROS_3);
s.set_lvel(body2, Vector3(10,0,0));
s.set_avel(body2, ZEROS_3);
...
std::multimap<Real, Contact> contact_map;
if (!scene.is_contact(dt, contact_map))
return; // return early if no contacts
// get the first time of contact
Real TOI = contact_map.begin()->first;
...
If you modify the velocity of only some of the bodies (by treating using an
impulse-based method, for instance), you can get a substantial speed increase
by having Ricochet only examine those bodies that have changed. See the
Scene::update_contacts() function for more details.