[Solved] What's wrong with this?

Jul 19, 2012 at 5:05 AM

      Body body = BodyFactory.CreateCircle(newWorld, 3.5f, 5, new Vector2(0 / MeterInPixels, 300 / MeterInPixels));
            body.BodyType = BodyType.Dynamic;
            body.Restitution = 1f;

            BodyFactory.CreateRectangle(newWorld, 1600/100, 100/100, 1f, new Vector2(0, 700 / 100));

I'm using just that to try and get a ball to fall onto the ground, theoretically the ball should drop and bounce infinitely upon that small plane. But it looks like the ball is stuck and moves nowhere. If I remove the plane, the ball appears to drop infinitely downwards. Am I constructing the plane wrong?

Jul 19, 2012 at 8:52 PM

Is your MeterInPixels=100? If it is the plane is above the box! If not why are you not using it in creating the plane but using a constant (intentional?)

Barring this issue there is nothing wrong with the code you might have a bug somewhere else.

Jul 19, 2012 at 9:49 PM

It is indeed 100, I forgot to change the 100 to the new constant I had creted. Why is my box above? 700 should be below 300... assuming we're talking screen cordinates. Or does Farseer use some kind of Cartesian plane? 

Jul 19, 2012 at 10:22 PM
Edited Jul 19, 2012 at 10:29 PM

Well formally every framework uses a cartesian plane :) But it's a good way to put it if you refer to how we studied it in school. In Farseer center of the screen is at 0,0 or equivalently 0,0 is the center of the screen. Positive y is up, negative y is down, positive x is right, negative x is left. It's different from the default in say XNA/WPF where 0,0 is top left and x and y increase going bottom-right. It's just a matter of setting your projection right. I'm not sure that's your problem (apart from the positioning issue and of course gravity which I suppose you initialize differently).

P.S: Copy and paste your code into the TestBedXNA and see that it works (putting a - before the y position of the plane to make sure it's below). The ball keeps bouncing.

Jul 19, 2012 at 10:43 PM

Thanks. So, the origin is indeed then at the center of the screen, OK. Is there a way I can write a helper class to convert to screen cordinates then? I take it I can just subtract half the screen width and height. 

After switching to -700, and -15 for gravity, everything works! I see in my console the ball body bouncing infinitely. Thanks. :)

Why didn't it work if gravity was reversed however, then? Logically, wouldn't that make it fly upwards?

Thanks for all the help! 

Jul 19, 2012 at 11:33 PM

TBH I don't know why it didn't work before. Must have been some funky maths especially in the view/projection matrices that would lead to cancelling of the changes in position. Might have been giving negative screen coordinates for example...

For conversion you have two options:

- The Samples has a Camera2D class that is very useful and has the methods ConvertScreenToWorld() and ConvertWorldToScreen(). Probably you'd need a camera anyway in your simulation so might as well use that or extend it.

- Alternatively the TestBed sets a projection in such a way that XNA and Farseer coincide. In my opinion it's more elegant but I don't know if it's robust enough (The debug view doesn't deal with sprites). And you would still need to convert pixels to meters for sprites.

In both cases it's better to deal with the transformation matrices rather that doing the conversion yourself. You will need those matrices in any case whether you draw primitives, use shaders or deal with the SpriteBatch.

Jul 20, 2012 at 12:27 AM

Typically in the past I just go with the Camera2D and a Matrix transformation, so I'll probably look into the one that is provided in the samples. Thanks. As for the 'weird math', this was a stock/blank code base. So that's really odd... that shouldn't have happened then. At any rate, I'll check out transforming my screen coordinates.