Box2D Forums

It is currently Wed Apr 16, 2014 12:16 am

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Sun Dec 04, 2011 3:27 pm 
Offline

Joined: Sun Dec 04, 2011 3:17 pm
Posts: 1
I can't seem to port everything from the provided test bed to a new XNA project properly - things don't seem to draw correctly. I took the same initialization code as the Edge test to try to duplicate the visual output, and there are a number of problems, chiefly:
- edges don't show up at all
- all shapes draw as an AABB square of identical size

I made a project that has the same Box2D.XNA project as the test bed used, added it to my references, and tried to move over the minimum necessary code to start doing my own thing. Here's the full Game1.cs (only file I modified) (also, no clue why it's all showing up as green in the preview).

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using Box2D;
using Box2D.XNA;

namespace Breakdown
{
    ////////////////////////////////////////////////////////////////////////////
    //
    public class ContactListener : IContactListener
    {
        public static int kMaxContactPoints = 2048;

        public ContactPoint[] gPoints = new ContactPoint[kMaxContactPoints];
        public int gPointCount;
        public int gTextLine;

        ////////////////////////////////////////////////////////////////////////
        //
        public void DrawDebugData()
        {
            Globals.gDebugDraw.DrawString(50, gTextLine, "bodies/contacts/joints/prexies = {0:n}/{1:n}/{2:n}",
                 Globals.gWorld.BodyCount, Globals.gWorld.ContactCount, Globals.gWorld.JointCount, Globals.gWorld.ProxyCount);
            gTextLine += 15;

            const float kAxisScale = 0.3f;
            for( int i = 0; i < gPointCount; ++i )
            {
                ContactPoint point = gPoints[i];

                if (point.state == PointState.Add)
                    Globals.gDebugDraw.DrawPoint(point.position, 1.5f, new Color(0.3f, 0.75f, 0.3f));

             else if (point.state == PointState.Persist)
                 Globals.gDebugDraw.DrawPoint(point.position, 0.65f, new Color(0.3f, 0.3f, 0.95f));

            Vector2 p1 = point.position;
                Vector2 p2 = p1 + kAxisScale * point.normal;
                Globals.gDebugDraw.DrawSegment(p1, p2, new Color(0.4f, 0.9f, 0.4f));
            }
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public virtual void PreSolve(Contact contact, ref Manifold old_manifold)
        {
            Manifold manifold;
            contact.GetManifold(out manifold);

            if (manifold._pointCount == 0)
            {
                return;
            }

            Fixture fixtureA = contact.GetFixtureA();
            Fixture fixtureB = contact.GetFixtureB();

            FixedArray2<PointState> state1, state2;
            Collision.GetPointStates(out state1, out state2, ref old_manifold, ref manifold);

            WorldManifold worldManifold;
            contact.GetWorldManifold(out worldManifold);

            for (int i = 0; i < manifold._pointCount && gPointCount < kMaxContactPoints; ++i)
            {
                if (fixtureA == null)
                {
                    gPoints[i] = new ContactPoint();
                }
                ContactPoint cp = gPoints[gPointCount];
                cp.fixtureA = fixtureA;
                cp.fixtureB = fixtureB;
                cp.position = worldManifold._points[i];
                cp.normal = worldManifold._normal;
                cp.state = state2[i];
                gPoints[gPointCount] = cp;
                ++gPointCount;
            }
        }

        ////////////////////////////////////////////////////////////////////////
        // empty in original test bed
        public virtual void PostSolve(Contact contact, ref ContactImpulse impulse) { }
        public virtual void BeginContact(Contact contact) { }
        public virtual void EndContact(Contact contact) { }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    public struct ContactPoint
    {
        public Fixture fixtureA;
        public Fixture fixtureB;
        public Vector2 normal;
        public Vector2 position;
        public PointState state;
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    public static class Globals
    {
        public static ContactListener gContactListener;
        public static DebugDraw gDebugDraw = new DebugDraw();
        public static Body gGroundBody;
        public static AABB gWorldAABB;
        public static World gWorld;
        public static int gStepCount;

        ////////////////////////////////////////////////////////////////////////
        //
        public static void InitBox2D()
        {
            Vector2 gravity = new Vector2(0f, -10f);
            bool do_sleep = true;
            gWorld = new World(gravity, do_sleep);

            gContactListener = new ContactListener();
            gContactListener.gTextLine = 30;

            gWorld.ContactListener = gContactListener;
            gWorld.DebugDraw = gDebugDraw;

            gStepCount = 0;

            BodyDef body_def = new BodyDef();
            gGroundBody = gWorld.CreateBody(body_def);

            ////////////////////////////////////////////////////////////////////
           
            BodyDef bd1 = new BodyDef();
            Body ground = gWorld.CreateBody(bd1);

            Vector2 v1 = new Vector2(-10f, 0f);
            Vector2 v2 = new Vector2(10f, 0f);
            Vector2 v3 = new Vector2(10f, 20f);
            Vector2 v4 = new Vector2(-10f, 20f);

            EdgeShape edge_shape = new EdgeShape();

            edge_shape.Set(v1, v2);
            ground.CreateFixture(edge_shape, 0f);

            edge_shape.Set(v2, v3);
            ground.CreateFixture(edge_shape, 0f);

            edge_shape.Set(v3, v4);
            ground.CreateFixture(edge_shape, 0f);

            edge_shape.Set(v4, v1);
            ground.CreateFixture(edge_shape, 0f);
           

            //////////

           
            BodyDef circle_bd = new BodyDef();
            circle_bd.type = BodyType.Dynamic;
            circle_bd.position = new Vector2(-0.5f, 0.5f);
            circle_bd.allowSleep = false;
            Body circle_body = gWorld.CreateBody(circle_bd);

            CircleShape circle_shape = new CircleShape();
            circle_shape._radius = 0.5f;
            circle_body.CreateFixture(circle_shape, 1f);
           

            //////////

           
            BodyDef poly_bd1 = new BodyDef();
            poly_bd1.type = BodyType.Dynamic;
            poly_bd1.position = new Vector2(0.5f, 0.5f);
            poly_bd1.allowSleep = false;
            Body poly_body1 = gWorld.CreateBody(poly_bd1);

            PolygonShape poly_shape1 = new PolygonShape();
            poly_shape1.SetAsBox(0.5f, 0.5f);
            poly_body1.CreateFixture(poly_shape1, 1f);
           

            //////////

           
            BodyDef poly_bd2 = new BodyDef();
            poly_bd2.type = BodyType.Dynamic;
            poly_bd2.position = new Vector2(2f, 3f);
            poly_bd2.allowSleep = true;
            Body poly_body2 = gWorld.CreateBody(poly_bd2);

            PolygonShape poly_shape2 = new PolygonShape();
            poly_shape2.SetAsBox(3f, 1f);
            poly_body2.CreateFixture(poly_shape2, 0.020f);
           
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public static void Step()
        {
            float time_step = 1f / 30f;

            gWorld.WarmStarting = true;
            gWorld.ContinuousPhysics = false;

            gContactListener.gPointCount = 0;

            gWorld.Step(time_step, 8, 8);
            gWorld.DrawDebugData();

            ++gStepCount;

            gContactListener.DrawDebugData();
        }

        ////////////////////////////////////////////////////////////////////////
        // needed?
        public static void SetTextLine(int line)
        { gContactListener.gTextLine = line; }

        ////////////////////////////////////////////////////////////////////////
        //
        public static void DrawTitle(int x, int y, string title)
        {
            gDebugDraw.DrawString(x, y, title);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    public class DebugDraw : Box2D.XNA.DebugDraw
    {
        public VertexPositionColor[] mVertsLines = new VertexPositionColor[100000];
        public VertexPositionColor[] mVertsFill = new VertexPositionColor[100000];
        public int mLineCount;
        public int mFillCount;
        public SpriteBatch mBatch;
        public SpriteFont mFont;
        public GraphicsDevice mDevice;

        private List<StringData> mStringData;
        struct StringData
        {
            public int x, y;
            public string s;
            public object[] args;

            public StringData(int x, int y, string s, object[] args)
            {
                this.x = x;
                this.y = y;
                this.s = s;
                this.args = args;
            }
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public DebugDraw()
        {
            mStringData = new List<StringData>();
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public override void DrawPolygon(ref Box2D.XNA.FixedArray8<Vector2> vertices, int count, Color color)
        {
            for (int i = 0; i < count - 1; ++i)
            {
                mVertsLines[mLineCount * 2].Position = new Vector3(vertices[i], 0f);
                mVertsLines[mLineCount * 2].Color = color;

                mVertsLines[mLineCount * 2 + 1].Position = new Vector3(vertices[i + 1], 0f);
                mVertsLines[mLineCount * 2 + 1].Color = color;

                ++mLineCount;
            }

            mVertsLines[mLineCount * 2].Position = new Vector3(vertices[count - 1], 0f);
            mVertsLines[mLineCount * 2].Color = color;

            mVertsLines[mLineCount * 2 + 1].Position = new Vector3(vertices[0], 0f);
            mVertsLines[mLineCount * 2 + 1].Color = color;

            ++mLineCount;
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public override void DrawSolidPolygon(ref Box2D.XNA.FixedArray8<Vector2> vertices, int count, Color color)
        {
            DrawSolidPolygon(ref vertices, count, color, true);
        }

        ////////////////////////////////////////////////////////////////////////
        //
        private void DrawSolidPolygon(ref Box2D.XNA.FixedArray8<Vector2> vertices, int count, Color color, bool outline)
        {
            if (count == 2)
            {
                DrawPolygon(ref vertices, count, color);
                return;
            }

            Color colorFill = color * (outline ? 0.5f : 1.0f);

            for (int i = 1; i < count - 1; i++)
            {
                mVertsFill[mFillCount * 3].Position = new Vector3(vertices[0], 0.0f);
                mVertsFill[mFillCount * 3].Color = colorFill;

                mVertsFill[mFillCount * 3 + 1].Position = new Vector3(vertices[i], 0.0f);
                mVertsFill[mFillCount * 3 + 1].Color = colorFill;

                mVertsFill[mFillCount * 3 + 2].Position = new Vector3(vertices[i + 1], 0.0f);
                mVertsFill[mFillCount * 3 + 2].Color = colorFill;

                mFillCount++;
            }

            if (outline)
            {
                DrawPolygon(ref vertices, count, color);
            }
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public override void DrawCircle(Vector2 center, float radius, Color color)
        {
            int segments = 16;
            double increment = Math.PI * 2.0 / (double)segments;
            double theta = 0.0;

            for (int i = 0; i < segments; i++)
            {
                Vector2 v1 = center + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
                Vector2 v2 = center + radius * new Vector2((float)Math.Cos(theta + increment), (float)Math.Sin(theta + increment));

                mVertsLines[mLineCount * 2].Position = new Vector3(v1, 0.0f);
                mVertsLines[mLineCount * 2].Color = color;
                mVertsLines[mLineCount * 2 + 1].Position = new Vector3(v2, 0.0f);
                mVertsLines[mLineCount * 2 + 1].Color = color;
                mLineCount++;

                theta += increment;
            }
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public override void DrawSolidCircle(Vector2 center, float radius, Vector2 axis, Color color)
        {
            int segments = 16;
            double increment = Math.PI * 2.0 / (double)segments;
            double theta = 0.0;

            Color colorFill = color * 0.5f;

            Vector2 v0 = center + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
            theta += increment;

            for (int i = 1; i < segments - 1; i++)
            {
                Vector2 v1 = center + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
                Vector2 v2 = center + radius * new Vector2((float)Math.Cos(theta + increment), (float)Math.Sin(theta + increment));

                mVertsFill[mFillCount * 3].Position = new Vector3(v0, 0.0f);
                mVertsFill[mFillCount * 3].Color = colorFill;

                mVertsFill[mFillCount * 3 + 1].Position = new Vector3(v1, 0.0f);
                mVertsFill[mFillCount * 3 + 1].Color = colorFill;

                mVertsFill[mFillCount * 3 + 2].Position = new Vector3(v2, 0.0f);
                mVertsFill[mFillCount * 3 + 2].Color = colorFill;

                mFillCount++;

                theta += increment;
            }
            DrawCircle(center, radius, color);

            DrawSegment(center, center + axis * radius, color);
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public override void DrawSegment(Vector2 p1, Vector2 p2, Color color)
        {
            mVertsLines[mLineCount * 2].Position = new Vector3(p1, 0.0f);
            mVertsLines[mLineCount * 2 + 1].Position = new Vector3(p2, 0.0f);
            mVertsLines[mLineCount * 2].Color = mVertsLines[mLineCount * 2 + 1].Color = color;
            mLineCount++;
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public override void DrawTransform(ref Box2D.XNA.Transform xf)
        {
            float axisScale = 0.4f;
            Vector2 p1 = xf.Position;

            Vector2 p2 = p1 + axisScale * xf.R.col1;
            DrawSegment(p1, p2, Color.Red);

            p2 = p1 + axisScale * xf.R.col2;
            DrawSegment(p1, p2, Color.Green);
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public void DrawPoint(Vector2 p, float size, Color color)
        {
            Box2D.XNA.FixedArray8<Vector2> verts = new Box2D.XNA.FixedArray8<Vector2>();
            float hs = size / 2.0f;
            verts[0] = p + new Vector2(-hs, -hs);
            verts[1] = p + new Vector2(hs, -hs);
            verts[2] = p + new Vector2(hs, hs);
            verts[3] = p + new Vector2(-hs, hs);

            DrawSolidPolygon(ref verts, 4, color, true);
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public void DrawString(int x, int y, string s)
        {
            mStringData.Add(new StringData(x, y, s, null));
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public void DrawString(int x, int y, string s, params object[] args)
        {
            mStringData.Add(new StringData(x, y, s, args));
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public void FinishDrawShapes()
        {
            mDevice.BlendState = BlendState.AlphaBlend;

            //_device.RenderState.CullMode = CullMode.None;
            //_device.RenderState.AlphaBlendEnable = true;

            if (mFillCount > 0)
                mDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.TriangleList, mVertsFill, 0, mFillCount);

            if (mLineCount > 0)
                mDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, mVertsLines, 0, mLineCount);

            mLineCount = mFillCount = 0;
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public void FinishDrawString()
        {
            for (int i = 0; i < mStringData.Count; i++)
            {
                var text = mStringData[i].args == null ? mStringData[i].s : string.Format(mStringData[i].s, mStringData[i].args);
                mBatch.DrawString(mFont, text, new Vector2(mStringData[i].x, mStringData[i].y), new Color(0.9f, 0.6f, 0.6f));
            }

            mStringData.Clear();
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public void DrawAABB(ref Box2D.XNA.AABB aabb, Color color)
        {
            Box2D.XNA.FixedArray8<Vector2> verts = new Box2D.XNA.FixedArray8<Vector2>();
            verts[0] = new Vector2(aabb.lowerBound.X, aabb.lowerBound.Y);
            verts[1] = new Vector2(aabb.upperBound.X, aabb.lowerBound.Y);
            verts[2] = new Vector2(aabb.upperBound.X, aabb.upperBound.Y);
            verts[3] = new Vector2(aabb.lowerBound.X, aabb.upperBound.Y);

            DrawPolygon(ref verts, 4, color);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager mGraphicsDM;
        SpriteBatch mSpriteBatch;
        BasicEffect mBasicEffect;
        //SpriteFont mSpriteFont;


        ////////////////////////////////////////////////////////////////////////////
        //
        void Resize(int w, int h)
        {
            int v_x = GraphicsDevice.Viewport.X;
            int v_y = GraphicsDevice.Viewport.Y;

            float ratio = (float)GraphicsDevice.Viewport.Width / (float)GraphicsDevice.Viewport.Height;

            Vector2 extents = new Vector2(ratio * 25f, 25f);
            extents *= 0.5f;

            Vector2 lower = -extents;
            Vector2 upper = extents;

            mBasicEffect.Projection = Matrix.CreateOrthographicOffCenter(lower.X, upper.X, lower.Y, upper.Y, -1, 1);
        }

        ////////////////////////////////////////////////////////////////////////
        //
        public Game1()
        {
            mGraphicsDM = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            mGraphicsDM.PreferMultiSampling = true;

            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);

            // Extend battery life under lock.
            InactiveSleepTime = TimeSpan.FromSeconds(1);
        }

        ////////////////////////////////////////////////////////////////////////
        // Allows the game to perform any initialization it needs to before starting to run.
        // This is where it can query for any required services and load any non-graphic
        // related content.  Calling base.Initialize will enumerate through any components
        // and initialize them as well.
        protected override void Initialize()
        {
            base.Initialize();

            Globals.InitBox2D();
        }

        ////////////////////////////////////////////////////////////////////////////
        // LoadContent will be called once per game and is the place to load
        // all of your content.
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            mSpriteBatch = new SpriteBatch(GraphicsDevice);
            //mSpriteFont = Content.Load<SpriteFont>("Courier New");
            mBasicEffect = new BasicEffect(GraphicsDevice);
            mBasicEffect.VertexColorEnabled = true;

            Globals.gDebugDraw.mDevice = GraphicsDevice;
            Globals.gDebugDraw.mBatch = mSpriteBatch;
            //Globals.gDebugDraw.mFont = mSpriteFont;

            Resize(GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight);
        }

        ////////////////////////////////////////////////////////////////////////////
        // UnloadContent will be called once per game and is the place to unload
        // all content.
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        ////////////////////////////////////////////////////////////////////////////
        // Allows the game to run logic such as updating the world,
        // checking for collisions, gathering input, and playing audio.
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        ////////////////////////////////////////////////////////////////////////////
        // This is called when the game should draw itself.
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            mBasicEffect.Techniques[0].Passes[0].Apply();

            Globals.SetTextLine(30);
            Globals.Step();
            Globals.gDebugDraw.FinishDrawShapes();

            //mSpriteBatch.Begin();
            //Globals.gDebugDraw.FinishDrawString();
            //mSpriteBatch.End();

            base.Draw(gameTime);
        }
    }
}


EDIT: I'm using the C#/XNA port of Box2D found here:
http://box2dxna.codeplex.com/


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group