Farseer Physics Engine 3.3 Manual

We include the same features as Box2D, you can view their manual here

Are you completely new to Farseer Physics Engine? Take a look at the Hello World project in the Downloads tab.

Getting started

To simulate a moving body that can collide with another moving body, you need 4 things: The world, a body, a shape and a fixture.

World
The world object is the manager of it all. It iterates all the objects in the world each time you call the Step() function and makes sure everything is consistent and stable.

Body
The body keeps track of world position. It is basically a point is space that is affected by forces such as impulses from collisions and gravity.

Shape
A shape is what extends the point in space to a 2d shape in space. The centroid and stuff like area, inertia and mass is calculated for the shape.

Fixture
A fixture attaches (fix) the shape to the body so that the centroid of the shape becomes the body’s position. Whenever you move the body, you also move the shape. Once a collision occur to the shape, the force is calculated and applied to the body.

Her is the code to create a World with a single body:

   1:  //Create a World object with a normal gravity
   2:  World world = new World(new Vector2(0f, 9.82f));
   3:              
   4:  //We create a body object and make it dynamic (movable)
   5:  Body myBody = world.CreateBody();
   6:  myBody.BodyType = BodyType.Dynamic;
   7:   
   8:  //We create a circle shape with a radius of 0.5 meters
   9:  CircleShape circleShape = new CircleShape(0.5f);
  10:   
  11:  //We fix the body and shape together using a Fixture object
  12:  Fixture fixture = myBody.CreateFixture(circleShape);

Now, that is what is needed to create a single body in the world. However, this does not show anything on the screen and the body does not move. To get a fully working sample, take a look at the HelloWorld project with each release of the engine.

Updating the World

To make everything move, we need to update the Wold.
To make the world update with a timestep of 30 FPS (Frames Per Second) it is as easy as:

   1:  // 1/3 = 0.033333 …
   2:  world.Step(0.033333f);

Now it updates 30 times each second and each body in the world will move a small amount on each update.

Reacting to a collision

You can be notified about a specific collision in a couple of ways.

OnBroadphaseCollision
The broad phase keeps track of the bodies in the world using a tree of AABBs. At some point you might need to know when a body is near by (or colliding with) your game character, but a precise collision is not required. Then you should use the OnBroadphaseCollision delegate. All you have to do is to subscribe to the delegate like this:

   1:  protected override void LoadContent()
   2:  {
   3:      _world.ContactManager.OnBroadphaseCollision += MyOnBroadphaseCollision;
   4:  }

And then you need to create the MyOnBroadphaseCollision method:

   1:  public void MyOnBroadphaseCollision(ref FixtureProxy fp1, ref FixtureProxy fp2)
   2:  {
   3:              
   4:  }

  

OnCollision
The OnCollision delegate gives you the information about a collision when it is happening. It is a lot more accurate than the OnBroadphaseCollision delegate, but at the cost of performance. You also have the ability to cancel a collision by returning false in the method you subscribe. To subscribe you just do the following:

   1:  protected override void LoadContent()
   2:  {
   3:      Fixture myFixture = FixtureFactory.CreateCircle(_world, 0.5f, 1);
   4:      myFixture.OnCollision += MyOnCollision;
   5:  }

And the MyOnCollision method looks like this:

   1:  public bool MyOnCollision(Fixture f1, Fixture f2, Contact contact)
   2:  {
   3:      //We want the collision to happen, so we return true.
   4:      return true;
   5:  } 

Drawing the World

Farseer Physics works with the KMS (Kilo, Meter, Second) system and does not directly translate to pixels. It is your responsibility to convert between meters and pixels. This has the advantage that you are able to dynamically scale your physics world (zooming f.eks.) and with a small scale, you will get a faster and more stable simulation. Farseer Physics is fine tuned for objects between 0.1 and 10 meters in size. F.eks. if your screen is 768x1024 pixels in size, you need to scale your units to meters to fit the fine tuned sizes.

   1:  // 1 meter = 64 pixels
   2:  ConvertUnits.SetDisplayUnitToSimUnitRatio(64f);
   3:   
   4:  //If you object is 512 pixels wide and 128 pixels high:
   5:  float width = ConvertUnits.ToSimUnits(512f) // 8 meters
   6:  float height = ConvertUnits.ToSimUnits(128f) // 2 meters

So the rules are:

  1. Whenever you need to input pixels to the engine, you need to convert the number to meters first.
  2. Whenever you take a value from the engine, and draw it on the screen, you need to convert it to pixels first.

If you follow those simple rules, you will have a stable physics simulation.

Factories

The factories make your life easier by providing a unified way of creating common objects like bodies, shapes, fixtures, paths and joints. Each object type has it’s own static factory with a lot of overloaded methods to give you the flexibility you need, to create an object with different parameters.

BodyFactory

To create a body that is positioned 10 meters to the right:

   1:  Body body = BodyFactory.CreateBody(_world, new Vector2(10, 0));
 

FixtureFactory

In Box2D you would create a body, a shape and then bind them together with a fixture object. Here we create the following:

  1. A body positioned 10 meters to the right.
  2. A circle shape with 0.5 meters radius.
  3. A fixture that binds the body and shape together. It has a density of 5.
   1:  Body body = BodyFactory.CreateBody(_world, new Vector2(10, 0)); 
   2:  CircleShape circleShape = new CircleShape(0.5f); 
   3:  Fixture fixture = body.CreateFixture(circleShape, 5);

In Farseer Physics Engine you can create all 3 objects using a single line of code like this:

   1:  Fixture fixture = FixtureFactory.CreateCircle(_world, 0.5f, 5, new Vector2(10, 0));

JointFactory

The JointFactory provides an easy way of adding joints to the world. We have fixed and non-fixed joint types in Farseer Physics Engine; fixed joints take in world anchor coordinates and non-fixed take in local anchor coordinates.

Here is how you create 2 balls and connect them with a DistanceJoint:

   1:  Fixture fix1 = FixtureFactory.CreateCircle(_world, 0.5f, 1, new Vector2(-5, 5));
   2:  fix1.Body.BodyType = BodyType.Dynamic;
   3:   
   4:  Fixture fix2 = FixtureFactory.CreateCircle(_world, 0.5f, 1, new Vector2(5, 5));
   5:  fix2.Body.BodyType = BodyType.Dynamic;
   6:   
   7:  JointFactory.CreateSliderJoint(_world, fix1.Body, fix2.Body, Vector2.Zero, Vector2.Zero, 10, 15);

Convex decomposition

Since Farseer Physics Engine 3.0, we only support convex polygons. If you need to add a concave polygon, you will have to decompose it to smaller convex polygons first. We provide a couple of different decomposition tools; all of them returns a list of convex polygons that can be used in the engine.

Ear clipping

The ear clipping algorithm in Farseer Physics Engine is provided by a contribution to Box2D. It is easy to use but does not support holes and runs in O(n^2) time. Here is a picture of a concave polygon before and after ear clipping.

combined2

 

To use the Ear clip algorithm, you simply call the EarclipDecomposer like this:

   1:  // We just imagine that this list contains a concave polygon
   2:  Vertices verts = new Vertices();
   3:  EarclipDecomposer.ConvexPartition(verts);

Bayazit

The Bayazit algorithm is another convex decomposition tool created by Mark Bayazit. The algorithm does not triangulate the polygon and then combine the triangles to form convex polygons like the ear clip algorithm, instead it decompose directly into convex polgyons. It does not officially support holes, but sometimes you get lucky and it works with holes. Here is a picture of before and after decomposition:

combined

 

To use the Bayazit algorithm, you simply call the BayazitDecomposer like this:

   1:  // We just imagine that this list contains a concave polygon
   2:  Vertices verts = new Vertices();
   3:  BayazitDecomposer.ConvexPartition(verts);

Besides the two described, we also have:

  • Flipcode triangulation
  • Constrained Delaunay triangulation
  • Seidel triangulation

Convex hull

Convex hull algorithms can come in handy when working with polygons. A convex hull algorithm takes in a point cloud and then returns the convex hull. We provide two different algorithms in Farseer Physics Engine:

Melkman

The Melkman algorithm is a very fast convex hull algorithm. Our implementation runs in O(n) time and it is restricted to simple polygons. It is very easy to use:

   1:  //We imagine that this list contains a simple polygon
   2:  Vertices verts = new Vertices();
   3:  Vertices hull = Melkman.GetConvexHull(verts);

Giftwrap

The Giftwrap algorithm works with point clouds and runs in O(N*S) time where S is the number of sides of the resulting polygon.

   1:  //We imagine that this list contains a point cloud
   2:  Vertices verts = new Vertices();
   3:  Vertices hull = GiftWrap.GetConvexHull(verts);

Boolean operations

Farseer Physics Engine contains a clipper that supports union, difference and intersection of polygons. The algorithm used is created by Yu Ping; it is fast and flexible, but may yield unexpected results if the polygons contain collinear points. Here is an example of two polygons (green and red) after being merged:

Clipper

To use the YuPengClipper, use the following code:

   1:  //We imagine that this list contains the first polygon
   2:  Vertices first = new Vertices();
   3:   
   4:  //We imagine that this list contains the second polygon
   5:  Vertices second = new Vertices();
   6:   
   7:  //Contains the error if the union operation fails.
   8:  PolyClipError err;
   9:  List<Vertices> union = YuPengClipper.Union(first, second, out err);

Cutting shapes

You can cut shapes using the boolean tools, however, if you just need to slice a polygon in two, then it is easier and faster to use the cutting tools. It is a great tool for lasers and the like. Here we cut a pyramid of rectangles using the cutting tools:

Cut

You just have to do the following:

   1:  CuttingTools.Cut(World, start, end, 0.001f);

The start/end arguments is the cutter starts and stops. The last argument is the thickness of the cutter. Beware that the cutter performs the operation on all bodies that it touches in the world object.

Simplifying polygons

Farseer Physics Engine likes simple polygons with a few points. Sometimes it is necessary to simplify your polygons to speed up collision detection and make the collisions more predictable. We have many different algorithms inside the SimplifyTools class:

CollinearSimplify
Simplifies the polygon by finding collinear points and removing them.

DouglasPeuckerSimplify
Simplifies the polygon using the Ramer-Douglas-Peucker algorithm. If you supply 0 as the tolerance, it will remove collinear points in the polygon.

MergeParallelEdges
A method contributed by Eric Jordan to Box2d and then ported over to FPE. It merges parallel edges to a single edge.

ReduceByArea
Reduces the number of points by area

ReduceByDistance
Reduces the number of points by distance between the points

ReduceByNth
Reduces the number of points by removing the n’th point.

Texture to polygon

You can detect the shape of a texture using the texture-to-polygon tool. This tool enables you to create the graphics for a game and then import it as a shape into Farseer Physics Engine. It is one of the more advanced tools to use in FPE; take a look at the following code:

   1:  //load texture that will represent the physics body
   2:  Texture2D polygonTexture = GameInstance.Content.Load<Texture2D>("Texture");
   3:   
   4:  //Create an array to hold the data from the texture
   5:  uint[] data = new uint[polygonTexture.Width * polygonTexture.Height];
   6:   
   7:  //Transfer the texture data to the array
   8:  polygonTexture.GetData(data);
   9:   
  10:  //Find the vertices that makes up the outline of the shape in the texture
  11:  Vertices verts = PolygonTools.CreatePolygon(data, polygonTexture.Width, polygonTexture.Height, true);
  12:   
  13:  //For now we need to scale the vertices (result is in pixels, we use meters)
  14:  Vector2 scale = new Vector2(0.07f, 0.07f);
  15:  verts.Scale(ref scale);
  16:   
  17:  //Since it is a concave polygon, we need to partition it into several smaller convex polygons
  18:  _list = BayazitDecomposer.ConvexPartition(verts);
  19:   
  20:  //Create a single body with multiple fixtures
  21:  List<Fixture> compund = FixtureFactory.CreateCompoundPolygon(World, _list, 1);
  22:  compund[0].Body.BodyType = BodyType.Dynamic;

Note: The algorithm used to convert your texture data to a polygon is only as good as the data you give it. Make sure to clean up your textures (remove artifacts) and use the alpha channel (transparent) as the background in your texture.

We have several different decomposing algorithms in Farseer Physics Engine:

  • Earclip triangulation
  • Bayazit convex decomposition
  • Flipcode triangulation
  • Constrained Delaunay triangulation
  • Seidel triangulation

Each of them can be found in the FarseerPhysics.Common.Decomposition namespace.

Note: It is recommended that you don’t use the tools as part of your game loop. Run the tools once when the game starts and save the data for later. The tools are not 100% reliable and may crash or give unusable output on invalid input.

Paths

Path and the PathFactory is a flexible tool that can create ropes, bridges, tracks and more. You can declare a path that a body need to follow like the platforms in Mario or create a soft body like the one on the picture below (the green rectangle is the anchor point).

SoftBody

Here is how you create the soft body from the picture:

   1:  //We define the path
   2:  Path path = new Path();
   3:  path.Add(new Vector2(0, 10));
   4:  path.Add(new Vector2(2.5f, 7.5f));
   5:  path.Add(new Vector2(10, 9));
   6:  path.Add(new Vector2(7.5f, 0.5f));
   7:  path.Add(new Vector2(-2.5f, 7));
   8:  path.Closed = true;
   9:   
  10:  //It consists of two shapes: a rectangle and a circle
  11:  List<Shape> shapes = new List<Shape>(2);
  12:  shapes.Add(new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.5f, new Vector2(-0.1f, 0), 0)));
  13:  shapes.Add(new CircleShape(0.5f));
  14:   
  15:  //We distribute the shapes along the path
  16:  List<Body> bodies = PathManager.EvenlyDistibuteShapesAlongPath(World, path, shapes, BodyType.Dynamic, 20, 1);
  17:   
  18:  //Attach the bodies together with revolute joints
  19:  PathManager.AttachBodiesWithRevoluteJoint(World, bodies, new Vector2(0, 0.5f), new Vector2(0, -0.5f), true, true);

The PolygonTools

The PolygonTools class creates all sorts of polygons. We currently support the following polygons:

  • Rectangle
  • Rounded rectangle
  • Edge
  • Circle
  • Ellipse
  • Capsule
  • Gear

All the methods in the class returns a vertices collection that you can use in a PolygonShape.

Settings

We have the same settings as Box2D, however, we simplified the engine and moved some settings from inside the engine and into the Settings file. At the same time we added a few new settings.

  • EnableDiagnostics
  • VelocityIterations
  • PositionIterations
  • ContinuousPhysics
  • EnableWarmstarting
  • AllowSleep
  • ConserveMemory

All of them are described inside the Settings file.

Performance

In order to get the most out of the engine, you should try and follow the guidelines below:

Enable sleeping
Sleeping enables you to have large number of bodies in the world. It can also increase the stability of the engine since small movements in a stack of bodies don’t spread in the stack. A sleeping body has little overhead, so enabling it is recommended.

Disable CCD
Continuous Collision Detection prevents tunneling but at the cost of performance. If you don’t have problems with tunneling, you should disable CCD all together.

Minimize the number of position and velocity iterations
A high number of iterations makes the engine more stable at the cost of performance. You should tweak the values to fit your game.

Last edited Oct 22, 2012 at 8:07 PM by genbox, version 129

Comments

rahulroy9202 Oct 4, 2013 at 12:24 AM 
Please update the documentation.

Gamecow Aug 20, 2013 at 10:53 AM 
Please update the Documentation, its outdated -.-'

freeubi May 1, 2013 at 2:39 PM 
FixtureFactory.CreateCompoundPolygon(World, _list, 1);
The fixtureFactory dont have that method.

nemoryoliver Nov 6, 2012 at 10:51 AM 
I really wish to earn money with this engine. And I will donate to the maker of this. The Engine is great.

Nextovoy Oct 20, 2012 at 10:48 AM 
"World world = new World(new Vector2(0f, 9.82f);" - where the last bracket? ._.

YM_Industries Feb 19, 2012 at 6:57 AM 
Is there a Convex Decomposition algorithm that supports holes always?