Farseer Physics Engine 3.0 Update (March)

Coordinator
Mar 20, 2010 at 10:26 AM

Time for another update.

The fixed joints are done. Just like FPE 2.x, you can now create a revolute joint without having 2 bodies (one anchor fixed to the world). It makes the engine easier to use and more intuitive. The fixed joints was created by David - All credit goes to him.

You can find the list of things that are planned for FPE 3.0 right here.

Mar 20, 2010 at 3:25 PM

Great job guys, I can't wait for FPE 3.0!!

Mar 22, 2010 at 8:51 AM
Great news! :) Genbox, are you planning to implement motor to the revolute joint like the one in robertdodd's patch for 2.1 version?
Mar 22, 2010 at 11:29 AM

Is there an ETA on FPE 3.0?

I'm loving 2.1, but there are a few features I really need for my game -- specifically, raycasting and fast queries for all bodies in a given AABB. I can hack around it for now, but I've been spoiled by Chipmunk :D

Mar 22, 2010 at 1:28 PM

Raycasting is already implemented in FPE 2.1

Developer
Mar 22, 2010 at 4:35 PM

@pnikosis: Farseer 3.0 already has motors for several joints!

@nornagon: There is no ETA as of yet for a beta release, however the version currently residing in source control is quite usable, you just don't have all the cool framework stuff that 2.1.3 has. Also I don't think there will be any huge changes in the API between now and when a release is made. We are basically just adding stuff onto the Box2D.XNA API

 

I actually encourage people to start using the 3.0 source control version of the engine. The last update for the 2.X version will come once the final release of XNA 4.0 is made. It will only be an upgrade for compatibility. By then I would hope 3.0 is close enough to finished to be released. I have been working on the new sample framework for some time now and once I'm happy with the API and structure I will add it to the source control.

I'm also working on an editor for Farseer 3.X. It will allow easy shape and joint layout. No more programming every vertex by hand! It will also contain my own custom GUI. Super simple GUI, no BS, total control! Follow progress on my new blog!

Mar 22, 2010 at 9:04 PM

"Cool framework stuff"? What's still missing from 3.0 that is in 2.1?

Mar 23, 2010 at 12:34 AM

I can start using 3.0?? Yes!

The samples seem fine, excellent work you 3!

Are there any changes you plan on making still or is everything layed out like you want it?

Mar 23, 2010 at 7:23 AM

Matt: Great news about the motor joints :) Are you suggesting that we can move on to Farseer 3.0? How difficult should be the migration (differences on the helpers, constructors, methods...)?

 

Developer
Mar 23, 2010 at 4:19 PM

Everyone: Here is my input on whether or not you should start using 3.x

  • I would not port an existing project to 3.0.
  • There won't be any devastating API changes to the base engine.
  • There are big differences between 2.x and 3.x
  • Don't use it if your afraid your code could gently break on a source check-in. (By gently I mean if your using an unfinished feature and some small changes occur causing you to have to change a few lines of code.)
  • Read the latest Box2D manual before switching. (3.x is based on Box2D 2.1.x)
  • 3.x doesn't use a pixel based scale. It uses Meters, Kilograms, and Seconds. Understand this before starting.
  • You must either scale the physics world to match your pixel-based code or write code that uses a smaller orthographic viewport.
  • It is currently pre-alpha, so support is probably limited to asking me questions. Or posting on the Box2D forums.
  • I use it without any problems. You should be able to as well.

I will try to answer any specific questions you guys have as I have been using the engine for quite some time now.

Developer
Mar 24, 2010 at 3:07 AM

3.x far outperforms 2.x. My version of SAT (Separation Axis Theorem) for 2.x was a huge improvement for certain scenarios. 3.x uses SAT for everything but has a much better design overall. If your writing a new game or were plagued with performance issues when using 2.x then upgrading to 3.x should be a huge benefit. On Windows I am able to easily have 500 plus objects all colliding at the same time and still keep 50+ fps. On Xbox360 there is still a lot of performance work to be done, but it is already much better then 2.x. If I remember correctly I was able to have 100 objects all colliding at the same time and still keep over 40 fps. We might also write a fixed point version of 3.x, but I read somewhere that doesn't help on the Xbox. I would love to move some of the calculations to the GPU, but that is for after the first full release.

I will set up a comparison stress test benchmark. I should have videos and numbers by Friday night. Let me know if there is a specific test you would like me to perform.

Also the latest version of 3.x allows for super easy variable stepping. This means your game can run as fast or slow as it wants and not suffer from the hiccups like 2.x version did. (Unless you go crazy with objects colliding everywhere)

 

Mar 25, 2010 at 2:44 AM
Edited Mar 25, 2010 at 11:06 AM

Just a quick question, why is the density located in the Shape class and not in the Fixture class, which already contains the friction and restitution? Shouldn't the shape only have the shape in it?

EDIT: And another question, if I want to check for a collision between 2 custom shapes(not in the simulator) is it best practice to use Collision.CollidePolygons or BooleanTools.VerticesIntersect? Also, if I use Collision.CollidePolygons, does the Manifold.Type tell you which shape the points are relative to?

EDIT: I'm busy upgrading my game to Farseer 3, and I am sooo excited! 

EDIT: Matt, Genbox and David: You guys are awesome. :) !!

Mar 25, 2010 at 6:54 AM

FP3 is still missing the Path class and associated factory methods, damn.

Coordinator
Mar 25, 2010 at 12:02 PM

@aventrix:

A detailed list of changes will be posted once the 3.0 version is released. I've not been able to keep a changelog (other than the source control log) because of the change in foundation, but I promise that I will post about the main features and what is different between 2.x and 3.0, once it is released.

@robertdodd:

Thanks. Glad to hear you can use it. If you have any comments, improvements or related, feel free to post on the forums or report an issue.'

Use the Collision.CollidePolygons() method. That is the internal SAT based collision method used by Farseer Physics Engine 3.0 itself. The BooleanTools.VerticesIntersect() is only used by the boolean polygon tool. The manifoldtype tells you what face the manifold belongs to. Have a look at the PolyCollisionTest in the TestBed for implementation details on how to use the Collision.CollidePolygons() method manually.

Mar 26, 2010 at 2:23 AM
Edited Mar 26, 2010 at 6:42 AM

Thanks Genbox, I didn't realize that sample showed that!

The only thing I don't like so far is the density being in the Shape class. I think it should be in the Fixture class and that Shapes should only be shapes. Before I make it into an issue though, is there a reason behind it?

I'd also like it if controllers could use collision groups, so that some objects aren't affected.

Coordinator
Mar 26, 2010 at 11:59 AM

I'm kinda curious why you chose to move the density into the shape as well.  I haven't dug into it enough to discover the reason... I assume you have good one.  If there isn't a good reason I'd think it should be kept in the Fixture so its more in alignment with the Box2D engine.

-Jeff Weber.

Developer
Mar 26, 2010 at 8:34 PM

I'm not sure why we moved that either. I know we had a reason, but now it definitely seems like we should move it back.

For everyone - when I say go ahead and start using Farseer 3.x I am staying that the source control version is stable enough to begin writing a game or program, but be prepared to have to make some changes for every release we make (or at least every few). Also there is no manual as of yet. You must consult the Box2D manual from the latest Box2D source code. It's not my job to teach you how to do this, but I will help you after you make a valiant attempt. That goes for using the 3.x version of the engine as well. Do your own research and try your best before post questions to the forums. If your a noob don't bother with the new engine yet, wait for the first release. If you find a bug send me or Ian (genbox) a pm with a full description then we will add an issue to the tracker.

Coordinator
Mar 28, 2010 at 5:00 PM

Sorry about not explaining the move of density from fixture to shape. I'll try to explain the reasons:

1. Simplifying the call structure

I wanted to simplify the call structure so that people don't have to worry about the properties of a shape. I went from this:

public abstract void ComputeMass(out MassData massData, float density);

to this:

protected override sealed void ComputeProperties()

If you change the vertices of a shape, it will automatically recalculate all the properties of the shape. This also enables us to do all the calculation on the shape, before we use it. (without the need of a fixture)

2. Dependencies

Density is a dependency for a shape to work. It is needed to calculate the inertia and mass of a shape. That is why I moved it into the constructor of the shape - you need to supply it with a density to make it work.

----

Those are the main reasons why I choose to move it. I'm unable to find any downsides to this (besides minor compatibility with Box2D), I would like to hear what potential problems there might be with this change.

Coordinator
Mar 28, 2010 at 5:08 PM
Edited Mar 28, 2010 at 5:08 PM

Update:

I've implemented OnCollision and OnSeparation into the Fixture class. At the same time I also implemented a way to cancel a collision (by disabling the contact and mark it not-touching) just like you know it from FPE 2.x.

There are also 2 new shapes:
- Rounded rectangle
- Capsule

Rounded rectangle is a contribution by Jonathan Smars and the capsule shape is a transfer from FPE 2.x (contributed by Yobiv). I would like the shapes to be real shapes instead of approximated, but because of limited time, I will have to move it to the next release.

As you can see here, we only need breakable bodies, path factory and a good samples framework. Just like Matthew says, you should be able to use FPE 3.0 it its current state, no major changes will be implemented in 3.0 before release. There are a couple of known bugs and we still need some code cleanup and comments. I hope to fix all that in this week and then prepare for a release.

Mar 28, 2010 at 9:55 PM
Edited Mar 28, 2010 at 10:37 PM

EDIT: Fixed problem, but I'm keeping this post for reference. You must add XNA as

an assembly directive in the Phone Game project, because of an XNA conditional

directive in the 3.0 code that I oversaw.

 

Hey guys.

I'm beginning the process of moving my game to Farseer 3.0 on XNA 4.0, and

the engine fails to compile because the Farseer file FarseerPhysics/Common/Vector2

is within the Xna Framework trying to override the default Vector2 as part of XNA.

 

It doesn't like that.

 

Has anyone come up with a quick solution to that, or should I just change the namespace

in Vector2.cs to be FarseerPhysics, and do a "using Vector2 = FarseerPhysics.Vector2;" wherever

I use Vector2?

 

 

Error, for reference:

Error 5 The type 'Microsoft.Xna.Framework.Vector2' exists in both 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone\Microsoft.Xna.Framework.dll' and 'C:\Users\Oranjoose\Documents\cannedessence\Disaster\DisasterPhone\FarseerPhysics\Bin\Debug\FarseerPhysics.dll' R:\ScreenManager\ScreenManager.cs 132 63 DisasterPhone

Remember, XNA 4.0 == Visual Studio 2010
Thanks!

 

 

ErrorEror 5 The type 'Microsoft.Xna.Framework.Vector2' exists in both 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone\Microsoft.Xna.Framework.dll' and 'C:\Users\Oranjoose\Documents\cannedessence\Disaster\DisasterPhone\FarseerPhysics\Bin\Debug\FarseerPhysics.dll' R:\ScreenManager\ScreenManager.cs 132 63 DisasterPhone
5 The type 'Microsoft.Xna.Framework.Vector2' exists in both 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\Profile\WindowsPhone\Microsoft.Xna.Framework.dll' and 'C:\Users\Oranjoose\Documents\cannedessence\Disaster\DisasterPhone\FarseerPhysics\Bin\Debug\FarseerPhysics.dll' R:\ScreenManager\ScreenManager.cs 132 63 DisasterPhon

EDIT: Source files contains unnecessary files.

For example: AABBFluidContainer.cs has the definition for AABBFluidContainer, but so does AABBContainer.cs

which resides in the same directory.

I noticed that the samples only reference AABBContainer.cs, yet that AABBFLuidContainer.cs still exists seemingly

for no reason .

Or is there a reason?

Mar 28, 2010 at 10:25 PM
Edited Mar 28, 2010 at 10:26 PM

@genbox: Thanks for explaining! It's no problem having density there and those reasons seem good enough.

@oranjoose: Does the testbed work, is it in your own program that it's not compiling? The XNA build of Farseer should have those files removed, while the normal build still has them so you can use the engine without XNA. Make sure you're using the XNA build.

Mar 28, 2010 at 10:27 PM

Yes, the testbed is linking the files in the Sourcefiles folder, but not all of them. Therefore, it

seems that some useless files in that folder that aren't being linked have been forgotten about.

 

That's not so much a problem. The problem with XNA Framework Vector2 still exists and is scary.

Developer
Mar 28, 2010 at 10:34 PM

@oranjoose: You need to add "XNA" to the projects "Conditional compilation symbols:" XNA 4.0 does not do this for you anymore. Also make sure you do this for both the Debug and Release configurations. Also you should be able to safely remove Vector2.cs, Vector3.cs, Matrix.cs, and any other files that replicate class's in XNA's framework. These are there only for Silverlight support.

Let me know if this fixes your problems. And are you using the port I uploaded?

Developer
Mar 28, 2010 at 10:36 PM

@genbox: I knew there was a good reason for moving density to Shape.

Mar 28, 2010 at 10:38 PM

@matt

lol, I just noticed your post. Yeap, that was the fix.

Are you planning on cleaning up those seemingly unnecessary files from the sourcefiles folder?

Developer
Mar 28, 2010 at 10:43 PM

@oranjoose:

Yes, all that will be cleaned up and working good. It's really just XNA 4.0s fault because when you create a project new Game project it doesn't define the "XNA" conditional flag. All our code is based on that flag! Anyway we aren't making an official XNA 4.0 release until it's in it's final state.

Mar 28, 2010 at 11:52 PM

Quick note or something:

I noticed that Vertices.cs doesn't have a namespace, and is therefore global. Why?

I'm giving it a namespace for my code, but I'm wondering what the plans are for that.

 

For your reference, I'm putting it as part of the FarseerPhysics.Common namespace.

 

Thanks.

Coordinator
Mar 30, 2010 at 12:24 AM

@oranjoose:

That must be an oversight on my part. I'll fix it tomorrow - thanks for pointing it out.

Mar 30, 2010 at 12:25 PM
Edited Mar 30, 2010 at 12:48 PM

Do you plan on having a SliderJoint with Farseer 3? I thought before that the LineJoint was the same thing, but I see now I was mistaken. :)

Also, I've just started running into trouble with the AABB constructor in VB.NET, and noticed that you had put a TODO in for that problem. Just wondering, what is it you plan to do? It doesn't seem a good solution to remove either one of them, but maybe you could replace the "by value" constructor with (x1, y1, x2, y2)? It's still not a good solution, as lots of people may want to create the Vector in the constructor.

btw: The List is looking really good! She's lost loads of "In progress"s and all those "Done"s she's wearing really bring out her features!

Mar 30, 2010 at 3:10 PM

This is looking better and better.

Migrating my game to 3.0 is too tempting. Must... resist... the temptation...

Mar 30, 2010 at 9:41 PM
Edited Mar 30, 2010 at 11:27 PM

@RobertDodd

Apparently, the SliderJoint is now called the "PrismaticJoint"

 

I'd like to add a few things. MathHelper.cs in FarseerPhysics.Common should have an #if (!XNA)

conditional directive, right? I've added one so that my code works

 

Second of all, are you guys planning on putting the InactivityController in the new version?

 

EDIT: Thirdly, I'm not finding a ResetDynamics (that was a method in Body.cs for 2.x) feature anywhere in

3.0. Am I missing something? What are you planning on including to perform a similar task? 

 

Thank you!

Developer
Mar 30, 2010 at 11:08 PM

@RobertDodd:

We do not officially support Visual Basic. If you would like to submit patches or expand our support by becoming the Visual Basic developer that would be great.

I listed a few changes here. The complete list will be ready for the beta release (I hope).

 

@oranjoose:

Firstly, all the code has to be gone through to make sure all conditionals are right still. If you are using Farseer 3.x then you are using an Alpha version.

Secondly, the new engine has built in sleeping. When creating your World (PhysicsSimulator in 2.x) pass true for "allowSleep". Individual bodies can also be set to "AllowSleep" or not.

Thirdly, is that a method you use frequently? If so we can easily add it. All it does is set LinearVelocity and AngularVelocity to 0.

Mar 31, 2010 at 12:36 AM

@genbox
I will definitely be making the changes for myself, so I wouldn't mind submitting them!

I see you wrote on the list that the PrismaticJoint is the new SliderJoint. It's similar, but the Prismaticjoint also prevents rotation. I experimented a little trying to remove the angular constraint by passing (0,0) as the axis, but it didn't work. Is it possible?

I also checked the Box2D forums and some peoples' solution was to use a Prismaticjoint attached to an object on a Revolute joint. I don't like that solution, and I think it would be useful to have the old slider joint back.

Developer
Mar 31, 2010 at 3:15 AM

@RobertDodd:

I apologize, the PrismaticJoint is a SliderJoint without rotation. What you want is a LineJoint. That is the same as the old slider.

Mar 31, 2010 at 3:32 AM

I don't think that's it either. While the line joint does allow the bodies to rotate, it only allows movement along a fixed axis.

Developer
Mar 31, 2010 at 3:40 AM

I apologize again, you are quite correct. I will add this to the features list.

 

Mar 31, 2010 at 6:58 AM

My project relies a bit on the old CollisionHandler that took a ContactList for the third parameter,

because I would use the contactList to determine if any of the contacts had a large enough separation to do <whatever>.

I used the Separation property as kind of a means of determining damage, but I am having trouble figuring out its equivalent

in Farseer 3.0.

 

In one of the tests in the Sample project, there's the BreakableTest that uses ContactImpulses to determine damage or at least

that's what appears to be happening. The piece of code that says "if (maxImpulse > 40.0f)" is where I see the actual check to be.

I changed 40.0f to 1000.0f to observe the difference. I found that this is an incredibly inconsistent way of determining whether or

not a fixture has received enough "impact" for something to happen. For example, when the double-block falls and hits the ground,

it breaks. However, if you intercept the block before it hits the ground, and throw it at the ground at a far greater velocity, it doesn't

break. Clearly, something's wrong here.

 

I found the old separation property in Contact to be a consistent way of determining damage based on velocity and mass, which

in physics, should imply impulse, right?

 

I've done quite a bit of reading in on this Manifold that is now given in the Collision, but I have not been able to determine a way

of extracting something like that old Separation property.

 

Anyone have some insight on this?

 

Thanks

Apr 1, 2010 at 11:44 AM

I've been playing around with the Distance class, and I just love how easy it makes things!

One thing I'd like to know is how can I get the normal of the points it finds? It looks like it will need modification to do this, but I thought I'd make sure before I start digging in.

Also, can you please explain how the UseRadii flag works? Thanks!

Apr 1, 2010 at 11:50 AM

Stupid question:

When i download the source files under download, it can't build, the namespaces are totally wrong!? Its pretty useless actually.

Apr 1, 2010 at 11:54 AM
Edited Apr 1, 2010 at 12:07 PM

And the Circles class is totally missing from demo 5. Guess i just have to wait.

Apr 1, 2010 at 5:36 PM

@arextion

If you want it to build, then remove the project "SimpleSamplesXNA" I think it was.

Use the testbed project as your "startup project."

 

SimpleSamplesXNA from what I saw is using namespaces from 2.x. It's possible that

the developer who included that project, also had the old Farseer engine still included,

so it wasn't throwing errors

 

While I'm at it, my question three posts up? Any takers?

 

I appreciate it.

 

Thanks

Developer
Apr 2, 2010 at 1:25 AM

I must have accidentally checked that in. I will fix it tomorrow.

Apr 2, 2010 at 1:50 PM

Are there any plans to add an AngleJoint to the new engine? I see it's a planned feature for Box2D release 2.3.0. I want it so I can adjust the softness of the constraint, which the Prismatic joint doesn't allow.

@oranjoose: When I run the breakable test the body breaks straight away when the simulation starts, with a maximpulse of 221.04. Also, your point about throwing the object with the mouse might be because of the MouseJoint, which limits the force, but if it looks like it's moving faster it should be, so I don't know.

Happy Easter Weekend!

Apr 3, 2010 at 3:32 AM

Is it just me, or is the OnCollision delegate fired before impulses are even calculated.

Each time I use OnCollision, the manifold it reports has 0.0f normal and tangent impulses for each point.

 

If I wanted that information, would I have to use the PostSolve delegate, because it's

far more expensive from glancing, and I'd rather not have to use it.

 

-Oranjoose

Apr 3, 2010 at 9:25 PM
Edited Apr 3, 2010 at 9:48 PM

Is anyone else trying to use this new version having trouble getting the gravity to work correctly?

 

In the TestBed, Test.cs initializes the World with the gravity as new Vector2(0, -10f) and false

Then in the update, step is called on the instance of World with a timestep of 1/60f, and iterations of

3 and 8 respectively (I think it was).

 

Just creating a simple project, with the same information, the -10 Y_Gravity makes objects go up (unlike the testbed)

and say 300f Y_Gravity makes objects fall very slowly downward, and even more concerning, without

any apparent acceleration

 

I've been trying to sort out this problem for my main project for many hours now, and it's just stumping

me pretty badly.

As a reference, I'll post the code that I've created to test the gravity:

 

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

using FarseerPhysics;
using FarseerPhysics.Factories;

namespace SmallFarseerReferenceProject
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Body testBody;
        Fixture testFixture;
        Texture2D testTexture;
        Rectangle drawBox;

        Fixture groundFixture;

        float timeStep;

        World world;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromSeconds(1 / 30.0);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            timeStep = 1 / 60f;

            world = new World(new Vector2(0, 300f), false);

            groundFixture = FixtureFactory.CreateEdge(world, new Vector2(-240, 0), new Vector2(240, 0));
            groundFixture.Body.Position = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height - 20);

            testBody = world.Add();
            testFixture = testBody.CreateFixture(new PolygonShape(PolygonTools.CreateRectangle(15, 5), 1f));
            testBody.Position = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2);
            testBody.Rotation = .1f;
            testBody.BodyType = BodyType.Dynamic;

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            testTexture = Content.Load<Texture2D>("testObject");
            drawBox = new Rectangle(0, 0, testTexture.Width, testTexture.Height);

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            if (Keyboard.GetState().IsKeyDown(Keys.Up))
                testBody.Position = new Vector2(testBody.Position.X, testBody.Position.Y - 5);
            else if (Keyboard.GetState().IsKeyDown(Keys.Down))
                testBody.Position = new Vector2(testBody.Position.X, testBody.Position.Y + 5);

            drawBox.X = (int)testBody.Position.X;
            drawBox.Y = (int)testBody.Position.Y;

            world.Step(timeStep, 10, 10);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            spriteBatch.Draw(testTexture, drawBox, null, Color.White, testBody.Rotation, new Vector2(testTexture.Width / 2, testTexture.Height / 2), SpriteEffects.None, 1f);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

 

 

Thanks

Developer
Apr 4, 2010 at 10:35 PM

@oranjoose:

Farseer 3.x uses a MKS (Meters Kilograms Seconds) scale. The testbed demo uses an orthographic projection to scale the World to screen coordinate sizes.

image hosting by http://www.thepicturebin.com/

The above picture is how the testbed sets up the viewport. Notice how the Y axis is flipped from what you would normally expect. If you need any more help please let me know.

Apr 5, 2010 at 6:19 PM

@matt

Thanks for the reply.

That does indeed explain how not only they can use a negative number for gravity, but also a small number.

However, I don't understand why using 300 m/s^2 in a non-shifted world would cause the physics to be weird.

Isn't it just a matter of scale?

 

Does the world get buggy when using large numbers like that?

Apr 5, 2010 at 10:50 PM

@matt @oranjoose I'm having a hard time with this also. Anyone have any

good sources for understanding scaling and viewport transformations. It

would be nice to see how to scale @oranjoose's example just to get my head

around this. Any help would be appreciated. Thanks.

Coordinator
Apr 6, 2010 at 4:45 PM

@scero,

Here is the best description of scaling and viewport that I've run accross.  It's from the FlatRedBall documentation, but it lays things out pretty clearly.

http://www.flatredball.com/frb/docs/index.php?title=FlatRedBallXna:Tutorials:Understanding_the_3D_Camera

Apr 6, 2010 at 5:24 PM
Edited Apr 6, 2010 at 5:28 PM

I think I figured out this whole World dilemma thing, and I just have to say: Oh...my...goodness.

What I suspected in my most recent post (besides this one) on this topic was the case.

 

Farseer 3.0 gets very confused when using large numbers. Therefore, it appears you must

scale your objects to a much smaller "world" and scale back up for drawing purposes.

 

Take my most recent code segment (a few posts up), and compare with this one:

 

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

using FarseerPhysics;
using FarseerPhysics.Factories;

namespace SmallFarseerReferenceProject
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Body testBody;
        Fixture testFixture;
        Texture2D testTexture;
        Rectangle drawBox;

        Fixture groundFixture;

        float timeStep;

        World world;

        Func<Vector2, Vector2> StoW;
        Func<Vector2, Vector2> WtoS;

        const float SCALE = 15f;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromSeconds(1 / 30.0);
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            timeStep = 1 / 30f;

            world = new World(new Vector2(0, 10f), false);

            StoW = new Func<Vector2,Vector2>(ConvertScreenToWorld);
            WtoS = new Func<Vector2,Vector2>(ConvertWorldToScreen);

            //make the ground
            groundFixture = FixtureFactory.CreateEdge(world, StoW(new Vector2(-240, 0)), StoW(new Vector2(240, 0)));
            groundFixture.Body.Position = StoW(new Vector2(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height - 20));

            testBody = world.Add();

            #region //testing vertices (commented out)
            //Vertices vertices = new Vertices(4);
            //vertices.Add(new Vector2(-15, -5));
            //vertices.Add(new Vector2(-15, 5));
            //vertices.Add(new Vector2(15, 5));
            //vertices.Add(new Vector2(15, -5));


            //testFixture = testBody.CreateFixture(new PolygonShape(vertices, 1f));
            #endregion

            //make the block 
            testFixture = testBody.CreateFixture(new PolygonShape(PolygonTools.CreateRectangle(15 / SCALE, 5 / SCALE), 1f));
            testBody.Position = StoW(new Vector2(graphics.GraphicsDevice.Viewport.Width / 2, graphics.GraphicsDevice.Viewport.Height / 2));
            testBody.Rotation = .1f;
            testBody.BodyType = BodyType.Dynamic;

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            testTexture = Content.Load<Texture2D>("testObject");
            drawBox = new Rectangle(0, 0, testTexture.Width, testTexture.Height);
        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            #region handle input (move and rotate blocks with keyboard)
            if (Keyboard.GetState().IsKeyDown(Keys.Up))
            {
                testBody.Position = new Vector2(testBody.Position.X, testBody.Position.Y - 1);
                ResetDynamics(testBody);
            }
            else if (Keyboard.GetState().IsKeyDown(Keys.Down))
            {
                testBody.Position = new Vector2(testBody.Position.X, testBody.Position.Y + 1);
                ResetDynamics(testBody);
            }
            if (Keyboard.GetState().IsKeyDown(Keys.Right))
                testBody.Rotation = testBody.Rotation + .08f;
            if (Keyboard.GetState().IsKeyDown(Keys.Left))
                testBody.Rotation = testBody.Rotation - .08f;
            #endregion
            
            drawBox.X = (int)(testBody.Position.X * SCALE);
            drawBox.Y = (int)(testBody.Position.Y * SCALE);

            world.Step(timeStep, 8, 3);

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            spriteBatch.Draw(testTexture, drawBox, null, Color.White, testBody.Rotation, new Vector2(testTexture.Width / 2, testTexture.Height / 2), SpriteEffects.None, 1f);
            spriteBatch.End();

            base.Draw(gameTime);
        }

        public static Vector2 ConvertScreenToWorld(Vector2 position)
        {
            return new Vector2(position.X / SCALE, position.Y / SCALE);
        }

        public static Vector2 ConvertWorldToScreen(Vector2 position)
        {
            return new Vector2(position.X * SCALE, position.Y * SCALE);
        }

        public static void ResetDynamics(Body body)
        {
            body.LinearVelocity = Vector2.Zero; body.AngularVelocity = 0;
        }
    }
}

As you can see, the only real differences lie within scaling (I added that ResetDynamics function for

the input region, because the body keeps adding up velocities even though it's being moved).

 

The last one was broken, this one works.

 

I hope this helps anyone else (By the way: "testObject" in Load is a 30 x 10 png)

 

-Oranjoose

Apr 7, 2010 at 12:31 AM
Edited Apr 7, 2010 at 12:38 AM
Box2D Manual:

Box2D has been tuned to work well with moving objects between 0.1 and 10 meters. So this means objects between soup cans and buses in size should work well. Static objects may be up to 50 meters without too much trouble.

Taken from the Box2D Manual.

Apr 7, 2010 at 12:58 AM

@crashlander @oranjoose Thanks for the posts! They really helped

a lot. I've learned quite a bit over the last couple of days trying to figure

this out. Hopefully, this will help out others as well. Thanks again.

Apr 7, 2010 at 1:51 AM
Box2D Manual:

Box2D has been tuned to work well with moving objects between 0.1 and 10 meters. So this means objects between soup cans and buses in size should work well. Static objects may be up to 50 meters without too much trouble.

@RobertDodd
I guess I missed that part =X

@scero
No problem =)

Developer
Apr 7, 2010 at 2:30 PM

This is why I have to rewrite the way Farseer draws it's examples.