/// <summary>
        /// Decompose the polygon into several smaller non-concave polygons.
        /// </summary>
        /// <param name="vertices">The polygon to decompose.</param>
        /// <param name="sheer">The sheer to use if you get bad results, try using a higher value.</param>
        /// <returns>A list of triangles</returns>
        public static List<Vertices> ConvexPartition(Vertices vertices, float sheer = 0.001f)
        {
            Debug.Assert(vertices.Count > 3);

            List<Point> compatList = new List<Point>(vertices.Count);

            foreach (Vector2 vertex in vertices)
            {
                compatList.Add(new Point(vertex.X, vertex.Y));
            }

            Triangulator t = new Triangulator(compatList, sheer);

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

            foreach (List<Point> triangle in t.Triangles)
            {
                Vertices outTriangles = new Vertices(triangle.Count);

                foreach (Point outTriangle in triangle)
                {
                    outTriangles.Add(new Vector2(outTriangle.X, outTriangle.Y));
                }

                list.Add(outTriangles);
            }

            return list;
        }
        public RectanglePhysicsComponent(Engine engine, Rectangle rectangle, Vector2 gameWorldPosition, bool dynamic)
            : base(engine)
        {
            // create vertices to create a rectangle in the physics world with
            Vertices vertices = new Vertices();
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Left, rectangle.Top)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Right, rectangle.Top)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Right, rectangle.Bottom)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Left, rectangle.Bottom)));

            MainFixture = FixtureFactory.CreatePolygon(Engine.Physics.World, vertices, 1.0f);
            MainFixture.Body.Position = Engine.Physics.PositionToPhysicsWorld(gameWorldPosition);
            if (dynamic)
            {
                MainFixture.Body.BodyType = BodyType.Dynamic;
            }
            else
            {
                MainFixture.Body.BodyType = BodyType.Static;
            }
            MainFixture.Restitution = 0.5f;

            // adding some linear damping gives a max speed and seems to smooth out player motion really well
            MainFixture.Body.LinearDamping = 1.0f;
        }
        public NetworkCollisionRemnant(Vector2 position, float size, float angleOfStartForce, int ownerId, Color color, World world, Player creator)
            : base(position, size, color, null, creator)
        {
            OwnerId = ownerId;

            body = BodyFactory.CreateBody(world);
            body.BodyType = BodyType.Dynamic;
            body.Position = ConvertUnits.ToSimUnits(position);
            body.FixedRotation = true;
            body.LinearDamping = 0.8f;

            //Create the vertices that will create the collision shape
            Vertices verts = new Vertices();
            verts.Add(new Vector2(-ConvertUnits.ToSimUnits(size / 2f), ConvertUnits.ToSimUnits(size / 2f)));
            verts.Add(new Vector2(-ConvertUnits.ToSimUnits(size / 2f), -ConvertUnits.ToSimUnits(size / 2f)));
            verts.Add(new Vector2(ConvertUnits.ToSimUnits(size / 2f), -ConvertUnits.ToSimUnits(size / 2f)));
            verts.Add(new Vector2(ConvertUnits.ToSimUnits(size / 2f), ConvertUnits.ToSimUnits(size / 2f)));

            //Create the shape and attach it to the body
            PolygonShape s = new PolygonShape(verts, 0);
            body.CreateFixture(s);
            body.FixtureList[0].IsSensor = true;
            body.UserData = this;

            body.CollidesWith = Category.Cat2;
            body.CollisionCategories = Category.Cat2;
            //body.OnSeparation += body_OnSeparation;

            body.ApplyLinearImpulse(new Vector2((float)Math.Cos(angleOfStartForce),(float)Math.Sin(angleOfStartForce)) * 10f);
        }
Ejemplo n.º 4
0
        public Platform(float width, float height, Vector2 position, string name, bool slopeDirection)
            : base(position, name, "Slope")
        {
            Vector2 bottomLeft = new Vector2(-width/2, height/2) / Camera.PixelsPerMeter;
            Vector2 bottomRight = new Vector2(width / 2, height / 2) / Camera.PixelsPerMeter;
            Vector2 top = Vector2.Zero;

            if (slopeDirection) //SLOPE //Remove top left vertex
            {
                top = new Vector2(width / 2, -height / 2) / Camera.PixelsPerMeter;
            }
            else //INVERSLOPE //Remove top right vertex
            {
                top = new Vector2(-width / 2, -height / 2) / Camera.PixelsPerMeter;
            }

            Vertices vertices = new Vertices(3);
            vertices.Add(top);
            vertices.Add(bottomRight);
            vertices.Add(bottomLeft);

            Body body = BodyFactory.CreatePolygon(GameManager.game.world, vertices, 1f, position/ Camera.PixelsPerMeter);
            body.IsStatic = true;
            body.Restitution = 0f;
            body.Friction = 0.5f;
            this.AddBody(body);
        }
Ejemplo n.º 5
0
 public Goalie(World world, GoalieData spawn)
 {
     var body = new Body(world);
     var angle = spawn.End - spawn.Begin;
     body.Rotation = FMath.Atan2(angle.Y, angle.X);
     segment.A = spawn.Begin;
     segment.B = spawn.End;
     var normal = new Vector2(-angle.Y, angle.X);
     normal.Normalize();
     delta = normal * .5f;
     segmentOut.A = spawn.Begin + delta;
     segmentOut.B = spawn.End + delta;
     segmentIn.A = spawn.Begin - delta;
     segmentIn.B = spawn.End - delta;
     body.Position = spawn.Begin;
     var verts = new Vertices();
     verts.Add(new Vector2(left, bottom));
     verts.Add(new Vector2(right, bottom));
     verts.Add(new Vector2(right, top));
     verts.Add(new Vector2(left, top));
     var shape = new PolygonShape(verts, 1f);
     body.FixedRotation = true;
     body.BodyType = BodyType.Dynamic;
     Fixture = body.CreateFixture(shape);
 }
Ejemplo n.º 6
0
        public SquareStack(Vector2 pos, Vector2 size, Vector2 subSize, float rot, SpriteBatch batch, Texture2D texture, World world)
            : base(pos, batch, texture, world)
        {
            this.size = size;
            this.subSize = subSize;
            this.rot = rot;
            this.texture = texture;
            this.color = Color.Green;
            this.spriteOrigin = new Vector2(texture.Width / 2, texture.Height / 2);
            this.backCol = new Color(color.R / 2, color.G / 2, color.B / 2);

            rMat = Matrix.CreateRotationZ(rot);

            if (Settings.MaxPolygonVertices < 24) Settings.MaxPolygonVertices = 24;

            Vector2 leftTop = Vector2.Transform(new Vector2(-size.X / 2, -size.Y / 2), rMat);
            Vector2 rightTop = Vector2.Transform(new Vector2(size.X / 2, -size.Y / 2), rMat);
            Vector2 leftBottom = Vector2.Transform(new Vector2(-size.X / 2, size.Y / 2), rMat);
            Vector2 rightBottom = Vector2.Transform(new Vector2(size.X / 2, size.Y / 2), rMat);

            Vertices verts = new Vertices();
            verts.Add(leftTop); verts.Add(rightTop); verts.Add(rightBottom); verts.Add(leftBottom);
            FixtureFactory.AttachPolygon(verts, density, body);

            this.width = max(max(leftTop.X, rightTop.X), max(leftBottom.X, rightBottom.X)) - min(min(leftTop.X, rightTop.X), min(leftBottom.X, rightBottom.X));
            this.height = max(max(leftTop.Y, rightTop.Y), max(leftBottom.Y, rightBottom.Y)) - min(min(leftTop.Y, rightTop.Y), min(leftBottom.Y, rightBottom.Y));
        }
Ejemplo n.º 7
0
        public Border(World world, ScreenManager screenManager, Camera2D camera)
        {
            _screenManager = screenManager;
            _camera = camera;

            float halfWidth = ConvertUnits.ToSimUnits(screenManager.GraphicsDevice.Viewport.Width) / 2f - 0.75f;
            float halfHeight = ConvertUnits.ToSimUnits(screenManager.GraphicsDevice.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(screenManager.GraphicsDevice);
            _basicEffect.VertexColorEnabled = true;
            _basicEffect.TextureEnabled = true;
            _basicEffect.Texture = 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];
        }
Ejemplo n.º 8
0
 private static Vertices MakeVertices(Vector2 sz)
 {
     Vertices v = new Vertices();
     v.Add(new Vector2(0, 0));
     v.Add(new Vector2(sz.X, 0));
     v.Add(new Vector2(sz.X, sz.Y));
     v.Add(new Vector2(0,sz.Y));
     return v;
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Build vertices to represent an axis-aligned box.
        /// </summary>
        /// <param name="hx">the half-width.</param>
        /// <param name="hy">the half-height.</param>
        public static Vertices CreateRectangle(float hx, float hy)
        {
            Vertices vertices = new Vertices(4);
            vertices.Add(new Vector2(-hx, -hy));
            vertices.Add(new Vector2(hx, -hy));
            vertices.Add(new Vector2(hx, hy));
            vertices.Add(new Vector2(-hx, hy));

            return vertices;
        }
Ejemplo n.º 10
0
        private RevoluteTest()
        {
            //Ground
            Body ground = BodyFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));

            {
                Body bodyB = BodyFactory.CreateCircle(World, 0.5f, 5f, new Vector2(-10.0f, 20.0f));
                bodyB.BodyType = BodyType.Dynamic;

                const float w = 100.0f;
                bodyB.AngularVelocity = w;
                bodyB.LinearVelocity = new Vector2(-8.0f * w, 0.0f);

                _joint = new RevoluteJoint(ground, bodyB, new Vector2(-10.0f, 12.0f), true);
                _joint.MotorSpeed = 1.0f * Settings.Pi;
                _joint.MaxMotorTorque = 10000.0f;
                _joint.MotorEnabled = false;
                _joint.LowerLimit = -0.25f * Settings.Pi;
                _joint.UpperLimit = 0.5f * Settings.Pi;
                _joint.LimitEnabled = true;
                _joint.CollideConnected = true;

                World.AddJoint(_joint);
            }

            {
                Body ball = BodyFactory.CreateCircle(World, 3.0f, 5.0f, new Vector2(5.0f, 30.0f));
                ball.BodyType = BodyType.Dynamic;
                ball.CollisionCategories = Category.Cat1;

                Vertices polygonVertices = PolygonTools.CreateRectangle(10.0f, 0.2f, new Vector2(-10.0f, 0.0f), 0.0f);

                Body polygonBody = BodyFactory.CreatePolygon(World, polygonVertices, 2, new Vector2(20, 10));
                polygonBody.BodyType = BodyType.Dynamic;
                polygonBody.IsBullet = true;

                RevoluteJoint joint = new RevoluteJoint(ground, polygonBody, new Vector2(20, 10), true);
                joint.LowerLimit = -0.25f * Settings.Pi;
                joint.UpperLimit = 0.0f * Settings.Pi;
                joint.LimitEnabled = true;

                World.AddJoint(joint);
            }

            // Tests mass computation of a small object far from the origin
            {
                Vertices verts = new Vertices(3);
                verts.Add(new Vector2(17.63f, 36.31f));
                verts.Add(new Vector2(17.52f, 36.69f));
                verts.Add(new Vector2(17.19f, 36.36f));

                Body polyShape = BodyFactory.CreatePolygon(World, verts, 1);
                polyShape.BodyType = BodyType.Dynamic;
            }
        }
Ejemplo n.º 11
0
        private void CreateBorder(float width, float height, float borderWidth)
        {
            width = Math.Abs(width);
            height = Math.Abs(height);

            _anchor = BodyFactory.CreateBody(_world);
            left = BodyFactory.CreateBody(_world);
            right = BodyFactory.CreateBody(_world);
            up = BodyFactory.CreateBody(_world);
            down = BodyFactory.CreateBody(_world);

            UserData userData = new UserData(-1, 3, true);

            Vertices vert = new Vertices();

            // top
            // counterclockwise
            Vertices vup = new Vertices();
            vup.Add(new Vector2(0, 10));
            vup.Add(new Vector2(0, 0));
            vup.Add(new Vector2(1000, 0));
            vup.Add(new Vector2(1000, 10));
            up.CreateFixture(new PolygonShape(vup, 0.0f), userData);
            //Bottom
            down.CreateFixture(new PolygonShape(vup, 0.0f), userData);
            down.Position = new Vector2(0, 990);
            //Left
            Vertices vl = new Vertices();
            vl.Add(new Vector2(0, 1000));
            vl.Add(new Vector2(0, 0));
            vl.Add(new Vector2(10, 0));
            vl.Add(new Vector2(10, 1000));
            left.CreateFixture(new PolygonShape(vl, 0.0f), userData);

            //Right

            right.CreateFixture(new PolygonShape(vl, 0.0f), userData);
            right.Position = new Vector2(990, 0);

            foreach (Fixture t in _anchor.FixtureList)
            {
                t.CollisionFilter.CollisionCategories = Category.All;
                t.CollisionFilter.CollidesWith = Category.All;
                t.Friction = _frictionValue;
                t.Restitution = _bouncyValue;
            }

            ContentManager content = Master.theMaster.game.Content;
            topBorder = content.Load<Texture2D>("images/BoarderHorizontal");
            bottomBorder = content.Load<Texture2D>("images/BoarderHorizontal");
            rightBorder = content.Load<Texture2D>("images/BoarderVertical");
            leftBorder = content.Load<Texture2D>("images/BoarderVertical");
        }
Ejemplo n.º 12
0
        public void InitBorders()
        {
            Vertices borders = new Vertices(4);
            borders.Add(new Vector2(0, 0));
            borders.Add(new Vector2(width, 0));
            borders.Add(new Vector2(width, height));
            borders.Add(new Vector2(0, height));

            borderBody = BodyFactory.CreateLoopShape(_world, borders);
            borderBody.CollisionCategories = Category.All;
            borderBody.CollidesWith = Category.All;
        }
Ejemplo n.º 13
0
Archivo: Wall.cs Proyecto: det/Rimbalzo
        public void addQuad(World world, WallCompiled wall, int a, int b)
        {
            var verts = new Vertices(4);
            verts.Add(wall.Verts1[a]);
            verts.Add(wall.Verts4[a]);
            verts.Add(wall.Verts4[b]);
            verts.Add(wall.Verts1[b]);

            var wallBody = new Body(world);
            var wallShape = new PolygonShape(verts, 1f);
            Fixtures[a] = wallBody.CreateFixture(wallShape);
            Fixtures[a].Friction = 0f;
        }
Ejemplo n.º 14
0
        private void CreateBodyFixture()
        {
            //Create the vertices that will create the collision shape
            Vertices verts = new Vertices();
            verts.Add(new Vector2(-ConvertUnits.ToSimUnits(size / 2f), ConvertUnits.ToSimUnits(size / 2f)));
            verts.Add(new Vector2(-ConvertUnits.ToSimUnits(size / 2f), -ConvertUnits.ToSimUnits(size / 2f)));
            verts.Add(new Vector2(ConvertUnits.ToSimUnits(size / 2f), -ConvertUnits.ToSimUnits(size / 2f)));
            verts.Add(new Vector2(ConvertUnits.ToSimUnits(size / 2f), ConvertUnits.ToSimUnits(size / 2f)));

            //Create the shape and attach it to the body
            PolygonShape s = new PolygonShape(verts, 0);
            body.CreateFixture(s);
            body.FixtureList[0].IsSensor = true;
        }
Ejemplo n.º 15
0
        public Entity BuildEntity(Entity e, params object[] args)
        {
            e.Tag = "Chassis";

            #region Body
            Body Chassis = e.AddComponent<Body>(new Body(_World, e));
            {
                Vertices vertices = new Vertices(8);
                vertices.Add(new Vector2(-2.5f, 0.08f));
                vertices.Add(new Vector2(-2.375f, -0.46f));
                vertices.Add(new Vector2(-0.58f, -0.92f));
                vertices.Add(new Vector2(0.46f, -0.92f));
                vertices.Add(new Vector2(2.5f, -0.17f));
                vertices.Add(new Vector2(2.5f, 0.205f));
                vertices.Add(new Vector2(2.3f, 0.33f));
                vertices.Add(new Vector2(-2.25f, 0.35f));
                PolygonShape chassisShape = new PolygonShape(vertices, 2f);

                Chassis.BodyType = BodyType.Dynamic;
                Chassis.Position = new Vector2(0.0f, -1.0f);
                Chassis.CreateFixture(chassisShape);
            }
            #endregion

            #region Sprite
            e.AddComponent<Sprite>(new Sprite(args[0] as Texture2D, (Rectangle)args[1],
               Chassis, 1, Color.White, 0f));
            #endregion
            return e;
        }
Ejemplo n.º 16
0
        public void CreateCollisionRectangle(Rectangle rectangle, Vector2 position)
        {
            Vertices vertices = new Vertices();
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Left, rectangle.Top)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Right, rectangle.Top)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Right, rectangle.Bottom)));
            vertices.Add(Engine.Physics.PositionToPhysicsWorld(new Vector2(rectangle.Left, rectangle.Bottom)));

            Fixture fixture = FixtureFactory.CreatePolygon(Engine.Physics.World, vertices, 1.0f);
            fixture.Body.Position = position;
            fixture.Body.BodyType = BodyType.Static;
            fixture.Restitution = 0.0f;
            fixture.CollisionFilter.CollisionCategories = (Category)Global.CollisionCategories.Structure;
        }
Ejemplo n.º 17
0
        private RayCastTest()
        {
            {
                Vertices vertices = new Vertices(3);
                vertices.Add(new Vector2(-0.5f, 0.0f));
                vertices.Add(new Vector2(0.5f, 0.0f));
                vertices.Add(new Vector2(0.0f, 1.5f));
                _polygons[0] = new PolygonShape(vertices, 1);
            }

            {
                Vertices vertices2 = new Vertices(3);
                vertices2.Add(new Vector2(-0.1f, 0.0f));
                vertices2.Add(new Vector2(0.1f, 0.0f));
                vertices2.Add(new Vector2(0.0f, 1.5f));
                _polygons[1] = new PolygonShape(vertices2, 1);
            }

            {
                const float w = 1.0f;
                float b = w / (2.0f + (float)Math.Sqrt(2.0));
                float s = (float)Math.Sqrt(2.0) * b;

                Vertices vertices3 = new Vertices(8);
                vertices3.Add(new Vector2(0.5f * s, 0.0f));
                vertices3.Add(new Vector2(0.5f * w, b));
                vertices3.Add(new Vector2(0.5f * w, b + s));
                vertices3.Add(new Vector2(0.5f * s, w));
                vertices3.Add(new Vector2(-0.5f * s, w));
                vertices3.Add(new Vector2(-0.5f * w, b + s));
                vertices3.Add(new Vector2(-0.5f * w, b));
                vertices3.Add(new Vector2(-0.5f * s, 0.0f));
                _polygons[2] = new PolygonShape(vertices3, 1);
            }

            {
                _polygons[3] = new PolygonShape(1);
                _polygons[3].Vertices = PolygonTools.CreateRectangle(0.5f, 0.5f);
            }

            {
                _circle = new CircleShape(0.5f, 1);
            }

            _bodyIndex = 0;

            _angle = 0.0f;
            _mode = RayCastMode.Closest;
        }
Ejemplo n.º 18
0
        public void InitializePhysics(World world)
        {
            Body body = new Body(world);
            Vertices verts = new Vertices();
            if (!IsStair) verts.Add(new Vector2(ConvertUnits.ToSimUnits(Bounds.X), ConvertUnits.ToSimUnits(Bounds.Y)));
            verts.Add(new Vector2(ConvertUnits.ToSimUnits(Bounds.X + Bounds.Width), ConvertUnits.ToSimUnits(Bounds.Y)));
            verts.Add(new Vector2(ConvertUnits.ToSimUnits(Bounds.X + Bounds.Width), ConvertUnits.ToSimUnits(Bounds.Y + Bounds.Height)));
            verts.Add(new Vector2(ConvertUnits.ToSimUnits(Bounds.X), ConvertUnits.ToSimUnits(Bounds.Y + Bounds.Height)));

            body.CreateFixture(new PolygonShape(verts, 0));

            body.Friction = 0.40f;
            Bodies = new List<Body>();
            Bodies.Add(body);
        }
Ejemplo n.º 19
0
        public override void Placed()
        {
            placed = true;
            dragable = false;

            //reset color
            color = Color.White;

            //Compute Vertices
            top = new Vector2((float)position.X, (float)position.Y - (float)size.Y / 2f);
            bottomLeft = new Vector2((float)position.X - (float)size.X / 2f, (float)position.Y + (float)size.Y / 2f);
            bottomRight = new Vector2((float)position.X + (float)size.X / 2f, (float)position.Y + (float)size.Y / 2f);

            //initialize body physics parameters
            Vertices vertices = new Vertices();
            vertices.Add(UnitConverter.toSimSpace(top));
            vertices.Add(UnitConverter.toSimSpace(bottomLeft));
            vertices.Add(UnitConverter.toSimSpace(bottomRight));
            brickBody = BodyFactory.CreatePolygon(Game1.world, vertices, 1.0f, "TriangleBrick");
            //brickBody = BodyFactory.CreateRectangle(Game1.world, UnitConverter.toSimSpace(brickWidth), UnitConverter.toSimSpace(brickHeight), 1.0f, UnitConverter.toSimSpace(position));
            brickBody.BodyType = BodyType.Static;
            brickBody.OnCollision += BrickBody_OnCollision;
            brickBody.Restitution = 0.1f;
            brickBody.AngularDamping = 20;
            brickBody.Friction = 0.5f;
        }
Ejemplo n.º 20
0
        private void MakePolygon()
        {

            Vector2 avgLoc = new Vector2();
            foreach (Vector2 vert in polyPoints)
            {
                avgLoc += vert;
            }
            avgLoc /= polyPoints.Count;

            

            Vertices verts = new Vertices();

            foreach (Vector2 v in polyPoints)
            {
                verts.Add(v - avgLoc);
            }

            Body b = new Body(game.farseerManager.world);
            List<Fixture> composition = FixtureFactory.AttachCompoundPolygon(EarclipDecomposer.ConvexPartition(verts), 1, b);
            b.Position = avgLoc;

            foreach (Fixture triangle in composition)
            {
                FarseerTextures.ApplyTexture(triangle, FarseerTextures.TextureType.Normal);
            }

            if (composition.Count > 0)
                FormManager.Property.setPendingObjects(new List<object>() { composition[0].Body });

            polyPoints.Clear();
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Create a new chainshape from the vertices.
        /// </summary>
        /// <param name="vertices">The vertices to use. Must contain 2 or more vertices.</param>
        /// <param name="createLoop">Set to true to create a closed loop. It connects the first vertice to the last, and automatically adjusts connectivity to create smooth collisions along the chain.</param>
        public ChainShape(Vertices vertices, bool createLoop = false)
            : base(0)
        {
            ShapeType = ShapeType.Chain;
            _radius = Settings.PolygonRadius;

            Debug.Assert(vertices != null && vertices.Count >= 3);
            Debug.Assert(vertices[0] != vertices[vertices.Count - 1]); // FPE. See http://www.box2d.org/forum/viewtopic.php?f=4&t=7973&p=35363

            for (int i = 1; i < vertices.Count; ++i)
            {
                Vector2 v1 = vertices[i - 1];
                Vector2 v2 = vertices[i];

                // If the code crashes here, it means your vertices are too close together.
                Debug.Assert(Vector2.DistanceSquared(v1, v2) > Settings.LinearSlop * Settings.LinearSlop);
            }

            Vertices = new Vertices(vertices);

            if (createLoop)
            {
                Vertices.Add(vertices[0]);
                PrevVertex = Vertices[Vertices.Count - 2]; //FPE: We use the properties instead of the private fields here.
                NextVertex = Vertices[1]; //FPE: We use the properties instead of the private fields here.
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Removes all collinear points on the polygon.
        /// </summary>
        /// <param name="vertices">The polygon that needs simplification.</param>
        /// <param name="collinearityTolerance">The collinearity tolerance.</param>
        /// <returns>A simplified polygon.</returns>
        public static Vertices CollinearSimplify(Vertices vertices, float collinearityTolerance)
        {
            //We can't simplify polygons under 3 vertices
            if (vertices.Count < 3)
                return vertices;

            Vertices simplified = new Vertices();

            for (int i = 0; i < vertices.Count; i++)
            {
                int prevId = vertices.PreviousIndex(i);
                int nextId = vertices.NextIndex(i);

                Vector2 prev = vertices[prevId];
                Vector2 current = vertices[i];
                Vector2 next = vertices[nextId];

                //If they collinear, continue
                if (MathUtils.Collinear(ref prev, ref current, ref next, collinearityTolerance))
                    continue;

                simplified.Add(current);
            }

            return simplified;
        }
Ejemplo n.º 23
0
        private ConvexHullTest2()
        {
            _pointCloud1 = new Vertices(32);

            for (int i = 0; i < 32; i++)
            {
                float x = Rand.RandomFloat(-10, 10);
                float y = Rand.RandomFloat(-10, 10);

                _pointCloud1.Add(new Vector2(x, y));
            }

            _pointCloud2 = new Vertices(_pointCloud1);
            _pointCloud3 = new Vertices(_pointCloud1);

            //Melkman DOES NOT work on point clouds. It only works on simple polygons.
            _pointCloud1.Translate(new Vector2(-20, 30));
            _melkman = Melkman.GetConvexHull(_pointCloud1);

            //Giftwrap works on point clouds

            _pointCloud2.Translate(new Vector2(20, 30));
            _giftWrap = GiftWrap.GetConvexHull(_pointCloud2);

            _pointCloud3.Translate(new Vector2(20, 10));
            _chainHull = ChainHull.GetConvexHull(_pointCloud3);
        }
Ejemplo n.º 24
0
        public PathTile(List<Vector2> localPoints, Vector2 position, World world, bool MakroCollision = false)
        {
            body = new Body(world);
            body.Position = ConvertUnits.ToSimUnits(position);
            body.UserData = "Wall";
            body.IsStatic = true;

            Vertices terrain = new Vertices();

            foreach (Vector2 point in localPoints)
            {
                terrain.Add(ConvertUnits.ToSimUnits(point));
            }

            for (int i = 0; i < terrain.Count - 1; ++i)
            {
                FixtureFactory.AttachEdge(terrain[i], terrain[i + 1], body);
                body.FixtureList[i].UserData = "Wall";
            }
            body.Restitution = 0f;
            body.Friction = float.MaxValue;
            if (!MakroCollision)
                body.CollisionCategories = Category.Cat15 & ~Category.Cat3;
            else
                body.CollidesWith = Category.Cat29;
        }
Ejemplo n.º 25
0
        //Rounded rectangle contributed by Jonathan Smars - [email protected]

        /// <summary>
        /// Creates a rounded rectangle with the specified width and height.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="xRadius">The rounding X radius.</param>
        /// <param name="yRadius">The rounding Y radius.</param>
        /// <param name="segments">The number of segments to subdivide the edges.</param>
        /// <returns></returns>
        public static Vertices CreateRoundedRectangle(float width, float height, float xRadius, float yRadius,
                                                      int segments)
        {
            if (yRadius > height / 2 || xRadius > width / 2)
                throw new Exception("Rounding amount can't be more than half the height and width respectively.");
            if (segments < 0)
                throw new Exception("Segments must be zero or more.");

            //We need at least 8 vertices to create a rounded rectangle
            Debug.Assert(Settings.MaxPolygonVertices >= 8);

            Vertices vertices = new Vertices();
            if (segments == 0)
            {
                vertices.Add(new Vector2(width * .5f - xRadius, -height * .5f));
                vertices.Add(new Vector2(width * .5f, -height * .5f + yRadius));

                vertices.Add(new Vector2(width * .5f, height * .5f - yRadius));
                vertices.Add(new Vector2(width * .5f - xRadius, height * .5f));

                vertices.Add(new Vector2(-width * .5f + xRadius, height * .5f));
                vertices.Add(new Vector2(-width * .5f, height * .5f - yRadius));

                vertices.Add(new Vector2(-width * .5f, -height * .5f + yRadius));
                vertices.Add(new Vector2(-width * .5f + xRadius, -height * .5f));
            }
            else
            {
                int numberOfEdges = (segments * 4 + 8);

                float stepSize = MathHelper.TwoPi / (numberOfEdges - 4);
                int perPhase = numberOfEdges / 4;

                Vector2 posOffset = new Vector2(width / 2 - xRadius, height / 2 - yRadius);
                vertices.Add(posOffset + new Vector2(xRadius, -yRadius + yRadius));
                short phase = 0;
                for (int i = 1; i < numberOfEdges; i++)
                {
                    if (i - perPhase == 0 || i - perPhase * 3 == 0)
                    {
                        posOffset.X *= -1;
                        phase--;
                    }
                    else if (i - perPhase * 2 == 0)
                    {
                        posOffset.Y *= -1;
                        phase--;
                    }

                    vertices.Add(posOffset + new Vector2(xRadius * (float)Math.Cos(stepSize * -(i + phase)),
                                                         -yRadius * (float)Math.Sin(stepSize * -(i + phase))));
                }
            }

            return vertices;
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Adds the vertices.
 /// </summary>
 /// <param name="vertices">The vertices.</param>
 /// <param name="position">The position.</param>
 /// <returns>the combined vertices</returns>
 public static Vertices AddVectorToVertices( Vertices vertices, Vector2 position )
 {
     Vertices verts = new Vertices( vertices.Count );
     for ( int i = 0; i < vertices.Count; i++ ) {
         verts.Add( vertices[ i ] + ConvertUnits.ToSimUnits( position ) );
     }
     return verts;
 }
Ejemplo n.º 27
0
        public Border(World world, Vector2 worldSize)
        {
            float simWidth = ConvertUnits.ToSimUnits(worldSize.X);
            float simHeight = ConvertUnits.ToSimUnits(worldSize.Y);

            Corners = new Vertices(4);
            Corners.Add(new Vector2(0f, 0f));
            Corners.Add(new Vector2(simWidth, 0f));
            Corners.Add(new Vector2(simWidth, simHeight));
            Corners.Add(new Vector2(0f, simHeight));

            _anchor = BodyFactory.CreateLoopShape(world, Corners);
            _anchor.CollisionCategories =
                (Category)CharacterEntity.CollisionCategory.Environment;
            _anchor.CollidesWith =
                (Category)CharacterEntity.CollidesWith.Environment;
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Initialize the proxy using the given shape. The shape
        /// must remain in scope while the proxy is in use.
        /// </summary>
        /// <param name="shape">The shape.</param>
        /// <param name="index">The index.</param>
        public void Set(Shape shape, int index)
        {
            switch (shape.ShapeType)
            {
                case ShapeType.Circle:
                    {
                        CircleShape circle = (CircleShape) shape;
                        Vertices = new Vertices(1);
                        Vertices.Add(circle.Position);
                        Radius = circle.Radius;
                    }
                    break;

                case ShapeType.Polygon:
                    {
                        PolygonShape polygon = (PolygonShape) shape;
                        Vertices = polygon.Vertices;
                        Radius = polygon.Radius;
                    }
                    break;

                case ShapeType.Loop:
                    {
                        LoopShape loop = (LoopShape) shape;
                        Debug.Assert(0 <= index && index < loop.Vertices.Count);

                        Buffer[0] = loop.Vertices[index];
                        if (index + 1 < loop.Vertices.Count)
                        {
                            Buffer[1] = loop.Vertices[index + 1];
                        }
                        else
                        {
                            Buffer[1] = loop.Vertices[0];
                        }

                        Vertices = new Vertices(2);
                        Vertices.Add(Buffer[0]);
                        Vertices.Add(Buffer[1]);
                        Radius = loop.Radius;
                    }
                    break;

                case ShapeType.Edge:
                    {
                        EdgeShape edge = (EdgeShape) shape;
                        Vertices = new Vertices(2);
                        Vertices.Add(edge.Vertex1);
                        Vertices.Add(edge.Vertex2);
                        Radius = edge.Radius;
                    }
                    break;

                default:
                    Debug.Assert(false);
                    break;
            }
        }
Ejemplo n.º 29
0
        //methods
        public void Add(Vertex element)
        {
            Vertices?.Add(element);

            element.Id = IdVertexesCounter;
            IdVertexesCounter++;

            AdjacencyMatrix.AddVertex();
        }
Ejemplo n.º 30
0
 /// Create a loop. This automatically adjusts connectivity.
 public void CreateLoop(Vertices vertices)
 {
     Debug.Assert(vertices.Count >= 3);
     Vertices = new Vertices(vertices);
     Vertices.Add(vertices[0]);
     _prevVertex = Vertices[Vertices.Count - 2];
     _nextVertex = Vertices[1];
     _hasPrevVertex = true;
     _hasNextVertex = true;
 }
Ejemplo n.º 31
0
        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;
            _anchor.AngularDamping      = 0;
            _anchor.Friction            = 0;
            _anchor.Restitution         = 1;

            _basicEffect = new BasicEffect(_screen.ScreenManager.GraphicsDevice)
            {
                VertexColorEnabled = true,
                TextureEnabled     = true,
                Texture            = this._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];
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Combine a list of triangles into a list of convex polygons.
        ///
        /// Note: This only works on triangles.
        /// </summary>
        ///<param name="triangles">The triangles.</param>
        ///<param name="maxPolys">The maximun number of polygons to return.</param>
        ///<param name="tolerance">The tolerance</param>
        public static List <Vertices> PolygonizeTriangles(List <Vertices> triangles, int maxPolys = int.MaxValue, float tolerance = 0.001f)
        {
            if (triangles.Count <= 0)
            {
                return(triangles);
            }

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

            bool[] covered = new bool[triangles.Count];
            for (int i = 0; i < triangles.Count; ++i)
            {
                covered[i] = false;

                //Check here for degenerate triangles
                Vertices triangle = triangles[i];
                Vector2  a        = triangle[0];
                Vector2  b        = triangle[1];
                Vector2  c        = triangle[2];

                if ((a.X == b.X && a.Y == b.Y) || (b.X == c.X && b.Y == c.Y) || (a.X == c.X && a.Y == c.Y))
                {
                    covered[i] = true;
                }
            }

            int polyIndex = 0;

            bool notDone = true;

            while (notDone)
            {
                int currTri = -1;
                for (int i = 0; i < triangles.Count; ++i)
                {
                    if (covered[i])
                    {
                        continue;
                    }

                    currTri = i;
                    break;
                }

                if (currTri == -1)
                {
                    notDone = false;
                }
                else
                {
                    Vertices poly = new Vertices(3);

                    for (int i = 0; i < 3; i++)
                    {
                        poly.Add(triangles[currTri][i]);
                    }

                    covered[currTri] = true;
                    int index = 0;
                    for (int i = 0; i < 2 * triangles.Count; ++i, ++index)
                    {
                        while (index >= triangles.Count)
                        {
                            index -= triangles.Count;
                        }
                        if (covered[index])
                        {
                            continue;
                        }
                        Vertices newP = AddTriangle(triangles[index], poly);
                        if (newP == null)
                        {
                            continue; // is this right
                        }
                        if (newP.Count > Settings.MaxPolygonVertices)
                        {
                            continue;
                        }

                        if (newP.IsConvex())
                        {
                            //Or should it be IsUsable?  Maybe re-write IsConvex to apply the angle threshold from Box2d
                            poly           = new Vertices(newP);
                            covered[index] = true;
                        }
                    }

                    //We have a maximum of polygons that we need to keep under.
                    if (polyIndex < maxPolys)
                    {
                        SimplifyTools.MergeParallelEdges(poly, tolerance);

                        //If identical points are present, a triangle gets
                        //borked by the MergeParallelEdges function, hence
                        //the vertex number check
                        if (poly.Count >= 3)
                        {
                            polys.Add(new Vertices(poly));
                        }
                        else
                        {
                            Debug.WriteLine("Skipping corrupt poly.");
                        }
                    }

                    if (poly.Count >= 3)
                    {
                        polyIndex++; //Must be outside (polyIndex < polysLength) test
                    }
                }
            }

            //TODO: Add sanity check
            //Remove empty vertice collections
            for (int i = polys.Count - 1; i >= 0; i--)
            {
                if (polys[i].Count == 0)
                {
                    polys.RemoveAt(i);
                }
            }

            return(polys);
        }
        private static Vertices AddTriangle(Triangle t, Vertices vertices)
        {
            // float32 equalTol = .001f;
            // First, find vertices that connect
            int firstP  = -1;
            int firstT  = -1;
            int secondP = -1;
            int secondT = -1;

            for (int i = 0; i < vertices.Count; i++)
            {
                if (t.X[0] == vertices[i].X && t.Y[0] == vertices[i].Y)
                {
                    if (firstP == -1)
                    {
                        firstP = i;
                        firstT = 0;
                    }
                    else
                    {
                        secondP = i;
                        secondT = 0;
                    }
                }
                else if (t.X[1] == vertices[i].X && t.Y[1] == vertices[i].Y)
                {
                    if (firstP == -1)
                    {
                        firstP = i;
                        firstT = 1;
                    }
                    else
                    {
                        secondP = i;
                        secondT = 1;
                    }
                }
                else if (t.X[2] == vertices[i].X && t.Y[2] == vertices[i].Y)
                {
                    if (firstP == -1)
                    {
                        firstP = i;
                        firstT = 2;
                    }
                    else
                    {
                        secondP = i;
                        secondT = 2;
                    }
                }
            }
            // Fix ordering if first should be last vertex of poly
            if (firstP == 0 && secondP == vertices.Count - 1)
            {
                firstP  = vertices.Count - 1;
                secondP = 0;
            }

            // Didn't find it
            if (secondP == -1)
            {
                return(null);
            }

            // Find tip index on triangle
            int tipT = 0;

            if (tipT == firstT || tipT == secondT)
            {
                tipT = 1;
            }
            if (tipT == firstT || tipT == secondT)
            {
                tipT = 2;
            }

            Vertices result = new Vertices(vertices.Count + 1);

            for (int i = 0; i < vertices.Count; i++)
            {
                result.Add(vertices[i]);

                if (i == firstP)
                {
                    result.Add(new Vector2(t.X[tipT], t.Y[tipT]));
                }
            }

            return(result);
        }
        private CharacterCollisionTest()
        {
            //Ground body
            Body ground = BodyFactory.CreateEdge(World, new Vector2(-20.0f, 0.0f), new Vector2(20.0f, 0.0f));

            // Collinear edges with no adjacency information.
            // This shows the problematic case where a box shape can hit
            // an internal vertex.
            EdgeShape shape = new EdgeShape(new Vector2(-8.0f, 1.0f), new Vector2(-6.0f, 1.0f));

            ground.CreateFixture(shape);
            shape = new EdgeShape(new Vector2(-6.0f, 1.0f), new Vector2(-4.0f, 1.0f));
            ground.CreateFixture(shape);
            shape = new EdgeShape(new Vector2(-4.0f, 1.0f), new Vector2(-2.0f, 1.0f));
            ground.CreateFixture(shape);

            // Chain shape
            {
                Vertices vs = new Vertices(4);
                vs.Add(new Vector2(5.0f, 7.0f));
                vs.Add(new Vector2(6.0f, 8.0f));
                vs.Add(new Vector2(7.0f, 8.0f));
                vs.Add(new Vector2(8.0f, 7.0f));

                Body body = BodyFactory.CreateChainShape(World, vs);
                body.Rotation = 0.25f * Settings.Pi;
            }

            // Square tiles. This shows that adjacency shapes may
            // have non-smooth collision. There is no solution
            // to this problem.
            PolygonShape tile = new PolygonShape(1);

            tile.Vertices = PolygonTools.CreateRectangle(1.0f, 1.0f, new Vector2(4.0f, 3.0f), 0.0f);
            ground.CreateFixture(tile);
            tile.Vertices = PolygonTools.CreateRectangle(1.0f, 1.0f, new Vector2(6.0f, 3.0f), 0.0f);
            ground.CreateFixture(tile);
            tile.Vertices = PolygonTools.CreateRectangle(1.0f, 1.0f, new Vector2(8.0f, 3.0f), 0.0f);
            ground.CreateFixture(tile);

            // Square made from an edge loop. Collision should be smooth.
            Vertices vertices = new Vertices(4);

            vertices.Add(new Vector2(-1.0f, 3.0f));
            vertices.Add(new Vector2(1.0f, 3.0f));
            vertices.Add(new Vector2(1.0f, 5.0f));
            vertices.Add(new Vector2(-1.0f, 5.0f));
            FixtureFactory.AttachLoopShape(vertices, ground);

            // Edge loop. Collision should be smooth.
            vertices = new Vertices(10);
            vertices.Add(new Vector2(0.0f, 0.0f));
            vertices.Add(new Vector2(6.0f, 0.0f));
            vertices.Add(new Vector2(6.0f, 2.0f));
            vertices.Add(new Vector2(4.0f, 1.0f));
            vertices.Add(new Vector2(2.0f, 2.0f));
            vertices.Add(new Vector2(0.0f, 2.0f));
            vertices.Add(new Vector2(-2.0f, 2.0f));
            vertices.Add(new Vector2(-4.0f, 3.0f));
            vertices.Add(new Vector2(-6.0f, 2.0f));
            vertices.Add(new Vector2(-6.0f, 0.0f));
            BodyFactory.CreateLoopShape(World, vertices, new Vector2(-10, 4));

            // Square character 1
            Body squareCharacter = BodyFactory.CreateRectangle(World, 1, 1, 20, new Vector2(-3.0f, 8.0f));

            squareCharacter.BodyType        = BodyType.Dynamic;
            squareCharacter.FixedRotation   = true;
            squareCharacter.SleepingAllowed = false;

            squareCharacter.OnCollision  += CharacterOnCollision;
            squareCharacter.OnSeparation += CharacterOnSeparation;

            // Square character 2
            Body squareCharacter2 = BodyFactory.CreateRectangle(World, 0.5f, 0.5f, 20, new Vector2(-5.0f, 5.0f));

            squareCharacter2.BodyType        = BodyType.Dynamic;
            squareCharacter2.FixedRotation   = true;
            squareCharacter2.SleepingAllowed = false;

            // Hexagon character
            float       angle = 0.0f;
            const float delta = Settings.Pi / 3.0f;

            vertices = new Vertices(6);

            for (int i = 0; i < 6; ++i)
            {
                vertices.Add(new Vector2(0.5f * (float)Math.Cos(angle), 0.5f * (float)Math.Sin(angle)));
                angle += delta;
            }

            Body hexCharacter = BodyFactory.CreatePolygon(World, vertices, 20, new Vector2(-5.0f, 8.0f));

            hexCharacter.BodyType        = BodyType.Dynamic;
            hexCharacter.FixedRotation   = true;
            hexCharacter.SleepingAllowed = false;

            // Circle character
            Body circleCharacter = BodyFactory.CreateCircle(World, 0.5f, 20, new Vector2(3.0f, 5.0f));

            circleCharacter.BodyType        = BodyType.Dynamic;
            circleCharacter.FixedRotation   = true;
            circleCharacter.SleepingAllowed = false;

            // Circle character
            _character                 = BodyFactory.CreateCircle(World, 0.25f, 20, new Vector2(-7.0f, 6.0f));
            _character.BodyType        = BodyType.Dynamic;
            _character.Friction        = 1.0f;
            _character.SleepingAllowed = false;
        }
Ejemplo n.º 35
0
        private CollisionProcessingTest()
        {
            //Ground
            BodyFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));

            const float xLo = -5.0f;
            const float xHi = 5.0f;
            const float yLo = 2.0f;
            const float yHi = 35.0f;

            // Small triangle
            Vertices vertices = new Vertices(3);

            vertices.Add(new Vector2(-1.0f, 0.0f));
            vertices.Add(new Vector2(1.0f, 0.0f));
            vertices.Add(new Vector2(0.0f, 2.0f));

            PolygonShape polygon = new PolygonShape(vertices, 1);

            Body body1 = BodyFactory.CreateBody(World);

            body1.BodyType = BodyType.Dynamic;
            body1.Position = new Vector2(Rand.RandomFloat(xLo, xHi), Rand.RandomFloat(yLo, yHi));

            Fixture fixture = body1.CreateFixture(polygon);

            fixture.OnCollision += OnCollision;

            // Large triangle (recycle definitions)
            vertices[0]     *= 2.0f;
            vertices[1]     *= 2.0f;
            vertices[2]     *= 2.0f;
            polygon.Vertices = vertices;

            Body body2 = BodyFactory.CreateBody(World);

            body2.BodyType       = BodyType.Dynamic;
            body2.Position       = new Vector2(Rand.RandomFloat(xLo, xHi), Rand.RandomFloat(yLo, yHi));
            fixture              = body2.CreateFixture(polygon);
            fixture.OnCollision += OnCollision;

            // Small box
            Vertices smallBox = PolygonUtils.CreateRectangle(1.0f, 0.5f);

            polygon.Vertices = smallBox;

            Body body3 = BodyFactory.CreateBody(World);

            body3.BodyType       = BodyType.Dynamic;
            body3.Position       = new Vector2(Rand.RandomFloat(xLo, xHi), Rand.RandomFloat(yLo, yHi));
            fixture              = body3.CreateFixture(polygon);
            fixture.OnCollision += OnCollision;

            // Large box (recycle definitions)
            Vertices largeBox = PolygonUtils.CreateRectangle(2.0f, 1.0f);

            polygon.Vertices = largeBox;

            Body body4 = BodyFactory.CreateBody(World);

            body4.BodyType       = BodyType.Dynamic;
            body4.Position       = new Vector2(Rand.RandomFloat(xLo, xHi), Rand.RandomFloat(yLo, yHi));
            fixture              = body4.CreateFixture(polygon);
            fixture.OnCollision += OnCollision;

            // Small circle
            CircleShape circle = new CircleShape(1.0f, 1);

            Body body5 = BodyFactory.CreateBody(World);

            body5.BodyType       = BodyType.Dynamic;
            body5.Position       = new Vector2(Rand.RandomFloat(xLo, xHi), Rand.RandomFloat(yLo, yHi));
            fixture              = body5.CreateFixture(circle);
            fixture.OnCollision += OnCollision;

            // Large circle
            circle.Radius *= 2.0f;

            Body body6 = BodyFactory.CreateBody(World);

            body6.BodyType       = BodyType.Dynamic;
            body6.Position       = new Vector2(Rand.RandomFloat(xLo, xHi), Rand.RandomFloat(yLo, yHi));
            fixture              = body6.CreateFixture(circle);
            fixture.OnCollision += OnCollision;
        }
Ejemplo n.º 36
0
 /// <summary>
 /// Добавление новой вершины
 /// </summary>
 /// <param name="vertex"></param>
 public void AddVertex(Point vertex)
 {
     Vertices.Add(vertex);
 }
Ejemplo n.º 37
0
        private PinballTest()
        {
            // Ground body
            Body ground;
            {
                ground = World.CreateBody();

                Vertices vertices = new Vertices(5);
                vertices.Add(new Vector2(0.0f, -2.0f));
                vertices.Add(new Vector2(8.0f, 6.0f));
                vertices.Add(new Vector2(8.0f, 20.0f));
                vertices.Add(new Vector2(-8.0f, 20.0f));
                vertices.Add(new Vector2(-8.0f, 6.0f));

                ChainShape chain = new ChainShape(vertices, true);
                ground.CreateFixture(chain);
            }

            // Flippers
            {
                Vector2 p1 = new Vector2(-2.0f, 0f);
                Vector2 p2 = new Vector2(2.0f, 0f);

                Body leftFlipper = World.CreateBody(p1);
                leftFlipper.BodyType = BodyType.Dynamic;
                Body rightFlipper = World.CreateBody(p2);
                rightFlipper.BodyType = BodyType.Dynamic;

                PolygonShape box = new PolygonShape(1);
                box.Vertices = PolygonTools.CreateRectangle(1.75f, 0.1f);

                leftFlipper.CreateFixture(box);
                rightFlipper.CreateFixture(box);

                _leftJoint = new RevoluteJoint(ground, leftFlipper, p1, Vector2.Zero);
                _leftJoint.MaxMotorTorque = 1000.0f;
                _leftJoint.LimitEnabled   = true;
                _leftJoint.MotorEnabled   = true;
                _leftJoint.MotorSpeed     = 0.0f;
                _leftJoint.LowerLimit     = -30.0f * MathHelper.Pi / 180.0f;
                _leftJoint.UpperLimit     = 5.0f * MathHelper.Pi / 180.0f;
                World.Add(_leftJoint);

                _rightJoint = new RevoluteJoint(ground, rightFlipper, p2, Vector2.Zero);
                _rightJoint.MaxMotorTorque = 1000.0f;
                _rightJoint.LimitEnabled   = true;
                _rightJoint.MotorEnabled   = true;
                _rightJoint.MotorSpeed     = 0.0f;
                _rightJoint.LowerLimit     = -5.0f * MathHelper.Pi / 180.0f;
                _rightJoint.UpperLimit     = 30.0f * MathHelper.Pi / 180.0f;
                World.Add(_rightJoint);
            }

            // Circle character
            {
                _ball          = World.CreateBody(new Vector2(1.0f, 15.0f));
                _ball.BodyType = BodyType.Dynamic;
                _ball.IsBullet = true;
                _ball.CreateFixture(new CircleShape(0.2f, 1.0f));
            }
        }
        //From Eric Jordan's convex decomposition library

        /// <summary>
        /// Merges all parallel edges in the list of vertices
        /// </summary>
        /// <param name="vertices">The vertices.</param>
        /// <param name="tolerance">The tolerance.</param>
        public static void MergeParallelEdges(Vertices vertices, float tolerance)
        {
            if (vertices.Count <= 3)
            {
                return; //Can't do anything useful here to a triangle
            }
            bool[] mergeMe      = new bool[vertices.Count];
            int    newNVertices = vertices.Count;

            //Gather points to process
            for (int i = 0; i < vertices.Count; ++i)
            {
                int lower  = (i == 0) ? (vertices.Count - 1) : (i - 1);
                int middle = i;
                int upper  = (i == vertices.Count - 1) ? (0) : (i + 1);

                float dx0   = vertices[middle].X - vertices[lower].X;
                float dy0   = vertices[middle].Y - vertices[lower].Y;
                float dx1   = vertices[upper].Y - vertices[middle].X;
                float dy1   = vertices[upper].Y - vertices[middle].Y;
                float norm0 = (float)Math.Sqrt(dx0 * dx0 + dy0 * dy0);
                float norm1 = (float)Math.Sqrt(dx1 * dx1 + dy1 * dy1);

                if (!(norm0 > 0.0f && norm1 > 0.0f) && newNVertices > 3)
                {
                    //Merge identical points
                    mergeMe[i] = true;
                    --newNVertices;
                }

                dx0 /= norm0;
                dy0 /= norm0;
                dx1 /= norm1;
                dy1 /= norm1;
                float cross = dx0 * dy1 - dx1 * dy0;
                float dot   = dx0 * dx1 + dy0 * dy1;

                if (Math.Abs(cross) < tolerance && dot > 0 && newNVertices > 3)
                {
                    mergeMe[i] = true;
                    --newNVertices;
                }
                else
                {
                    mergeMe[i] = false;
                }
            }

            if (newNVertices == vertices.Count || newNVertices == 0)
            {
                return;
            }

            int currIndex = 0;

            //Copy the vertices to a new list and clear the old
            Vertices oldVertices = new Vertices(vertices);

            vertices.Clear();

            for (int i = 0; i < oldVertices.Count; ++i)
            {
                if (mergeMe[i] || newNVertices == 0 || currIndex == newNVertices)
                {
                    continue;
                }

                Debug.Assert(currIndex < newNVertices);

                vertices.Add(oldVertices[i]);
                ++currIndex;
            }
        }
Ejemplo n.º 39
0
        public List <Vertices> DetectVertices()
        {
            #region Check TextureConverter setup.

            if (_data == null)
            {
                throw new Exception("'_data' can't be null. You have to use SetTextureData(uint[] data, int width) before calling this method.");
            }

            if (_data.Length < 4)
            {
                throw new Exception("'_data' length can't be less then 4. Your texture must be at least 2 x 2 pixels in size. " +
                                    "You have to use SetTextureData(uint[] data, int width) before calling this method.");
            }

            if (_width < 2)
            {
                throw new Exception("'_width' can't be less then 2. Your texture must be at least 2 x 2 pixels in size. " +
                                    "You have to use SetTextureData(uint[] data, int width) before calling this method.");
            }

            if (_data.Length % _width != 0)
            {
                throw new Exception("'_width' has an invalid value. You have to use SetTextureData(uint[] data, int width) before calling this method.");
            }

            #endregion

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

            Vector2?holeEntrance    = null;
            Vector2?polygonEntrance = null;

            List <Vector2> blackList = new List <Vector2>();

            bool searchOn;
            do
            {
                Vertices polygon;
                if (detectedPolygons.Count == 0)
                {
                    // First pass / single polygon
                    polygon = new Vertices(CreateSimplePolygon(Vector2.Zero, Vector2.Zero));

                    if (polygon.Count > 2)
                    {
                        polygonEntrance = GetTopMostVertex(polygon);
                    }
                }
                else if (polygonEntrance.HasValue)
                {
                    // Multi pass / multiple polygons
                    polygon = new Vertices(CreateSimplePolygon(polygonEntrance.Value, new Vector2(polygonEntrance.Value.X - 1f, polygonEntrance.Value.Y)));
                }
                else
                {
                    break;
                }

                searchOn = false;


                if (polygon.Count > 2)
                {
                    if (_holeDetection)
                    {
                        do
                        {
                            holeEntrance = SearchHoleEntrance(polygon, holeEntrance);

                            if (holeEntrance.HasValue)
                            {
                                if (!blackList.Contains(holeEntrance.Value))
                                {
                                    blackList.Add(holeEntrance.Value);
                                    Vertices holePolygon = CreateSimplePolygon(holeEntrance.Value,
                                                                               new Vector2(holeEntrance.Value.X + 1, holeEntrance.Value.Y));

                                    if (holePolygon != null && holePolygon.Count > 2)
                                    {
                                        switch (_polygonDetectionType)
                                        {
                                        case VerticesDetectionType.Integrated:

                                            // Add first hole polygon vertex to close the hole polygon.
                                            holePolygon.Add(holePolygon[0]);

                                            int vertex1Index, vertex2Index;
                                            if (SplitPolygonEdge(polygon, holeEntrance.Value, out vertex1Index, out vertex2Index))
                                            {
                                                polygon.InsertRange(vertex2Index, holePolygon);
                                            }

                                            break;

                                        case VerticesDetectionType.Separated:
                                            if (polygon.Holes == null)
                                            {
                                                polygon.Holes = new List <Vertices>();
                                            }

                                            polygon.Holes.Add(holePolygon);
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }while (true);
                    }

                    detectedPolygons.Add(polygon);
                }

                if (_multipartDetection || polygon.Count <= 2)
                {
                    if (SearchNextHullEntrance(detectedPolygons, polygonEntrance.Value, out polygonEntrance))
                    {
                        searchOn = true;
                    }
                }
            }while (searchOn);

            if (detectedPolygons == null || (detectedPolygons != null && detectedPolygons.Count == 0))
            {
                throw new Exception("Couldn't detect any vertices.");
            }

            // Post processing.
            if (PolygonDetectionType == VerticesDetectionType.Separated) // Only when VerticesDetectionType.Separated? -> Recheck.
            {
                ApplyTriangulationCompatibleWinding(ref detectedPolygons);
            }

            if (_transform != Matrix.Identity)
            {
                ApplyTransform(ref detectedPolygons);
            }

            return(detectedPolygons);
        }
Ejemplo n.º 40
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="entrance"></param>
        /// <param name="last"></param>
        /// <returns></returns>
        private Vertices CreateSimplePolygon(Vector2 entrance, Vector2 last)
        {
            bool entranceFound = false;
            bool endOfHull     = false;

            Vertices polygon       = new Vertices(32);
            Vertices hullArea      = new Vertices(32);
            Vertices endOfHullArea = new Vertices(32);

            Vector2 current = Vector2.Zero;

            #region Entrance check

            // Get the entrance point. //todo: alle möglichkeiten testen
            if (entrance == Vector2.Zero || !InBounds(ref entrance))
            {
                entranceFound = SearchHullEntrance(out entrance);

                if (entranceFound)
                {
                    current = new Vector2(entrance.X - 1f, entrance.Y);
                }
            }
            else
            {
                if (IsSolid(ref entrance))
                {
                    if (IsNearPixel(ref entrance, ref last))
                    {
                        current       = last;
                        entranceFound = true;
                    }
                    else
                    {
                        Vector2 temp;
                        if (SearchNearPixels(false, ref entrance, out temp))
                        {
                            current       = temp;
                            entranceFound = true;
                        }
                        else
                        {
                            entranceFound = false;
                        }
                    }
                }
            }

            #endregion

            if (entranceFound)
            {
                polygon.Add(entrance);
                hullArea.Add(entrance);

                Vector2 next = entrance;

                do
                {
                    // Search in the pre vision list for an outstanding point.
                    Vector2 outstanding;
                    if (SearchForOutstandingVertex(hullArea, out outstanding))
                    {
                        if (endOfHull)
                        {
                            // We have found the next pixel, but is it on the last bit of the hull?
                            if (endOfHullArea.Contains(outstanding))
                            {
                                // Indeed.
                                polygon.Add(outstanding);
                            }

                            // That's enough, quit.
                            break;
                        }

                        // Add it and remove all vertices that don't matter anymore
                        // (all the vertices before the outstanding).
                        polygon.Add(outstanding);
                        hullArea.RemoveRange(0, hullArea.IndexOf(outstanding));
                    }

                    // Last point gets current and current gets next. Our little spider is moving forward on the hull ;).
                    last    = current;
                    current = next;

                    // Get the next point on hull.
                    if (GetNextHullPoint(ref last, ref current, out next))
                    {
                        // Add the vertex to a hull pre vision list.
                        hullArea.Add(next);
                    }
                    else
                    {
                        // Quit
                        break;
                    }

                    if (next == entrance && !endOfHull)
                    {
                        // It's the last bit of the hull, search on and exit at next found vertex.
                        endOfHull = true;
                        endOfHullArea.AddRange(hullArea);

                        // We don't want the last vertex to be the same as the first one, because it causes the triangulation code to crash.
                        if (endOfHullArea.Contains(entrance))
                        {
                            endOfHullArea.Remove(entrance);
                        }
                    }
                } while (true);
            }

            return(polygon);
        }
Ejemplo n.º 41
0
        //Melkman based convex hull algorithm contributed by Cowdozer

        /// <summary>
        /// Creates a convex hull.
        /// Note:
        /// 1. Vertices must be of a simple polygon, i.e. edges do not overlap.
        /// 2. Melkman does not work on point clouds
        /// </summary>
        /// <remarks>
        /// Implemented using Melkman's Convex Hull Algorithm - O(n) time complexity.
        /// Reference: http://www.ams.sunysb.edu/~jsbm/courses/345/melkman.pdf
        /// </remarks>
        /// <returns>A convex hull in counterclockwise winding order.</returns>
        public static Vertices GetConvexHull(Vertices vertices)
        {
            //With less than 3 vertices, this is about the best we can do for a convex hull
            if (vertices.Count < 3)
            {
                return(vertices);
            }

            //We'll never need a queue larger than the current number of Vertices +1
            //Create double-ended queue
            Vector2[] deque = new Vector2[vertices.Count + 1];
            int       qf = 3, qb = 0; //Queue front index, queue back index
            int       qfm1, qbm1;     //qfm1 = second element, qbm1 = second last element

            //Start by placing first 3 vertices in convex CCW order
            int   startIndex = 3;
            float k          = MathUtils.Area(vertices[0], vertices[1], vertices[2]);

            if (k == 0)
            {
                //Vertices are collinear.
                deque[0] = vertices[0];
                deque[1] = vertices[2]; //We can skip vertex 1 because it should be between 0 and 2
                deque[2] = vertices[0];
                qf       = 2;

                //Go until the end of the collinear sequence of vertices
                for (startIndex = 3; startIndex < vertices.Count; startIndex++)
                {
                    Vector2 tmp = vertices[startIndex];
                    if (MathUtils.Area(ref deque[0], ref deque[1], ref tmp) == 0) //This point is also collinear
                    {
                        deque[1] = vertices[startIndex];
                    }
                    else
                    {
                        break;
                    }
                }
            }
            else
            {
                deque[0] = deque[3] = vertices[2];
                if (k > 0)
                {
                    //Is Left.  Set deque = {2, 0, 1, 2}
                    deque[1] = vertices[0];
                    deque[2] = vertices[1];
                }
                else
                {
                    //Is Right. Set deque = {2, 1, 0, 2}
                    deque[1] = vertices[1];
                    deque[2] = vertices[0];
                }
            }

            qfm1 = qf == 0 ? deque.Length - 1 : qf - 1; //qfm1 = qf - 1;
            qbm1 = qb == deque.Length - 1 ? 0 : qb + 1; //qbm1 = qb + 1;

            //Add vertices one at a time and adjust convex hull as needed
            for (int i = startIndex; i < vertices.Count; i++)
            {
                Vector2 nextPt = vertices[i];

                //Ignore if it is already within the convex hull we have constructed
                if (MathUtils.Area(ref deque[qfm1], ref deque[qf], ref nextPt) > 0 &&
                    MathUtils.Area(ref deque[qb], ref deque[qbm1], ref nextPt) > 0)
                {
                    continue;
                }

                //Pop front until convex
                while (!(MathUtils.Area(ref deque[qfm1], ref deque[qf], ref nextPt) > 0))
                {
                    //Pop the front element from the queue
                    qf   = qfm1;                                //qf--;
                    qfm1 = qf == 0 ? deque.Length - 1 : qf - 1; //qfm1 = qf - 1;
                }
                //Add vertex to the front of the queue
                qf        = qf == deque.Length - 1 ? 0 : qf + 1; //qf++;
                qfm1      = qf == 0 ? deque.Length - 1 : qf - 1; //qfm1 = qf - 1;
                deque[qf] = nextPt;

                //Pop back until convex
                while (!(MathUtils.Area(ref deque[qb], ref deque[qbm1], ref nextPt) > 0))
                {
                    //Pop the back element from the queue
                    qb   = qbm1;                                //qb++;
                    qbm1 = qb == deque.Length - 1 ? 0 : qb + 1; //qbm1 = qb + 1;
                }
                //Add vertex to the back of the queue
                qb        = qb == 0 ? deque.Length - 1 : qb - 1; //qb--;
                qbm1      = qb == deque.Length - 1 ? 0 : qb + 1; //qbm1 = qb + 1;
                deque[qb] = nextPt;
            }

            //Create the convex hull from what is left in the deque
            Vertices convexHull = new Vertices(vertices.Count + 1);

            if (qb < qf)
            {
                for (int i = qb; i < qf; i++)
                {
                    convexHull.Add(deque[i]);
                }
            }
            else
            {
                for (int i = 0; i < qf; i++)
                {
                    convexHull.Add(deque[i]);
                }
                for (int i = qb; i < deque.Length; i++)
                {
                    convexHull.Add(deque[i]);
                }
            }
            return(convexHull);
        }
Ejemplo n.º 42
0
        //Andrew's monotone chain 2D convex hull algorithm.
        //Copyright 2001, softSurfer (www.softsurfer.com)

        /// <summary>
        /// Gets the convex hull.
        /// </summary>
        /// <remarks>
        /// http://www.softsurfer.com/Archive/algorithm_0109/algorithm_0109.htm
        /// </remarks>
        /// <returns></returns>
        public static Vertices GetConvexHull(Vertices P)
        {
            P.Sort(new PointComparer());

            Vector2[] H   = new Vector2[P.Count];
            Vertices  res = new Vertices();

            int n = P.Count;

            int bot, top = -1; // indices for bottom and top of the stack
            int i;             // array scan index

            // Get the indices of points with min x-coord and min|max y-coord
            int   minmin = 0, minmax;
            float xmin = P[0].X;

            for (i = 1; i < n; i++)
            {
                if (P[i].X != xmin)
                {
                    break;
                }
            }
            minmax = i - 1;
            if (minmax == n - 1)
            {
                // degenerate case: all x-coords == xmin
                H[++top] = P[minmin];
                if (P[minmax].Y != P[minmin].Y)                 // a nontrivial segment
                {
                    H[++top] = P[minmax];
                }
                H[++top] = P[minmin];                 // add polygon endpoint

                for (int j = 0; j < top + 1; j++)
                {
                    res.Add(H[j]);
                }

                return(res);
            }

            top = res.Count - 1;

            // Get the indices of points with max x-coord and min|max y-coord
            int   maxmin, maxmax = n - 1;
            float xmax = P[n - 1].X;

            for (i = n - 2; i >= 0; i--)
            {
                if (P[i].X != xmax)
                {
                    break;
                }
            }
            maxmin = i + 1;

            // Compute the lower hull on the stack H
            H[++top] = P[minmin];             // push minmin point onto stack
            i        = minmax;
            while (++i <= maxmin)
            {
                // the lower line joins P[minmin] with P[maxmin]
                if (MathUtils.Area(P[minmin], P[maxmin], P[i]) >= 0 && i < maxmin)
                {
                    continue;                   // ignore P[i] above or on the lower line
                }
                while (top > 0)                 // there are at least 2 points on the stack
                {
                    // test if P[i] is left of the line at the stack top
                    if (MathUtils.Area(H[top - 1], H[top], P[i]) > 0)
                    {
                        break;                         // P[i] is a new hull vertex
                    }
                    else
                    {
                        top--;                         // pop top point off stack
                    }
                }
                H[++top] = P[i];                 // push P[i] onto stack
            }

            // Next, compute the upper hull on the stack H above the bottom hull
            if (maxmax != maxmin)     // if distinct xmax points
            {
                H[++top] = P[maxmax]; // push maxmax point onto stack
            }
            bot = top;                // the bottom point of the upper hull stack
            i   = maxmin;
            while (--i >= minmax)
            {
                // the upper line joins P[maxmax] with P[minmax]
                if (MathUtils.Area(P[maxmax], P[minmax], P[i]) >= 0 && i > minmax)
                {
                    continue;                     // ignore P[i] below or on the upper line
                }
                while (top > bot)                 // at least 2 points on the upper stack
                {
                    // test if P[i] is left of the line at the stack top
                    if (MathUtils.Area(H[top - 1], H[top], P[i]) > 0)
                    {
                        break;                         // P[i] is a new hull vertex
                    }
                    else
                    {
                        top--;                         // pop top point off stack
                    }
                }
                H[++top] = P[i];                 // push P[i] onto stack
            }
            if (minmax != minmin)
            {
                H[++top] = P[minmin];                 // push joining endpoint onto stack
            }
            for (int j = 0; j < top + 1; j++)
            {
                res.Add(H[j]);
            }

            return(res);
        }
        private SerializationTest()
        {
            Body ground = BodyFactory.CreateEdge(World, new Vector2(-20, 0), new Vector2(20, 0));

            //Friction and distance joint
            {
                Body bodyA = BodyFactory.CreateCircle(World, 1, 1.5f, new Vector2(10, 25));
                bodyA.BodyType = BodyType.Dynamic;

                Body bodyB = BodyFactory.CreateRectangle(World, 1, 1, 1, new Vector2(-1, 25));
                bodyB.BodyType = BodyType.Dynamic;

                FrictionJoint frictionJoint = JointFactory.CreateFrictionJoint(World, bodyB, ground, Vector2.Zero);
                frictionJoint.CollideConnected = true;
                frictionJoint.MaxForce         = 100;

                JointFactory.CreateDistanceJoint(World, bodyA, bodyB);
            }

            //Wheel joint
            {
                Vertices vertices = new Vertices(6);
                vertices.Add(new Vector2(-1.5f, -0.5f));
                vertices.Add(new Vector2(1.5f, -0.5f));
                vertices.Add(new Vector2(1.5f, 0.0f));
                vertices.Add(new Vector2(0.0f, 0.9f));
                vertices.Add(new Vector2(-1.15f, 0.9f));
                vertices.Add(new Vector2(-1.5f, 0.2f));

                Body carBody = BodyFactory.CreatePolygon(World, vertices, 1, new Vector2(0, 1));
                carBody.BodyType = BodyType.Dynamic;

                Body wheel1 = BodyFactory.CreateCircle(World, 0.4f, 1, new Vector2(-1.0f, 0.35f));
                wheel1.BodyType = BodyType.Dynamic;
                wheel1.Friction = 0.9f;

                Body wheel2 = BodyFactory.CreateCircle(World, 0.4f, 1, new Vector2(1.0f, 0.4f));
                wheel2.BodyType = BodyType.Dynamic;
                wheel2.Friction = 0.9f;

                Vector2 axis = new Vector2(0.0f, 1.0f);

                WheelJoint spring1 = JointFactory.CreateWheelJoint(World, carBody, wheel1, axis);
                spring1.MotorSpeed     = 0.0f;
                spring1.MaxMotorTorque = 20.0f;
                spring1.MotorEnabled   = true;
                spring1.Frequency      = 4;
                spring1.DampingRatio   = 0.7f;

                WheelJoint spring2 = JointFactory.CreateWheelJoint(World, carBody, wheel2, axis);
                spring2.MotorSpeed     = 0.0f;
                spring2.MaxMotorTorque = 10.0f;
                spring2.MotorEnabled   = false;
                spring2.Frequency      = 4;
                spring2.DampingRatio   = 0.7f;
            }

            //Prismatic joint
            {
                Body body = BodyFactory.CreateRectangle(World, 2, 2, 5, new Vector2(-10.0f, 10.0f));
                body.BodyType = BodyType.Dynamic;
                body.Rotation = 0.5f * Settings.Pi;

                Vector2 axis = new Vector2(2.0f, 1.0f);
                axis.Normalize();

                PrismaticJoint joint = JointFactory.CreatePrismaticJoint(World, ground, body, Vector2.Zero, axis);
                joint.MotorSpeed    = 5.0f;
                joint.MaxMotorForce = 1000.0f;
                joint.MotorEnabled  = true;
                joint.LowerLimit    = -10.0f;
                joint.UpperLimit    = 20.0f;
                joint.LimitEnabled  = true;
            }

            // Pulley joint
            {
                Body body1 = BodyFactory.CreateRectangle(World, 2, 4, 5, new Vector2(-10.0f, 16.0f));
                body1.BodyType = BodyType.Dynamic;

                Body body2 = BodyFactory.CreateRectangle(World, 2, 4, 5, new Vector2(10.0f, 16.0f));
                body2.BodyType = BodyType.Dynamic;

                Vector2 anchor1      = new Vector2(-10.0f, 16.0f + 2.0f);
                Vector2 anchor2      = new Vector2(10.0f, 16.0f + 2.0f);
                Vector2 worldAnchor1 = new Vector2(-10.0f, 16.0f + 2.0f + 12.0f);
                Vector2 worldAnchor2 = new Vector2(10.0f, 16.0f + 2.0f + 12.0f);

                JointFactory.CreatePulleyJoint(World, body1, body2, anchor1, anchor2, worldAnchor1, worldAnchor2, 1.5f, true);
            }

            //Revolute joint
            {
                Body ball = BodyFactory.CreateCircle(World, 3.0f, 5.0f, new Vector2(5.0f, 30.0f));
                ball.BodyType = BodyType.Dynamic;

                Body polygonBody = BodyFactory.CreateRectangle(World, 20, 0.4f, 2, new Vector2(10, 10));
                polygonBody.BodyType = BodyType.Dynamic;
                polygonBody.IsBullet = true;

                RevoluteJoint joint = JointFactory.CreateRevoluteJoint(World, ground, polygonBody, new Vector2(10, 0));
                joint.LowerLimit   = -0.25f * Settings.Pi;
                joint.UpperLimit   = 0.0f * Settings.Pi;
                joint.LimitEnabled = true;
            }

            //Weld joint
            {
                PolygonShape shape = new PolygonShape(PolygonUtils.CreateRectangle(0.5f, 0.125f), 20);

                Body prevBody = ground;
                for (int i = 0; i < 10; ++i)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-14.5f + 1.0f * i, 5.0f);
                    body.CreateFixture(shape);

                    Vector2 anchor = new Vector2(0.5f, 0);

                    if (i == 0)
                    {
                        anchor = new Vector2(-15f, 5);
                    }

                    JointFactory.CreateWeldJoint(World, prevBody, body, anchor, new Vector2(-0.5f, 0));
                    prevBody = body;
                }
            }

            //Rope joint
            {
                LinkFactory.CreateChain(World, new Vector2(-10, 10), new Vector2(-20, 10), 0.1f, 0.5f, 10, 0.1f, true);
            }

            //Angle joint
            {
                Body fA = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(-5, 4));
                fA.BodyType = BodyType.Dynamic;
                fA.Rotation = (float)(Math.PI / 3);

                Body fB = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(5, 4));
                fB.BodyType = BodyType.Dynamic;

                AngleJoint joint = new AngleJoint(fA, fB);
                joint.TargetAngle = (float)Math.PI / 2;
                World.AddJoint(joint);
            }

            //Motor joint
            {
                Body body = BodyFactory.CreateRectangle(World, 4, 1, 2, new Vector2(0, 35));
                body.BodyType = BodyType.Dynamic;
                body.Friction = 0.6f;

                MotorJoint motorJoint = JointFactory.CreateMotorJoint(World, ground, body);
                motorJoint.MaxForce      = 1000.0f;
                motorJoint.MaxTorque     = 1000.0f;
                motorJoint.LinearOffset  = new Vector2(0, 35);
                motorJoint.AngularOffset = (float)(Math.PI / 3f);
            }
        }
Ejemplo n.º 44
0
        private void ReadBody(List <string> section, PlyElement element)
        {
            foreach (string line in section)
            {
                string[] tokens = line.Split(splitter, StringSplitOptions.RemoveEmptyEntries);
                if (element.Type == PlyElementType.vertex)
                {
                    float[]   floatTokens = new float[tokens.Length];
                    PlyVertex Vertex      = new PlyVertex();
                    for (int i = 0; i < tokens.Length; i++)
                    {
                        string          typeName = element.Properties[i].TypeName;
                        string          name     = element.Properties[i].Name;
                        PlyPropertyType propType = element.Properties[i].Type;
                        byte            r        = 0;
                        byte            g        = 0;
                        byte            b        = 0;
                        if (propType == PlyPropertyType.x)
                        {
                            Vertex.X = float.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.y)
                        {
                            Vertex.Y = float.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.z)
                        {
                            Vertex.Z = float.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.nx)
                        {
                            Vertex.Normal.X = double.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.ny)
                        {
                            Vertex.Normal.Y = double.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.nz)
                        {
                            Vertex.Normal.Z = double.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.red)
                        {
                            r = byte.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.green)
                        {
                            g = byte.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.blue)
                        {
                            b = byte.Parse(tokens[i]);
                        }
                        Vertex.Col = System.Drawing.Color.FromArgb(r, g, b);
                    }

                    Vertices.Add(Vertex);
                }
                if (element.Type == PlyElementType.face)
                {
                    var indexList = new List <int>();
                    for (int i = 1; i < tokens.Length; i++)
                    {
                        int temp = int.Parse(tokens[i]);
                        indexList.Add(temp);
                    }
                    Faces.Add(new PlyFace(indexList));
                }
                if (element.Type == PlyElementType.edge)
                {
                    PlyEdge edge = new PlyEdge(element.containsColor);
                    for (int i = 0; i < tokens.Length; i++)
                    {
                        string          typeName = element.Properties[i].TypeName;
                        string          name     = element.Properties[i].Name;
                        PlyPropertyType propType = element.Properties[i].Type;
                        byte            r        = 0;
                        byte            b        = 0;
                        byte            g        = 0;

                        if (propType == PlyPropertyType.red)
                        {
                            r = byte.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.green)
                        {
                            g = byte.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.blue)
                        {
                            b = byte.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.vertex1)
                        {
                            edge.Vertex1 = int.Parse(tokens[i]);
                        }
                        if (propType == PlyPropertyType.vertex2)
                        {
                            edge.Vertex2 = int.Parse(tokens[i]);
                        }
                        edge.Color = System.Drawing.Color.FromArgb(r, g, b);
                    }
                    Edges.Add(edge);
                }
                if (element.Type == PlyElementType.material)
                {
                    for (int i = 0; i < tokens.Length; i++)
                    {
                    }
                }
                if (element.Type == PlyElementType.other)
                {
                    for (int i = 0; i < tokens.Length; i++)
                    {
                    }
                }
            }
        }
Ejemplo n.º 45
0
        private CantileverTest()
        {
            Body ground = World.CreateEdge(new Vector2(-40, 0), new Vector2(40, 0));

            {
                PolygonShape shape = new PolygonShape(20);
                shape.Vertices = PolygonTools.CreateRectangle(0.5f, 0.125f);

                Body prevBody = ground;
                for (int i = 0; i < Count; ++i)
                {
                    Body body = World.CreateBody();
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-14.5f + 1.0f * i, 5.0f);
                    body.CreateFixture(shape);

                    Vector2   anchor = new Vector2(-15.0f + 1.0f * i, 5.0f);
                    WeldJoint jd     = new WeldJoint(prevBody, body, anchor, anchor, true);
                    World.Add(jd);

                    prevBody = body;
                }
            }

            {
                PolygonShape shape = new PolygonShape(20f);
                shape.Vertices = PolygonTools.CreateRectangle(1f, 0.125f);

                Body prevBody = ground;
                for (int i = 0; i < 3; ++i)
                {
                    Body body = World.CreateBody();
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-14.0f + 2.0f * i, 15.0f);
                    body.CreateFixture(shape);

                    Vector2   anchor = new Vector2(-15.0f + 2.0f * i, 15.0f);
                    WeldJoint jd     = new WeldJoint(prevBody, body, anchor, anchor, true);
                    jd.FrequencyHz  = 5.0f;
                    jd.DampingRatio = 0.7f;
                    World.Add(jd);

                    prevBody = body;
                }
            }

            {
                PolygonShape shape = new PolygonShape(20f);
                shape.Vertices = PolygonTools.CreateRectangle(0.5f, 0.125f);

                Body prevBody = ground;
                for (int i = 0; i < Count; ++i)
                {
                    Body body = World.CreateBody();
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-4.5f + 1.0f * i, 5.0f);

                    body.CreateFixture(shape);

                    if (i > 0)
                    {
                        Vector2   anchor = new Vector2(-5.0f + 1.0f * i, 5.0f);
                        WeldJoint jd     = new WeldJoint(prevBody, body, anchor, anchor, true);
                        World.Add(jd);
                    }

                    prevBody = body;
                }
            }

            {
                PolygonShape shape = new PolygonShape(20f);
                shape.Vertices = PolygonTools.CreateRectangle(0.5f, 0.125f);

                Body prevBody = ground;
                for (int i = 0; i < Count; ++i)
                {
                    Body body = World.CreateBody();
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(5.5f + 1.0f * i, 10.0f);

                    body.CreateFixture(shape);

                    if (i > 0)
                    {
                        Vector2   anchor = new Vector2(5.0f + 1.0f * i, 10.0f);
                        WeldJoint jd     = new WeldJoint(prevBody, body, anchor, anchor, true);
                        jd.FrequencyHz  = 8.0f;
                        jd.DampingRatio = 0.7f;

                        World.Add(jd);
                    }

                    prevBody = body;
                }
            }

            //Triangels
            Vertices vertices = new Vertices(3);

            vertices.Add(new Vector2(-0.5f, 0.0f));
            vertices.Add(new Vector2(0.5f, 0.0f));
            vertices.Add(new Vector2(0.0f, 1.5f));

            for (int i = 0; i < 2; ++i)
            {
                PolygonShape shape = new PolygonShape(vertices, 1);

                Body body = World.CreateBody();
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(-8.0f + 8.0f * i, 12.0f);

                body.CreateFixture(shape);
            }

            //Circles
            for (int i = 0; i < 2; ++i)
            {
                CircleShape shape = new CircleShape(0.5f, 1);

                Body body = World.CreateBody();
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(-6.0f + 6.0f * i, 10.0f);

                body.CreateFixture(shape);
            }
        }
Ejemplo n.º 46
0
        /// <summary>
        /// Calculates the polygon(s) from the result simplical chain.
        /// </summary>
        /// <remarks>Used by method <c>Execute()</c>.</remarks>
        private static PolyClipError BuildPolygonsFromChain(List <Edge> simplicies, out List <Vertices> result)
        {
            result = new List <Vertices>();
            PolyClipError errVal = PolyClipError.None;

            while (simplicies.Count > 0)
            {
                Vertices output = new Vertices();
                output.Add(simplicies[0].EdgeStart);
                output.Add(simplicies[0].EdgeEnd);
                simplicies.RemoveAt(0);
                bool closed = false;
                int  index  = 0;
                int  count  = simplicies.Count; // Needed to catch infinite loops
                while (!closed && simplicies.Count > 0)
                {
                    if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeStart))
                    {
                        if (VectorEqual(simplicies[index].EdgeEnd, output[0]))
                        {
                            closed = true;
                        }
                        else
                        {
                            output.Add(simplicies[index].EdgeEnd);
                        }
                        simplicies.RemoveAt(index);
                        --index;
                    }
                    else if (VectorEqual(output[output.Count - 1], simplicies[index].EdgeEnd))
                    {
                        if (VectorEqual(simplicies[index].EdgeStart, output[0]))
                        {
                            closed = true;
                        }
                        else
                        {
                            output.Add(simplicies[index].EdgeStart);
                        }
                        simplicies.RemoveAt(index);
                        --index;
                    }
                    if (!closed)
                    {
                        if (++index == simplicies.Count)
                        {
                            if (count == simplicies.Count)
                            {
                                result = new List <Vertices>();
                                Debug.WriteLine("Undefined error while building result polygon(s).");
                                return(PolyClipError.BrokenResult);
                            }
                            index = 0;
                            count = simplicies.Count;
                        }
                    }
                }
                if (output.Count < 3)
                {
                    errVal = PolyClipError.DegeneratedOutput;
                    Debug.WriteLine("Degenerated output polygon produced (vertices < 3).");
                }
                result.Add(output);
            }
            return(errVal);
        }
Ejemplo n.º 47
0
        //Extracted from Box2D

        /// <summary>Returns the convex hull from the given vertices.</summary>
        /// <param name="vertices">The vertices.</param>
        public static Vertices GetConvexHull(Vertices vertices)
        {
            if (vertices.Count <= 3)
            {
                return(vertices);
            }

            // Find the right most point on the hull
            int   i0 = 0;
            float x0 = vertices[0].X;

            for (int i = 1; i < vertices.Count; ++i)
            {
                float x = vertices[i].X;
                if (x > x0 || x == x0 && vertices[i].Y < vertices[i0].Y)
                {
                    i0 = i;
                    x0 = x;
                }
            }

            int[] hull = new int[vertices.Count];
            int   m    = 0;
            int   ih   = i0;

            for (;;)
            {
                hull[m] = ih;

                int ie = 0;
                for (int j = 1; j < vertices.Count; ++j)
                {
                    if (ie == ih)
                    {
                        ie = j;
                        continue;
                    }

                    Vector2 r = vertices[ie] - vertices[hull[m]];
                    Vector2 v = vertices[j] - vertices[hull[m]];
                    float   c = MathUtils.Cross(ref r, ref v);
                    if (c < 0.0f)
                    {
                        ie = j;
                    }

                    // Collinearity check
                    if (c == 0.0f && v.LengthSquared() > r.LengthSquared())
                    {
                        ie = j;
                    }
                }

                ++m;
                ih = ie;

                if (ie == i0)
                {
                    break;
                }
            }

            Vertices result = new Vertices(m);

            // Copy vertices.
            for (int i = 0; i < m; ++i)
            {
                result.Add(vertices[hull[i]]);
            }

            return(result);
        }
        /// <summary>
        /// Turns a list of triangles into a list of convex polygons. Very simple
        /// method - start with a seed triangle, keep adding triangles to it until
        /// you can't add any more without making the polygon non-convex.
        ///
        /// Returns an integer telling how many polygons were created.  Will fill
        /// polys array up to polysLength entries, which may be smaller or larger
        /// than the return value.
        ///
        /// Takes O(N/// P) where P is the number of resultant polygons, N is triangle
        /// count.
        ///
        /// The final polygon list will not necessarily be minimal, though in
        /// practice it works fairly well.
        /// </summary>
        /// <param name="triangulated">The triangulated.</param>
        /// <param name="maxPolys"></param>
        /// <returns></returns>
        public static List <Vertices> PolygonizeTriangles(List <Triangle> triangulated, int maxPolys, float tolerance)
        {
            List <Vertices> polys = new List <Vertices>(50);

            int polyIndex = 0;

            if (triangulated.Count <= 0)
            {
                // return empty polygon list
                return(polys);
            }

            bool[] covered = new bool[triangulated.Count];
            for (int i = 0; i < triangulated.Count; ++i)
            {
                covered[i] = false;

                // Check here for degenerate triangles
                if (((triangulated[i].X[0] == triangulated[i].X[1]) && (triangulated[i].Y[0] == triangulated[i].Y[1]))
                    ||
                    ((triangulated[i].X[1] == triangulated[i].X[2]) && (triangulated[i].Y[1] == triangulated[i].Y[2]))
                    ||
                    ((triangulated[i].X[0] == triangulated[i].X[2]) && (triangulated[i].Y[0] == triangulated[i].Y[2])))
                {
                    covered[i] = true;
                }
            }

            bool notDone = true;

            while (notDone)
            {
                int currTri = -1;
                for (int i = 0; i < triangulated.Count; ++i)
                {
                    if (covered[i])
                    {
                        continue;
                    }
                    currTri = i;
                    break;
                }
                if (currTri == -1)
                {
                    notDone = false;
                }
                else
                {
                    Vertices poly = new Vertices(3);

                    for (int i = 0; i < 3; i++)
                    {
                        poly.Add(new Vector2(triangulated[currTri].X[i], triangulated[currTri].Y[i]));
                    }

                    covered[currTri] = true;
                    int index = 0;
                    for (int i = 0; i < 2 * triangulated.Count; ++i, ++index)
                    {
                        while (index >= triangulated.Count)
                        {
                            index -= triangulated.Count;
                        }
                        if (covered[index])
                        {
                            continue;
                        }
                        Vertices newP = AddTriangle(triangulated[index], poly);
                        if (newP == null)
                        {
                            continue; // is this right
                        }
                        if (newP.Count > Settings.MaxPolygonVertices)
                        {
                            continue;
                        }

                        if (newP.IsConvex())
                        {
                            // Or should it be IsUsable?  Maybe re-write IsConvex to apply the angle threshold from Box2d
                            poly           = new Vertices(newP);
                            covered[index] = true;
                        }
                    }

                    // We have a maximum of polygons that we need to keep under.
                    if (polyIndex < maxPolys)
                    {
                        SimplifyTools.MergeParallelEdges(poly, tolerance);

                        // If identical points are present, a triangle gets
                        // borked by the MergeParallelEdges function, hence
                        // the vertex number check
                        if (poly.Count >= 3)
                        {
                            polys.Add(new Vertices(poly));
                        }
                        // else
                        // printf("Skipping corrupt poly\n");
                    }
                    if (poly.Count >= 3)
                    {
                        polyIndex++; // Must be outside (polyIndex < polysLength) test
                    }
                }
            }

            return(polys);
        }
Ejemplo n.º 49
0
        /// <summary>
        /// This function makes a simple cube shape.
        /// </summary>
        private void CreateCubeGeometry()
        {
            UVs.Add(new UV(0, 0));
            UVs.Add(new UV(0, 1));
            UVs.Add(new UV(1, 1));
            UVs.Add(new UV(1, 0));

            //    Add the vertices.
            Vertices.Add(new Vertex(-1, -1, -1));
            Vertices.Add(new Vertex(1, -1, -1));
            Vertices.Add(new Vertex(1, -1, 1));
            Vertices.Add(new Vertex(-1, -1, 1));
            Vertices.Add(new Vertex(-1, 1, -1));
            Vertices.Add(new Vertex(1, 1, -1));
            Vertices.Add(new Vertex(1, 1, 1));
            Vertices.Add(new Vertex(-1, 1, 1));

            //    Add the faces.
            Face face = new Face();    //    bottom

            face.Indices.Add(new Index(1, 0));
            face.Indices.Add(new Index(2, 1));
            face.Indices.Add(new Index(3, 2));
            face.Indices.Add(new Index(0, 3));
            Faces.Add(face);

            face = new Face();        //    top
            face.Indices.Add(new Index(7, 0));
            face.Indices.Add(new Index(6, 1));
            face.Indices.Add(new Index(5, 2));
            face.Indices.Add(new Index(4, 3));
            Faces.Add(face);

            face = new Face();        //    right
            face.Indices.Add(new Index(5, 0));
            face.Indices.Add(new Index(6, 1));
            face.Indices.Add(new Index(2, 2));
            face.Indices.Add(new Index(1, 3));
            Faces.Add(face);

            face = new Face();        //    left
            face.Indices.Add(new Index(7, 0));
            face.Indices.Add(new Index(4, 1));
            face.Indices.Add(new Index(0, 2));
            face.Indices.Add(new Index(3, 3));
            Faces.Add(face);

            face = new Face();        // front
            face.Indices.Add(new Index(4, 0));
            face.Indices.Add(new Index(5, 1));
            face.Indices.Add(new Index(1, 2));
            face.Indices.Add(new Index(0, 3));
            Faces.Add(face);

            face = new Face();        //    back
            face.Indices.Add(new Index(6, 0));
            face.Indices.Add(new Index(7, 1));
            face.Indices.Add(new Index(3, 2));
            face.Indices.Add(new Index(2, 3));
            Faces.Add(face);
        }
Ejemplo n.º 50
0
        private ApplyForceTest()
        {
            World.Gravity = Vector2.Zero;

            const float restitution = 0.4f;

            Body ground;
            {
                ground          = BodyFactory.CreateBody(World);
                ground.Position = new Vector2(0.0f, 20.0f);

                EdgeShape shape = new EdgeShape(new Vector2(-20.0f, -20.0f), new Vector2(-20.0f, 20.0f));

                // Left vertical
                Fixture fixture = ground.CreateFixture(shape);
                fixture.Restitution = restitution;

                // Right vertical
                shape = new EdgeShape(new Vector2(20.0f, -20.0f), new Vector2(20.0f, 20.0f));
                ground.CreateFixture(shape);

                // Top horizontal
                shape = new EdgeShape(new Vector2(-20.0f, 20.0f), new Vector2(20.0f, 20.0f));
                ground.CreateFixture(shape);

                // Bottom horizontal
                shape = new EdgeShape(new Vector2(-20.0f, -20.0f), new Vector2(20.0f, -20.0f));
                ground.CreateFixture(shape);
            }

            {
                Transform xf1 = new Transform();
                xf1.q.Set(0.3524f * Settings.Pi);
                xf1.p = MathUtils.Mul(ref xf1.q, new Vector2(1.0f, 0.0f));

                Vertices vertices = new Vertices(3);
                vertices.Add(MathUtils.Mul(ref xf1, new Vector2(-1.0f, 0.0f)));
                vertices.Add(MathUtils.Mul(ref xf1, new Vector2(1.0f, 0.0f)));
                vertices.Add(MathUtils.Mul(ref xf1, new Vector2(0.0f, 0.5f)));

                PolygonShape poly1 = new PolygonShape(vertices, 4);

                Transform xf2 = new Transform();
                xf2.q.Set(-0.3524f * Settings.Pi);
                xf2.p = MathUtils.Mul(ref xf2.q, new Vector2(-1.0f, 0.0f));

                vertices[0] = MathUtils.Mul(ref xf2, new Vector2(-1.0f, 0.0f));
                vertices[1] = MathUtils.Mul(ref xf2, new Vector2(1.0f, 0.0f));
                vertices[2] = MathUtils.Mul(ref xf2, new Vector2(0.0f, 0.5f));

                PolygonShape poly2 = new PolygonShape(vertices, 2);

                _body                 = BodyFactory.CreateBody(World);
                _body.BodyType        = BodyType.Dynamic;
                _body.Position        = new Vector2(0.0f, 2.0f);
                _body.Rotation        = Settings.Pi;
                _body.AngularDamping  = 5.0f;
                _body.LinearDamping   = 0.8f;
                _body.SleepingAllowed = true;

                _body.CreateFixture(poly1);
                _body.CreateFixture(poly2);
            }

            {
                Vertices     box   = PolygonTools.CreateRectangle(0.5f, 0.5f);
                PolygonShape shape = new PolygonShape(box, 1);

                for (int i = 0; i < 10; ++i)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.Position = new Vector2(0.0f, 5.0f + 1.54f * i);
                    body.BodyType = BodyType.Dynamic;

                    Fixture fixture = body.CreateFixture(shape);
                    fixture.Friction = 0.3f;

                    const float gravity = 10.0f;
                    float       I       = body.Inertia;
                    float       mass    = body.Mass;

                    // For a circle: I = 0.5 * m * r * r ==> r = sqrt(2 * I / m)
                    float radius = (float)Math.Sqrt(2.0 * (I / mass));

                    FrictionJoint jd = new FrictionJoint(ground, body, Vector2.Zero);
                    jd.CollideConnected = true;
                    jd.MaxForce         = mass * gravity;
                    jd.MaxTorque        = mass * radius * gravity;

                    World.AddJoint(jd);
                }
            }
        }
Ejemplo n.º 51
0
        BridgeTest()
        {
            Body ground;
            {
                ground = new Body(World);

                EdgeShape shape = new EdgeShape(new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));
                ground.CreateFixture(shape);
            }
            {
                Vertices     box   = PolygonTools.CreateRectangle(0.5f, 0.125f);
                PolygonShape shape = new PolygonShape(box, 20);

                Body prevBody = ground;
                for (int i = 0; i < Count; ++i)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-14.5f + 1.0f * i, 5.0f);

                    Fixture fixture = body.CreateFixture(shape);
                    fixture.Friction = 0.2f;

                    Vector2       anchor = new Vector2(-15f + 1.0f * i, 5.0f);
                    RevoluteJoint jd     = new RevoluteJoint(prevBody, body, anchor, true);
                    World.AddJoint(jd);

                    prevBody = body;
                }

                Vector2       anchor2 = new Vector2(-15.0f + 1.0f * Count, 5.0f);
                RevoluteJoint jd2     = new RevoluteJoint(ground, prevBody, anchor2, true);
                World.AddJoint(jd2);
            }

            Vertices vertices = new Vertices(3);

            vertices.Add(new Vector2(-0.5f, 0.0f));
            vertices.Add(new Vector2(0.5f, 0.0f));
            vertices.Add(new Vector2(0.0f, 1.5f));

            for (int i = 0; i < 2; ++i)
            {
                PolygonShape shape = new PolygonShape(vertices, 1);

                Body body = BodyFactory.CreateBody(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(-8.0f + 8.0f * i, 12.0f);

                body.CreateFixture(shape);
            }

            for (int i = 0; i < 3; ++i)
            {
                CircleShape shape = new CircleShape(0.5f, 1);

                Body body = BodyFactory.CreateBody(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(-6.0f + 6.0f * i, 10.0f);

                body.CreateFixture(shape);
            }
        }
Ejemplo n.º 52
0
        /// <summary>Returns the convex hull from the given vertices..</summary>
        public static Vertices GetConvexHull(Vertices vertices)
        {
            if (vertices.Count <= 3)
            {
                return(vertices);
            }

            Vertices pointSet = new Vertices(vertices);

            //Sort by X-axis
            pointSet.Sort(PointComparerPrivate);

            Vector2[] h = new Vector2[pointSet.Count];
            Vertices  res;

            int top = -1; // indices for bottom and top of the stack
            int i;        // array scan index

            // Get the indices of points with min x-coord and min|max y-coord
            const int minmin = 0;
            float     xmin   = pointSet[0].X;

            for (i = 1; i < pointSet.Count; i++)
            {
                if (pointSet[i].X != xmin)
                {
                    break;
                }
            }

            // degenerate case: all x-coords == xmin
            int minmax = i - 1;

            if (minmax == pointSet.Count - 1)
            {
                h[++top] = pointSet[minmin];

                if (pointSet[minmax].Y != pointSet[minmin].Y) // a nontrivial segment
                {
                    h[++top] = pointSet[minmax];
                }

                h[++top] = pointSet[minmin]; // add polygon endpoint

                res = new Vertices(top + 1);
                for (int j = 0; j < top + 1; j++)
                {
                    res.Add(h[j]);
                }

                return(res);
            }

            top = -1;

            // Get the indices of points with max x-coord and min|max y-coord
            int   maxmax = pointSet.Count - 1;
            float xmax   = pointSet[pointSet.Count - 1].X;

            for (i = pointSet.Count - 2; i >= 0; i--)
            {
                if (pointSet[i].X != xmax)
                {
                    break;
                }
            }

            int maxmin = i + 1;

            // Compute the lower hull on the stack H
            h[++top] = pointSet[minmin]; // push minmin point onto stack
            i        = minmax;
            while (++i <= maxmin)
            {
                // the lower line joins P[minmin] with P[maxmin]
                if (MathUtils.Area(pointSet[minmin], pointSet[maxmin], pointSet[i]) >= 0 && i < maxmin)
                {
                    continue; // ignore P[i] above or on the lower line
                }

                while (top > 0) // there are at least 2 points on the stack
                {
                    // test if P[i] is left of the line at the stack top
                    if (MathUtils.Area(h[top - 1], h[top], pointSet[i]) > 0)
                    {
                        break; // P[i] is a new hull vertex
                    }

                    top--; // pop top point off stack
                }

                h[++top] = pointSet[i]; // push P[i] onto stack
            }

            // GetNext, compute the upper hull on the stack H above the bottom hull
            if (maxmax != maxmin)            // if distinct xmax points
            {
                h[++top] = pointSet[maxmax]; // push maxmax point onto stack
            }

            int bot = top;

            i = maxmin;
            while (--i >= minmax)
            {
                // the upper line joins P[maxmax] with P[minmax]
                if (MathUtils.Area(pointSet[maxmax], pointSet[minmax], pointSet[i]) >= 0 && i > minmax)
                {
                    continue; // ignore P[i] below or on the upper line
                }

                while (top > bot) // at least 2 points on the upper stack
                {
                    // test if P[i] is left of the line at the stack top
                    if (MathUtils.Area(h[top - 1], h[top], pointSet[i]) > 0)
                    {
                        break; // P[i] is a new hull vertex
                    }

                    top--; // pop top point off stack
                }

                h[++top] = pointSet[i]; // push P[i] onto stack
            }

            if (minmax != minmin)
            {
                h[++top] = pointSet[minmin]; // push joining endpoint onto stack
            }

            res = new Vertices(top + 1);

            for (int j = 0; j < top + 1; j++)
            {
                res.Add(h[j]);
            }

            return(res);
        }
Ejemplo n.º 53
0
        public Border(World world, PhysicsGameScreen screen, Viewport viewport)
        {
            _world  = world;
            _screen = screen;

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

            Vertices borders = new Vertices(4);

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

#if IPAD
            //Room on top
            borders.Add(new Vector2(halfWidth + 28, -halfHeight - 5));
            //Room on top
            borders.Add(new Vector2(-halfWidth - 28, -halfHeight - 5));
#else
            //Room on top
            borders.Add(new Vector2(halfWidth + 16, -halfHeight - 5));
            //Room on top
            borders.Add(new Vector2(-halfWidth - 16, -halfHeight - 5));
#endif

            _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/blank");

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

            _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];
        }
Ejemplo n.º 54
0
        private CarTest()
        {
            _hz    = 4.0f;
            _zeta  = 0.7f;
            _speed = 50.0f;

            Body ground = BodyFactory.CreateEdge(World, new Vector2(-20.0f, 0.0f), new Vector2(20.0f, 0.0f));
            {
                float[] hs = { 0.25f, 1.0f, 4.0f, 0.0f, 0.0f, -1.0f, -2.0f, -2.0f, -1.25f, 0.0f };

                float       x = 20.0f, y1 = 0.0f;
                const float dx = 5.0f;

                for (int i = 0; i < 10; ++i)
                {
                    float y2 = hs[i];
                    FixtureFactory.AttachEdge(new Vector2(x, y1), new Vector2(x + dx, y2), ground);
                    y1 = y2;
                    x += dx;
                }

                for (int i = 0; i < 10; ++i)
                {
                    float y2 = hs[i];
                    FixtureFactory.AttachEdge(new Vector2(x, y1), new Vector2(x + dx, y2), ground);
                    y1 = y2;
                    x += dx;
                }

                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 40.0f, 0.0f), ground);
                x += 80.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 40.0f, 0.0f), ground);
                x += 40.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 10.0f, 5.0f), ground);
                x += 20.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x + 40.0f, 0.0f), ground);
                x += 40.0f;
                FixtureFactory.AttachEdge(new Vector2(x, 0.0f), new Vector2(x, 20.0f), ground);

                ground.Friction = 0.6f;
            }

            // Teeter
            {
                Body body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(140.0f, 1.0f);

                PolygonShape box = new PolygonShape(1);
                box.Vertices = PolygonUtils.CreateRectangle(10.0f, 0.25f);
                body.CreateFixture(box);

                RevoluteJoint jd = JointFactory.CreateRevoluteJoint(World, ground, body, Vector2.Zero);
                jd.LowerLimit   = -8.0f * Settings.Pi / 180.0f;
                jd.UpperLimit   = 8.0f * Settings.Pi / 180.0f;
                jd.LimitEnabled = true;

                body.ApplyAngularImpulse(100.0f);
            }

            //Bridge
            {
                const int    N     = 20;
                PolygonShape shape = new PolygonShape(1);
                shape.Vertices = PolygonUtils.CreateRectangle(1.0f, 0.125f);

                Body prevBody = ground;
                for (int i = 0; i < N; ++i)
                {
                    Body body = new Body(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(161.0f + 2.0f * i, -0.125f);
                    Fixture fix = body.CreateFixture(shape);
                    fix.Friction = 0.6f;

                    Vector2 anchor = new Vector2(-1, 0);
                    JointFactory.CreateRevoluteJoint(World, prevBody, body, anchor);

                    prevBody = body;
                }

                Vector2 anchor2 = new Vector2(1.0f, 0);
                JointFactory.CreateRevoluteJoint(World, ground, prevBody, anchor2);
            }

            // Boxes
            {
                PolygonShape box = new PolygonShape(0.5f);
                box.Vertices = PolygonUtils.CreateRectangle(0.5f, 0.5f);

                Body body = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 0.5f);
                body.CreateFixture(box);

                body          = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 1.5f);
                body.CreateFixture(box);

                body          = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 2.5f);
                body.CreateFixture(box);

                body          = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 3.5f);
                body.CreateFixture(box);

                body          = new Body(World);
                body.BodyType = BodyType.Dynamic;
                body.Position = new Vector2(230.0f, 4.5f);
                body.CreateFixture(box);
            }

            // Car
            {
                Vertices vertices = new Vertices(8);
                vertices.Add(new Vector2(-1.5f, -0.5f));
                vertices.Add(new Vector2(1.5f, -0.5f));
                vertices.Add(new Vector2(1.5f, 0.0f));
                vertices.Add(new Vector2(0.0f, 0.9f));
                vertices.Add(new Vector2(-1.15f, 0.9f));
                vertices.Add(new Vector2(-1.5f, 0.2f));

                PolygonShape chassis = new PolygonShape(vertices, 1);

                CircleShape circle = new CircleShape(0.4f, 1);

                _car          = new Body(World);
                _car.BodyType = BodyType.Dynamic;
                _car.Position = new Vector2(0.0f, 1.0f);
                _car.CreateFixture(chassis);

                _wheel1          = new Body(World);
                _wheel1.BodyType = BodyType.Dynamic;
                _wheel1.Position = new Vector2(-1.0f, 0.35f);
                _wheel1.CreateFixture(circle);
                _wheel1.Friction = 0.9f;

                _wheel2          = new Body(World);
                _wheel2.BodyType = BodyType.Dynamic;
                _wheel2.Position = new Vector2(1.0f, 0.4f);
                _wheel2.CreateFixture(circle);
                _wheel2.Friction = 0.9f;

                Vector2 axis = new Vector2(0.0f, 1.0f);
                _spring1                = new WheelJoint(_car, _wheel1, _wheel1.Position, axis, true);
                _spring1.MotorSpeed     = 0.0f;
                _spring1.MaxMotorTorque = 20.0f;
                _spring1.MotorEnabled   = true;
                _spring1.Frequency      = _hz;
                _spring1.DampingRatio   = _zeta;
                World.AddJoint(_spring1);

                _spring2                = new WheelJoint(_car, _wheel2, _wheel2.Position, axis, true);
                _spring2.MotorSpeed     = 0.0f;
                _spring2.MaxMotorTorque = 10.0f;
                _spring2.MotorEnabled   = false;
                _spring2.Frequency      = _hz;
                _spring2.DampingRatio   = _zeta;
                World.AddJoint(_spring2);
            }
        }
Ejemplo n.º 55
0
        /// <summary>
        /// Activate the explosion at the specified position.
        /// </summary>
        /// <param name="pos">The position where the explosion happens </param>
        /// <param name="radius">The explosion radius </param>
        /// <param name="maxForce">The explosion force at the explosion point (then is inversely proportional to the square of the distance)</param>
        /// <returns>A list of bodies and the amount of force that was applied to them.</returns>
        public Dictionary <Fixture, Vector2> Activate(Vector2 pos, float radius, float maxForce)
        {
            AABB aabb;

            aabb.LowerBound = pos + new Vector2(-radius, -radius);
            aabb.UpperBound = pos + new Vector2(radius, radius);
            var shapes = new Fixture[MaxShapes];

            // More than 5 shapes in an explosion could be possible, but still strange.
            var  containedShapes = new Fixture[5];
            bool exit            = false;

            int shapeCount          = 0;
            int containedShapeCount = 0;

            // Query the world for overlapping shapes.
            World.QueryAABB(
                fixture =>
            {
                if (fixture.TestPoint(ref pos))
                {
                    if (IgnoreWhenInsideShape)
                    {
                        exit = true;
                        return(false);
                    }

                    containedShapes[containedShapeCount++] = fixture;
                }
                else
                {
                    shapes[shapeCount++] = fixture;
                }

                // Continue the query.
                return(true);
            }, ref aabb);

            if (exit)
            {
                return(new Dictionary <Fixture, Vector2>());
            }

            var exploded = new Dictionary <Fixture, Vector2>(shapeCount + containedShapeCount);

            // Per shape max/min angles for now.
            var vals     = new float[shapeCount * 2];
            int valIndex = 0;

            for (int i = 0; i < shapeCount; ++i)
            {
                PolygonShape ps;
                var          cs = shapes[i].Shape as CircleShape;
                if (cs != null)
                {
                    // We create a "diamond" approximation of the circle
                    var v   = new Vertices();
                    var vec = Vector2.Zero + new Vector2(cs.Radius, 0);
                    v.Add(vec);
                    vec = Vector2.Zero + new Vector2(0, cs.Radius);
                    v.Add(vec);
                    vec = Vector2.Zero + new Vector2(-cs.Radius, cs.Radius);
                    v.Add(vec);
                    vec = Vector2.Zero + new Vector2(0, -cs.Radius);
                    v.Add(vec);
                    ps = new PolygonShape(v, 0);
                }
                else
                {
                    ps = shapes[i].Shape as PolygonShape;
                }

                if ((shapes[i].Body.BodyType == BodyType.Dynamic) && ps != null)
                {
                    var toCentroid      = shapes[i].Body.GetWorldPoint(ps.MassData.Centroid) - pos;
                    var angleToCentroid = (float)Math.Atan2(toCentroid.Y, toCentroid.X);
                    var min             = float.MaxValue;
                    var max             = float.MinValue;
                    var minAbsolute     = 0.0f;
                    var maxAbsolute     = 0.0f;

                    for (var j = 0; j < ps.Vertices.Count; ++j)
                    {
                        var toVertex = (shapes[i].Body.GetWorldPoint(ps.Vertices[j]) - pos);
                        var newAngle = (float)Math.Atan2(toVertex.Y, toVertex.X);
                        var diff     = (newAngle - angleToCentroid);

                        diff = (diff - MathHelper.Pi) % (2 * MathHelper.Pi);

                        // the minus pi is important. It means cutoff for going other direction is at 180 deg where it needs to be

                        if (diff < 0.0f)
                        {
                            diff += 2 * MathHelper.Pi;                             // correction for not handling negs
                        }
                        diff -= MathHelper.Pi;

                        if (Math.Abs(diff) > MathHelper.Pi)
                        {
                            continue;                             // Something's wrong, point not in shape but exists angle diff > 180
                        }
                        if (diff > max)
                        {
                            max         = diff;
                            maxAbsolute = newAngle;
                        }

                        if (diff < min)
                        {
                            min         = diff;
                            minAbsolute = newAngle;
                        }
                    }

                    vals[valIndex] = minAbsolute;
                    ++valIndex;
                    vals[valIndex] = maxAbsolute;
                    ++valIndex;
                }
            }

            Array.Sort(vals, 0, valIndex, _rdc);
            _data.Clear();
            var rayMissed = true;

            for (var i = 0; i < valIndex; ++i)
            {
                Fixture fixture = null;
                float   midpt;

                var iplus = (i == valIndex - 1 ? 0 : i + 1);
                if (vals[i] == vals[iplus])
                {
                    continue;
                }

                if (i == valIndex - 1)
                {
                    // the single edgecase
                    midpt = (vals[0] + MathHelper.Pi * 2 + vals[i]);
                }
                else
                {
                    midpt = (vals[i + 1] + vals[i]);
                }

                midpt = midpt / 2;

                var p1 = pos;
                var p2 = radius * new Vector2((float)Math.Cos(midpt), (float)Math.Sin(midpt)) + pos;

                // RaycastOne
                bool hitClosest = false;
                World.RayCast((f, p, n, fr) =>
                {
                    var body = f.Body;

                    if (!IsActiveOn(body))
                    {
                        return(0);
                    }

                    hitClosest = true;
                    fixture    = f;
                    return(fr);
                }, p1, p2);

                // draws radius points
                if ((hitClosest) && (fixture.Body.BodyType == BodyType.Dynamic))
                {
                    if ((_data.Any()) && (_data.Last().Body == fixture.Body) && (!rayMissed))
                    {
                        var laPos = _data.Count - 1;
                        var la    = _data[laPos];
                        la.Max       = vals[iplus];
                        _data[laPos] = la;
                    }
                    else
                    {
                        // make new
                        ShapeData d;
                        d.Body = fixture.Body;
                        d.Min  = vals[i];
                        d.Max  = vals[iplus];
                        _data.Add(d);
                    }

                    if ((_data.Count > 1) &&
                        (i == valIndex - 1) &&
                        (_data.Last().Body == _data.First().Body) &&
                        (_data.Last().Max == _data.First().Min))
                    {
                        var fi = _data[0];
                        fi.Min = _data.Last().Min;
                        _data.RemoveAt(_data.Count - 1);
                        _data[0] = fi;
                        while (_data.First().Min >= _data.First().Max)
                        {
                            fi.Min  -= MathHelper.Pi * 2;
                            _data[0] = fi;
                        }
                    }

                    var lastPos = _data.Count - 1;
                    var last    = _data[lastPos];
                    while ((_data.Count > 0) &&
                           (_data.Last().Min >= _data.Last().Max))                        // just making sure min<max
                    {
                        last.Min       = _data.Last().Min - 2 * MathHelper.Pi;
                        _data[lastPos] = last;
                    }

                    rayMissed = false;
                }
                else
                {
                    rayMissed = true;                     // raycast did not find a shape
                }
            }

            for (int i = 0; i < _data.Count; ++i)
            {
                if (!IsActiveOn(_data[i].Body))
                {
                    continue;
                }

                var arclen = _data[i].Max - _data[i].Min;

                var first        = MathHelper.Min(maxEdgeOffset, EdgeRatio * arclen);
                var insertedRays = (int)Math.Ceiling(((arclen - 2.0f * first) - (MinRays - 1) * MaxAngle) / MaxAngle);

                if (insertedRays < 0)
                {
                    insertedRays = 0;
                }

                float offset = (arclen - first * 2.0f) / ((float)MinRays + insertedRays - 1);

                //Note: This loop can go into infinite as it operates on floats.
                //Added FloatEquals with a large epsilon.
                for (float j = _data[i].Min + first;
                     j < _data[i].Max || MathUtils.FloatEquals(j, _data[i].Max, 0.0001f);
                     j += offset)
                {
                    var p1        = pos;
                    var p2        = pos + radius * new Vector2((float)Math.Cos(j), (float)Math.Sin(j));
                    var hitpoint  = Vector2.Zero;
                    var minlambda = float.MaxValue;

                    var fl = _data[i].Body.FixtureList;
                    for (int x = 0; x < fl.Count; x++)
                    {
                        Fixture      f = fl[x];
                        RayCastInput ri;
                        ri.Point1      = p1;
                        ri.Point2      = p2;
                        ri.MaxFraction = 50f;

                        RayCastOutput ro;
                        if (f.RayCast(out ro, ref ri, 0))
                        {
                            if (minlambda > ro.Fraction)
                            {
                                minlambda = ro.Fraction;
                                hitpoint  = ro.Fraction * p2 + (1 - ro.Fraction) * p1;
                            }
                        }

                        // the force that is to be applied for this particular ray.
                        // offset is angular coverage. lambda*length of segment is distance.
                        var impulse = (arclen / (MinRays + insertedRays)) * maxForce * 180.0f / MathHelper.Pi *
                                      (1.0f - Math.Min(1.0f, minlambda));

                        // We Apply the impulse!!!
                        var vectImp =
                            Vector2.Dot(impulse * new Vector2((float)Math.Cos(j), (float)Math.Sin(j)), -ro.Normal) *
                            new Vector2((float)Math.Cos(j), (float)Math.Sin(j));
                        _data[i].Body.ApplyLinearImpulse(ref vectImp, ref hitpoint);

                        // We gather the fixtures for returning them
                        if (exploded.ContainsKey(f))
                        {
                            exploded[f] += vectImp;
                        }
                        else
                        {
                            exploded.Add(f, vectImp);
                        }

                        if (minlambda > 1.0f)
                        {
                            hitpoint = p2;
                        }
                    }
                }
            }

            // We check contained shapes
            for (var i = 0; i < containedShapeCount; ++i)
            {
                var fix = containedShapes[i];

                if (!IsActiveOn(fix.Body))
                {
                    continue;
                }

                var     impulse = MinRays * maxForce * 180.0f / MathHelper.Pi;
                Vector2 hitPoint;

                var circShape = fix.Shape as CircleShape;
                if (circShape != null)
                {
                    hitPoint = fix.Body.GetWorldPoint(circShape.Position);
                }
                else
                {
                    var shape = fix.Shape as PolygonShape;
                    hitPoint = fix.Body.GetWorldPoint(shape.MassData.Centroid);
                }

                var vectImp = impulse * (hitPoint - pos);

                fix.Body.ApplyLinearImpulse(ref vectImp, ref hitPoint);

                if (!exploded.ContainsKey(fix))
                {
                    exploded.Add(fix, vectImp);
                }
            }

            return(exploded);
        }
Ejemplo n.º 56
0
        protected override void LoadContent(PloobsEngine.Engine.GraphicInfo GraphicInfo, PloobsEngine.Engine.GraphicFactory factory, PloobsEngine.SceneControl.IContentManager contentManager)
        {
            tile = factory.GetTexture2D("Textures/tile");
            FarseerWorld fworld = this.World.PhysicWorld as FarseerWorld;

            //ground
            {
                Vertices Vertices = new Vertices(3);
                Vertices.Add(new Vector2(-200, 0));
                Vertices.Add(new Vector2(0, 200));
                Vertices.Add(new Vector2(200, 0));

                SpriteFarseer          SpriteFarseer = new SpriteFarseer(factory, Vertices, Color.Red);
                Basic2DTextureMaterial mat           = new Basic2DTextureMaterial();
                FarseerObject          fs            = new FarseerObject(fworld, SpriteFarseer, 1, BodyType.Static);
                I2DObject o = new I2DObject(fs, mat, SpriteFarseer);
                this.World.AddObject(o);
            }

            ///from texture
            {
                Texture2D tex              = factory.GetTexture2D("Textures//goo");
                IModelo2D model            = new SpriteFarseer(tex);
                Basic2DTextureMaterial mat = new Basic2DTextureMaterial();
                FarseerObject          fs  = new FarseerObject(fworld, tex);
                I2DObject o = new I2DObject(fs, mat, model);
                this.World.AddObject(o);
            }

            ///rectangle
            Vertices verts = PolygonTools.CreateRectangle(50, 50);

            {
                IModelo2D model = new SpriteFarseer(factory, verts, Color.Red);
                model.LayerDepth = 0;
                Basic2DTextureMaterial mat = new Basic2DTextureMaterial();
                FarseerObject          fs  = new FarseerObject(fworld, model, 1, BodyType.Static);
                I2DObject o = new I2DObject(fs, mat, model);
                this.World.AddObject(o);
            }

            //rectangle
            //cria em Display
            verts = PolygonTools.CreateRectangle(50, 50);

            {
                IModelo2D model = new SpriteFarseer(factory, verts, Color.Green);
                model.LayerDepth = 1;
                Basic2DTextureMaterial mat = new Basic2DTextureMaterial();
                FarseerObject          fs  = new FarseerObject(fworld, model, 1, BodyType.Static);
                I2DObject o = new I2DObject(fs, mat, model);

                o.PhysicObject.Position = new Vector2(50, 50);
                this.World.AddObject(o);
            }


            ///rectangle
            verts = PolygonTools.CreateRectangle(50, 50);
            {
                IModelo2D model = new SpriteFarseer(factory, verts, Color.Orange);
                model.LayerDepth = 0;
                Basic2DTextureMaterial mat = new Basic2DTextureMaterial();
                FarseerObject          fs  = new FarseerObject(fworld, model, 1, BodyType.Static);
                I2DObject o = new I2DObject(fs, mat, model);
                o.PhysicObject.Position = new Vector2(-GraphicInfo.BackBufferWidth / 2, 0);
                this.World.AddObject(o);
            }

            ///circle
            CircleShape circle = new CircleShape(50, 1);

            {
                IModelo2D model            = new SpriteFarseer(factory, circle, Color.Yellow);
                Basic2DTextureMaterial mat = new Basic2DTextureMaterial();
                FarseerObject          fs  = new FarseerObject(fworld, model);
                I2DObject o = new I2DObject(fs, mat, model);
                o.PhysicObject.Position = new Vector2(0, -GraphicInfo.BackBufferHeight / 2);
                this.World.AddObject(o);
            }

            ///animated sprite
            {
                Texture2D      tex = factory.GetTexture2D("Textures//DudeSheet");
                SpriteAnimated sa  = new SpriteAnimated(tex, 8, 2);
                sa.AddAnimation("ANIM1", 1, 8, 0);
                sa.AddAnimation("ANIM2", 2, 4, MathHelper.PiOver2);

                Basic2DTextureMaterial mat = new Basic2DTextureMaterial();
                Texture2D     frame        = factory.GetTexturePart(tex, sa.GetFrameRectangle("ANIM1", 0));
                FarseerObject fs           = new FarseerObject(fworld, frame);

                I2DObject sheet = new I2DObject(fs, mat, sa);
                sheet.PhysicObject.Position = new Vector2(100, 100);
                this.World.AddObject(sheet);
            }

            ///camera
            this.World.Camera2D = new Camera2D(GraphicInfo);
            base.LoadContent(GraphicInfo, factory, contentManager);
        }
Ejemplo n.º 57
0
        private void CreateLeg(float s, Vector2 wheelAnchor)
        {
            Vector2 p1 = new Vector2(5.4f * s, -6.1f);
            Vector2 p2 = new Vector2(7.2f * s, -1.2f);
            Vector2 p3 = new Vector2(4.3f * s, -1.9f);
            Vector2 p4 = new Vector2(3.1f * s, 0.8f);
            Vector2 p5 = new Vector2(6.0f * s, 1.5f);
            Vector2 p6 = new Vector2(2.5f * s, 3.7f);

            PolygonShape poly1 = new PolygonShape(1);
            PolygonShape poly2 = new PolygonShape(1);

            Vertices vertices = new Vertices(3);

            if (s > 0.0f)
            {
                vertices.Add(p1);
                vertices.Add(p2);
                vertices.Add(p3);
                poly1.Vertices = vertices;

                vertices[0]    = Vector2.Zero;
                vertices[1]    = p5 - p4;
                vertices[2]    = p6 - p4;
                poly2.Vertices = vertices;
            }
            else
            {
                vertices.Add(p1);
                vertices.Add(p3);
                vertices.Add(p2);
                poly1.Vertices = vertices;

                vertices[0]    = Vector2.Zero;
                vertices[1]    = p6 - p4;
                vertices[2]    = p5 - p4;
                poly2.Vertices = vertices;
            }

            Body body1 = BodyFactory.CreateBody(World);

            body1.BodyType       = BodyType.Dynamic;
            body1.Position       = _offset;
            body1.AngularDamping = 10.0f;

            Body body2 = BodyFactory.CreateBody(World);

            body2.BodyType       = BodyType.Dynamic;
            body2.Position       = p4 + _offset;
            body2.AngularDamping = 10.0f;

            Fixture f1 = body1.CreateFixture(poly1);

            f1.CollisionGroup = -1;

            Fixture f2 = body2.CreateFixture(poly2);

            f2.CollisionGroup = -1;

            // Using a soft distanceraint can reduce some jitter.
            // It also makes the structure seem a bit more fluid by
            // acting like a suspension system.
            DistanceJoint djd = new DistanceJoint(body1, body2, p2 + _offset, p5 + _offset, true);

            djd.DampingRatio = 0.5f;
            djd.Frequency    = 10.0f;

            World.AddJoint(djd);

            DistanceJoint djd2 = new DistanceJoint(body1, body2, p3 + _offset, p4 + _offset, true);

            djd2.DampingRatio = 0.5f;
            djd2.Frequency    = 10.0f;

            World.AddJoint(djd2);

            DistanceJoint djd3 = new DistanceJoint(body1, _wheel, p3 + _offset, wheelAnchor + _offset, true);

            djd3.DampingRatio = 0.5f;
            djd3.Frequency    = 10.0f;

            World.AddJoint(djd3);

            DistanceJoint djd4 = new DistanceJoint(body2, _wheel, p6 + _offset, wheelAnchor + _offset, true);

            djd4.DampingRatio = 0.5f;
            djd4.Frequency    = 10.0f;

            World.AddJoint(djd4);

            Vector2       anchor = p4 - new Vector2(0.0f, 0.8f) /*+ _offset*/;
            RevoluteJoint rjd    = new RevoluteJoint(body2, _chassis, p4 + _offset, true);

            World.AddJoint(rjd);
        }
Ejemplo n.º 58
0
        /// <summary>
        /// Decompose the polygon into triangles
        /// </summary>
        /// <param name="contour">The list of points describing the polygon</param>
        /// <returns></returns>
        public static List <Vertices> ConvexPartition(Vertices contour)
        {
            int n = contour.Count;

            if (n < 3)
            {
                return(new List <Vertices>());
            }

            int[] V = new int[n];

            // We want a counter-clockwise polygon in V
            if (contour.IsCounterClockWise())
            {
                for (int v = 0; v < n; v++)
                {
                    V[v] = v;
                }
            }
            else
            {
                for (int v = 0; v < n; v++)
                {
                    V[v] = (n - 1) - v;
                }
            }

            int nv = n;

            // Remove nv-2 Vertices, creating 1 triangle every time
            int count = 2 * nv; /* error detection */

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

            for (int v = nv - 1; nv > 2;)
            {
                // If we loop, it is probably a non-simple polygon
                if (0 >= (count--))
                {
                    // Triangulate: ERROR - probable bad polygon!
                    return(new List <Vertices>());
                }

                // Three consecutive vertices in current polygon, <u,v,w>
                int u = v;
                if (nv <= u)
                {
                    u = 0; // Previous
                }
                v = u + 1;
                if (nv <= v)
                {
                    v = 0; // New v
                }
                int w = v + 1;
                if (nv <= w)
                {
                    w = 0; // Next
                }
                _tmpA = contour[V[u]];
                _tmpB = contour[V[v]];
                _tmpC = contour[V[w]];

                if (Snip(contour, u, v, w, nv, V))
                {
                    int s, t;

                    // Output Triangle
                    Vertices triangle = new Vertices(3);
                    triangle.Add(_tmpA);
                    triangle.Add(_tmpB);
                    triangle.Add(_tmpC);
                    result.Add(triangle);

                    // Remove v from remaining polygon
                    for (s = v, t = v + 1; t < nv; s++, t++)
                    {
                        V[s] = V[t];
                    }
                    nv--;

                    // Reset error detection counter
                    count = 2 * nv;
                }
            }

            return(result);
        }
Ejemplo n.º 59
0
        private EdgeShapesTest()
        {
            // Ground body
            {
                Body ground = BodyFactory.CreateBody(World);

                float x1 = -20.0f;
                float y1 = 2.0f * (float)Math.Cos(x1 / 10.0f * (float)Math.PI);
                for (int i = 0; i < 80; ++i)
                {
                    float x2 = x1 + 0.5f;
                    float y2 = 2.0f * (float)Math.Cos(x2 / 10.0f * (float)Math.PI);

                    EdgeShape shape = new EdgeShape(new Vector2(x1, y1), new Vector2(x2, y2));
                    ground.CreateFixture(shape);

                    x1 = x2;
                    y1 = y2;
                }
            }

            {
                Vertices vertices = new Vertices(3);
                vertices.Add(new Vector2(-0.5f, 0.0f));
                vertices.Add(new Vector2(0.5f, 0.0f));
                vertices.Add(new Vector2(0.0f, 1.5f));
                _polygons[0] = new PolygonShape(vertices, 20);
            }

            {
                Vertices vertices = new Vertices(3);
                vertices.Add(new Vector2(-0.1f, 0.0f));
                vertices.Add(new Vector2(0.1f, 0.0f));
                vertices.Add(new Vector2(0.0f, 1.5f));
                _polygons[1] = new PolygonShape(vertices, 20);
            }

            {
                const float w = 1.0f;
                float       b = w / (2.0f + (float)Math.Sqrt(2.0f));
                float       s = (float)Math.Sqrt(2.0f) * b;

                Vertices vertices = new Vertices(8);
                vertices.Add(new Vector2(0.5f * s, 0.0f));
                vertices.Add(new Vector2(0.5f * w, b));
                vertices.Add(new Vector2(0.5f * w, b + s));
                vertices.Add(new Vector2(0.5f * s, w));
                vertices.Add(new Vector2(-0.5f * s, w));
                vertices.Add(new Vector2(-0.5f * w, b + s));
                vertices.Add(new Vector2(-0.5f * w, b));
                vertices.Add(new Vector2(-0.5f * s, 0.0f));
                _polygons[2] = new PolygonShape(vertices, 20);
            }

            {
                _polygons[3]          = new PolygonShape(20);
                _polygons[3].Vertices = PolygonUtils.CreateRectangle(0.5f, 0.5f);
            }

            {
                _circle = new CircleShape(0.5f, 1);
            }

            _bodyIndex = 0;
            _angle     = 0.0f;
        }
Ejemplo n.º 60
-1
        public static List<Vertices> ConvexPartition(Vertices vertices)
        {
            Polygon poly = new Polygon();

            foreach (FVector2 vertex in vertices)
            {
                poly.Points.Add(new TriangulationPoint(vertex.X, vertex.Y));
            }

            DTSweepContext tcx = new DTSweepContext();
            tcx.PrepareTriangulation(poly);
            DTSweep.Triangulate(tcx);

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

            foreach (DelaunayTriangle triangle in poly.Triangles)
            {
                Vertices v = new Vertices();
                foreach (TriangulationPoint p in triangle.Points)
                {
                    v.Add(new FVector2((float)p.X, (float)p.Y));
                }
                results.Add(v);
            }

            return results;
        }