OnCollision with Pooled objects

Topics: User Forum
Jun 30, 2009 at 9:22 PM

To make things easy in my program, I have most objects pooled (bullets, for example).  When bullets hit something, I want to deactivate them.  My DeActivate code looks like this:

public void DeActivate()
{
  PhysicsBody.Enabled = false;
  IsActive = false;
  PhysicsBody.ResetDynamics();
}

In my OnCollision event method, I call DeActivate().  However, physics aren't applied to the object it hits.

I added a bool called ToDestroy to the bullet, and instead set that to True in the OnCollision event, then do a seperate Update check after the physics engine has updated for the frame, checking if ToDestroy = true, and calling DeActivate at that time.  Is this the best solution?  I read another thread that mentioned calling Remove on the Physics body (or geom, can't remember), and that will do the same thing, but since this is a pooled object, I don't want to remove it from the simulator.  Any other ideas, or am I on the right track?

Jul 1, 2009 at 5:16 AM

I'm not sure if this is the endorsed approach, but I would suggest removing your bullet's body and geom from the sim. This should make the sim's body and geom lists as small as possible. I'm not sure whether simply deactivating would be a better solution. I suspect it will depend on a number of factors (eg number of bullets, how many are active on average etc) and would need profiling to be sure of the best approach.

Also, when you remove/deactivate your bullet, make sure you insert it back into the pool, otherwise the pool will become empty. This is all assuming that by "pool" you mean the Farseer class "Pool<T>".

Coordinator
Jul 1, 2009 at 12:51 PM

I'm not sure, but I think this is because of a bugfix that comes back to bite my every once in a while. This time it is actually ok as the behavior that happens is the expected one.

Just to give you a clue of what I am talking about: OnCollision is called right after the collision system has done all its work and right before all the physics calculations start. If you disable a body before the physics start, it will not give a reaction because the arbiter is removed. Anyway, that is what I think happens and it is actually a good thing since that is what I would expect.

Removing the geometry/body from the physics simulator on the other hand would produce the correct result. This is because geometries and bodies are removed on the next simulation update, and not the current. I would recommend to disable bodies, but if you end up in a situation like this you might want to remove them instead. It is just easier. As for the performance, I don't think that there is a lot of difference and you should worry more about the active geometries than the inactive/disabled ones.

Jul 1, 2009 at 3:07 PM

It makes perfect sense, actually...  it means that I'm forced to use a preUpdate method, and a postUdate method, in all my objects.  I was thinking of doing this anyways to get around something else...

I'm using a custom pool class, rather than the farseer pool class.  I'm still learning programming, and don't have much experience with generics yet.

Now, if a body and geom is removed from the physics simulator using Remove(), how expensive is it (in terms of time) to re-add the body and geom back to the simulator?  And is it as simple as running body.Add and Geom.Add when "reactivating" a pooled object?