Geom position not in sync with Body's

Aug 30, 2009 at 3:59 PM


Genbox, as you already know, Conkerjo has integrated Farseer into our 2D game engine "IceCream" a few months ago. I've just started to use Farseer this week as I am starting to work on my new game (Little Gamers 2),  a 2D platformer, and I must say that I love it: I had a simple physic sandbox running within a few minutes.

Now after playing with it a bit more I have encountered 2 issues that seems problematic:

1) After a collision of a wall with a simple falling rectangular geometry (created with the factory helpers), the moving body sometimes penetrates the static wall's body, and is pushed out in the next 2 physic updates. Shouldn't Farseer automatically separate the 2 bodies upon impact, then apply the resulting impules? The result in my game is that the character seems to enter the ground for a split second then come back to normal position.

This is the ouput of the body's Position and LinearVelocity over time:

53] Update component LG pos: {X:0 Y:206,2407} Vel: {X:0 Y:449,9678}
54] Update component LG pos: {X:0 Y:213,879} Vel: {X:0 Y:458,2999}
55] Update component LG pos: {X:0 Y:221,6563} Vel: {X:0 Y:466,632}
56] Update component LG pos: {X:0 Y:229,5723} Vel: {X:0 Y:474,964}
BroadPhase Collision!
Collision! Contact[0]: {X:-32 Y:229,5723}
57] Update component LG pos: {X:0 Y:225,4465} Vel: {X:0 Y:-0,2812556}
59] Update component LG pos: {X:0,0001631853 Y:224,4681} Vel: {X:-2,328306E-10 Y:-2,682209E-07}

As you can see, the position is going to Y229 then is correct to Y224 after updates, while it should never penetrate to 229 in the first place. Now I don't think it's an issue with the lack of CCD, because both polygon are fairly large, and the velocity is quite slow, and the penetration is very small: 5 pixels. The height of the moving rect is 100px and the width 64px (the wall is much larger). Is it a known issue or normal behavior?

2) This might be related to the first problem, but it seems that the position of the Body is sometimes not in synch with the position of the Geom when the rect is falling, and a gap appears between the drawn vertices using the Geom WorldVertices and the character's sprite using the Body's Position. Here is a screenshot:

(as you can see there is a gap between the feet and the vertices, even though this gap is not present when the Body is on the ground, then it matches the bottom of the feet correctly).

I've seen the thread linked in the doc about the centering issue, but I don't think it's the same issue here because the offset between the polygon and the sprite is not constant. Is this a known issue too?

Now I realize that due to Farseer beeing integrated into our lib as a Component, those issues might be due to IceCream and not to Farseer, but after a lenghty session of debugging I've come to the conclusion that it's most likely the lib or an error in setting up my data.







Aug 30, 2009 at 4:24 PM

Hi Epsicode,

I did see the integration of FPE into IceCream when I updated my local SVN folder.

The problems you mention could be related, and might be the setup of the engine. The first problem you mention could be related to the timestep you give FPE. In the samples I use 10 ms (100 fps) and give the engine gameTime.ElapsedGameTime.Milliseconds * .001f as the delta time argument in the Update() method. This ensures the engine takes small steps each time and thus is more accurate.

There are 2 more factors that can cause this: Iterations and distance grid precision

Since we use iterative algorithms for speed, a solution is converged over several timesteps. To make it more accurate we have iterations that simply are sub-timesteps. Make sure your iterations are 5 (default) or more. The distance grid precision is usually calculated automatically. Problem is that if you have too large geometries or narrow geometries, the precision of the collisions will not be sufficient with automatic settings and you will have to supply your own grid cell size. I don't think this is a factor in your case, I just write this for future reference.

As for your second problem - Do you use some kind of camera? If you use the PhysicsSimulatorView from our samples, it should be as simple as just updating the physics engine and drawing the debug view. I've seen some users have this problem before, I think they "fixed" it by changing the order of physics updates and debug draws. I've never had the problem, so I'm not sure what causes it.

Aug 30, 2009 at 6:34 PM

Thanks for your quick answer!

To solve #1, Ive tried to slow down the timestep (just to be sure, to change the timeStep you just change the delta time passed in PhysicsSimulator.Update(), nothing else like a properties somewere?) to 1/100 of what it is now (60 fps), but then of course everything gets 100 times slower, so in order to keep the same "speed" I have to multiply each forces by 100, getting huge numbers, so it produced the same issue.

I've also tried to change the Iterations to 1000, just to be safe, and I still had the issue. Changing to grid size to small values (up to 0.1f) didn't help either.

As for #2, we indeed use a camera but we pass the same Matrix to the SpriteBatch of the debug view, and anyway my tests are done on a 0,0 default zoom position. I've checked the ordering of updates, and this is the order used in IceCream:

simulator.Update(1/60f); sprite.Position = farseerBody.Position; sprite.Draw(); debugView.Draw();

I'll try to see if I can dig deeper, but from my tests i've seen a few cases where the geom was in a different position than the body, which seems strange, as if they were desynchronized?





Aug 31, 2009 at 11:56 AM

Please disregard the drawing issue (problem #2), it was indeed a problem within IceCream with the specific class used to render the Character, not Farseer's physics or debug view, my bad.

I'm still getting issue #1 though, light polygon penetration in a wall.

Aug 31, 2009 at 4:49 PM

Good you fixed problem #2.

As for the penetration, if you have a high delta time value passed to the update method, it is probably the cause. I can't reproduce the problem with the safe values used in the samples. I gave a geometry a linear velocity of 500 + gravity of 150 and it still fell correctly and recovered correctly.

Could you send me the code so I could have a look at it?

Aug 31, 2009 at 5:19 PM

Well, to keep the same overall speed if I pass a lower delta time value, let's say 1/2th, I have to multiply each forces (gravity, impulses etc) by 2 right? So the issue wouldnt really go away since the displacement itself will always be x pixels per seconds?

I'll try to reproduce the issue with the smallest sample I can produce. Btw, my gravity is 500 and the linear velocity shows problem at around 650