Rejecting contacts in collision handlers

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Mishkin
Posts: 2
Joined: Mon Oct 15, 2012 4:03 am

Rejecting contacts in collision handlers

Post by Mishkin »

Hi,

Is there a way to reject a contact after it has been created, but before it has an impact on the scene? I would like to be able to have a contact's info be created and then run some logic that might decide to throw away (ignore) the contact. When this happens, two bodies would pass right through each other.

I've tried calling ClearContacts() on the CollidablePairHandler inside the DetectingInitialCollision event. That works for non-compound collisions, but for a compound collision, there is a "leak" in the call "this.Parent.AddSolverUpdatable(...)" inside StandardPairHandler::UpdateCollision(). RemoveSolverUpdatable() does not get called and so an exception is thrown on the next update because the updatable is still attached to the parent solver.

I also tried calling ClearContacts() inside the CreatingContact event. This works, but causes an out of bounds exception during the call to this.Remove(0) inside SphereContactManifold::Update() because the contact was removed but the manifold is tracking it as if it were added.

Is there a better way to go about this? Alternatively, is there a way to just listen to when contacts would be created, but not have them created at all?

Thanks.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Rejecting contacts in collision handlers

Post by Norbo »

Most operations should be assumed to be unsafe within immediate events; adjusting pair state during pair execution requires some finesse. ClearContacts() is akin to bludgeoning the state of the pair into submission. I can see why ClearContacts would appear to be a safe since it's just (ostensibly) modifying the pair's local state and has no big warning messages about its usage; I'll see if it can be made a little safer or at least make its use clearer when I get a chance.
Is there a better way to go about this? Alternatively, is there a way to just listen to when contacts would be created, but not have them created at all?
To stop a pair from causing collision response, the collision rule of the pair could be changed. Collision response will only execute if a pair's CollisionRule is Normal. So, upon detecting contacts that disqualify the pair, set the collision rule to NoSolver or a more restrictive rule. [EDIT: I should mention that, as of a recent version, the pair's collision rule is updated by the broad phase each time step. Changing it once won't 'stick.' So, use something that fires repeatedly like PairTouching or PairUpdating to manage the collision rules if the behavior needs to persist for more than one time step.]

There's not a particularly great way to handle this for individual contacts without some deeper integration. One option would be to make a contact's data completely redundant with another contact. This would 'work,' though the resulting behavior might not be the cleanest. If it's the only contact, then just disable the pair with collision rules.

(For the most part, the system is designed for pair-level rejection. The specifics of manifold management are left up to the individual implementations. Most of them are built on the assumption of some level of temporal coherency and that all valid contact locations are acceptable; ripping out those assumptions by deleting individual contacts (as opposed to the whole pair) will cause nasty jittery behaviors.)
Mishkin
Posts: 2
Joined: Mon Oct 15, 2012 4:03 am

Re: Rejecting contacts in collision handlers

Post by Mishkin »

Thanks for the response. Setting the CollisionRule on the pair works perfectly. Didn't even realize that property was there :)
Post Reply