[Solved] Texture to Polygon problem

May 18, 2010 at 10:43 AM
Edited May 18, 2010 at 10:47 AM

Hello everybody, I am new to using Farseer so excuse me for making stupid questions.

I was palying around with Farseer 2.1 for the last few days and now I am trying to use the "Texture to Polygon" feature. My problem is that the geometry is placed slightly off, a common problem as I read through the forum, but unfortunately I couldn't undestand how to solve it.

First of all here is the code I am using i order to create the body and geometry:

 

            Texture2D texture = item.texture;

            //Create an array to hold the data from the texture
            uint[] data = new uint[texture.Width * texture.Height];

            //Transfer the texture data to the array
            texture.GetData(data);

            //Calculate the vertices from the array
            Vertices verts = Vertices.CreatePolygon(data, texture.Width, texture.Height);

            //Make sure that the origin of the texture is the centroid (real center of geometry)
            Vector2 polygonOrigin = verts.GetCentroid();

            //Create body
            Body body = BodyFactory.Instance.CreatePolygonBody(verts, 1);
            body.Position = new Vector2(item.Position.X, item.Position.Y);

            body.IsStatic = true;


            //Add to physics simulator
            ps.Add(body);

            //Create geometry
            Geom geom = GeomFactory.Instance.CreatePolygonGeom(body, verts, 0);

            //Add to physics simulator
            ps.Add(geom);

 

The result I am getting is this:

Pic1:

 

Photobucket

 

Pic2:

Photobucket

 

As you can see in Pic2 the geometry is slightly placed to the left and up. The texture is being drew in the right place. Can someone help me with my code in order to place the geometry in the right place? Thanks in advance.

May 19, 2010 at 6:13 PM
Edited May 19, 2010 at 7:40 PM

Bump. Any help please?

 

May 19, 2010 at 8:35 PM

The problem is that the CreatePolygon routine assumes an offset relative to the drawn texture, which sometimes isn't useful when placing geometry in the world using absolute coordinates. Why don't you try something like this:

var polygonOffset = new Vector2(-texture.Width / 2, -texture.Height / 2);
verts.Translate(ref polygonOffset);

right after you create the polygon.

I find this is the most common cause for placement errors. If something else is the matter, it may have to do with your coordinate system (i.e. the way you're drawing your sprite).

Good luck

May 19, 2010 at 10:20 PM
Edited May 19, 2010 at 10:25 PM

Thanks a lot for your reply.

Unfortunately it didn't work (at first), I placed the code after the:

 

//Calculate the vertices from the array
Vertices verts = Vertices.CreatePolygon(data, texture.Width, texture.Height);

var polygonOffset = new Vector2(-texture.Width/2, -texture.Height/2);
verts.Translate(ref polygonOffset);

 

but I got again the same output. But this got me thinking, it felt weird that it didn't affect at all the geom position.

I remembered something that I read from another topic and I checked out the code of the CreatePolygonGeom method:

 

public Geom CreatePolygonGeom(Body body, Vertices vertices, Vector2 positionOffset, float rotationOffset, float collisionGridSize)
{
            if (body == null)
                throw new ArgumentNullException("body", "Body must not be null");

            if (vertices == null)
                throw new ArgumentNullException("vertices", "Vertices must not be null");
            
            //Adjust the verts to be relative to the centroid.
            Vector2 centroid = vertices.GetCentroid();

            Vector2.Multiply(ref centroid, -1, out centroid);

            //vertices.Translate(ref centroid);

            Geom geometry = new Geom(body, vertices, positionOffset, rotationOffset, collisionGridSize);
            return geometry;
}

 

In this code it translates the verts again with refernece to -centroid. So I disabled this line and it worked! 
The geom appeared where it should because of the translation you proposed.
Should it bother me that i had to mess with Farseer code?
Thanks again for your help, I'll play around with some polygons to check if this works for every polygon.
May 19, 2010 at 10:52 PM

Well, if it bothers you, just create your own "CreatePolygonGeom" method :) It's not that big anyway, more of a convenience.

I think those translations are there because you usually want to place dynamic objects which rotate correctly about their center of mass, which can vary depending on how you draw your texture. Unfortunately, some times you really want to be exact about the vertices you extract from the texture, especially (from my experience), when placing static world geometry.

Good thing you got your code working :)

May 19, 2010 at 11:01 PM
Chance wrote:

Well, if it bothers you, just create your own "CreatePolygonGeom" method :) It's not that big anyway, more of a convenience.

Yeah I thought of that and this is what I'm going to do. Thanks again for your time and help!