SamplesFramework Border algorithm

Topics: User Forum
Nov 1, 2011 at 8:06 PM

Hello,

I'm new to XNA and FPE. I used to develop minigames in java since a couple of years but I never used an physics engine before.

I decided to swap to C# as I read some articles about XNA. My first project with a view to learn XNA is an shooter.  In my opinion it is necessary to use a physics engine for such games.

On my way learing how to use FPE I stumbled on the Border class in the Samples given by this site. I don't understand all steps of this class.

namespace FarseerPhysics.SamplesFramework{
    public class Border{
        private Body _anchor;
        private BasicEffect _basicEffect;
        private VertexPositionColorTexture[] _borderVerts;
        private PhysicsGameScreen _screen;
        private World _world;

        public Border(World world, PhysicsGameScreen screen, Viewport viewport) {
            _world = world;
            _screen = screen;

            float halfWidth = ConvertUnits.ToSimUnits(viewport.Width) / 2f - 0.75f;
            float halfHeight = ConvertUnits.ToSimUnits(viewport.Height) / 2f - 0.75f;

            Vertices borders = new Vertices(4);
            borders.Add(new Vector2(-halfWidth, halfHeight));
            borders.Add(new Vector2(halfWidth, halfHeight));
            borders.Add(new Vector2(halfWidth, -halfHeight));
            borders.Add(new Vector2(-halfWidth, -halfHeight));

            _anchor = BodyFactory.CreateLoopShape(_world, borders);
            _anchor.CollisionCategories = Category.All;
            _anchor.CollidesWith = Category.All;

            _basicEffect = new BasicEffect(_screen.ScreenManager.GraphicsDevice);
            _basicEffect.VertexColorEnabled = true;
            _basicEffect.TextureEnabled = true;
            _basicEffect.Texture = _screen.ScreenManager.Content.Load<Texture2D>("Materials/pavement");

            VertexPositionColorTexture[] vertice = new VertexPositionColorTexture[8];
            vertice[0] = new VertexPositionColorTexture(new Vector3(-halfWidth, -halfHeight, 0f),
                                                        Color.LightGray, new Vector2(-halfWidth, -halfHeight) / 5.25f);
            vertice[1] = new VertexPositionColorTexture(new Vector3(halfWidth, -halfHeight, 0f),
                                                        Color.LightGray, new Vector2(halfWidth, -halfHeight) / 5.25f);
            vertice[2] = new VertexPositionColorTexture(new Vector3(halfWidth, halfHeight, 0f),
                                                        Color.LightGray, new Vector2(halfWidth, halfHeight) / 5.25f);
            vertice[3] = new VertexPositionColorTexture(new Vector3(-halfWidth, halfHeight, 0f),
                                                        Color.LightGray, new Vector2(-halfWidth, halfHeight) / 5.25f);
            vertice[4] = new VertexPositionColorTexture(new Vector3(-halfWidth - 2f, -halfHeight - 2f, 0f),
                                                        Color.LightGray,
                                                        new Vector2(-halfWidth - 2f, -halfHeight - 2f) / 5.25f);
            vertice[5] = new VertexPositionColorTexture(new Vector3(halfWidth + 2f, -halfHeight - 2f, 0f),
                                                        Color.LightGray,
                                                        new Vector2(halfWidth + 2f, -halfHeight - 2f) / 5.25f);
            vertice[6] = new VertexPositionColorTexture(new Vector3(halfWidth + 2f, halfHeight + 2f, 0f),
                                                        Color.LightGray,
                                                        new Vector2(halfWidth + 2f, halfHeight + 2f) / 5.25f);
            vertice[7] = new VertexPositionColorTexture(new Vector3(-halfWidth - 2f, halfHeight + 2f, 0f),
                                                        Color.LightGray,
                                                        new Vector2(-halfWidth - 2f, halfHeight + 2f) / 5.25f);

            _borderVerts = new VertexPositionColorTexture[24];
            _borderVerts[0] = vertice[0];
            _borderVerts[1] = vertice[5];
            _borderVerts[2] = vertice[4];
            _borderVerts[3] = vertice[0];
            _borderVerts[4] = vertice[1];
            _borderVerts[5] = vertice[5];
            _borderVerts[6] = vertice[1];
            _borderVerts[7] = vertice[6];
            _borderVerts[8] = vertice[5];
            _borderVerts[9] = vertice[1];
            _borderVerts[10] = vertice[2];
            _borderVerts[11] = vertice[6];
            _borderVerts[12] = vertice[2];
            _borderVerts[13] = vertice[7];
            _borderVerts[14] = vertice[6];
            _borderVerts[15] = vertice[2];
            _borderVerts[16] = vertice[3];
            _borderVerts[17] = vertice[7];
            _borderVerts[18] = vertice[3];
            _borderVerts[19] = vertice[4];
            _borderVerts[20] = vertice[7];
            _borderVerts[21] = vertice[3];
            _borderVerts[22] = vertice[0];
            _borderVerts[23] = vertice[4];
        }

        public void Draw(){
            [...]
        }
    }
}

Why are pixels converted to simulation units? What is the meaning of "Vertices borders = new Vertices (4)"? I do not understand why negative values are used...

I do not understand why there is first an VertexPositionColorTexture array with an size of 8 and afterwards an VertexPositionColortextrue array with an size of 24 (member variable)?

Could anybody help with words and deeds? Thanks!

Developer
Nov 2, 2011 at 1:13 AM

All of the vertice stuff is just for rendering the border.

            float halfWidth = ConvertUnits.ToSimUnits(viewport.Width) / 2f - 0.75f;
            float halfHeight = ConvertUnits.ToSimUnits(viewport.Height) / 2f - 0.75f;

            Vertices borders = new Vertices(4);
            borders.Add(new Vector2(-halfWidth, halfHeight));
            borders.Add(new Vector2(halfWidth, halfHeight));
            borders.Add(new Vector2(halfWidth, -halfHeight));
            borders.Add(new Vector2(-halfWidth, -halfHeight));

            _anchor = BodyFactory.CreateLoopShape(_world, borders);
            _anchor.CollisionCategories = Category.All;
            _anchor.CollidesWith = Category.All;
The above is all that is needed for the physics engine. ConvertUnits is used to make the border the size of the window but in physics units. You need to keep your physics world in meters and your rendering can be any scale you like.

Nov 2, 2011 at 11:10 AM
Edited Nov 2, 2011 at 1:43 PM

Thank you for your quick answer!

Am I right if I say that the float value of 0.75 in line "float halfWidth = ConvertUnits.ToSimUnits(viewport.Width) / 2f - 0.75f;" is the borders thickness in simulation units?

That means, that  "float halfWidht = ConvertUnits.ToSimUnits (viewport.Width) / 2f" figures out the horizontal center of my viewport in simulation units (same with halfHeight). This is followed by the subtaction of the border-thickness in simulation units. In my case 10px are 1m. This follows in a border thickness of 7.5px (~8px). Am I right with this situation?

 

            Vertices borders = new Vertices(4);
            borders.Add(new Vector2(-halfWidth, halfHeight));
            borders.Add(new Vector2(halfWidth, halfHeight));
            borders.Add(new Vector2(halfWidth, -halfHeight));
            borders.Add(new Vector2(-halfWidth, -halfHeight));

 

When I regard these lines the values halfWidth and halfHeight must be relative to the viewports centre.

That means that in order to create an assymetric border I have to implement s.th. like this:

            float horizontalBorder = ConvertUnits.ToSimUnits(viewport.Width) / 2f - 0.75f; // Left and right border (7.5px -> 8px)
            float topBorder= ConvertUnits.ToSimUnits(viewport.Height) / 2f -1f; // Top border is larger than left/right border (10.0px)
            float bottomBorder= ConvertUnits.ToSimUnits(viewport.Height) / 2f - 5f; // Bottom border is largest (50.0px)

            Vertices borders = new Vertices(4);
            borders.Add(new Vector2(-horizontalBorder ,bottomBorder));
            borders.Add(new Vector2(horizontalBorder , bottomBorder));
            borders.Add(new Vector2(horizontalBorder , -topBorder));
            borders.Add(new Vector2(-horizontalBorder , -topBorder));

In addition to this could someone give me a hint what the vertice stuff for rendering does? I do not unterstand why some Vector2 by 5.25f or halfWidth/halfHeight is increased/decreased with the value 2...