Texture to multipolygon

Topics: Developer Forum, User Forum
Mar 5, 2011 at 4:58 PM
Edited Mar 5, 2011 at 5:12 PM

Does anyone has an example for texture to multipolygon with

 public static List<Vertices> CreatePolygon(uint[] data, int width, int height, float hullTolerance, byte alphaTolerance, bool multiPartDetection, bool holeDetection);

 

Now I use it without multiPart detection

 

            alphaTexture = game.Content.Load<Texture2D>("Textures\\collisionlevel");
uint[] data = new uint[alphaTexture.Width * alphaTexture.Height];
alphaTexture.GetData(data);
_verts = PolygonTools.CreatePolygon(data, alphaTexture.Width, alphaTexture.Height, true);
Vector2 scale = new Vector2(-1.000f, -1.00f);
_verts.Scale(ref scale);


  _list = BayazitDecomposer.ConvexPartition(_verts);
List<Vertices> toRemove = new List<Vertices>();

foreach (Vertices item in _list) { if (item.Count == 0) { toRemove.Add(item); } }
foreach (Vertices item in toRemove) { _list.Remove(item); }

compund = FixtureFactory.CreateCompoundPolygon(WorldPhysX, _list, 1.0f);

compund[0].Body.BodyType = BodyType.Static;
compund[0].Body.Position = new Vector2(12500, -500.0f);

 

This works great for 1 shape, but my level got alot of floating things.

Any idea how to make it multipolygon.

thanks in advance,

greets

Developer
Mar 5, 2011 at 10:53 PM

Which farseer version do you use? And show us the texture please: How can I know what's going on withouth beeing able to reproduce the situation?

Mar 5, 2011 at 11:36 PM

I use Farseer 3.2 for windows phone 7

 

here is the map, sorry I forgot

http://i52.tinypic.com/2hchybm.png

 

greets

Mar 6, 2011 at 11:50 AM
Edited Mar 6, 2011 at 11:53 AM

Hi, I've been experiencing an extremely similar problem where some parts seem to be missing.

maybe someone could shed some light on this?

cheers!

Developer
Mar 6, 2011 at 2:30 PM

Missing parts are fixed in the latest source.

I'll check out your Texture xeppex and post again.

Developer
Mar 6, 2011 at 2:55 PM

Take a look at this.

There shouldn't be any missing parts anymore (in the latest source).

Just make sure your texture doesn't have any one or two pixel "artifacts". That was the reason why the algorithm was quitting the detection. Also, if you are using complex shapes like on pixel wide spikes, then set the HullTolerance higher.

Mar 6, 2011 at 3:22 PM
sickbattery wrote:

Take a look at this.

There shouldn't be any missing parts anymore (in the latest source).

Just make sure your texture doesn't have any one or two pixel "artifacts". That was the reason why the algorithm was quitting the detection. Also, if you are using complex shapes like on pixel wide spikes, then set the HullTolerance higher.

thanks, but do I have to change my code?

_verts = PolygonTools.CreatePolygon(data, alphaTexture.Width, alphaTexture.Height, true); ?
or do I have t use
CreatePolygon(uint[] data, int width, int height, float hullTolerance, byte alphaTolerance, bool multiPartDetection, bool holeDetection);

because I don't know how to use it.

ty
Mar 6, 2011 at 3:42 PM

sickbattery, is there any chance you could post the code for that? I would be interested in learning how that is done.

Mar 6, 2011 at 4:51 PM

Seconded =D

Developer
Mar 6, 2011 at 7:01 PM

There is an example in the Samples Framework. Check the latest source and see the Texture to Vertices sample which is in AdvancedDemo1.cs.

Mar 6, 2011 at 8:15 PM
mattbettcher wrote:

There is an example in the Samples Framework. Check the latest source and see the Texture to Vertices sample which is in AdvancedDemo1.cs.

Hi, I checked the code, but BodyFactory doesn't have a function createcompoundpolygon in Farseer engine 3.2 WP7. (I forgot to tell it was wp7)

 

greets

Developer
Mar 7, 2011 at 12:26 AM

All CreateCompoundPolygon simply loops over all the vertices passed to it and creates and adds fixtures to a single object.

//load texture that will represent the physics body
polygonTexture = Content.Load<Texture2D>("picture");

//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
List<Vertices> textureVertices = PolygonTools.CreatePolygon(data, _polygonTexture.Width, hullTolerance, alphaTolerance, true, false);

foreach (Vertices polygon in textureVertices)
{
    List<Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices);

    //scale the vertices from graphics space to sim space
    Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1));
    foreach (Vertices vertices in list)
    {
        vertices.Scale(ref vertScale);
    }

    Body body = BodyFactory.CreateBody(World);

    foreach (Vertices vertices in list)
    {
        PolygonShape shape = new PolygonShape(vertices, density);
        body.CreateFixture(shape);
    }
}

Above is an example I wrote from memory so there may be errors, but it should provide the basic idea. If you need more help feel free to ask.

Developer
Mar 7, 2011 at 10:00 AM
Edited Mar 7, 2011 at 10:04 AM

Here is the code I used to generate the image I linked in one of my posts above, but remember that I'm using the latest source code and not the release version 3.2.

 

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            _spriteBatch = new SpriteBatch(GraphicsDevice);
            _debugView.LoadContent(GraphicsDevice, Content);

            // TODO: use this.Content to load your game content here
            //_test1 = Content.Load<Texture2D>("test1_256p");
            _test1 = Content.Load<Texture2D>("2hchybm");

            // Get texture data
            uint[] data = new uint[_test1.Width * _test1.Height];
            _test1.GetData<uint>(data);

            // TextureConverter instance
            TextureConverter tc =
                new TextureConverter(data, _test1.Width)
                {
                    //HullTolerance = 2.5f, // Try 2.5f if you get errors - I don't want to go into details, sorry.
                    MultipartDetection = true,
                    HoleDetection = true,
                    PolygonDetectionType = VerticesDetectionType.Separated,

                    // Here is how you center and scale the result.
                    /*Transform = 
                        Matrix.CreateTranslation(new Vector3((float)_test1.Width / -2f, (float)_test1.Height / -2f, 0f)) * 
                        Matrix.CreateScale(new Vector3(0.15f, -0.15f, 1f))*/
                };

            // Start detection
            List<DetectedVertices> verts = tc.DetectVertices();

            // Create fixtures.
            _test1Fix = new List<List<Fixture>>(verts.Count);
            for (int i = 0; i < verts.Count; i++)
            {
                var v = Decomposer.CDTDecomposer.ConvexPartition(verts[i]);
                _test1Fix.Add(FixtureFactory.AttachCompoundPolygon(v, 1f, BodyFactory.CreateCompoundPolygon(_world, v, 1f)));
            }
        }
Mar 8, 2011 at 10:32 PM

Thank you so much Sickbattery and mattbettcher, I used the latest source code and It works now.

Is there a way to move the hole shape in update? Because I got a camera, and my DebugView Draw in Screen and I want it to be in World?

 

tysm for the help!

 

greets