Sunday, July 22, 2018

xna - Create a body of an irregular 2D sprite in Farseer


I'm trying to create a body of a irregular 2D sprite Farseer 3.3.1.
The regular shapes that BodyFactory provides are not that I want. Is there a way that one can create irregular objects? Could it be done using the BodyFactory.CreateCompoundPolygon method?



Answer



Farseer Physics Engine's support of polygons is otherwise well-documented. Although the documentation may need to be updated to the latest version.


You can create polygons using a list of Vertices, which (simply put) are just the coordinates of all the corners. Vertices can either be defined in code, or be generated on the basis of an image file using some of the tools provided.


Straight from the documentation:


  //load texture that will represent the physics body
Texture2D polygonTexture = GameInstance.Content.Load("Texture");


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

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

//Find the vertices that makes up the outline of the shape in the texture
Vertices verts = PolygonTools.CreatePolygon(data, polygonTexture.Width, polygonTexture.Height, true);


//For now we need to scale the vertices (result is in pixels, we use meters)
Vector2 scale = new Vector2(0.07f, 0.07f);
verts.Scale(ref scale);

//Since it is a concave polygon, we need to partition it into several smaller convex polygons
_list = BayazitDecomposer.ConvexPartition(verts);

//Create a single body with multiple fixtures
List compund = FixtureFactory.CreateCompoundPolygon(World, _list, 1);
compund[0].Body.BodyType = BodyType.Dynamic;


To get textures (sprites) from polygons generated on-the-fly instead of from an image file, you need a little extra code. In the samples project bundled with the latest version of FPE, there is a class called AssetCreator that can generate polygons on the basis of vertices and a base (fill) texture.


Once you have added the AssetCreator-class and its dependencies to your code, you can use it to generate polygon textures e.g. like this:


        AssetCreator assetCreator = new AssetCreator(graphics.GraphicsDevice);
assetCreator.LoadContent(this.Content);

Vertices vertices = new Vertices();
vertices.Add(new Vector2(ConvertUnits.ToSimUnits(0), ConvertUnits.ToSimUnits(0)));
vertices.Add(new Vector2(ConvertUnits.ToSimUnits(20), ConvertUnits.ToSimUnits(0)));
vertices.Add(new Vector2(ConvertUnits.ToSimUnits(30), ConvertUnits.ToSimUnits(30)));

vertices.Add(new Vector2(ConvertUnits.ToSimUnits(10), ConvertUnits.ToSimUnits(60)));
vertices.Add(new Vector2(ConvertUnits.ToSimUnits(-10), ConvertUnits.ToSimUnits(30)));

//polygon body
PolygonShape shape = new PolygonShape(vertices, 1);
sprite = new Sprite(assetCreator.TextureFromShape(shape, MaterialType.Blank, Color.DimGray, 1f));
body = BodyFactory.CreatePolygon(world, vertices, 1f);
Fixture fixture = FixtureFactory.AttachPolygon(vertices, 1f, body);
fixture.Body.BodyType = BodyType.Dynamic;


I hope this is helpful. If it is, please mark my answer as 'Answer'.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...