How can I tell which *side* a collision happened on?

Topics: User Forum
Dec 4, 2011 at 11:22 PM
Edited Dec 4, 2011 at 11:39 PM

I have two super simple bodies in my world. Nothing complicated, they're just square boxes; there's no circular or polygonal geometry. One is moving around, one is standing still. When they collide, how can I tell which side the collision happened on? (e.g., from the perspective of the box that's standing still)

 


 

 ▒
 ▓      ▓▒     ▓     ▒▓
               ▒
Top   Right Bottom  Left

 


 

I've been trying to use the NormalImpulse, TangentImpulse, and Manifold points in the Contact object in the AfterCollisionEventHandler, but I can't make sense of what those values mean.

This seems like it should be the simplest thing in the world. What am I missing?

Dec 20, 2011 at 10:33 PM

Hi theremin,

I've been doing the same thing, I can tell you what I know.  The code I use In the OnAfterCollision event is below.  The logic below seems to work most of the time, but sometimes it gives the reverse answer instead of the correct answer.  The input I got from Ian here was this: "Normally the normal points from A to B where A is the oldest object (created before B). It has been a long time since to took a look at that part of the engine, but I’m pretty sure it still is that way. The engine does not care about the direction of the normal, but if you care, you could check if A.Id > B.Id and reverse the normal."

I have not implemented that last bit yet, but what I think needs done is looking at the Fixtures self and other and examing their .FixtureID numbers as per the quote above.  Let me know how you get on with this, my game only uses this for animations so the odd wrong choice isn't so noticeable for me. 

 protected virtual void OnAfterCollision(Fixture self, Fixture other, Contact contact)

...

            // Work out collision direction
            Vector2 colNorm = contact.Manifold.LocalNormal;
            if (Math.Abs(colNorm.X) > Math.Abs(colNorm.Y))
            {
               // X direction is dominant
               if (colNorm.X > 0)
                  _collisionDirectionTrigger = CollisionDirection.Right;
               else
                  _collisionDirectionTrigger = CollisionDirection.Left;
            }
            else
            {
               // Y direction is dominant
               if (colNorm.Y > 0)
                  _collisionDirectionTrigger = CollisionDirection.Down;
               else
                  _collisionDirectionTrigger = CollisionDirection.Up;
            }