Farseer Physics Engine 2.0.1 Manual

Contents

Introduction. 2

Overview.. 2

Body. 3

Body Factory. 3

Geometry. 4

GeomFactory. 5

Physics Simulator View.. 5

Joints. 7

Revolute Joint 9

Angle Joint 10

Angle Limit Joint 10

Pin Joint 11

Slider Joint 12

Joint Factories. 12

Springs. 13

Linear Spring. 15

Angle Spring. 15

Spring Factories. 16

Collision detection. 17

Broad phase. 17

Narrow phase. 18

AABB. 18

Grid. 19

Collision group and categories. 20

Collision Events. 22

Impulses. 23

Physics Properties. 24

Extensions to Farseer. 26

Texture to vertices. 26

Path Generator. 27

Performance. 27

Known issues. 32

 

Introduction

The Farseer Physics Engine is an easy to use 2D physics engine. It supports a wide range of platforms such as Microsoft's XNA, Silverlight, WPF, and Vanilla .NET. The Farseer Physics Engine focuses on simplicity, useful features, and enabling the creation of fun, dynamic games.

Overview

Getting right to the nut, the Farseer Physics Engine is designed to control the position and rotation of game entities over time. 

 

In the real world, things move and spin due to applied forces and torques. In Farseer, the same is true. Objects called "Bodies" represent the real world things. As forces and torques are applied, the bodies react according to the laws of 2D physics. The position and rotation of these bodies are then used to update game entities.

 

In the very simplest outline it works like this:

 

1.      Create "Body" object

2.      Add Body object to simulator.

3.      Begin Game Loop

1.      Apply forces and torques to Body.

2.      Update the simulator

4.      End Game Loop

 

Bodies, by design, have no geometry in the 2D world and therefore have no concept of collisions. 

 

For collision, Farseer has the "Geometry" object. Geometry objects are represented as 2D polygons and can be either concave or convex. They are defined by a set of vertices. One or more geometries are attached to a body in order to give the body geometrical awareness.

This allows the Body to participate in collisions with other Bodies (actually other Geometries attached to other Bodies, but you get the picture.)

Body

Body is the core physics object in Farseer. Forces, torques, and impulses are applied to bodies and the bodies react by moving accordingly. Bodies do not contain any form of collision awareness by themselves. To create a body you usually use the BodyFactory, but first, here is how you create a body manually:

 

int mass = 1;

float width = 128;

float height = 128;

Body rectBody = new Body();

rectBody.Mass = mass;

rectBody.MomentOfInertia = mass * (width * width + height * height) / 12;

rectBody.Position = new Vector2(100, 200);

 

As you can see, calculating MOI (Moment Of Inertia) for a rectangle is done like this:

 

MOIRectangle

 

Instead of remembering MOI for each shape, Farseer Physics can calculate the MOI for you. All you have to do is use the BodyFactory class as described in the "Body Factory" chapter.

One thing to note about bodies is that their position is relative to the center of the body.

 

Normal position

LeftTopGeom

Center position

CenterGeom

This has relevance to your positioning and drawing code. When you position your Body, you will need to position it relative to the center of the Body. Also, when you want to draw the Body onto the screen, make sure that you draw it relative to the center.

Body Factory

You create a body with the factory like this:


Body rectBody = BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator, 128, 128, 1);

This body has a size of 128 width, 128 height and a mass of 1. The MOI (Moment Of Inertia) is calculated for you. Note that the body is added right away by adding the PhysicsSimulator as a parameter.

You can create each of these types of bodies with the factory:

 

·         Rectangle

·         Circle

·         Polygon

·         Body

 

The last item (Body) is for when you want to create a body, without Farseer calculating the MOI for you. You can also use it to create clones of bodies.

 

There are some overloads for each BodyFactory method. One that takes a PhysicsSimulator object and another one that doesn’t. If you provide a PhysicsSimulator object, the body you create will be added to the simulator.

Geometry

The geometry (Called Geom in Farseer) is the heart of collision detection. A geometry needs a body and a set of vertices (laid out counter-clockwise) that define the edge of your shape.

 

While the body is in control of forces, torques, and impulses, the geometry is in control of collision detection and calculating the impulses associated with colliding with other geometries.

 

To create a geometry you usually use the GeomFactory, but first, here is how you create a geometry manually:

 

Body rectBody = BodyFactory.Instance.CreateRectangleBody(128, 128, 1);

 

Vertices vertices = new Vertices();

vertices.Add(new Vector2(-64, -64));

vertices.Add(new Vector2(64, -64));

vertices.Add(new Vector2(64, 64));

vertices.Add(new Vector2(-64, 64));

 

Geom rectGeom = new Geom(rectBody, vertices, 11);

 

This will create a rectangle body, a set of vertices that represent the outline of a rectangle (relative to 0, 0) and a new geometry with the defined vertices. The 11 inserted as a parameter in the Geom constructor is the grid cell size.

We will have a deeper look into grid cell size in the Grid chapter.

GeomFactory

Another and much easier way to create a geometry is by using the GeomFactory. The GeomFactory can create a vertices collection for simple shapes such as rectangle and circle. All you need is the width, height for rectangles or radius for circles.

 

Here is an example of creating a Geom using the GeomFactory:

 

Body rectBody = BodyFactory.Instance.CreateRectangleBody(128, 64, 1);

Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128, 64);

 

Notice that you don't have to supply any vertices or grid cell size. The GeomFactory creates the vertices and calculates the grid cell size for you.

 

There are situations where you would want to control the grid cell size. This is also very easy with the GeomFactory, just use the overloaded methods that takes a grid cell size:

 

Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128, 64, 6.4f);

 

Now we have a grid cell size of 6.4. (the f after the number indicates in C# that it's a float)

 

If you pass 0 into the grid cell size, it will get calculated for you. They way it's calculated is by finding the shortest side of the geometry (64 in this instance) and multiply it by the default grid cell size factor of 0.1. This would yeld 6.4.

 

You can adjust the default grid cell size by setting the GridCellSizeAABBFactor on the GeomFactory object.

Physics Simulator View

Physics simulator view is used for debugging joint anchors, body positions, geometry alignment and collisions. When you activate the view, you will see the anchors, collisions, contact points, centers, AABB's and a lot of other information that might be essential in debugging a Farseer physics related problem.

 

The physics simulator view only work in XNA. There will be debug views for other platforms in the future.

 

Without debug view:

 

With debug view:

 

Explanation:

There is a lot of configuration for the debug view. Here is a list of the possibilities:

 

·         Performance panel

o   Shows some information about the timing of the engine and the current count of bodies, geometries, joints, springs, controllers and arbiters.

o   Clean up: The time it took to add and remove geometries, bodies, joints, controllers and springs in the last update.

o   Broad Phase Collision: The time it took to do the broad phase collision detection.

o   Narrow Phase Collision: The time it took to do the narrow phase collision detection.

o   Apply Forces: The time it took to apply forces to all springs, controllers and bodies.

o   Apply Impulses: The time it took to apply impulses to joints and arbiters

o   Update Positions: The time it took to update the position of all bodies

·         Vertices

o   Shows the vertices that makes up the geometry. They are viewed as small black pixels around the geometry.

·         AABB

o   Shows the Axis Aligned Bounding Box (more on AABB's in the AABB chapter).

·         Contacts

o   Shows the vertices that have contact. Shown as small red pixels.

·         Coordinate axis

o   Shows the center of bodies. Shown with a black cross.

·         Grid

o   Shows the geometries distance grid used in narrow phase collision detection. There can be a lot of points in the grid, so this option might slow down the drawing a lot. Shown as black circles. (not enabled on the debug view picture above)

·         Edge

o   Shows the outlines of the edge of the geometries. Shown as a black edge.

·         Joints

o   Revolute, Pin and Slider joints have visualizations.

·         Springs

o   Linear springs (both fixed and normal) are shown with a black line between the two end points. 3 circles are positioned on the line to show the contraction and expansion of the line.

Joints

Farseer Physics Engine provides you with some of the basic joints. You can create almost any dynamic behavior by combining these joints:

 

·         Revolute joint*

·         Angle joint*

·         Angle limit joint*

·         Pin joint

·         Slider joint

·         Gear joint – experimental

 

* Has a "fixed" version. The fixed versions mean that the joint is anchored to the world and not to another body as their non-fixed versions.

 

Important Notes for all joints

·         Some joints need anchors relative to the bodies’ position and some need world anchor points. So pay attention to the type of joint your using.

·         Joints are attached to bodies.

·         All joints share some variables and methods.

·         Anchors don’t have to be inside a bodies attached geometry.

·         When joints break, they are disabled.

 

If joints don’t work as expected

1.      Check that your anchors are correct. Use PhysicsSimulatorView to find them (right now this means XNA only).

2.      Don’t change properties dramatically. Adjust them slowly and recheck your simulation.

3.      Anchors don’t have to be inside a bodies attached geometry. Don’t let your geometry limit your ability to overcome problems. Remember games are 50% fake. Do what it takes to make the end result ‘look’ right.

 

Developer note:

All joints are derived from the base class Joint and if you have the knowhow to add your own constraint be sure to derive yours from Joint as well (Please also share it with the community).

 

Shared variables – (these apply to all the joints)

·         Enabled – Simply lets the engine know whether to enforce the constraint or not.

·         IsDisposed – Lets you and the PhysicsSimulator know if the joint has been disposed of.

·         JointError – Get the error of the joint. Note that not all joints produce an error.

·         Breakpoint – Defines the maximum allowed value that JointError can reach before the joint is broken. The default is unbreakable (highest floating point number possible).

·         Softness – This coefficient used to allow joint softness. It should be between 0.0f and 1.0f, everything else is undefined. This is really just used to adjust the simulation to your liking. Something to note is that all joints will have some softness even with softness set to 0.0f.

·         BiasFactor – This coefficient determines how strongly the error will be corrected. It should be between 0.0f and 1.0f, everything else is undefined. Defaults to 0.2f. Note that setting this too high or low can cause dramatic instability, so change this in small increments.

·         Broke – This event handler fires when a joint breaks. It is up to you to provide a method here otherwise nothing will happen.

·         Tag – A generic object you can set to anything you like.

 

Shared Methods – (these apply to all the joints)

·         Validate – Determines if all bodies involved are not disposed. If any are then the joint is disposed.

·         PreStep – Performs the math necessary to update the joint. Should only be used of your writing your own joint.

·         Update – Performs the math necessary to update the joint. Should only be used of your writing your own joint.

·         Dispose – Disposes the joint.

Revolute Joint

This type of joint is great for adding wheels or linking multiple objects together. This joint takes a world vector but stores the joints position as two local vectors internally. The joint error is determined by finding the distance between the two local vectors. This joint comes in body to body and body to fixed types. Something to note is that when using the body to body type, the bodies can still move linearly, and when using the body to fixed type, the body can only rotate.

 

Properties

·         Body1 – Get/set the first body of the joint. This property is named Body in Fixed Revolute joints.

·         Body2 - Get/set the second body of the joint. This property doesn’t exist in Fixed Revolute joints.

·         Anchor – Get/set the anchor of the joint. This is in world coordinates.

·         CurrentAnchor – Gets the world position of the joint after simulation has started. Useful for drawing the joint.

·         SetInitialAnchor – Sets the anchor before the simulation has started.

 

Get Microsoft Silverlight

 

Demo description:

The yellow rectangle is pinned in place with a revolute joint. It can't move, only rotate. Use the mouse to rotate the rectangle. A fixed revolute joint is used to achieve this.

 

Next to the rectangle, you will see a green rectangle pinned to a red rectangle. They can move around in the world, but they can't move relative to each other, only rotate. A normal revolute joint is used to achieve this.

Angle Joint

This joint works great for linking two bodies’ angles to the same value or to a target angle. The fixed version simply holds a body at a target angle. These work great for programmatically changing a body’s angle without causing it to snap to that angle. If you change the angle the body or bodies will respond quickly to achieve that angle.

 

Properties

·         TargetAngle – Get/set the angle in radians that the body/bodies will attempt to achieve.

·         MaxImpulse – Get/set the maximum torque the body/bodies will use in attempting to achieve the TargetAngle. Defaults to the highest floating point number possible.

·         Body1 – Get/set the first body of the joint. This property is named Body in Fixed Angle joints.

·         Body2 - Get/set the second body of the joint. This property doesn’t exist in Fixed Angle joints.

 

Get Microsoft Silverlight

 

Demo description:

To the left you see a green rectangle that is kept at a specific angle all the time. It can't rotate, only move. A fixed angle joint is used to achieve this.

 

To the right you see 2 yellow rectangles that share the same angle/rotation. If you rotate one of them, the other one will rotate with the same amount. A normal angle joint is used to achieve this.

Angle Limit Joint

Same as an Angle joint but with limits, no target angle, and no torque impulses.

 

Properties

·         LowerLimit – Get/set the minimum angle, in radians, of the body.

·         UpperLimit – Get/set the maximum angle, in radians, of the body.

·         Slop – Get/set the slop allowed in the past the Min/Max limits.

·         Body1 – Get/set the first body of the joint. This property is named Body in Fixed Angle Limit joints.

·         Body2 – Get/set the second body of the joint. This property doesn’t exist in Fixed Angle Limit joints.

 

Get Microsoft Silverlight

 

Demo description:

The green rectangle to the left is kept rotated within a defined limit at all time. Minimum 15 degrees and maximum 50 degrees. A fixed angle limit joint is used to achieve this.

 

The two yellow rectangles are at a always within a specified angle limit relative to each other. Try putting both of them on the ground and you will see that it's impossible to make both stand firmly on the ground. Minimum 15 degrees and maximum 50 degrees. A normal angle limit joint is used to achieve this.

Pin Joint

This joint should probably be called a rod joint. It will hold two bodies a set distance apart while still allowing them to rotate.

 

Properties

·         TargetDistance – Get/set the desired distance between the two anchors. If no distance is specified, the offset between the bodies will be the target distance.

·         Body1 – Get/set the first body of the joint. Changing this without recalculating the TargetDistance could lead to instability.

·         Body2 - Get/set the second body of the joint. Changing this without recalculating the TargetDistance could lead to instability.

·         Anchor1 – Get/set the local anchor for Body1.

·         Anchor2 – Get/set the local anchor for Body2.

·         WorldAnchor1 – Get the world anchor for Body1. Useful for drawing the joint.

·         WorldAnchor2 – Get the world anchor for Body2. Useful for drawing the joint.

 

Get Microsoft Silverlight

 

Demo description:

The two red rectangles are using a pin joint to keep a target distance between each other. They can't more further away or closer to each other. Both bodies are still allowed to rotate.

 

The two yellow rectangles are using a slider joint (seen below) to keep a minimum and maximum distance between each other. They can move further away and closer to each other compared to pin joint.

Slider Joint

This joint is just like a Pin joint but with min/max limits on the distance. It will hold two bodies a set minimum to maximum distance apart while still allowing them to rotate.

 

Properties

·         TargetDistance – Get/set the desired distance between the two anchors.

·         Body1 – Get/set the first body of the joint. Changing this without recalculating the TargetDistance could lead to instability.

·         Body2 - Get/set the second body of the joint. Changing this without recalculating the TargetDistance could lead to instability.

·         Anchor1 – Get/set the local anchor for Body1.

·         Anchor2 – Get/set the local anchor for Body2.

·         WorldAnchor1 – Get the world anchor for Body1. Useful for drawing the joint.

·         WorldAnchor2 – Get the world anchor for Body2. Useful for drawing the joint.

·         Min – Get/set the minimum distance the anchors can come together.

·         Max – Get/set the maximum distance the anchors can separate from each other.

·         Slop – Get/set the slop allowed in the past the Min/Max limits.

Joint Factories

Joint Factories allow you to create joints in much the same way as you can create a body with a factory. As all the parameters have been described for the various joints I will just list the various methods used. Note that the factories don’t always set all the needed parameters of the joint.

 

Revolute Joint Factory

1.      CreateRevoluteJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2, Vector2 initialAnchorPosition)

2.      CreateRevoluteJoint(Body body1, Body body2, Vector2 initialAnchorPosition)

 

Fixed Revolute Joint Factory

1.      CreateFixedRevoluteJoint(PhysicsSimulator physicsSimulator, Body body, Vector2 anchor)

2.      CreateFixedRevoluteJoint(Body body, Vector2 anchor)

 

Pin Joint Factory

1.      CreatePinJoint(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2)

2.      CreatePinJoint(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2)

 

Slider Joint Factory

1.      CreateSliderJoint(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float min, float max)

2.      CreateSliderJoint(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float min, float max)

 

Angle Joint Factory

1.      CreateAngleJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2)

2.      CreateAngleJoint(Body body1, Body body2)

3.      CreateAngleJoint(PhysicsSimulator physicsSimulator, Body body1, Body body2, float softness, float biasFactor)

4.      CreateAngleJoint(Body body1, Body body2, float softness, float biasFactor)

 

Fixed Angle Joint Factory

1.      CreateFixedAngleJoint(PhysicsSimulator physicsSimulator, Body body)

2.      CreateFixedAngleJoint(Body body)

 

Angle Limit Joint Factory

1.      CreateAngleLimitJoint (PhysicsSimulator physicsSimulator, Body body1, Body body2, float min, float max)

2.      CreateAngleLimitJoint (Body body1, Body body2, float min, float max)

 

Fixed Angle Limit Joint Factory

1.      CreateFixedAngleLimitJoint (PhysicsSimulator physicsSimulator, Body body, float min, float max)

2.      CreateFixedAngleLimitJoint (Body body, float min, float max)

Springs

Farseer Physics Engine provides you with some of the basic springs. You can create almost any dynamic behavior by combining these springs:

 

·         Linear spring*

·         Angle spring*

 

* Has a "fixed" version. The fixed versions mean that the spring is anchored to the world and not to another body as their non-fixed versions.

 

Important Notes for all springs

·         Some springs need anchors relative to the bodies’ position and some need world anchor points. So pay attention to the type of spring your using.

·         Springs are attached to bodies.

·         All springs share some variables and methods.

·         Anchors don’t have to be inside a bodies attached geometry.

·         When springs break, they are disabled.

 

If springs don’t work as expected

·         Check that your anchors are correct. Use PhysicsSimulatorView to find them (right now this means XNA only).

·         Don’t change properties dramatically. Adjust them slowly and recheck your simulation.

·         Anchors don’t have to be inside a bodies attached geometry. Don’t let your geometry limit your ability to overcome problems. Remember games are 50% fake. Do what it takes to make the end result ‘look’ right.

 

Developer note:

All springs are derived from the base class Spring and if you have the knowhow to add your own constraint be sure to derive yours from Spring as well (Please also share it with the community).

 

Shared variables – (these apply to all the springs)

·         Enabled – Simply lets the engine know whether to enforce the constraint or not.

·         IsDisposed – Lets you and the PhysicsSimulator know if the spring has been disposed of.

·         DampningConstant – Get/set the dampening of the spring. This acts much like a shock absorber.

·         SpringConstant – Get/set the pull/push of the spring. Could be considered the force of the spring.

·         SpringError – Get the error of the spring. Note that not all springs produce an error.

·         Breakpoint – Defines the maximum allowed value that SpringError can reach before the spring is broken. The default is unbreakable (highest floating point number possible).

·         Broke – This event handler fires when a spring breaks. It is up to you to provide a method here otherwise nothing will happen.

·         Tag – A generic object you can set to anything you like.

 

Shared Methods – (these apply to all the joints)

·         Validate – Ensures the spring’s body/bodies still exist. If any are disposed then the spring is disposed also.

·         Update – Performs the math necessary to update the spring. Should only be used of your writing your own spring.

·         Dispose – Disposes the spring.

Linear Spring

This spring provides a pull/push of body/bodies. These can push as well as pull and can work in all kinds of ways. When combined with the right joints anything can be simulated.

 

Properties

·         Body1 – Get/set the first body of the joint. This property is named Body in Fixed Linear springs.

·         Body2 - Get/set the second body of the joint. This property doesn’t exist in Fixed Linear springs.

·         Anchor1 – Get/set the local anchor for Body1. This property is named Body in Fixed Linear springs.

·         Anchor2 – Get/set the local anchor for Body2. This property doesn’t exist in Fixed Linear springs.

·         RestLength – This is the length the spring will be when it’s not pulling or pushing at all. Note when using a factory the rest length is calculated as the distance between the anchors. If you want a spring to start pulling or pushing as soon as it’s created you should scale this property. A bigger scale value will cause the spring to push the body/bodies apart, smaller scale value will cause the body/bodies to pull together.

 

Get Microsoft Silverlight

 

Demo description:

The two yellow bodies are kept together with a linear spring. The bodies can be moved apart with enough force. It's like they are joined with a rubber band. A normal linear spring is used in this demo.

 

All the demos in this manual use a fixed linear spring to move/apply force to bodies. It's illustrated with a black line.

Angle Spring

This spring acts like a torsion bar.

 

Properties

·         Body1 – Get/set the first body of the joint. This property is named Body in Fixed Angle springs.

·         Body2 - Get/set the second body of the joint. This property doesn’t exist in Fixed Angle springs.

·         Anchor1 – Get/set the local anchor for Body1. This property is named Body in Angle Linear springs.

·         Anchor2 – Get/set the local anchor for Body2. This property doesn’t exist in Fixed Angle springs.

·         TargetAngle This is the angle in radians that the spring will be centered and offers no force.

·         MaxTorque – This is the maximum torque that will be applied to attempt to reach the TargetAngle.

·         TorqueMultiplier – The torque is multiplied by this value. Use 1.0f to use normal torque. This defaults to 1.0f.

 

Get Microsoft Silverlight

 

Demo description:

The white element in the middle functions just like a springboard. The angle spring is of fixed type. This means that it's attached to the "world". A revolute joint is used to pin the spring board to the world so that it stays in the same position, but still allow it to rotate around the pivot point.

Spring Factories

Spring factories allow you to create springs in much the same way as you can create a body with a factory. As all the parameters have been described for the various springs I will just list the various methods used. Note that the factories don’t always set all the needed parameters of the spring.

 

Linear Spring Factory

·         CreateLinearSpring(PhysicsSimulator physicsSimulator, Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float springConstant, float dampningConstant)

·         CreateLinearSpring(Body body1, Vector2 anchor1, Body body2, Vector2 anchor2, float springConstant, float dampningConstant)

 

Fixed Linear Spring Factory

·         CreateFixedLinearSpring(PhysicsSimulator physicsSimulator, Body body, Vector2 anchor1, Vector2 anchor2, float springConstant, float dampningConstant)

·         CreateFixedLinearSpring(Body body, Vector2 anchor1, Vector2 anchor2, float springConstant, float dampningConstant)

 

Angle Spring Factory

·         CreateAngleSpring(PhysicsSimulator physicsSimulator, Body body1, Body body2, float springConstant, float dampningConstant)

·         CreateAngleSpring(Body body1, Body body2, float springConstant, float dampningConstant)

 

Fixed Angle Spring Factory

·         CreateFixedAngleSpring(PhysicsSimulator physicsSimulator, Body body, float springConstant, float dampningConstant)

·         CreateFixedAngleSpring(Body body, float springConstant, float dampningConstant)

Collision detection

Farseer Physics Engine provides you with an easy to use collisions system containing 4 different parts:

 

1.      Broad phase collision detection

2.      Narrow phase collision detection

3.      AABB (Axis Aligned Bounding Box)

4.      Grid collision detection

 

Each system is described below:

Broad phase

The broad phase collision detection relies on advanced algorithms to speed up the collision detection by reducing the work the engine has to do.

We currently have 3 kinds of broad phase collision detection algorithms:

 

1.      Sweep And Prune (called SAP)

2.      Selective Sweep

3.      Brute Force

 

The Sweep And Prune algorithm is frame coherent, this means that if objects around the screen a lot, this might be a bad choice. This also means that if your objects are near the position they were the last frame, this algorithm is good.

Also note that the SAP algorithm does not like teleporting objects or very high speed objects such as moving from one end of the world to the other or bullets. It may break down from it and cause unreliable collisions.

More information on SAP can be found here and here (called sort and sweep).

 

The Selective Sweep algorithm is developed by BioSlayer. The SS algorithm is the default one in Farseer Physics Engine. SS was originally built on Sweep And Prune, but had some changes that made it perform better than SAP.

More information on SS can be found here.

 

The Brute Force algorithm is the most simple of them all, but also the least performing of the 3. It iterates all the geometries in the world and compares their AABB's. The Brute Force algorithm is O(n^2) complexity, but is still very fast for low geometry count.

Narrow phase

The narrow phase is where we take all the collision pairs generated by the broad phase, and do further calculation on them. All the narrow phase code lives inside the Arbiter class.

Here is a short overview of what happens in the narrow phase:
We assume that the broad phase provided us with a pair of colliding geometries contained in an Arbiter object.

 

1)      Iterate all the world vertices on the first geometry

2)      If the current vector intersects with the second geometry

a)      If false: Continue to next vector in vertices list

b)      If true: Create a contact and insert it in a contact list

3)      Do 1. and 2. on the second geometry

4)      If there are any contacts in the contact list, fire the OnCollision event providing the 2 geometries and the contact list.

 

The Arbiter class is also used to calculate the impulse that should be applied to the geometries, when they collide.

AABB

AABB stands for Axis Aligned Bounding Box and as the name says, it's a bounding box that aligns itself to an axis. All geometries have an AABB that is recalculated on each update, AABB are relatively inexpensive and used to quickly test if 2 geometries are close to each other (or even touching).

 

You can test if 2 geometries are close to each other by doing this:

 

if (AABB.Intersect(_circleGeom.AABB,_rectangleGeom.AABB))
{
    //The 2 AABB's intersect
}

 

Remember that because the AABB's are not rotated and they outline the geometry with a rectangle, when you test for intersection between 2 AABB's, the geometries might actually not touch. Have a look at these pictures.

 

Intersection

Intersection

Intersection and collision (touching)

IntersectionTouching

 

The AABB is the black outline of the geometries. As you see, they are not rotated, but are axis aligned. If you look real close, you can see that the contact created when colliding is red.

Grid

All geometries contains a Grid object. It's used by the narrow phase collision detection and uses a "distance grid". A distance grid is a pre-computed grid where each grid point contains the distance to the closest point on the geometry and the normal at that point. (For more information on normals, see the Physics chapter)

 

All distances for grid points that fall inside the geometry are negated. A picture of the grid and it's points is shown below:

 

Grid

 

Once the distance grid is pre-computed, the distance and normal for ANY point within the grid can be computed by interpolating between the known grid point values.

The grid is calculated from the provided grid cell size in the Geom constructor or when using the GeomFactory. A small grid cell size makes the grid more precise and therefore also makes the collision detection more precise.

 

Calculation of the grid can be quite time consuming, so it might be a good idea to pre-instantiate all your geometries beforehand and choose a grid cell size that is perfect for the geometry. More on this in the "Performance" chapter.

Collision group and categories

Farseer provides you with a way of creating different collision groups and the more advanced collision categories.

 

By default all geometries are in collision group 0, this means that it collides with all other geometries. If two geometries are in the same collision group, they will not collide with each other, the 0 collision group is an exception.

 

Here is how to set the collision group on a geometry:

 

Body rectBody = BodyFactory.Instance.CreateRectangleBody(PhysicsSimulator, 128, 128, 1);

rectBody.Position = new Vector2(250, 400);

Geom rectGeom = GeomFactory.Instance.CreateRectangleGeom(PhysicsSimulator, rectBody, 128, 128);

rectGeom.CollisionGroup = 10;

 

Body circleBody = BodyFactory.Instance.CreateCircleBody(PhysicsSimulator, 64, 1);

circleBody.Position = new Vector2(300, 400);<