Disregard collision response

Topics: User Forum
Aug 31, 2011 at 12:25 PM

I am in a situation where I need to detect and respond to collisions without any actual physics updating happening.  It's in a level editor, with a "Play" button allowing me to begin the simulation.  However, when it's not playing, I need to detect collisions (sensors, mainly).  I thought that passing 0 seconds to the update function would accomplish this (nothing moves, but collisions are detected), but there must be some kind of short-circuiting that skips collision detection if update is set to 0.  I thought of doing broadphase and point-test with manual calls on the World object, but this is an inelegant and inefficient solution.  Anyone have any ideas?

Aug 31, 2011 at 10:32 PM

Suscribe to all collisions and make them all return false.

Aug 31, 2011 at 10:46 PM

This is an inelegant, inefficient, and incomplete solution.  It doesn't account for bodies that are already in motion, nor various force controllers (gravity among them).  It would require me to subscribe and unsubscribe from EVERY fixture *each time* the simulation was started/stopped, or force my way into the object creation process more than I am willing to do.  It would require me to loop through every object and ClearForces() on it, saving them to reapply later, set gravity to zero and remove/cache all other force controllers.

Sep 1, 2011 at 2:34 PM

(Uhg, just wrote up this long reply to my solution, and it got deleted in a server request error =(  This will probably be less eloquent.)

So, after digging into the internals of the Farseer Step function, it seems to follow these steps:

  1. Process cached Add/Removes before we start doing anything
  2. Short-circuit and return if dt == 0
  3. Find any new contacts that might have occurred.
  4. Create a TimeStep and update the controllers
  5. Run "Collide", which updates any existing contacts and deletes obsolete ones
  6. Do collision response (including TOI)
  7. Update breakable bodies separately.

At first I tried just removing the dt==0 check, but that led to all kinds of issues (divide by zero when we calculate inv_dt, it still builds up torque and forces while paused, so once you unpause it the simulation explodes, etc.)  I'm not familiar with what kinds of assumptions are made for the ordering of these events, so my solution could have screwed something subtle up that's going to come back to bite me in the ass later.  If one of the developers could weigh in on this, I'd be greatly appreciative.  Anyway, I reordered things to happen like this:

  1. Process cached Add/Remove before we start doing anything
  2. Find new contacts that might have occurred.
  3. Run "Collide", which updates any existing contacts and deletes obsolete ones
  4. ShortCircuit on dt==0
  5. Create a timestep and update the controllers
  6. Do collision Response (Including TOI)
  7. Update breakable bodies separately.

It seems to be working (I get all the appropriate callbacks whether the simulation is paused or not), but I haven't done any rigorous accuracy-verification.  Here's the code if anyone wants it: http://pastebin.com/cKy5G6DT