Question

We're creating a game for a school project. It's a 2D platformer and it is in its very early stages. We use C#/XNA and we're implementing Farseer Physics Engine. I'm currently struggling with the map-class. In the class we have a List of DrawableGameObjects, were we store each tile of the map and draw them. But when we try to draw them we get a "Assertion Failed". Examining the problem even further I've come to the conclusion that whenever we try to add more than to static bodies to the world (even without drawing them) we get this failure. Throw message

Game1.cs:line 210 is:

world.Step(0.033333f);

And Program.cs:line 15 is:

game.Run();

Here is the code for the Map class:

class Map
{
    private List<DrawableGameObject> ground = new List<DrawableGameObject>();

    public Map(World world, Texture2D texture)
    {
        for (int i = 0; i < 32; i++)
        {
            DrawableGameObject floor = new DrawableGameObject(world, texture, new Vector2(40, 40), 100, "ground");
            floor.Position = new Vector2(i * 40, 500);
            floor.body.BodyType = BodyType.Static;
            ground.Add(floor);
        }

    }

    public void Draw(SpriteBatch spriteBatch){
        foreach (DrawableGameObject dgo in ground)
            dgo.Draw(spriteBatch);

    }

}

Any ideas? I've posted the problem on Farseer's forum, but they haven't been very helpful yet...

Was it helpful?

Solution

This is a bug in Farseer. (Version 3.3.1)

I opened up the Farseer source code to the method in question (World.SolveTOI) and found two calls to Debug.Assert. And, in fact, in my copy of the code, I've actually already come across this bug and commented one of them out, specifically:

Debug.Assert(typeA == BodyType.Dynamic || typeB == BodyType.Dynamic);

Basically it doesn't want to attempt to handle contacts between two bodies that are static.

Fortunately the code immediately below actually checks for essentially the same condition, and continues the loop if that is the case:

bool awakeA = bA.Awake && typeA != BodyType.Static;
bool awakeB = bB.Awake && typeB != BodyType.Static;

// Is at least one body awake?
if (awakeA == false && awakeB == false)
{
    continue;
}

So it's quite safe to simply comment out or remove the assertion. (You should, of course, be building Farseer from source - it makes life much easier.)


To reproduce the Farseer bug: Have two static bodies and one dynamic body that is in contact with both, then make the dynamic body static. The assert will trigger.

The assert is in the contact handling loop. Normally a pair of static bodies wouldn't create contacts. But if a body starts out as dynamic, contacts can be created - they don't get removed when the body is made static.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top