Playing around with texture to polygon tools

Topics: Developer Forum, User Forum
Jan 3, 2011 at 9:39 AM

Howdy,

I'm new to farseer and I've been experimenting a bit with the texture to polygon tools. I have some questions I was hoping to get help with.

Here's a view of the texture and the generated polygon (enlarged to make it easier to see):

http://www.flickr.com/photos/52325734@N02/5318921607/

code:

            //Build polygon for texture
            uint[] data = new uint[texture2d.Width*texture2d.Height];
            texture2d.GetData(data);
            Vertices verts = PolygonTools.CreatePolygon(data, texture2d.Width, texture2d.Height);

            //translate and scale polygon to screen
            Vector2 origin = new Vector2(-texture2d.Width / 2, -texture2d.Height / 2);
            verts.Translate(ref origin);
            Vector2 scale = new Vector2(1, -1);
            scale = Vector2.Transform(scale, game.worldparams.PixelToMeterMatrix);
            verts.Scale(ref scale);

            //decompose vertices
            List<Vertices> list = EarclipDecomposer.ConvexPartition(verts);

            //remove empty vertices
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].Count == 0)
                {
                    list.RemoveAt(i);
                    i--;
                }
            }

            List<Fixture> compound = FixtureFactory.CreateCompoundPolygon(game.fs_world, list, 1);         

            fs_body = compound[0].Body;
            fs_fixture = compound[0];

 

A few of the questions I have are:

1) Is it unusual to have so many polygons for a simple texture? Is there any sort of performance penalty that comes with having a body represented by more polygons?

2) I added some code to apply a force to the texture, and I noticed there's a slight rotation that is getting applied over time. This rotation does not happen if I use a rectangular body created by BodyFactory. Is this because the generated polygons are not perfectly symmetrical?

 

                Vector2 impulse = new Vector2(0, 3);
                Matrix rotation = Matrix.CreateRotationZ(playerobj.Fs_body.Rotation);
                impulse = Vector2.Transform(impulse, rotation);
                playerobj.Fs_body.ApplyForce(ref impulse);

Thanks for any help!

 

Developer
Jan 3, 2011 at 10:50 AM
warmonked wrote:

1) Is it unusual to have so many polygons for a simple texture? Is there any sort of performance penalty that comes with having a body represented by more polygons?

I can't see your picture, as Flickr wants me to login first or something, so I have to guess a bit :)

Farseer needs convex polygons with a maximum of 8 points. So depending on the shape in your texture, you could end up with quite some fixtures. So most likely the answer is: No not unsual.

In general you want to minimize the body count as well as the fixture count, where possible. If your geometry is concave however you have at least two fixtures for one body.

2) I added some code to apply a force to the texture, and I noticed there's a slight rotation that is getting applied over time. This rotation does not happen if I use a rectangular body created by BodyFactory. Is this because the generated polygons are not perfectly symmetrical?

I think in theory it should not rotate. In practice Farseer uses an iterative solver and I guess due to some rounding errors e.g. the center of mass might not be exactly where it should be. If you don't want your body to rotate at all you can set fixed rotation to true or use a fixed angle joint.

Jan 3, 2011 at 6:45 PM

Oops, try this link:

http://flickr.com/gp/52325734@N02/1bowPi

Basically, the texture I have is an isometric triangle. The generated polygon is made of 6 polygons.

 Is there a tool in farseer to reduce these? I know practically, 6 vs 1 polygons isn't going to kill performance, it's the OCD in me that wants to optimize everything as much as possible :)

 

Developer
Jan 4, 2011 at 12:52 AM

Genbox once posted something about a method to join triangles to convex polygons inside the EarClipDecomposer class. Also there are the clipping tools which can be used to combine polygons. All of those methods are however quite computing intensive for your goal, e.g. one triangle. Even texture2polygon seems like breaking a butterfly on a wheel in your case though and is better suited to quickly generate convex polygons from complex shapes. If you want complete control over where and how your fixtures are created I'd suggest creating them by hand. I'd suggest having a look at the fixture factories.

That should imho be the much more common case, as you normally know the size and shape of most of your game assets beforehand. Dynamically generating such content will always need a lot of tweaking and experimenting.

Jan 4, 2011 at 8:32 PM

Cool, I'll take a look at the EarClipDecomposer methods. I don't mind if any of the methods are slow, I imagine computing any polygons separately and storing the data in a file to be the way to go.

Using texture2polygon is really appealing to me. I like the idea of just being able to draw up sprites and not having to worry about the polygons behind it all.

thanks for the help!

Jan 5, 2011 at 9:30 AM

I think I figured out the rotating-texture-when-applying-force problem. I fixed it by translating the vertices by the centroid of the polygon rather than the sprite texture dimensions.

            //translate and scale polygon to screen
            spritecenter = verts.GetCentroid();

            Vector2 scale = new Vector2(1, -1);
            scale = Vector2.Transform(scale, game.worldparams.PixelToMeterMatrix);
            verts.Scale(ref scale);

            Vector2 centroid = -verts.GetCentroid();
            verts.Translate(ref centroid);