[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.7.7 Catastrophes

A catastrophe is an event where there is a discontinuity in the system and the ODE solver can't cope with it. So you need to resolve the catastrophe situation before the system can be evolved any further. The main catastrophe event (actually the only one used in most rigid-body simulations) we deal with is a collision. So I use the terms catastrophe and collision interchangeably here.

Setting Up a Collision Catastrophe

Note: There is no collision detection capability in `csphyziks'. Ben Sprague has been making good progress on one and hopefully it will be integrated in the future. SOLID is a pretty decent GPL collision detection engine that works well for colliding contacts, although it requires a few more features before it can be used for resting contact.

First thing you need to do is subclass `ctCatastropheManager' and implement check_catastrophe() which returns a value greater 0 if there was a catastrophe, and handle_catastrophe() which will be called when the simulation has been backed up to a point just before the first catastrophe was encountered (within the catastrophe defined epsilon of time). Then you add your `ctCatastropheManager' to the world using:

 
ctWorld::register_catastrophe_manager(
  ctCatastropheManager* your_cat_manager);

Now every time you call ctWorld::evolve(real t1, real t2) it will make a callback to check_catastrophe() where you do your collision (or whatever) check using the position and orientations of the rigid bodies at that time. If there was a collision, keep track of what objects collided and return the maximum interpenetration distance (or just a number greater than 0 if you like). If there was no collision return 0. Now the physics engine will rewind the state of the system and call check_catastrophe() again, and repeat until you finally return 0, indicating there was no catastrophe.

Now the physics engine will make a callback to handle_catastrophe() where you must resolve all catastrophes that occurred during the most recent call to check_catastrophe(), so you need to maintain a list of those objects that collided last check. In the case of resolving collisions you need to fill out a `ctCollidingContact' object and pass it to ctWorld::resolve_collision() for each collision, which will apply an impulse to both bodies and send them on a path away from each other.

A couple of things need to be explained. The collision normal and contact point must be figured out by the collision detection routines, which are not part of the `csphyziks' library. The collision normal is the vector that specifies what component of the objects momentum to bounce back.

The collision normal is calculated once you know what features of each object collided. If it was a vertex or edge of one object hitting a face of another object, the collision normal is just the normal of that face. If it is an edge-edge collision the normal is the cross-product (normalized) of those two edges. Or you can just take a best guess if you don't have a very accurate collision detection system.

To find the exact time of collision involves rewinding the `csphyziks' simulation and trying with smaller time steps until `csphyziks' has reached a minimum collision distance. This can be quite a time-consuming process.

The collision response code does not accurately handle multiple points of simultaneous collision on one object.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html