How to make bodies from triangle strips and lists?

Dec 15, 2010 at 1:15 PM

Hi Guys,

 

I'm just wondering how I would go about creating bodies in Farseer using triangle strips and triangle lists. Is there a method for creating one with either?


Thanks for any help!

Developer
Dec 15, 2010 at 1:42 PM

As Farseer is a physics engine, it is completely independet from any graphics representations of physical objects. Thus there is no direct way to pass in vertexbuffers or such things. You can create polygon shapes from your triangle data though or use FixtureFactory.CreateCompoundPolygon.

Do you want to create one body per triangle or do you want to attach a whole triangle strip to just one body? In the latter case you would have to figure out how to get the outline of the resulting polygon.

Dec 15, 2010 at 2:13 PM
Elsch wrote:

As Farseer is a physics engine, it is completely independet from any graphics representations of physical objects. Thus there is no direct way to pass in vertexbuffers or such things. You can create polygon shapes from your triangle data though or use FixtureFactory.CreateCompoundPolygon.

Do you want to create one body per triangle or do you want to attach a whole triangle strip to just one body? In the latter case you would have to figure out how to get the outline of the resulting polygon.

Sorry I should have phrased more clearly then! If I have a bunch of vertices which I use as a strip vs. a bunch of vertices I use as a list to draw I get different results. My question was if I could convert these results into a physical object that farseer could understand.

So I just wanted to know if Farseer had any method for simplifying this process, like if I passed it an array of vector2's which form a triangle strip of a light house if I could make farseer create a physical body in the shape of the light house.

I can work with either strips or lists, I'd actually prefer to create physical representations using lists but either is fine.

Developer
Dec 15, 2010 at 2:47 PM

Well in that case the answer is yes and no :)

Farseer knows circles, edges and convex polygons as shapes for physical objects. Also Farseer can aid you in decomposing non-convex polygons into convex polygons. What you need is basically the opposite. You would want to join several convex polygons (your triangles) into one big polygon, which you can attach to a body via a fixture. Creating the outline is not that hard though: Create a list of all the triangle's edges and throw out all duplicate edges and your are stuck with all the edges forming the outline of your polygon. Just join them back together in a "Vertices" object and pass that to FixtureFactory.CreatePolygon.

Alternatively you could attach every single triangle via multiple fixtures to one body: create a "Vertices" object out of 3 "Vector2"s and add it to a "list<Vertices>", which you can pass to FixtureFactory.CreateCompoundPolygon. I don't know how good/bad that is performance wise compared to the above solution.

Coordinator
Dec 15, 2010 at 6:18 PM

There actually is method to combine triangles to convex polygons. You find it inside the EarClipDecomposer class. Not very known as it is only used internally in the EarClip algorithm, but it might come in handy in your case.

 

Dec 15, 2010 at 6:45 PM

This is the method I made and it seems to be working:

 

for (int i = 0; i < triangles.Count; i++)
                {
                    Vector2 []tri = new Vector2[3];
                    tri[0] = triangles[i];
                    ++i;
                    tri[1] = triangles[i];
                    ++i;
                    tri[2] = triangles[i];

                    Vertices vertices = new Vertices(tri);
                    PolygonShape shape = new PolygonShape(vertices);
                    body.CreateFixture(shape, 1.0f);
                }

It works so I'm not too fussed about it but is there a better way to do it?

Coordinator
Dec 15, 2010 at 6:57 PM

A single body with multiple fixtures have a lot of proxies in the broadphase - for performance reasons it is best to keep the number of fixtures (and bodies) as low as possible. If you find that the performance suffers from this, you can combine the triangles into convex polygons.

Dec 15, 2010 at 7:29 PM
Edited Dec 15, 2010 at 7:44 PM
Genbox wrote:

A single body with multiple fixtures have a lot of proxies in the broadphase - for performance reasons it is best to keep the number of fixtures (and bodies) as low as possible. If you find that the performance suffers from this, you can combine the triangles into convex polygons.

I tried using the EarclipDecomposer.ConvexPartition function like this:

 

Vertices vertices = new Vertices();
                for (int i = 0; i < triangles.Count; i++)
                {
                    vertices.Add(triangles[i]);
                }
                

                List verts = FarseerPhysics.Common.Decomposition.EarclipDecomposer.ConvexPartition(vertices);

                for (int i = 0; i < verts.Count; i++)
                {
                    System.Diagnostics.Debug.Assert(verts[i].Count > 0);
                    if (verts[i].Count > 0)
                    {
                        PolygonShape shape = new PolygonShape(verts[i]);
                        actor.body.CreateFixture(shape, 1.0f);
                    }
                }

But it didn't work, and for some verts  the assert: System.Diagnostics.Debug.Assert(verts[i].Count > 0); failed...

I also tried using the PolygonizeTriangles function like this:

 

Vertices vertices = new Vertices();
                for (int i = 0; i < triangles.Count; i++)
                {
                    triangles[i]/=100.0f;
                    //ertices.Add(triangles[i]/100.0f);
                }
                List tris = new List();
                for (int i = 0; i < triangles.Count; )
                {
                    tris.Add(new FarseerPhysics.Common.Decomposition.Triangle( triangles[i++].X, triangles[i++].Y, triangles[i++].X, triangles[i++].Y, triangles[i++].X, triangles[i++].Y ));
                }
                List verts = FarseerPhysics.Common.Decomposition.EarclipDecomposer.PolygonizeTriangles(tris, 33, 0.2f);

                for (int i = 0; i < verts.Count; i++)
                {
                    System.Diagnostics.Debug.Assert(verts[i].Count > 0);
                    if (verts[i].Count > 0)
                    {
                        PolygonShape shape = new PolygonShape(verts[i]);
                        actor.body.CreateFixture(shape, 1.0f);
                    }
                }*
But that failed asserts (on CreateFixture) and didn't build any bodies...

Coordinator
Dec 15, 2010 at 8:04 PM

PolygonizeTriangles() should combine the triangles for you - however, it might need a special layout for the triangles, I'm not sure as I did not write it.

Dec 16, 2010 at 5:32 PM

Maybe that's it... the behaviour was quite wierd.

I'm more or less happy with the results I'm getting with my current method, it's enough to create bits of terrain and tables and whatever else I need, WP7 handles it all well.