Nothing Moving FP3

Topics: Developer Forum, User Forum
Jun 5, 2010 at 5:19 PM

So I know this is most likely just something stupid I passed up but nothing is moving in my game after changing from FP2.1.x to FP3. I don't think it has to do with how I apply impulses (could be wrong) and I think I'm calling step right. This is what I have

Farseer.World.Step((float)(1 / 60), 10, 10);

I have tried messing with these values. When I change from 1/60th time step to 1/30th, the character sinks into the ground and then the game essentially freezes. With just 1, the game instantly freezes. Sorry to be bugging you guys about this, I know I probably am passing something up but I need help finding it :)

 

Jun 5, 2010 at 8:27 PM

Since I've just recently ported from FP2 to FP3 I think I might know what this is.

First, make sure your units are much smaller. The big change was the size of all objects is in meters, not pixels. So something that used to be width of 400 is now enormous! Make it something like 4 instead and then multiply any such unit by an arbitrary world scalar value to get everything back to pixel sizes (I used 24 or something like that) for display.

Your step looks fine, but 10,10 is probably overkill. I've been using 7,3 with good results.

It would probably help to see the relevant parts of your code since it could be many other things causing this. But try those first.

Jun 6, 2010 at 2:28 AM
Edited Jun 6, 2010 at 2:48 AM

Make sure you set body.BodyType = BodyType.Dynamic;

By default all bodies are static.

EDIT: Oops, I just read the title, not the last part which says your bodies are in fact moving! Never mind this then! XD

Coordinator
Jun 6, 2010 at 3:29 PM

Have a look at how the Testbed does it. It might be quite confusing at first, but it is a great place to get knowledge on how to use the engine. I will create some simpler samples in the future that show the bare essentials.

As for the position and velocity iterations: I've moved both settings into the Settings class. The default values are velocity = 8 and position = 3.

Jun 8, 2010 at 11:08 AM
Edited Jun 8, 2010 at 11:11 AM

You are sending 0 as step. You make a integer division, then it's cast to float.

Farseer.World.Step((float)(1 / 60), 10, 10);

Use this instead: Farseer.World.Step(1 / 60f, 10, 10);

Jun 8, 2010 at 11:16 AM

Dam, nice spot!

Jun 8, 2010 at 5:02 PM

Hahaha I can't believe I did that. Thanks! Well now it is running somewhat. It freezes after like 10 seconds but I must be doing something else wrong later. Thanks for at least getting something to happen for me! Probably be back later with a new thread and question :)

Jun 8, 2010 at 7:22 PM

It's still not working properly... I tried changing values around and it barely does a thing. Just to see if something is truly up, I'm setting gravity in the y direction to be 1000000. It still moves VERY slowly down. Is there a way I could send it to one of you to figure it out? I don't know what to do.

Jun 8, 2010 at 8:30 PM

How often is Step being called? It should be called as often as you say you want the step to advance. (i.e. 1/60 means it should be called about every 16 miliseconds)

Is this XNA or Silverlight or something else?

Also, I would double check your units. I set my gravity vector to (0, 9.8f). 1000000 is way off. Remember distance units are in meters, not pixels.

Maybe provding more snippets of your code would help us identify the issue.

Jun 8, 2010 at 8:44 PM

No I get that. I have gravity at 15. It moves makes the character fall really slowly and I decided to mess with that value. It didn't seem to change at all how it was working. I set it to 1000000 just see if it would make a SIGNIFICANT difference or if something was up. It made almost no change to the game. Main character still fell slowly. What should I give you guys to look at? I guess I'll put some of the movement code and then creation of world for now.

 

World Creation:

static readonly World world = new World(new Vector2(0, 15.0f))

Character Jump: 

//JUMPVELOCITY = 15000000 or 15 (they both move essentially the same speed)
this.mainBody.ApplyLinearImpulse(new Vector2(0, -JUMPVELOCITY));

All of this moves REALLY slow. I'm going to keep messing with stuff and see if I'm just doing something REALLY stupid in my code.

 

Jun 8, 2010 at 9:06 PM

Here is a video showing what is going on. If you guys need anything else, I can do that too.

 

http://www.youtube.com/watch?v=Psq1lKEkqHY

Jun 8, 2010 at 9:16 PM

Can you print out some diagnostic traces to the debugger that show the delta time in miliseconds between calls to Step?

The 2 things I've seen that cause this are:

1) Not calling Step often enough (or calling it with the wrong DT, which you've already fixed). Also calling Step more or less often than the DT parameter indicates gives weird results too.

2) Having units wrong (i.e. density not around 1.0, Body width/height not in meters, etc...)

But I would definitely check to see if Step is being called with the right delta between calls. It appears that it's not. It looks like it's called maybe every 100ms or longer which makes it run in slow motion.

How did you implement the timer that calls Step()? Maybe the interval is wrong or there's just a bug there?

Jun 9, 2010 at 9:32 AM

Up is positive y-axis in Box2D/fps 3.0.

Gravity should be negative in Y axis.

Jun 9, 2010 at 4:31 PM

That may be true, but I've been using positive Y for gravity and it seems to work fine. Things would float upwards if that was the case.

I'm 99% sure his problem is he's not calling Step often enough.

Jun 9, 2010 at 6:55 PM
Edited Jun 9, 2010 at 7:05 PM

How often should I be calling Step then? I guess I don't understand what I should do for that one. I'll look at the TestBed. Right now I'm going through and making sure sizes are converted to meters and checking densities.

I'm thinking I may hold off a little bit for a complete switch. Just until there is a stable release. There are too many things I'm still questioning. How to offset fixtures to bodies, how to get a simulation view, how to do revolute joints, etc. One thing I don't get is why was the ConvertUnits class removed? It seems more necessary than it was in FP2.1.x because of the conversion needed to make everything in meters. Essentially I make everything move around in meters but when I go to draw, I should convert all of that into pixel sizes right? Sorry, just having trouble getting my head around everything. I've been looking through my code, and size and positions are still in pixels. Not movement though which may be a big cause. I'm probably not calling Step enough either. I have one call to it in my main Update method. 

Jun 9, 2010 at 8:56 PM

It sounds like you're understanding things fine. But it does take a little getting used to. As long as you think of your physics "world" in terms of meters, and your "display" in pixels, that helps keep the 2 seperate. All you really need to do, is multiply your physics world coordinate (usually a Vector2) by a scalar (like 25) before you display that. To go the other way, just divide. You can even dynamically adjust the scalar at runtime and get the ability to zoom in/out of your world. In short, all units of size and position in the physics engine should be in meters, and they should only be in pixels when it comes to drawing on the screen.

As far as your Step() problem, as I said, all you need to do is print a debugging trace with the delta time between the last call to Step and the current call to Step and see if it's around 16ms (or less). If you are simply using your game's update loop for this, then I would make sure your game's framerate is locked at some fixed interval. Is this XNA? Can you turn on frame counters?

If you want to post some code, it would help a lot.

Developer
Jun 10, 2010 at 1:01 AM

Most of this has been said but

Make your physics units small.

Make sure you are using a fixed time step for your game. I.e. IsFixedTimestep = true;

Gravity should be close to 10.

Read through Box2D's manual in the source control from Google. Farseer 3.0 is directly based off that engine.

 

I hope this helps.

 

 

Jun 10, 2010 at 11:22 PM
Edited Jun 10, 2010 at 11:23 PM

Ok, it was that I didn't change the sizes of the bodies. They were still being based off the pixel sizes. I'm looking through densities now. Things are at least moving now at speeds that look correct. One final question I have is how to get a debug view working? This would be a HUGE help because I can't tell what any of my bodies are doing. For instance, I have no clue how my bodies are attached to each other or how the offset is working with the fixtures. If someone could write a small example showing how to connect fixtures together to make this just to make sure I am doing it right, that would be great. If not it's fine, I'll learn. I'm going to reread Box2D's manual to make sure I didn't misinterpret something because I know it allows for multiple fixtures, I just don't know the offsetting of them.

 

 

Some of my bodies have multiple fixtures to them but I don't know how to offset them. I think it's causing really weird bugs to how things should work. But thank you for everything you guys have helped me with :) I have learned METERS != PIXELS and to watch what I pass to my Step(). And I am using my Step() in XNA's main update loop. It is working fine now from what I can see. The elapsed game time is roughly always 16.6 milliseconds which I'm happy with :)

Developer
Jun 11, 2010 at 3:59 AM

In order to get a Debug view working you'll need to add a reference to DebugViewXna.dll from the source control. (You seem very capable so I will assume you can get that)

Next add "using FarseerPhyiscs.DebugViewXNA;" to your using statements.

In your LoadContent method add "DebugViewXNA.LoadContent()" and pass your graphics device and content manager. Be sure your using the static method from the class.

Create a DebugViewXNA object somewhere. Pass the World object so it will know what to draw. Right after that call AppendFlags(DebugViewFlags.Shape) on your DebugViewXNA object. (Otherwise nothing will draw.)

Now in your draw method call DrawDebugData() from your DebugViewXNA object and then RenderDebugData() with ref's to your projection, view and world matrices. That should get you a debug view on the XY plane. (0 Z coordinates)

Try that out and let me know if you have any problems. Once you get all this set up I should have an answer for how to offset Fixtures. Your gonna need a debug view so I figured that was more important.

Jun 11, 2010 at 5:04 AM

So I can't get this to work... I followed exactly what you said.

Added in references and added the using statement.

 

Called the static method LoadContent()...

 

	    DebugViewXNA.LoadContent(graphicsDevice, Content);

 

 

Created a DebugViewXNA object and passed the world and then called AppendFlags...

 

            debugView = new DebugViewXNA(Farseer.World);
            debugView.AppendFlags(DebugViewFlags.Shape);

 

And in my draw method I did the DrawDebugData() and RenderDebugData()...

            if (drawDebugView)
            {
                debugView.DrawDebugData();
                debugView.RenderDebugData(ref camera.cameraMatrix);
            }

And it does execute those methods when drawDebugview is on. The camera object here is from this thread: http://farseerphysics.codeplex.com/Thread/View.aspx?ThreadId=50483

I changed a few things so it would work (can't send camera.CameraMatrix as a property). Here are my changes.

 

This is the property first off that I send:

        /// <summary>
        /// A matrix representing the camera's current position, rotation, and zoom.
        /// Feed this to SpriteBatch.Begin (or use it in your matrix calculations for 
        /// drawing 2D polygons)
        /// </summary>
        public Matrix CameraMatrix
        {
            get
            {
                return Matrix.Identity * 
                      Matrix.CreateTranslation(new Vector3(-_position, 0)) * 
                      Matrix.CreateScale(_zoom) * 
                      Matrix.CreateRotationZ(_rotation) * 
                      Matrix.CreateTranslation(new Vector3(_size / 2, 0));
            }
        }

 

So you can see they never have a matrix object saved. So what I did was created a Matrix object that on each time at the end of the camera.Update(), updates the cameraMatrix object.

            cameraMatrix = Matrix.Identity *
                      Matrix.CreateTranslation(new Vector3(-_position, 0)) *
                      Matrix.CreateScale(_zoom) *
                      Matrix.CreateRotationZ(_rotation) *
                      Matrix.CreateTranslation(new Vector3(_size / 2, 0)); 

 

The cameraMatrix object is what I pass. The only thing I can think of that would cause an issue is how would the DebugViewXNA object know what my scale is to draw properly to the screen? The way I currently check my scale was by taking the previous ConvertUnits object from FP2.1.x. Maybe that was a bad idea? I don't see anything so far that shows this comes with FP3. Maybe I missed it somewhere?

 

 

 

Developer
Jun 11, 2010 at 3:30 PM

When you call RenderDebugView it needs the projection matrix first and then the cameras view matrix. If your not using any projection matrix because all your code is rendered using SpriteBatch at pixel level then create a projection matrix using-

Matrix.CreateOrthographicOffCenter(0, widthOfScreen, heightOfScreen, 0, 0, 1);

then for the second matrix pass your camera matrix.

Try this and let me know how it works.

Jun 11, 2010 at 6:19 PM

Changed: 

                debugView.DrawDebugData();
                debugView.RenderDebugData(ref projectionMatrix, ref camera.cameraMatrix);

 

To: 

                debugView.DrawDebugData();
                Matrix projectionMatrix = Matrix.CreateOrthographicOffCenter(0, graphicsDevice.PresentationParameters.BackBufferWidth, 
                    graphicsDevice.PresentationParameters.BackBufferHeight, 0, 0, 1);
                debugView.RenderDebugData(ref projectionMatrix, ref camera.cameraMatrix);

 

 

Still doesn't work. I wish I knew more about what exactly this is all doing to draw and everything but I know much about matrices. I'm assuming it draws a ton of primitives in 3 dimensional space but all on the z axis. I don't know, that's where my comprehension ends. 

Developer
Jun 11, 2010 at 6:47 PM

If you can send your project to me I can fix it up for you. mattbettcher@gmail.com