collision notification callbacks

Please don't post Bullet support questions here, use the above forums instead.
vicviper
Posts: 21
Joined: Thu Jun 01, 2006 9:55 pm

collision notification callbacks

Post by vicviper »

In my simple collision detection library, I want to notify the objects that collided with a callback, so they can act upon the collision.

The problem:

When I process a new simulation test, I create a list of collision pairs, each pair has a pointer to two objects that have collided.

Then, I iterate the list, solving each collision, AND calling the "OnCollision" of each object.

Now, what if, in response of a collision, I delete the object that collided?

the worst case scenario is that, the deleted object was also colliding with
another object, and when the next collision pair of the list is computed, it would cast a protection fault on an non existing object!

So, how physics engines solve the problem of calling back a user function, while taking care the user does not mess the whole system?

thanks in advance
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: collision notification callbacks

Post by Erwin Coumans »

vicviper wrote: So, how physics engines solve the problem of calling back a user function, while taking care the user does not mess the whole system?

thanks in advance
Most physics engines don't allow deletion, adding or moving of rigid bodies during a collision callback. Addition, removal or moving of objects is deferred until the end of the simulation step. You can implement this by storing actions (added/removed/moved objects) in a separate array, and process this array after the simulation step finished.

Hope this helps,
Erwin
Erin Catto
Posts: 316
Joined: Fri Jul 01, 2005 5:29 am
Location: Irvine

Post by Erin Catto »

Erwin, I'm guessing that solution only works with reference counting. Do you think reference counting is the way to go?
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

Why does that require reference counting?

I would prefer not to make a distiguishment between move, add and remove, and let the SDK just assert when the user tries to perform such action during a collision callback. So can't we leave the bookkeeping up to the user to move, add, remove objects outside of the collision callback?

Wouldn't it be a trivial solution for the user to postpone the removal by storing the pointers of to-be-deleted objects in their own separate array, and let them iterate over this array (and remove the object from the SDK, and then delete the object) once the simulation step is finished?

Thanks,
Erwin

On a side-note, reference counting can be useful, especially when sharing collision shapes among several rigid bodies. However, the user can also do this bookkeeping their own way. My experience is that providing reference counting to the user can open a can of worms. Distributing the ownership using reference counting can make it more complicated to keep control over object lifetime/memory usage.
Erin Catto
Posts: 316
Joined: Fri Jul 01, 2005 5:29 am
Location: Irvine

Post by Erin Catto »

Well if a user deletes a body inside a collision callback and the engine tries to defer deletion, the engine will have an orphaned pointer.

Code: Select all

world->Remove(body);
delete body;
On the other hand, with reference counting, the user would not call delete.

Code: Select all

world->Remove(body);
body->DecrementReferenceCount();
My current approach is to cache all the collision results during the physics step and then send out the messages after the step. However, there may still be situations where a user needs to modify a collision response. In that context they should not modify the physics world.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Post by Erwin Coumans »

Erin Catto wrote:Well if a user deletes a body inside a collision callback and the engine tries to defer deletion
No, the engine just asserts if the user makes such attempt. And the manual tells the user not to move, add or remove rigidbodies during a callback.

Simple and effective :-)
Erwin