Keep track of current colliding objects

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
jlongstreet
Posts: 8
Joined: Mon Jul 04, 2011 8:00 pm

Keep track of current colliding objects

Post by jlongstreet »

We currently keep track of the actors currently colliding with each actor. The way we do this is by adding the CollidablePairHandler passed to the InitialCollisionDetected delegate to a list stored on the actor, and removing it in the CollisionEnded delegate.

This seems to be unsafe, and I probably should have paid more attention to the Collision Events documentation page, which says "References to these objects should not be kept outside of the event handler."

My question boils down to the best way to keep track of current collision pairs and the contacts in them. My current thought is to create a class that effectively mirrors the data I need from CollidablePairHandler:

Code: Select all

class MyCollisionPair
{
    class Contact
    {
        Vector3 Normal;
        Vector3 Position;
    }

    Collection<Contact> ContactCollection;
    Actor OtherActor;
}
and then switch my collision list to use these, updating them on InitialCollisionDetected/CollisionEnded, and updating the contacts on ContactCreated/ContactRemoved.

Does this make sense? Is there a simpler approach, or is there some similar collection on Entity or Collidable that I can access both outside the context of Space.Update() and inside collision event handlers?

Also, in this case, there's a couple issues I could see cropping up:
1) If ContactCreated is called before InitialCollisionDetected when the first contact is created on a pair, I won't have a corresponding MyCollisionPair yet. I could always ignore ContactCreated for a nonexistent pair, and then add all the contacts in the pair's ContactCollection on InitialCollisionDetected. Does this seem reasonable?
2) If an existing contact has a new position/normal, is a new contact created, or is the old one updated? If the old one is updated, then how do I update my client-side version?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keep track of current colliding objects

Post by Norbo »

It would probably be easiest to use the EntityCollidable's listing.

Specifically, you can get all CollidablePairHandlers associated with an entity by using its entity.CollisionInformation.Pairs property. Every CollidablePairHandler has a Contacts list. The Contacts list provides direct access to the current Contact object, as well as the normal force, friction force, relative velocity, and CollidablePairHandler that most directly owns the Contact (some types of collisions have nested CollidablePairHandlers, like compound-compound).

Edit for a bit more general info:
This can be used in deferred events or externally to the engine. It should technically work in immediate events as well, though immediate events provide you the contact directly (if a contact is involved).
If an existing contact has a new position/normal, is a new contact created, or is the old one updated?
A contact update does not trigger an event.
jlongstreet
Posts: 8
Joined: Mon Jul 04, 2011 8:00 pm

Re: Keep track of current colliding objects

Post by jlongstreet »

If I'm not mistaken, doesn't the Collidable.Pairs list contain all pairs that are in the NarrowPhase, meaning that they don't necessarily have any contacts? I'm definitely seeing collidables with pairs in their Pairs list that have no contacts.

What I need is a collection of pairs that have contacts, both from deferred event handlers and outside the space update. The contacts also need to be up-to-date, so ideally I would reference the pairs within the engine themselves instead of mirroring them.

Is there anything that would satisfy this outside of filtering the pairs list for pairs with contacts?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keep track of current colliding objects

Post by Norbo »

Is there anything that would satisfy this outside of filtering the pairs list for pairs with contacts?
The engine does not explicitly keep track of only pairs with contacts. If it were internally supported, it would take the form of a create a wrapping enumerable that contained the pairs collection and only returned pairs with a nonzero contact count. I'd like to avoid implementing too many arbitrary features, though, so it would be best to do something like this externally.
Post Reply