Modifying contactList in OnCollision

Topics: User Forum
Aug 17, 2009 at 6:07 AM

Correct me if I'm wrong, but it looks as though it's possible to modify the contactList when handling the OnCollision method of a geometry. I'm looking at doing this as a sort of "narrower" phase collision detection. It looks like for any Contact, it is necessary to set its Position, Normal, and Separation. I'm not so sure about some of the others, such as normalImpulse and tangentImpulse. Are those three the only values I need to set myself? Also, what exactly does the Normal and the Separation represent?

I know that as things are currently, Contact points only occur on vertex points of the colliding geometries, but I haven't seen anything indicating that they must occur on vertex points. Would it work to create my own Contact points, not on any particular vertices?

Aug 23, 2009 at 6:15 PM

Okay, so I've created some OnCollision methods that clear the contactList and then I add my own contacts, specified by their position, normal, and separation. I am colliding a non-static body with a static body, so for me, position is a location on the static body, normal is the static body's surface normal at that point, and separation is the distance (in pixels) that the non-static body has penetrated at this point.

This is working surprisingly well... but only for some objects! For other objects, they pass right through, and they only collide properly if I reverse the normals of the Contacts. I'm pretty sure I've used the included helper methods to create all of my geometries; is there a chance that some of them might not have CCW winding order? I doubt winding order is the culprit, because they all collide with everything else just fine. I am using SAT if that makes a difference.

Thanks.

Sep 17, 2009 at 6:06 PM

I've done some investigation as to why sometimes the Contact points need a normal pointed in one direction and sometimes in the opposite direction, depending on the objects colliding. I think it's to do with the order in which the geometries and bodies are added to the physics simulator. Is there something I can do to fix this? I see that Geoms have ID's. Are Geoms assigned ID's when added to the simulator, and if so, can I just compare ID's and reverse the normal if needed? Thanks!

Sep 25, 2009 at 9:38 PM

I seem to have found the solution to the problem I was having earlier. To ensure that the normal points the correct way, regardless of the order in which geometries were added to the simulator, I make the following check:

//Define the norm as usual, and then...
if (GeomA.Id < GeomB.Id)
    norm = -norm;

Almost everything is working now, but I may need some help with a seemingly trivial issue. What I am doing is using the OnCollision event to collide a polygon with a static sprite image. Every time there is a collision, my code looks at the overlap of the polygon and the sprite, and creates an ad-hoc "surface" for the polygon to collide off of. In order to do this, I need to know the direction of entry, so what I thought would work would be to take the linear velocity of the non-static geom.

private bool PixelCollision(Geom spriteGeom, Geom collider, ContactList contactList){
    Vector2 collisionAxis = collider.Body.LinearVelocity;
    collisionAxis.Normalize();
    ...
}

As an example, if collisionAxis == Vector2.UnitY, then the collision would react as if it had collided from above. If you don't see why direction is important, I can explaint.

Unfortunately, this isn't working. I can hardcode the collision axis to a particular direction and it will work fine (colliding in that general direction), but using the linear velocity to determine direction is not working reliably. I can see there being issues if linear velocity was 0, but I would hope that this logic is sound:

1.the two objects start not overlapping.
2.for objects to overlap, one has to move onto the other, thus linearvelocity isn't 0.
3.whenever objects overlap, collision response will separate them.
4.if linearvelocity is 0, then the object cannot move to overlap another object.

I'm guessing that either the above logic does not hold, or that multi-iteration steps have consequences that I wasn't expecting. Does anyone have any ideas? Thanks. :)