Farseer Physics Engine 3.0 Update (April)

Coordinator
Apr 18, 2010 at 8:02 PM

Here is an update to our TODO list:

I've hacked together a quick BreakableBody type that should provide the very basics in breakable bodies. You can provide it with a bunch of vertices, it will triangulate the list and create a bunch of fixtures that are fixed together. Once a threshold is reached, it will break apart. It is not finished yet - I don't have the time to complete it and make it flexible. If anyone wants to take a stab at it and extend it a little, feel free to do it.

All we need now is the Path generator and port over the old samples to the new framework. There are also some minor adjustments to the consistency of the code and some of the API might still change. If you are feeling brave, you can go ahead and download the latest source code check-in directly from the source control.

Apr 21, 2010 at 7:42 PM
Edited Apr 21, 2010 at 7:44 PM

It's good to hear you guys are keeping busy ;)

I noticed in the "Source Code" section that the newest version has PostSolve available to fixtures now.

I used to have the problem where OnCollision was not providing the impulse data after Solve, but I

remedied it by firing the method (OnCollision) inside of "StoreImpulses" in ContactSolver.cs. Putting it

there allowed me to do the quick null checks on the fixtures without having to iterate through the contact

list because StoreImpulses already iterates through the contactlist.

The tradeoff is that OnCollision doesn't have the option of cancelling a collision, but I don't need that

as of yet, so I figured it wasn't important.

 

Secondly, I noticed the mention of World.Add() being removed for the arrival of the BodyFactory. I created

a static class in the projects I've been working on that has all the BodyFactory and GeomFactory overloads

I needed, to make the conversion process from 2.0 to 3.0 relatively painless (I wouldn't have to go in and change

all the instantiating of Bodies and [now] Fixtures to reflect 3.0, I just made them all point to one static class).

 

As a reference, I'll paste the code here:

 

static class ConversionHelper
    {
        public static class BodyFactory
        {
            public static class Instance
            {
                /// <summary>
                /// Instantiate Bodies the classic way
                /// </summary>
                /// <param name="world">PhysicsSimulator</param>
                /// <param name="width"></param>
                /// <param name="height"></param>
                /// <param name="mass">This parameter is just a placeholder, because mass is calculated with Fixture densities</param>
                /// <returns></returns>
                public static Body CreateRectangleBody(World world, float width, float height, float mass)
                {
                    Body body = world.Add();
                    body.BodyType = BodyType.Dynamic;

                    return body;
                }

                public static Body CreatePolygonBody(World world, FarseerPhysics.Common.Vertices vertices, float mass)
                {
                    Body body = world.Add();
                    body.BodyType = BodyType.Dynamic;

                    return body;
                }

                public static Body CreateCircleBody(World world, float radius, float mass)
                {
                    Body body = world.Add();
                    body.BodyType = BodyType.Dynamic;

                    return body;
                }
            }
        }

        public static class GeomFactory
        {
            public static class Instance
            {
                public static Fixture CreatePolygonGeom(World world, Body body, FarseerPhysics.Common.Vertices vertices, float density)
                {
                    return body.CreateFixture(new PolygonShape(vertices, density));
                }

                public static Fixture CreatePolygonGeom(World world, Body body, FarseerPhysics.Common.Vertices vertices, Vector2 offset, float rotationOffset, float density)
                {                
                    Transform xf = new Transform();
                    xf.Position = offset;
                    xf.R.Set(rotationOffset);

                    // Transform vertices
                    for (int i = 0; i < 4; ++i)
                    {
                        vertices[i] = MathUtils.Multiply(ref xf, vertices[i]);
                    }

                    return body.CreateFixture(new PolygonShape(vertices, density));
                }

                public static Fixture CreateCircleGeom(World world, Body body, float radius, int numberOfEdges)
                {
                    return body.CreateFixture(new CircleShape(radius, Densities.HAIL_DENSITY));
                }
            }
        }
        
        public static class Vertices
        {
            public static FarseerPhysics.Common.Vertices CreateSimpleRectangle(float width, float height)
            {
                return PolygonTools.CreateRectangle(width / 2, height / 2); //the parameters take half width and half height
            }

        }

    }

 

This is not complete of course. I've just put the ones that I used in my project prior to moving the engine to 3.0.

As of now, the Body constructor does not add itself to the bodyList in World, even though you pass World as a

parameter. Currently, I find World.Add() to be the best way to instantiate a body, am I wrong?

 

Good luck on the update!

 

-Oranjoose

 

Developer
Apr 21, 2010 at 9:13 PM

World.Add() actually does add the body it returns to the world. The name is a little misleading.

Apr 22, 2010 at 1:23 AM

@mattbettcher

No, I was saying that the constructor for the Body, ie, new Body(World world) does not

add the body to the bodylist of the World. I was making the point that World.Add does

and therefore better

Coordinator
Apr 22, 2010 at 11:35 AM
Thanks for the notes oranjoose. Let me know if you find more of that kind. You are correct about the impulse data: Use OnCollision if you need to detect collisions - use PostSolve on Fixture if you need collision data such as the impulses involved. As for the body that takes in World as a parameter: A reference to world is needed in several properties and it is required by the CreateFixture(Shape) method. I've been trying to remove the dependency on World inside the Body class (to enable caching of Bodies and decouple it from World), but at the same time some updated came from Box2D that required the two to be coupled - I decided to let Body and World be coupled for now and perhaps I will decouple them later. I would like a more streamlined approach to adding bodies and fixtures to the world. Just like we have in FPE 2.x with the factories. Right now Body is in charge of creating Fixtures, I would like Body and Fixture to be decoupled and put a factory in charge of creating both of them instead.
Coordinator
Apr 29, 2010 at 2:02 PM
Matthew has uploaded his Path class to FPE 3.0, this means we are almost feature complete! I've updated the source code to reflect the changes in Box2D rev 103 - this includes a good performance boost in the dynamic tree (Since the broad phase is built on the dynamic tree, it also have the performance boost). Try running the pyramid test (broadphase intensive) before and after you update to the latest revision of FPE 3.0 to see the difference. The only things left are the samples (They should to be converted to the new framework) and the project files for all the different platforms we support. If you are willing to help out with this, contact me using codeplex or use the "join project" button on the frontpage.