This project has moved and is read-only. For the latest updates, please go here.

SAT Bug with one static body

Topics: Developer Forum
Aug 13, 2009 at 10:43 PM

There is a problem I have come across while using the SAT narrow phase collider, and colliding a static body with a non-static body. From looking at the Youtube videos I found here and here (they show the effects of the problem), I think this might be related to the closed work item Vertices.CreateSimpleRectangle Bug?, but I think the original diagnosis was incorrect.

In the SAT Collide() method, no Contacts are added to the contactList for any body where IsStatic == true. This is good for ensuring that two static bodies don't collide, but if only one body is static, I think we need to be including Contacts from both geometries.

I have posted code that fixes the problem below. Most of the changes were to move conditionals outside of loops (although I don't know if the C# compiler is smart enough to do that itself). The only functional change was to put the IsStatic checks at the start, and to ignore contact points ONLY if BOTH bodies are static.

public void Collide(Geom geomA, Geom geomB, ContactList contactList)
    if (!geomA.Body.IsStatic || !geomB.Body.IsStatic)
        PolygonCollisionResult result = PolygonCollision(geomA.WorldVertices, geomB.WorldVertices, geomB.body.LinearVelocity - geomA.body.LinearVelocity);
        float distance = result.MinimumTranslationVector.Length();

        if (result.Intersect && distance > 0.001f)
            int contactsDetected = 0;
            Vector2 normal = Vector2.Normalize(-result.MinimumTranslationVector);

            for (int i = 0; i < geomA.WorldVertices.Count && contactsDetected <= PhysicsSimulator.MaxContactsToDetect; i++)
                if (InsidePolygon(geomB.WorldVertices, geomA.WorldVertices[i]))
                    contactList.Add(new Contact(geomA.WorldVertices[i], normal, -distance, new ContactId(, i,;

            contactsDetected = 0;

            for (int i = 0; i < geomB.WorldVertices.Count && contactsDetected <= PhysicsSimulator.MaxContactsToDetect; i++)
                if (InsidePolygon(geomA.WorldVertices, geomB.WorldVertices[i]))
                    contactList.Add(new Contact(geomB.WorldVertices[i], normal, -distance, new ContactId(, i,;

Aug 13, 2009 at 11:21 PM
Edited Aug 13, 2009 at 11:21 PM

Thanks for taking the time to look into this and providing us with a fix. I think Matthew fixed this bug before and it should reside in the source control. He is in charge of the SAT implementation and has since the initial release rewritten the implementation two times. Unfortunately he is busy at the moment, so I've not been able to provide the new implementation with the fix.

I will try to get a hold of him again and see if we can get the new release out the door.

Aug 14, 2009 at 3:42 AM

Thanks genbox for the reply. I had done a few google searches to see if this problem had been addressed, but hadn't thought to look at the latest source in case there were updates. Another thing you might want to ask Matthew about is that when SAT makes Contacts, the parameter float separation is the same for each Contact. The Arbiter class should be able to optimize a bit for this; for example, one of the first things an Arbiter does in Collide() is it sorts the contactList by separation amount.

BTW, do you know if there is a way to show the year on timestamps for forum posts? Sometimes I come upon a thread and wonder if the information is still relevant to the current version of Farseer, and a year marker would be nice. I think I have seen year markers on this forum once in a while, but I have no idea why they show sometimes and not others.

Aug 14, 2009 at 3:48 AM

I would also like it if a year marker could be shown on the forums if you have any control over that...

Did you end up getting the 360 and xna working and everything?

Aug 14, 2009 at 3:54 AM

@Cowdozer: It does not seem that I have that kind of control. I don't have a lot of control over the forum really.

@danthekilla: No, I have not received the Xbox yet. They did not have it in stock, so they have to get one first and then send it to me. Takes a lot of time apparently.

Aug 14, 2009 at 4:10 AM

That's ok. This forum being part of what CodePlex provides, I didn't really expect there would be many customization options. I'll try contacting CodePlex and giving that as a suggestion.

Aug 14, 2009 at 4:11 AM

Thats a really good idea. Full dates would be great. But i wonder if they would listen?


Aug 14, 2009 at 4:17 AM

They have a process to submit bugs and feature requests. I have made a work item here. Vote or comment on it if you like!