Need Help with Compound Polygons

Topics: User Forum
Nov 4, 2013 at 8:50 PM
I'm a complete noob using any physics engine.

Using XNA and Farseer 3.5.

I managed to create a compound body and now want to create some routines to draw outlines around the individual polygons for my own debugging. Got it to work; but, there's one issue. As the body rotates; I can't figure out how to get the vertices to rotate along with it.

Here's my code which is called during the screen draw:
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            //Draw concave polygon
            spriteBatch.Begin();
            
            spriteBatch.Draw(polySprite, ConvertUnits.ToDisplayUnits(polyBody.Position), null, Color.White, polyBody.Rotation, polyOrigin, 1f, SpriteEffects.None, 0f);

            List<Vertices> listVerts = new List<Vertices>();

            for (int i = 0; i < list.Count; i++)
            {
                listVerts.Add(new Vertices());
                for (int j = 0; j < list[i].Count; j++)
                {
                    listVerts[i].Add( ConvertUnits.ToDisplayUnits(list[i][j]) + ConvertUnits.ToDisplayUnits(polyBody.Position) );                    
                }
                
                //Draw the outline of the polygon
                DrawPolygon(spriteBatch, listVerts[i], Color.Red, 1);
            }
           
            spriteBatch.End();

            base.Draw(gameTime);
        }
Any help would be appreciated, please let me know if I haven't included enough code.

Thank You.
Nov 5, 2013 at 1:22 AM
Download and have a look at the Samples / Test Beds. There's a class in there called DebugView and you can use that to draw all the shapes on the screen.

If you want to carry on using your own code you need to get the transformation of the body and then multiply the vertices by the value.

Something like:
                    Transform xf;
                    body.GetTransform(out xf);

     for (int i = 0; i < list.Count; i++)
            {
                listVerts.Add(new Vertices());
                for (int j = 0; j < list[i].Count; j++)
                {
                            listVerts[i].Add(MathUtils.Mul(ref xf, ConvertUnits.ToDisplayUnits(list[i][j])));                    
                }
                
                //Draw the outline of the polygon
                DrawPolygon(spriteBatch, listVerts[i], Color.Red, 1);
            }
           
Nov 6, 2013 at 7:44 PM
Thank You so much HAL_9000.

I was able to get my code to work with your help.
Combing through the DebugView code however; I was not able to implement.
I think I'm missing something, as I am not able to render the outlines.

This is what I have:
protected DebugViewXNA DebugView;
.
.
/////////  LoadContent() ////////
          DebugView = new DebugViewXNA(world);
          .
         DebugView.LoadContent(GraphicsDevice, this.Content);

//////// Draw() ////////////
           DebugView.BeginCustomDraw(Matrix.Identity, Matrix.Identity);
            for (int i = 0; i < list.Count; i++)
            {
                DebugView.DrawPolygon(list[i].ToArray(), list[i].Count, Color.Red);
            }
            DebugView.EndCustomDraw();
I have no idea if this is the "right" way to use this class. The scale and rotation are off. I now know how to use the transform to correct the rotation.
But, I keep thinking I'm doing this the "hard" way and there must be an easier way that I'm missing.
Nov 6, 2013 at 8:41 PM
Yep, that's the hard way :)

DebugView has a RenderDebugData method that will render everything in the world.

It's probably looking weird because your projection matrix isn't right.

You can make your projection matrix like this

Matrix _Projection = Matrix.CreateOrthographicOffCenter(0f, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0f, 0f, 1f);

As long as you're not rotating/zooming then using Matrix.Identity should be fine for the View matrix (I think)
Nov 6, 2013 at 9:42 PM
Awsome !!!

That worked. Thank You So Much.
I'll put it here in case someone else needs this.
protected DebugViewXNA DebugView;
protected Matrix _Projection;
.
.
/////////  LoadContent() ////////

           DebugView = new DebugViewXNA(world);
                    
            DebugView = new DebugViewXNA(world);
            DebugView.DefaultShapeColor = Color.White;
            DebugView.SleepingShapeColor = Color.White;            
            DebugView.AppendFlags(DebugViewFlags.Shape);
            DebugView.AppendFlags(DebugViewFlags.PolygonPoints);

            DebugView.LoadContent(GraphicsDevice, this.Content);

           _Projection = Matrix.CreateOrthographicOffCenter(0f, ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Width), ConvertUnits.ToSimUnits(GraphicsDevice.Viewport.Height), 0f, 0f, 1f); 

//////// Draw() ////////////
DebugView.RenderDebugData(ref _Projection);