[SOLVED] Issues with Texture To Vertices (TTV)

Topics: Developer Forum, User Forum
Apr 3, 2010 at 8:09 PM

Hey all,

So I'm working on a simple 2D game, and right up until now, all my objects in-game have primitive geom shapes (circle or rectangle) for collisions. Recently, I was going through the Farseer Manual, and came across the little code snippet
for converting a texture to vertices and then basing the physics body and geom objects off that data (http://www.farseergames.com/storage/farseerphysics/Manual2.1.htm#_Toc213068512). As I understand, this should allow me to have some
irregularly shaped objects with proper collisions along their outlines instead of just a bounding box/circle, which would be really useful so that I could make game objects without worrying how well they'd fit in a square or circle collision only...

However, on actually trying out that code, I got all sorts of weird results, ranging from a few crashes, to my other objects flying through my ground object or out of view, etc. Also, my Sprite, which is the visible representation of the physics objects
never showed up onscreen, which I found rather puzzling. Upon debugging, I found that something causes the object to fly off drastically and so fast, that as soon as the game renders, its nowhere to be seen. As a concrete example, I created my
object (a simple square texture) at (0.0f, 2.0f) position at the start, and after probably 2/3 passes through the update loop, the X-position was a -63.0f - wayyy outta my boundaries. Similar behaviour on the Y too.

I just don't get what could be causing that kind of behaviour. I've tried altering the object's mass, and also setting the CollisionGridSize property to a variety of values (including 0), all to no avail.
I searched the forums on here, and found nothing, except for this one topic (http://farseerphysics.codeplex.com/Thread/View.aspx?ThreadId=204329&ProjectName=FarseerPhysics). I also tried using wcholland's class from that thread, and got
the same kind of behaviour.

Can someone more experienced kindly shed some light on what's going on here and if there's a possible solution? I'd really like to be able to draw irregularly shaped objects and have them have precise collisions with other objects in my game.
Is there any other method to do that, and if so, any code samples I can take a look at?
I'm using Farseer Physics with the FlatRedBall XNA Game Engine, if that helps any.

Many thanks in advance! 

Apr 4, 2010 at 10:40 PM

Is there any way to get a sample program demonstrating the problem? It's probably a simple fix, but it's difficult to determine the problem without any code.

Apr 5, 2010 at 6:11 AM

Alrighty, I shall throw together a simple sample project and upload it within the next hour or two. Might be a while as my internet speed is shaped for the month :-/
But I'll definitely get it done somehow.

Thanks for taking the time, Matt - really do hope its simple, need to get it working ASAP for my project.

Apr 5, 2010 at 9:12 AM
Edited Apr 5, 2010 at 9:15 AM

Here's a simple test project I set up to demonstrate the problem I'm having:

The scene consists of a ground (rectangle Geom), crate (rectangle Geom), ball (circle Geom), and an "irregularPlatform" (texture-to-vertices). The actual object has been placed at (0,0), however
the collisions it exhibits just doesn't make any sense at all: they seem to extend far below and to the sides of the object, and possibly even above it. You can control the ball
using the left/right arrows and jump using Spacebar. For testing purposes, you can jump as many times as you like, even in the air. You'll notice that as you jump the ball higher, it seems
to be pushing against the irregularPlatform's collision and moving it (it has a pretty light mass).
Oh and if you set the object to be static (just uncomment line 110 in Game1.cs), you'll see that the green crate goes all crazy, because its intersecting with the irregularPlatform's weird collision.

Again, I tried a lot of settings for the CollisionGridSize property, but no go. I'm using code from wcholland's post on this topic, btw: http://farseerphysics.codeplex.com/Thread/View.aspx?ThreadId=204329 .
I've modified it a bit to show how I intend to use it, but I've also left a copy of the original code in the TTV class just in case. To be honest, I'm not quite sure how to use his original stuff, as it returns
an ArrayList which I'm not sure what to do with.

Code of interest mainly lies in the "Game1.cs" and "TTV.cs" files.

My end goal is to have a working TTV class that I can use to create all my game objects which are not perfectly shaped primitives (box or circle). It's severely limiting at the moment, and I would really
like the ability to have odd-shaped stuff with proper collisions on them, for eg:, the platform in this project.

Thanks for taking a look and any subsequent advice/help you can provide me with. Apologies if I'm missing something stupid or trivial, but I'm just totally stumped.

Cheers :) 

Apr 6, 2010 at 7:35 PM


Anyone at all? Am on the verge of killing myself trying to figure this out! (>_<)

Apr 6, 2010 at 8:27 PM
Edited Apr 6, 2010 at 8:28 PM

Right I think that you are having the same issue as I did first when I tried the same but in Silverlight.

When you call the CreatePolygon function Farseer will reposition the polygon object for you.

So in order to get the correct drawin you need to translate your object with the result from verts.GetCentroid() function. The variable orgin that you use to save this data in.

I didn't read all of your code but I'm pretty sure that this is the cause of the problem.



Apr 7, 2010 at 6:26 PM
Edited Apr 7, 2010 at 6:26 PM

@ dweebster: Thanks for the reply, mate, although I'm afraid I've no clue how to go about what you said, i.e., translating the body/geom using the "origin" variable. Could you possibly explain that in some more detail,
and also how exactly it helps fix the problem? Any concrete code sample I could possibly nick off you, if I'm not being too greedy? I assume you've fixed the issue with your SilverLight project, so I might be able to get
somewhere with my XNA one if you could tell me what exactly you did with yours...

Many thanks again. Anyone else have any solutions to this, please fire away, I need this working *urgently*, as its for a Uni. project more than a hobby thing right now. 

Apr 7, 2010 at 7:34 PM

The answer is actually located right here in the forum.

Read this post: http://farseerphysics.codeplex.com/Thread/View.aspx?ThreadId=56417

My code for Silverlight is a bit different but here it is:

Vertices verts = Vertices.CreatePolygon(data, (int)(ImageTest.ActualWidth * st.ScaleX), (int)(ImageTest.ActualHeight * st.ScaleY));

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

                //Use the body factory to create the physics body
                polygonBody = BodyFactory.Instance.CreatePolygonBody(physicsSimulator, verts, 5);
                polygonBody.Position = new Vector2(8000, 400);
                polygonBody.IsStatic = true;
                GeomFactory.Instance.CreatePolygonGeom(physicsSimulator, polygonBody, verts, 0);

                //Move image to location
                    Convert.ToDouble(polygonBody.Position.X - (polygonOrigin.X)));
                    Convert.ToDouble(polygonBody.Position.Y - (polygonOrigin.Y)));


Hope this helps!

Apr 7, 2010 at 8:34 PM

@ dweebster:

First, thanks very much for sharing your code! And second, thanks again for that link to the other post, never came across it in all my searches before.
I shall take a look at both, your code and that article, and give my test project another shot after that to see if I can finally nail it or not.
Either way, will report back on here.

Cheers! :) 

Apr 8, 2010 at 9:47 AM

Ok, so my situation's not improved one bit, unfortunately :(

I read up on the posts at http://farseerphysics.codeplex.com/Thread/View.aspx?ThreadId=56417 and http://farseerphysics.codeplex.com/Thread/View.aspx?ThreadId=19911, and also looked up AndyBeaulieu's code from
this article for his SilverLight/Farseer project, but haven't been able to implement anything useful for my XNA scenario at all...

What I did just realise is that the variable we use to get and store the centroid (eg: in my code - Vector2 origin = verts.GetCentroid();) never actually gets used anywhere. I'm guessing this is what dweebster meant when
he said that the verts need translating by that amount to fix the problem. Keeping that in mind, I also tried adding verts.Translate(ref origin); and verts.Translate(ref originInv); (where originInv is just origin * -1) to my code
before the Body and Geom are created, as well as inbetween the Body and Geom creation, all to absolutely no avail. The behaviour remains exactly the same.

I notice in your code you multiply the texture width and height by some ScaleX and ScaleY values. Why exactly do you need to do this and where do you get those values from? When I tried something like that
(multiplied the width and height by the ScaleX and ScaleY of my Sprite object), the program crashed upon startup with an error at line 895 in Vertices.cs:
"An unhandled exception of type 'System.Exception' occurred in FarseerPhysics.dll
 Additional information: Sizes don't match: Color array must contain texture width * texture height elements."

I'll be honest and say that I'm extremely desperate at this point, because theoretically, I would imagine that this should work without this much of a hassle. I need to have this working somehow within a day in my project,
as I have deliverables to submit first thing Monday morning. I don't mean to be a nag, but again, can someone...
anyone...whose gotten this working in XNA, or one of the devs, please respond with a possible solution to my
predicament? I'd be grateful beyond measure.

Thanks a tonne in advance. 


Apr 9, 2010 at 2:52 PM

How about you post your code and maybe we can help you a bit more.


In my code I scale the texture by a certain amount due to conserving bandwith in the Silverlight app so this is not something that you should do.

When you draw your objects you need to translate them by the amount of verts.GetCentroid().

Apr 9, 2010 at 7:42 PM
Edited Apr 9, 2010 at 7:43 PM

The code's the exact same as what I had in the test project I uploaded earlier, but I'll just post the parts relevant to my problem over here:

TextureToVertices class 

class TTV

        // ***************************************************************
        // Class-scope Variables
        // ***************************************************************

        private SpriteUtility spriteUtility;

        private Body body;
        private Geom geom;
        private Sprite sprite;

        // ***************************************************************
        // Default Constructor
        // ***************************************************************

        public TTV()
            spriteUtility = new SpriteUtility();           

        // ***************************************************************
        // Create()
        //  - NOTE: Based on tutorial from Farseer Manual
        // ***************************************************************

        public void Create(PhysicsSimulator physicsSimulator, Texture2D texture)

            // Create graphics object
            sprite = SpriteManager.AddSprite(texture);

            uint[] data = new uint[texture.Width * texture.Height];
            Vertices verts = Vertices.CreatePolygon(data, texture.Width, texture.Height);
            Vector2 origin = verts.GetCentroid();            

            // Create physics objects based on texture
            body = BodyFactory.Instance.CreatePolygonBody(physicsSimulator, verts, 3.0f);
            geom = GeomFactory.Instance.CreatePolygonGeom(physicsSimulator, body, verts, 0);


        // ***************************************************************
        // Update()
        //  - Updates the graphics object based on physics behaviour.
        // ***************************************************************

        public void Update()

            // Update position
            sprite.X = body.Position.X;
            sprite.Y = body.Position.Y;           

            // Update rotation
            sprite.RotationZ = body.Rotation;


        // ***************************************************************
        // Access methods for newly created Body and Geom objects
        // ***************************************************************
        public Body physicsBody
            get { return body; }

        public Geom physicsGeometry
            get { return geom; }

        public Sprite graphicsObject
            get { return sprite; }

In the game's Initialize() method: 

// Irregular Platform (Created using Texture-To-Vertices)
            irregularPlatform = new TTV();
            irregularPlatform.Create(physicsSimulator, FlatRedBallServices.Load<Texture2D>("Content/Sprites/IrregularPlatform"));
            irregularPlatform.physicsBody.Position = new Vector2(0.0f, 0.0f);
// Irregular Platform (Created using Texture-To-Vertices)
TTV irregularPlatform = new TTV();
irregularPlatform.Create(physicsSimulator, FlatRedBallServices.Load<Texture2D>("Content/Sprites/IrregularPlatform"));
irregularPlatform.physicsBody.Position = new Vector2(0.0f, 0.0f);

And then in Update():
// Update the physics engine

// Update all graphics objects based on physics:

So basically, I've got a little class that will take in a texture, and then do the "Texture to Vertices" thing in the Create() method and create the physics Body and Geom objects. It also creates my Sprite (FlatRedBall game engine object) using the texture, which is to be used as my visible representation
of my physics object. In case anyone's wondering, the "spriteUtility.ScaleSpriteToTextureSize (...)" is just a method that makes the Sprite the same size as the actual texture, so that I don't have to bother experimenting with scaling my objects manually.

Once the object is created, I just give it a starting position of (0, 0), and then in my Update() loop, I call the object's Update() method, which as you can see, simply sets the Sprite's position and rotation to that of the physics Body object.

The problem, as I mentioned earlier, lies in the fact that the collision of my irregularPlatform seems to fill almost the whole screen, extending wayyy off to the left, right, bottom, and top of the actual Sprite/texture. The Sprite shows up onscreen at the expected size correctly...

@ dweebster:
Given this explanation of what my code's doing, would you please be able to point out how/where I do that translate with

@ anyone else:
Help! (>_<) 

Apr 13, 2010 at 9:09 PM

*Double Bump!*

Anybody at all? I'm in desperate need of help with this, just can't get any further since the past whole week :-( 

Apr 14, 2010 at 7:34 PM

I think that you should actually try to use your own rendering engine to understand how this works and how it should work and you should probably put more effort in trying to change your code on your own.

But given the time frame I understand your panic.

One thing that might fix your problem is to declare your variable "origin" as a global in your class.

Then when you do your update try this instead:

sprite.X = body.Position.X - origin.X;
sprite.Y = body.Position.Y - origin.Y;


Apr 14, 2010 at 9:43 PM
Edited Apr 14, 2010 at 9:56 PM

@ dweebster:

Thanks for replying, and honestly, I wouldn't have been so pushy if this were not for something that was assessable at Uni. where my lecturer wants to see significantly new stuff added every single week...

Unfortunately, I've tried that exact bit of code before in the test project, and it doesn't fix anything at all - I still get the same weird behaviour with the collision, except that my sprite is nowhere to be seen either (I guess origin has a number big enough to send it off screen).
Since my sprite simply won't sit correctly with the body/geom, is there a way in Farseer to draw the outlines of an object? Like a method from the Body or Geom class? I couldn't find anything so far, but I'm guessing if I can somehow get the collision bounds to show up onscreen, then that might help see what's going on more clearly, and also, I could probably post some screenshots on here. Or alternatively, a way to plot the vertices it's using as a set of points on the screen...

Apr 15, 2010 at 7:05 AM
Edited Apr 15, 2010 at 7:07 AM

To be honest, I wouldn't trust the scaleCoefficient in your code. It's set to 0.021f and it is multiplied with the width and height of the texture to set the sprites dimensions oO ? Why ? This might explain why your texture isn't drawn (or is it, I just hat a few minutes to read this) ... I didn't find the sprite utility here http://www.flatredball.com/frb/docs/index.php?title=Category:FlatRedBall_XNA_Code_Reference so it's something you wrote?

I've never used FRB and I'm at work ... so I can't really help you now. I just feel the need to tell you that TTV works fine.

Apr 15, 2010 at 5:44 PM

@ sickbattery:

I did think that was a possible blockage in the functionality, so I'd removed that bit and given it a shot, but no luck. And yep, the SpriteUtility is something I wrote for myself. The ScaleCoefficient is basically used to scale each sprite to the actual size of the texture as drawn and saved from Photoshop.

Thanks for taking the time to look over my stuff and reply here, doesn't matter if you provided a fix or not. Since you've said that TTV does work as expected, would you happen to have any code for it (that's different from the example code) that you might be willing to share? So far from what I've read, it seems as though the tutorial code from the Farseer Manual needs some Mathsy tweaking with the vertices, so I'm wondering if you made any modifications, and if so, what they were?

Apr 15, 2010 at 8:53 PM
Edited Apr 15, 2010 at 9:00 PM

"would you happen to have any code for it (that's different from the example code)"

Of course, but it will look like in the documentation ...

public static bool CreateBodyAndGeom(PhysicsSimulator physicsSimulator, Texture2D texture, bool holeDetection, float mass, out Body body, out Geom geom)
if (texture != null)
uint[] data = new uint[texture.Width * texture.Height];

PolygonCreationAssistance pca = new PolygonCreationAssistance(data, texture.Width, texture.Height);
pca.HoleDetection = holeDetection;
pca.MultipartDetection = false;

List<Vertices> polygons = Vertices.CreatePolygon(ref pca);

if (polygons != null && polygons.Count == 1 && polygons[0].Count > 2)
body = BodyFactory.Instance.CreatePolygonBody(physicsSimulator, polygons[0], mass);
geom = GeomFactory.Instance.CreatePolygonGeom(physicsSimulator, body, polygons[0], 0);

return true;
body = null;
geom = null;
return false;
body = null;
geom = null;
return false;


After that I get the centroid and set it as the center of my texture ...

_textureOrigin = _geom.WorldVertices.GetCentroid();


... then I draw it:

spriteBatch.Draw(_texture, _body.Position, null, Color.White, _body.Rotation, _textureOrigin, 1f, SpriteEffects.None, _drawLayer);

That's it. At least with XNA.

Check this out, to know what each parameter does: http://msdn.microsoft.com/en-us/library/bb196416.aspx

One can do it like this because the polygon is created with texture coordinates. However, that's how you can do it and I haven't seen any code where  you draw the sprite, it's probably drawn by the flat red ball engine automatically? I don't know if the sprites are drawn centered by default?

What's with the red flat ball coordinate system? Is Y = -1 up or down? In XNA it's up. Also what's the scale of the coordinate system? If you have to scale the sprite that much down with your util ... maybe you should do the same with the vertices? ... but I already wrote a 2.5d engine powered by farseer and at that scale you might run into some trouble (jittering, tunneling, etc?).


"Since you've said that TTV does work as expected" and "so I'm wondering if you made any modifications"

I've made no modifications and I know that TTV works because I wrote it o_O.


Try scaling down the vertices, but since you wrote: "@ dweebster: Thanks for the reply, mate, although I'm afraid I've no clue how to go about what you said, i.e., translating the body/geom using the "origin" variable."

I'll give you some untested code (it's late and my girlfriend will kill me if I don't go to bed now) ...


Matrix scaleCoefficientMatrix = Matrix.CreateScale(scaleCoefficient) * Matrix.CreateTranslation(-vertices.GetCentroid()); // Minus centroid, I guess ...
Vector2[] verticesArray = vertices.ToArray(); Vector2[] scaledVerticesArray; Vector2.Transform(verticesArray, ref scaleCoefficientMatrix, out scaledVerticesArray); Vertices scaledVertices = new Vertices(ref scaledVerticesArray);



I should have more time for this tomorrow.

Good Night :).

Apr 16, 2010 at 10:33 AM

@ sickbattery:

Can't thank you enough for posting all that info, man! Greatly appreciated, cheers!
I'm currently working on another project for Uni., but I will be getting back to my game project over tomorrow and dayafter, so I will tinker around with the stuff you've mentioned and see what I can come up with.

To answer your questions about FlatRedBall:
1) A 'Sprite' is a class object in the engine for drawing purposes. It takes in a texture and draws it to the screen, alongwith providing access to a bunch of methods/operations for their manipulation. So for each item I want on the screen, I have a Sprite object. It is specified and set manually by me, not something
    that gets done automatically.
2) Y = -1 is down and Y = +1 is up in FlatRedBall. So basically I notice its the opposite of regular XNA. Does that make a difference to how TTV would work?
3) If you add a Sprite object to the engine, but don't do any scaling to it, it appears very small in the middle of the screen (0, 0), something like a 16x16 or 32x32 texture, irrespective of its actual size. So hence, to get it to the desired size in my game, I wrote that SpriteUtility method (SetSpriteScaleToTextureSize)
    to set the Sprite to the actual texture size. This saves me time from manually experimenting with the ScaleX and ScaleY values for each object in my scene until I get the desired size. Is there another way I should be drawing my texture/sprite to the screen?
Will test out your suggestions first thing tomorrow and report back with what happens.

Again, thanks heaps for your time and patience! 

Apr 16, 2010 at 11:20 PM


I have seen similar behavior before, and it usually (for me) happens when the new object I put in the physics simulator is bigger than the screen, so it sees all the other objects as "inside" it's geometry and tries to push them out. It happens all the time when I throw a new geom in there and I haven't checked if the scale is correct.

Apr 17, 2010 at 2:18 PM

@ sickbattery:

Tried out a whole heap of stuff with your code, and no luck at all...same behaviour with the weird enormous collisions. Substituted my TTV method with your CreateBodyAndGeom() method, and got the exact same thing. Used your "untested" matrix scaling code to work with my sprite scaling thing and didn't help either. Thanks very much for trying though!

I had a thought which may/may not be of help, not sure: Seeing that an image has its height and width specified in pixels (eg: 512 x 256) and my game's coordinate system isn't in screen coordinates (Eg: (20.0f, 0.0f) is nearly the right edge of my screen), wouldn't there be a need to convert the texture.width and texture.height to match my coordinate system first and only then try out the TTV method? Because from all the examples I've seen on the web of people using regular XNA, I think the positions and such are specified directly in pixel coordinates (Eg: (400, 300))?
That's the only reason I can think of why I get gigantic collisions around my texture. Also, while I was debugging, I noticed that my origin variable which has the value from verts.GetCentroid(), had a value of (118.something, 31.something) for a texture size of (256, 55), which should definitely not be the case - anything with a centroid position of those values would be way out of bounds of my camera in the first place. Furthermore, I've noticed that if I make the texture a smaller resolution, then the collision around it gets a bit smaller as well, but still 4-5 times bigger than the texture.
So you see, all these reasons lead me to believe that there should be some conversion of units for the texture dimensions before I try and create the body and geom. If so, what code can I use to perform this conversion?
And if this is not the case that helps fix it, then I'm totally lost and out of ideas...

As a side note, I've also posted about this on the FRB forums, and linked to this thread on there. I will report back on here if they say anything that I've not heard from you guys up here already.

Thanks for your time and any further help. 

Apr 17, 2010 at 8:08 PM
Edited Apr 17, 2010 at 8:09 PM

I think I've got it figured out by changing the following in the Create function of the TTV class.

  public void Create(PhysicsSimulator physicsSimulator, Texture2D texture)

            // Create graphics object
            sprite = SpriteManager.AddSprite(texture);
            uint[] data = new uint[texture.Width * texture.Height];
            Vertices verts = Vertices.CreatePolygon(data, texture.Width, texture.Height);

            Vertices scaledVerts = new Vertices(verts.Capacity); //now that we have list of the texture vertices we have to format it
                                                                                    //in this case I'm just  making a new list for simplicity
            for (int i = 0; i < verts.Count; i++)
                //Going step by step for Clarity
                Vector2 tempVert = new Vector2(); //create the temporary variable to store the new vertice before we add it to the list
                tempVert = verts[i];    //set it the vert we are currently modifying

                //the verts are currently in texture coordinates, which means the Y value is inverted
                tempVert.Y *= -1; // booyah, fixed that problem

                //right now the vertices are the size of the texture, definately not what we want.
                tempVert.X /= texture.Width;  
                tempVert.Y /= texture.Height;
                //hurray now the units are independent of the size of the texture

                //now we need to scale the verts up to match the FRB sprite
                tempVert.X *= this.sprite.ScaleX * 2;
                tempVert.Y *= this.sprite.ScaleY * 2;

               //add that sucker to the list
            //one last thing
            //a sprite is positioned based on the center of its texture, a polygon body is positioned based on its centroid
            //unless the centroid of the shape happens to be in the middle of the texture we need to take this into account when updating the sprites position
            //in order to do this we need to find the difference between these two positions
            //get the centroid of the shape
           //centroid is a Vector2 defined at class scope since we need it when updating
            centroid = scaledVerts.GetCentroid();

            //FRB defines the origin as the middle but the centroid returned by that function seems to be relative to the top left corner just like a texture
            //translate it to the middle and were good to go, the
            centroid.X -= sprite.ScaleX;
            centroid.Y += sprite.ScaleY;

            body = BodyFactory.Instance.CreatePolygonBody(physicsSimulator, scaledVerts, 3.0f);
            geom = GeomFactory.Instance.CreatePolygonGeom(physicsSimulator, body, scaledVerts, 0);


As mentioned we also have to use the centriod when updating position

  public void Update()
            // Update position taking into account that there needs to be a difference between the shapes position and the sprites position
            sprite.X = body.Position.X -centroid.X;
            sprite.Y = body.Position.Y-centroid.Y;           
            // Update rotation
            sprite.RotationZ = body.Rotation;


If you've got any questions let me know

Apr 17, 2010 at 8:28 PM

@ cdndave:

Thanks heaps, man, that worked perfectly! Cheers for taking the time to look through and put in all those comments, really helped put everything into perspective.
Tried it out with a few odd-shaped sprites, and it all seems good.

@ sickbattery:

Cheers to you again, mate, thanks for your detailed responses too!