Пример #1
0
        public override EngineShapes.Shape ToEngineShape()
        {
            var engineShape = new EngineShapes.PolygonShape(ShapeSettings.DefaultDensity);

            engineShape.Set(new Vertices(
                                Points.Select(p => (p - Center).ToSimulation()).ToList()));
            return(engineShape);
        }
        private ConfinedTest()
        {
            {
                Body ground = BodyFactory.CreateBody(World);

                // Floor
                Vertices edge = PolygonTools.CreateEdge(new Vector2(-10.0f, 0.0f), new Vector2(10.0f, 0.0f));
                PolygonShape shape = new PolygonShape(edge, 0);

                ground.CreateFixture(shape);

                // Left wall
                shape.Set(PolygonTools.CreateEdge(new Vector2(-10.0f, 0.0f), new Vector2(-10.0f, 20.0f)));
                ground.CreateFixture(shape);

                // Right wall
                shape.Set(PolygonTools.CreateEdge(new Vector2(10.0f, 0.0f), new Vector2(10.0f, 20.0f)));
                ground.CreateFixture(shape);

                // Roof
                shape.Set(PolygonTools.CreateEdge(new Vector2(-10.0f, 20.0f), new Vector2(10.0f, 20.0f)));
                ground.CreateFixture(shape);
            }

            const float radius = 0.5f;
            CircleShape shape2 = new CircleShape(radius, 1);
            shape2.Position = Vector2.Zero;

            for (int j = 0; j < ColumnCount; ++j)
            {
                for (int i = 0; i < RowCount; ++i)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-10.0f + (2.1f*j + 1.0f + 0.01f*i)*radius,
                                                (2.0f*i + 1.0f)*radius);

                    Fixture fixture = body.CreateFixture(shape2);
                    fixture.Friction = 0.1f;
                }
            }

            World.Gravity = Vector2.Zero;
        }
Пример #3
0
        public override EngineShapes.Shape ToEngineShape()
        {
            var offset = Offset - Center;
            var shape  = new EngineShapes.PolygonShape(ShapeSettings.DefaultDensity);

            shape.Set(new Vertices(new[]
            {
                offset.ToSimulation(),
                (offset + new Vector2(Size.X, 0)).ToSimulation(),
                (offset + Size).ToSimulation(),
                (offset + new Vector2(0, Size.Y)).ToSimulation(),
            }));
            return(shape);
        }
Пример #4
0
        public override bool TestPoint(Vector2 point)
        {
            var test = new EngineShapes.PolygonShape(1.0f);

            test.Set(new Vertices(
                         Points.Select(x => new Xna.Vector2(x.X, x.Y)).ToList()));

            var transform = new Transform();

            transform.SetIdentity();
            var mouseXna = new Xna.Vector2(point.X, point.Y);

            return(test.TestPoint(ref transform, ref mouseXna));
        }
        private CircleBenchmarkTest()
        {
            Body ground = BodyFactory.CreateBody(World);

            // Floor
            Vertices edge = PolygonTools.CreateEdge(new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));
            PolygonShape ashape = new PolygonShape(edge, 0);

            ground.CreateFixture(ashape);

            // Left wall
            ashape.Set(PolygonTools.CreateEdge(new Vector2(-40.0f, 0.0f), new Vector2(-40.0f, 45.0f)));
            ground.CreateFixture(ashape);

            // Right wall
            ashape.Set(PolygonTools.CreateEdge(new Vector2(40.0f, 0.0f), new Vector2(40.0f, 45.0f)));
            ground.CreateFixture(ashape);

            // Roof
            ashape.Set(PolygonTools.CreateEdge(new Vector2(-40.0f, 45.0f), new Vector2(40.0f, 45.0f)));
            ground.CreateFixture(ashape);

            CircleShape shape = new CircleShape(1.0f, 1);

            for (int i = 0; i < XCount; i++)
            {
                for (int j = 0; j < YCount; ++j)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-38f + 2.1f*i, 2.0f + 2.0f*j);

                    body.CreateFixture(shape);
                }
            }
        }
Пример #6
0
        private EdgeShapeBenchmark()
        {
            // 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;
                }
            }

            const float w = 1.0f;
            const float t = 2.0f;
            float b = w / (2.0f + (float)Math.Sqrt(t));
            float s = (float)Math.Sqrt(t) * 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));

            _polyShape = new PolygonShape(20);
            _polyShape.Set(vertices);
        }
Пример #7
0
        public void Deserialize(World world, Stream stream)
        {
            world.Clear();

            XMLFragmentElement root = XMLFragmentParser.LoadFromStream(stream);

            if (root.Name.ToLower() != "world")
                throw new Exception();

            foreach (XMLFragmentElement main in root.Elements)
            {
                if (main.Name.ToLower() == "gravity")
                {
                    world.Gravity = ReadVector(main);
                }
            }

            foreach (XMLFragmentElement shapeElement in root.Elements)
            {
                if (shapeElement.Name.ToLower() == "shapes")
                {
                    foreach (XMLFragmentElement n in shapeElement.Elements)
                    {
                        if (n.Name.ToLower() != "shape")
                            throw new Exception();

                        ShapeType type = (ShapeType)Enum.Parse(typeof(ShapeType), n.Attributes[0].Value, true);

                        switch (type)
                        {
                            case ShapeType.Circle:
                                {
                                    CircleShape shape = new CircleShape();

                                    foreach (XMLFragmentElement sn in n.Elements)
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "radius":
                                                shape.Radius = float.Parse(sn.Value);
                                                break;
                                            case "position":
                                                shape.Position = ReadVector(sn);
                                                break;
                                            default:
                                                throw new Exception();
                                        }
                                    }

                                    _shapes.Add(shape);
                                }
                                break;
                            case ShapeType.Polygon:
                                {
                                    PolygonShape shape = new PolygonShape();

                                    foreach (XMLFragmentElement sn in n.Elements)
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "vertices":
                                                {
                                                    List<Vector2> verts = new List<Vector2>();

                                                    foreach (XMLFragmentElement vert in sn.Elements)
                                                        verts.Add(ReadVector(vert));

                                                    shape.Set(new Vertices(verts.ToArray()));
                                                }
                                                break;
                                            case "centroid":
                                                shape.MassData.Centroid = ReadVector(sn);
                                                break;
                                        }
                                    }

                                    _shapes.Add(shape);
                                }
                                break;
                            case ShapeType.Edge:
                                {
                                    EdgeShape shape = new EdgeShape();
                                    foreach (XMLFragmentElement sn in n.Elements)
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "hasvertex0":
                                                shape.HasVertex0 = bool.Parse(sn.Value);
                                                break;
                                            case "hasvertex3":
                                                shape.HasVertex0 = bool.Parse(sn.Value);
                                                break;
                                            case "vertex0":
                                                shape.Vertex0 = ReadVector(sn);
                                                break;
                                            case "vertex1":
                                                shape.Vertex1 = ReadVector(sn);
                                                break;
                                            case "vertex2":
                                                shape.Vertex2 = ReadVector(sn);
                                                break;
                                            case "vertex3":
                                                shape.Vertex3 = ReadVector(sn);
                                                break;
                                            default:
                                                throw new Exception();
                                        }
                                    }
                                    _shapes.Add(shape);
                                }
                                break;
                        }
                    }
                }
            }

            foreach (XMLFragmentElement fixtureElement in root.Elements)
            {
                if (fixtureElement.Name.ToLower() == "fixtures")
                {
                    foreach (XMLFragmentElement n in fixtureElement.Elements)
                    {
                        Fixture fixture = new Fixture();

                        if (n.Name.ToLower() != "fixture")
                            throw new Exception();

                        foreach (XMLFragmentElement sn in n.Elements)
                        {
                            switch (sn.Name.ToLower())
                            {
                                case "shape":
                                    fixture.Shape = _shapes[int.Parse(sn.Value)];
                                    break;
                                case "density":
                                    fixture.Shape.Density = float.Parse(sn.Value);
                                    break;
                                case "filterdata":
                                    foreach (XMLFragmentElement ssn in sn.Elements)
                                    {
                                        switch (ssn.Name.ToLower())
                                        {
                                            case "categorybits":
                                                fixture._collisionCategories = (Category)int.Parse(ssn.Value);
                                                break;
                                            case "maskbits":
                                                fixture._collidesWith = (Category)int.Parse(ssn.Value);
                                                break;
                                            case "groupindex":
                                                fixture._collisionGroup = short.Parse(ssn.Value);
                                                break;
                                        }
                                    }

                                    break;
                                case "friction":
                                    fixture.Friction = float.Parse(sn.Value);
                                    break;
                                case "issensor":
                                    fixture.IsSensor = bool.Parse(sn.Value);
                                    break;
                                case "restitution":
                                    fixture.Restitution = float.Parse(sn.Value);
                                    break;
                                case "userdata":
                                    fixture.UserData = ReadSimpleType(sn, null, false);
                                    break;
                            }
                        }

                        _fixtures.Add(fixture);
                    }
                }
            }

            foreach (XMLFragmentElement bodyElement in root.Elements)
            {
                if (bodyElement.Name.ToLower() == "bodies")
                {
                    foreach (XMLFragmentElement n in bodyElement.Elements)
                    {
                        Body body = new Body(world);

                        if (n.Name.ToLower() != "body")
                            throw new Exception();

                        body.BodyType = (BodyType)Enum.Parse(typeof(BodyType), n.Attributes[0].Value, true);

                        foreach (XMLFragmentElement sn in n.Elements)
                        {
                            switch (sn.Name.ToLower())
                            {
                                case "active":
                                    if (bool.Parse(sn.Value))
                                        body.Flags |= BodyFlags.Enabled;
                                    else
                                        body.Flags &= ~BodyFlags.Enabled;
                                    break;
                                case "allowsleep":
                                    body.SleepingAllowed = bool.Parse(sn.Value);
                                    break;
                                case "angle":
                                    {
                                        Vector2 position = body.Position;
                                        body.SetTransformIgnoreContacts(ref position, float.Parse(sn.Value));
                                    }
                                    break;
                                case "angulardamping":
                                    body.AngularDamping = float.Parse(sn.Value);
                                    break;
                                case "angularvelocity":
                                    body.AngularVelocity = float.Parse(sn.Value);
                                    break;
                                case "awake":
                                    body.Awake = bool.Parse(sn.Value);
                                    break;
                                case "bullet":
                                    body.IsBullet = bool.Parse(sn.Value);
                                    break;
                                case "fixedrotation":
                                    body.FixedRotation = bool.Parse(sn.Value);
                                    break;
                                case "lineardamping":
                                    body.LinearDamping = float.Parse(sn.Value);
                                    break;
                                case "linearvelocity":
                                    body.LinearVelocity = ReadVector(sn);
                                    break;
                                case "position":
                                    {
                                        float rotation = body.Rotation;
                                        Vector2 position = ReadVector(sn);
                                        body.SetTransformIgnoreContacts(ref position, rotation);
                                    }
                                    break;
                                case "userdata":
                                    body.UserData = ReadSimpleType(sn, null, false);
                                    break;
                                case "fixtures":
                                    {
                                        foreach (XMLFragmentElement v in sn.Elements)
                                        {
                                            Fixture blueprint = _fixtures[int.Parse(v.Value)];
                                            Fixture f = new Fixture(body, blueprint.Shape, blueprint.CollisionCategories);
                                            f.Restitution = blueprint.Restitution;
                                            f.UserData = blueprint.UserData;
                                            f.Friction = blueprint.Friction;
                                            f.CollidesWith = blueprint.CollidesWith;
                                            f.CollisionGroup = blueprint.CollisionGroup;
                                        }
                                        break;
                                    }
                            }
                        }

                        _bodies.Add(body);
                    }
                }
            }

            foreach (XMLFragmentElement jointElement in root.Elements)
            {
                if (jointElement.Name.ToLower() == "joints")
                {
                    foreach (XMLFragmentElement n in jointElement.Elements)
                    {
                        Joint joint;

                        if (n.Name.ToLower() != "joint")
                            throw new Exception();

                        JointType type = (JointType)Enum.Parse(typeof(JointType), n.Attributes[0].Value, true);

                        int bodyAIndex = -1, bodyBIndex = -1;
                        bool collideConnected = false;
                        object userData = null;

                        foreach (XMLFragmentElement sn in n.Elements)
                        {
                            switch (sn.Name.ToLower())
                            {
                                case "bodya":
                                    bodyAIndex = int.Parse(sn.Value);
                                    break;
                                case "bodyb":
                                    bodyBIndex = int.Parse(sn.Value);
                                    break;
                                case "collideconnected":
                                    collideConnected = bool.Parse(sn.Value);
                                    break;
                                case "userdata":
                                    userData = ReadSimpleType(sn, null, false);
                                    break;
                            }
                        }

                        Body bodyA = _bodies[bodyAIndex];
                        Body bodyB = _bodies[bodyBIndex];

                        switch (type)
                        {
                            case JointType.Distance:
                                joint = new DistanceJoint();
                                break;
                            case JointType.Friction:
                                joint = new FrictionJoint();
                                break;
                            case JointType.Line:
                                joint = new LineJoint();
                                break;
                            case JointType.Prismatic:
                                joint = new PrismaticJoint();
                                break;
                            case JointType.Pulley:
                                joint = new PulleyJoint();
                                break;
                            case JointType.Revolute:
                                joint = new RevoluteJoint();
                                break;
                            case JointType.Weld:
                                joint = new WeldJoint();
                                break;
                            case JointType.Rope:
                                joint = new RopeJoint();
                                break;
                            case JointType.Angle:
                                joint = new AngleJoint();
                                break;
                            case JointType.Slider:
                                joint = new SliderJoint();
                                break;
                            case JointType.Gear:
                                throw new Exception("GearJoint is not supported.");
                            default:
                                throw new Exception("Invalid or unsupported joint.");
                        }

                        joint.CollideConnected = collideConnected;
                        joint.UserData = userData;
                        joint.BodyA = bodyA;
                        joint.BodyB = bodyB;
                        _joints.Add(joint);
                        world.AddJoint(joint);

                        foreach (XMLFragmentElement sn in n.Elements)
                        {
                            // check for specific nodes
                            switch (type)
                            {
                                case JointType.Distance:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "dampingratio":
                                                ((DistanceJoint)joint).DampingRatio = float.Parse(sn.Value);
                                                break;
                                            case "frequencyhz":
                                                ((DistanceJoint)joint).Frequency = float.Parse(sn.Value);
                                                break;
                                            case "length":
                                                ((DistanceJoint)joint).Length = float.Parse(sn.Value);
                                                break;
                                            case "localanchora":
                                                ((DistanceJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((DistanceJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Friction:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "localanchora":
                                                ((FrictionJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((FrictionJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                            case "maxforce":
                                                ((FrictionJoint)joint).MaxForce = float.Parse(sn.Value);
                                                break;
                                            case "maxtorque":
                                                ((FrictionJoint)joint).MaxTorque = float.Parse(sn.Value);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Line:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "enablemotor":
                                                ((LineJoint)joint).MotorEnabled = bool.Parse(sn.Value);
                                                break;
                                            case "localanchora":
                                                ((LineJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((LineJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                            case "motorspeed":
                                                ((LineJoint)joint).MotorSpeed = float.Parse(sn.Value);
                                                break;
                                            case "dampingratio":
                                                ((LineJoint)joint).DampingRatio = float.Parse(sn.Value);
                                                break;
                                            case "maxmotortorque":
                                                ((LineJoint)joint).MaxMotorTorque = float.Parse(sn.Value);
                                                break;
                                            case "frequencyhz":
                                                ((LineJoint)joint).Frequency = float.Parse(sn.Value);
                                                break;
                                            case "localxaxis":
                                                ((LineJoint)joint).LocalXAxis = ReadVector(sn);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Prismatic:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "enablelimit":
                                                ((PrismaticJoint)joint).LimitEnabled = bool.Parse(sn.Value);
                                                break;
                                            case "enablemotor":
                                                ((PrismaticJoint)joint).MotorEnabled = bool.Parse(sn.Value);
                                                break;
                                            case "localanchora":
                                                ((PrismaticJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((PrismaticJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                            case "local1axis1":
                                                ((PrismaticJoint)joint).LocalXAxis1 = ReadVector(sn);
                                                break;
                                            case "maxmotorforce":
                                                ((PrismaticJoint)joint).MaxMotorForce = float.Parse(sn.Value);
                                                break;
                                            case "motorspeed":
                                                ((PrismaticJoint)joint).MotorSpeed = float.Parse(sn.Value);
                                                break;
                                            case "lowertranslation":
                                                ((PrismaticJoint)joint).LowerLimit = float.Parse(sn.Value);
                                                break;
                                            case "uppertranslation":
                                                ((PrismaticJoint)joint).UpperLimit = float.Parse(sn.Value);
                                                break;
                                            case "referenceangle":
                                                ((PrismaticJoint)joint).ReferenceAngle = float.Parse(sn.Value);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Pulley:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "groundanchora":
                                                ((PulleyJoint)joint).GroundAnchorA = ReadVector(sn);
                                                break;
                                            case "groundanchorb":
                                                ((PulleyJoint)joint).GroundAnchorB = ReadVector(sn);
                                                break;
                                            case "lengtha":
                                                ((PulleyJoint)joint).LengthA = float.Parse(sn.Value);
                                                break;
                                            case "lengthb":
                                                ((PulleyJoint)joint).LengthB = float.Parse(sn.Value);
                                                break;
                                            case "localanchora":
                                                ((PulleyJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((PulleyJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                            case "maxlengtha":
                                                ((PulleyJoint)joint).MaxLengthA = float.Parse(sn.Value);
                                                break;
                                            case "maxlengthb":
                                                ((PulleyJoint)joint).MaxLengthB = float.Parse(sn.Value);
                                                break;
                                            case "ratio":
                                                ((PulleyJoint)joint).Ratio = float.Parse(sn.Value);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Revolute:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "enablelimit":
                                                ((RevoluteJoint)joint).LimitEnabled = bool.Parse(sn.Value);
                                                break;
                                            case "enablemotor":
                                                ((RevoluteJoint)joint).MotorEnabled = bool.Parse(sn.Value);
                                                break;
                                            case "localanchora":
                                                ((RevoluteJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((RevoluteJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                            case "maxmotortorque":
                                                ((RevoluteJoint)joint).MaxMotorTorque = float.Parse(sn.Value);
                                                break;
                                            case "motorspeed":
                                                ((RevoluteJoint)joint).MotorSpeed = float.Parse(sn.Value);
                                                break;
                                            case "lowerangle":
                                                ((RevoluteJoint)joint).LowerLimit = float.Parse(sn.Value);
                                                break;
                                            case "upperangle":
                                                ((RevoluteJoint)joint).UpperLimit = float.Parse(sn.Value);
                                                break;
                                            case "referenceangle":
                                                ((RevoluteJoint)joint).ReferenceAngle = float.Parse(sn.Value);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Weld:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "localanchora":
                                                ((WeldJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((WeldJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Rope:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "localanchora":
                                                ((RopeJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((RopeJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                            case "maxlength":
                                                ((RopeJoint)joint).MaxLength = float.Parse(sn.Value);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Gear:
                                    throw new Exception("Gear joint is unsupported");
                                case JointType.Angle:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "biasfactor":
                                                ((AngleJoint)joint).BiasFactor = float.Parse(sn.Value);
                                                break;
                                            case "maximpulse":
                                                ((AngleJoint)joint).MaxImpulse = float.Parse(sn.Value);
                                                break;
                                            case "softness":
                                                ((AngleJoint)joint).Softness = float.Parse(sn.Value);
                                                break;
                                            case "targetangle":
                                                ((AngleJoint)joint).TargetAngle = float.Parse(sn.Value);
                                                break;
                                        }
                                    }
                                    break;
                                case JointType.Slider:
                                    {
                                        switch (sn.Name.ToLower())
                                        {
                                            case "dampingratio":
                                                ((SliderJoint)joint).DampingRatio = float.Parse(sn.Value);
                                                break;
                                            case "frequencyhz":
                                                ((SliderJoint)joint).Frequency = float.Parse(sn.Value);
                                                break;
                                            case "maxlength":
                                                ((SliderJoint)joint).MaxLength = float.Parse(sn.Value);
                                                break;
                                            case "minlength":
                                                ((SliderJoint)joint).MinLength = float.Parse(sn.Value);
                                                break;
                                            case "localanchora":
                                                ((SliderJoint)joint).LocalAnchorA = ReadVector(sn);
                                                break;
                                            case "localanchorb":
                                                ((SliderJoint)joint).LocalAnchorB = ReadVector(sn);
                                                break;
                                        }
                                    }
                                    break;
                            }
                        }
                    }
                }
            }
        }
        private CollisionFilteringTest()
        {
            //Ground
            BodyFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.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 triangleBody = BodyFactory.CreateBody(World);
                triangleBody.BodyType = BodyType.Dynamic;
                triangleBody.Position = new Vector2(-5.0f, 2.0f);

                Fixture triangleFixture = triangleBody.CreateFixture(polygon);
                triangleFixture.CollisionGroup = SmallGroup;
                triangleFixture.CollisionCategories = TriangleCategory;
                triangleFixture.CollidesWith = TriangleMask;

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

                Body triangleBody2 = BodyFactory.CreateBody(World);
                triangleBody2.BodyType = BodyType.Dynamic;
                triangleBody2.Position = new Vector2(-5.0f, 6.0f);
                triangleBody2.FixedRotation = true; // look at me!

                Fixture triangleFixture2 = triangleBody2.CreateFixture(polygon);
                triangleFixture2.CollisionGroup = LargeGroup;
                triangleFixture2.CollisionCategories = TriangleCategory;
                triangleFixture2.CollidesWith = TriangleMask;

                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-5.0f, 10.0f);

                    Vertices box = PolygonTools.CreateRectangle(0.5f, 1.0f);
                    PolygonShape p = new PolygonShape(box, 1);
                    body.CreateFixture(p);

                    PrismaticJoint jd = new PrismaticJoint(triangleBody2, body,
                                                           triangleBody2.GetLocalPoint(body.Position),
                                                           Vector2.Zero, new Vector2(0.0f, 1.0f));
                    jd.LimitEnabled = true;
                    jd.LowerLimit = -1.0f;
                    jd.UpperLimit = 1.0f;

                    World.AddJoint(jd);
                }

                // Small box
                polygon.SetAsBox(1.0f, 0.5f);

                Body boxBody = BodyFactory.CreateBody(World);
                boxBody.BodyType = BodyType.Dynamic;
                boxBody.Position = new Vector2(0.0f, 2.0f);

                Fixture boxFixture = boxBody.CreateFixture(polygon);
                boxFixture.Restitution = 0.1f;

                boxFixture.CollisionGroup = SmallGroup;
                boxFixture.CollisionCategories = BoxCategory;
                boxFixture.CollidesWith = BoxMask;

                // Large box (recycle definitions)
                polygon.SetAsBox(2, 1);

                Body boxBody2 = BodyFactory.CreateBody(World);
                boxBody2.BodyType = BodyType.Dynamic;
                boxBody2.Position = new Vector2(0.0f, 6.0f);

                Fixture boxFixture2 = boxBody2.CreateFixture(polygon);
                boxFixture2.CollisionGroup = LargeGroup;
                boxFixture2.CollisionCategories = BoxCategory;
                boxFixture2.CollidesWith = BoxMask;

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

                Body circleBody = BodyFactory.CreateBody(World);
                circleBody.BodyType = BodyType.Dynamic;
                circleBody.Position = new Vector2(5.0f, 2.0f);

                Fixture circleFixture = circleBody.CreateFixture(circle);

                circleFixture.CollisionGroup = SmallGroup;
                circleFixture.CollisionCategories = CircleCategory;
                circleFixture.CollidesWith = CircleMask;

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

                Body circleBody2 = BodyFactory.CreateBody(World);
                circleBody2.BodyType = BodyType.Dynamic;
                circleBody2.Position = new Vector2(5.0f, 6.0f);

                Fixture circleFixture2 = circleBody2.CreateFixture(circle);
                circleFixture2.CollisionGroup = LargeGroup;
                circleFixture2.CollisionCategories = CircleCategory;
                circleFixture2.CollidesWith = CircleMask;

                // Large circle - Ignore with other large circle
                Body circleBody3 = BodyFactory.CreateBody(World);
                circleBody3.BodyType = BodyType.Dynamic;
                circleBody3.Position = new Vector2(6.0f, 9.0f);

                //Another large circle. This one uses IgnoreCollisionWith() logic instead of categories.
                Fixture circleFixture3 = circleBody3.CreateFixture(circle);
                circleFixture3.CollisionGroup = LargeGroup;
                circleFixture3.CollisionCategories = CircleCategory;
                circleFixture3.CollidesWith = CircleMask;

                circleFixture3.IgnoreCollisionWith(circleFixture2);
            }
        }
Пример #9
0
        private void CreateLeg(World world, float s, Vector2 wheelAnchor, int index)
        {
            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(1f);
            PolygonShape poly2 = new PolygonShape(2f);

            Vertices vertices = new Vertices(3);

            if (s < 0f)
            {
                vertices.Add(p1);
                vertices.Add(p2);
                vertices.Add(p3);
                poly1.Set(vertices);

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

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

            Body body1 = BodyFactory.CreateBody(world);
            body1.BodyType = BodyType.Dynamic;
            body1.Position = _position;
            body1.AngularDamping = 10f;
            if (s < 0f)
            {
                _leftLegs[index] = body1;
            }
            else
            {
                _rightLegs[index] = body1;
            }

            Body body2 = BodyFactory.CreateBody(world);
            body2.BodyType = BodyType.Dynamic;
            body2.Position = p4 + _position;
            body2.AngularDamping = 10f;
            if (s < 0f)
            {
                _leftShoulders[index] = body2;
            }
            else
            {
                _rightShoulders[index] = body2;
            }

            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, body1.GetLocalPoint(p2 + _position),
                                                  body2.GetLocalPoint(p5 + _position));
            djd.DampingRatio = 0.5f;
            djd.Frequency = 10f;

            world.AddJoint(djd);
            _walkerJoints.Add(djd);

            DistanceJoint djd2 = new DistanceJoint(body1, body2, body1.GetLocalPoint(p3 + _position),
                                                   body2.GetLocalPoint(p4 + _position));
            djd2.DampingRatio = 0.5f;
            djd2.Frequency = 10f;

            world.AddJoint(djd2);
            _walkerJoints.Add(djd2);

            DistanceJoint djd3 = new DistanceJoint(body1, _wheel, body1.GetLocalPoint(p3 + _position),
                                                   _wheel.GetLocalPoint(wheelAnchor + _position));
            djd3.DampingRatio = 0.5f;
            djd3.Frequency = 10f;

            world.AddJoint(djd3);
            _walkerJoints.Add(djd3);

            DistanceJoint djd4 = new DistanceJoint(body2, _wheel, body2.GetLocalPoint(p6 + _position),
                                                   _wheel.GetLocalPoint(wheelAnchor + _position));
            djd4.DampingRatio = 0.5f;
            djd4.Frequency = 10f;

            world.AddJoint(djd4);
            _walkerJoints.Add(djd4);

            Vector2 anchor = p4 - new Vector2(0f, -0.8f);
            RevoluteJoint rjd = new RevoluteJoint(body2, _chassis, body2.GetLocalPoint(_chassis.GetWorldPoint(anchor)),
                                                  anchor);
            world.AddJoint(rjd);
        }
        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.Set(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 = PolygonTools.CreateRectangle(1.0f, 0.5f);
            polygon.Set(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 = PolygonTools.CreateRectangle(2.0f, 1.0f);
            polygon.Set(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;
        }
Пример #11
0
        private DominosTest()
        {
            //Ground
            BodyFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));

            {
                Vertices box = PolygonTools.CreateRectangle(6.0f, 0.25f);
                PolygonShape shape = new PolygonShape(box, 0);

                Body ground = BodyFactory.CreateBody(World);
                ground.Position = new Vector2(-1.5f, 10.0f);

                ground.CreateFixture(shape);
            }

            {
                Vertices box = PolygonTools.CreateRectangle(0.1f, 1.0f);
                PolygonShape shape = new PolygonShape(box, 20);

                for (int i = 0; i < 10; ++i)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(-6.0f + 1.0f * i, 11.25f);

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

            {
                Vertices box = PolygonTools.CreateRectangle(7.0f, 0.25f, Vector2.Zero, 0.3f);
                PolygonShape shape = new PolygonShape(box, 0);

                Body ground = BodyFactory.CreateBody(World);
                ground.Position = new Vector2(1.0f, 6.0f);

                ground.CreateFixture(shape);
            }

            Body b2;
            {
                Vertices box = PolygonTools.CreateRectangle(0.25f, 1.5f);
                PolygonShape shape = new PolygonShape(box, 0);

                b2 = BodyFactory.CreateBody(World);
                b2.Position = new Vector2(-7.0f, 4.0f);

                b2.CreateFixture(shape);
            }

            Body b3;
            {
                Vertices box = PolygonTools.CreateRectangle(6.0f, 0.125f);
                PolygonShape shape = new PolygonShape(box, 10);

                b3 = BodyFactory.CreateBody(World);
                b3.BodyType = BodyType.Dynamic;
                b3.Position = new Vector2(-0.9f, 1.0f);
                b3.Rotation = -0.15f;

                b3.CreateFixture(shape);
            }

            Vector2 anchor = new Vector2(-2.0f, 1.0f);
            FixedRevoluteJoint jd = new FixedRevoluteJoint(b3, b3.GetLocalPoint(anchor), anchor);
            jd.CollideConnected = true;
            World.AddJoint(jd);

            Body b4;
            {
                Vertices box = PolygonTools.CreateRectangle(0.25f, 0.25f);
                PolygonShape shape = new PolygonShape(box, 10);

                b4 = BodyFactory.CreateBody(World);
                b4.BodyType = BodyType.Dynamic;
                b4.Position = new Vector2(-10.0f, 15.0f);

                b4.CreateFixture(shape);
            }

            anchor = new Vector2(-7.0f, 15.0f);
            FixedRevoluteJoint jd2 = new FixedRevoluteJoint(b4, b4.GetLocalPoint(anchor), anchor);
            World.AddJoint(jd2);

            Body b5;
            {
                b5 = BodyFactory.CreateBody(World);
                b5.BodyType = BodyType.Dynamic;
                b5.Position = new Vector2(6.5f, 3.0f);

                Vertices vertices = PolygonTools.CreateRectangle(1.0f, 0.1f, new Vector2(0.0f, -0.9f), 0.0f);
                PolygonShape shape = new PolygonShape(vertices, 10);

                Fixture fix = b5.CreateFixture(shape);
                fix.Friction = 0.1f;

                vertices = PolygonTools.CreateRectangle(0.1f, 1.0f, new Vector2(-0.9f, 0.0f), 0.0f);

                shape.Set(vertices);
                fix = b5.CreateFixture(shape);
                fix.Friction = 0.1f;

                vertices = PolygonTools.CreateRectangle(0.1f, 1.0f, new Vector2(0.9f, 0.0f), 0.0f);

                shape.Set(vertices);
                fix = b5.CreateFixture(shape);
                fix.Friction = 0.1f;
            }

            anchor = new Vector2(6.0f, 2.0f);
            FixedRevoluteJoint jd3 = new FixedRevoluteJoint(b5, b5.GetLocalPoint(anchor), anchor);
            World.AddJoint(jd3);

            Body b6;
            {
                Vertices box = PolygonTools.CreateRectangle(1.0f, 0.1f);
                PolygonShape shape = new PolygonShape(box, 30);

                b6 = BodyFactory.CreateBody(World);
                b6.BodyType = BodyType.Dynamic;
                b6.Position = new Vector2(6.5f, 4.1f);

                b6.CreateFixture(shape);
            }

            anchor = new Vector2(1.0f, -0.1f);
            RevoluteJoint jd4 = new RevoluteJoint(b5, b6, b5.GetLocalPoint(b6.GetWorldPoint(anchor)), anchor);
            jd4.CollideConnected = true;
            World.AddJoint(jd4);

            Body b7;
            {
                Vertices box = PolygonTools.CreateRectangle(0.1f, 1.0f);
                PolygonShape shape = new PolygonShape(box, 10);

                b7 = BodyFactory.CreateBody(World);
                b7.BodyType = BodyType.Dynamic;
                b7.Position = new Vector2(7.4f, 1.0f);

                b7.CreateFixture(shape);
            }

            DistanceJoint djd = new DistanceJoint(b3, b7, new Vector2(6.0f, 0.0f), new Vector2(0.0f, -1.0f));
            Vector2 d = djd.BodyB.GetWorldPoint(djd.LocalAnchorB) - djd.BodyA.GetWorldPoint(djd.LocalAnchorA);
            djd.Length = d.Length();
            World.AddJoint(djd);

            {
                const float radius = 0.2f;

                CircleShape shape = new CircleShape(radius, 10);

                for (int i = 0; i < 4; ++i)
                {
                    Body body = BodyFactory.CreateBody(World);
                    body.BodyType = BodyType.Dynamic;
                    body.Position = new Vector2(5.9f + 2.0f * radius * i, 2.4f);

                    Fixture fix = body.CreateFixture(shape);
                    fix.OnCollision += BallCollision;
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Load a map from file and create collision objects for it.  Appends map horizontally if one exists.
        /// </summary>
        /// <param name="filename">File to load map from.</param>
        public void LoadOrExtendMap(string filename, bool spawnPlayer = false)
        {
            Tiled.Map map = Tiled.Map.Load(Path.Combine(Game.Content.RootDirectory, filename), Game.Content);

            // Destroy and re-create collision body for map.
            if (WorldBody == null) {
                WorldBody = world.CreateBody();
                WorldBody.IsStatic = true;
            }

            Vector2 tileHalfSize = new Vector2(map.TileWidth, map.TileHeight) / 2;
            Vector2 tileSize = new Vector2(map.TileWidth, map.TileHeight);

            CollisionType[,] levelCollision = new CollisionType[map.Width, map.Height];

            float defaultZVal = 0.001f; //changed from 0.9f, was drawing after foreground objects

            // Tile id to collision type mapping.
            List<CollisionType> collision = new List<CollisionType>();

            foreach (KeyValuePair<string, Tiled.Layer> layer in map.Layers) {
                defaultZVal -= 0.001f;

                for (int x = 0; x < layer.Value.Width; ++x)
                    for (int y = 0; y < layer.Value.Height; ++y) {
                        int tileId = layer.Value.GetTile(x, y);

                        if (tileId >= collision.Count || collision[tileId] == 0) {
                            Tiled.Tileset.TilePropertyList props = GetTileProperties(map, tileId);

                            // The only way to add new elements at arbitrary indices is to fill up the rest of the array.  Do so.
                            for (int i = collision.Count; i < tileId + 1; ++i) collision.Add(0);

                            if (props != null && props.ContainsKey("collision")) {
                                string value = props["collision"];
                                if (value.Equals("solid", StringComparison.OrdinalIgnoreCase)) {
                                    collision[tileId] = CollisionType.Solid;
                                } else if (value.Equals("slopeup", StringComparison.OrdinalIgnoreCase)) {
                                    collision[tileId] = CollisionType.SlopeUp;
                                } else if (value.Equals("slopedown", StringComparison.OrdinalIgnoreCase)) {
                                    collision[tileId] = CollisionType.SlopeDown;
                                } else if (value.Equals("halfslopeup1", StringComparison.OrdinalIgnoreCase)) {
                                    collision[tileId] = CollisionType.HalfSlopeUp1;
                                } else if (value.Equals("halfslopeup2", StringComparison.OrdinalIgnoreCase)) {
                                    collision[tileId] = CollisionType.HalfSlopeUp2;
                                } else if (value.Equals("halfslopedown1", StringComparison.OrdinalIgnoreCase)) {
                                    collision[tileId] = CollisionType.HalfSlopeDown1;
                                } else if (value.Equals("halfslopedown2", StringComparison.OrdinalIgnoreCase)) {
                                    collision[tileId] = CollisionType.HalfSlopeDown2;
                                } else {
                                    collision[tileId] = CollisionType.None;
                                }
                            } else {
                                collision[tileId] = CollisionType.None;
                            }
                        }

                        levelCollision[x, y] = collision[tileId];
                    }

                float z = defaultZVal;

                if (layer.Value.Properties.ContainsKey("zindex")) {
                    if (!float.TryParse(layer.Value.Properties["zindex"], out z)) {
                        z = defaultZVal;
                    }
                }

                MapLayer ml = new MapLayer(this, map, layer.Key, z);
                addObject(ml);
            }

            // Go through collision and try to create large horizontal collision shapes.
            for (int y = 0; y < map.Height; ++y) {
                int firstX = 0;
                bool hasCollision = false;

                for (int x = 0; x < map.Width; ++x) {
                    if (levelCollision[x, y] == CollisionType.Solid) {
                        if (hasCollision) continue;
                        else {
                            hasCollision = true;
                            firstX = x;
                        }
                    } else {
                        if (hasCollision) {
                            hasCollision = false;
                            int tilesWide = x - firstX;
                            if (tilesWide == 1) continue;

                            for (int i = firstX; i <= x; ++i) levelCollision[i, y] = CollisionType.None;

                            AddCollisionRectangle(
                                tileHalfSize * new Vector2(tilesWide, 1.0f)
                                , new Vector2(tileSize.X * (x - (float) tilesWide / 2), tileSize.Y * (y + 0.5f))
                            );
                        }
                    }
                }

                // Create final collision.
                if (hasCollision) {
                    for (int i = firstX; i < map.Width; ++i) levelCollision[i, y] = CollisionType.None;

                    int tilesWide = map.Width - firstX;
                    AddCollisionRectangle(
                        tileHalfSize * new Vector2(tilesWide, 1.0f)
                        , new Vector2(tileSize.X * (map.Width - (float) tilesWide / 2), tileSize.Y * (y + 0.5f))
                    );
                }
            }

            // Go through collision and try to create large vertical collision shapes.
            for (int x = 0; x < map.Width; ++x) {
                int firstY = 0;
                bool hasCollision = false;

                for (int y = 0; y < map.Height; ++y) {
                    if (levelCollision[x, y] == CollisionType.Solid) {
                        if (hasCollision) continue;
                        else {
                            hasCollision = true;
                            firstY = y;
                        }
                    } else {
                        if (hasCollision) {
                            hasCollision = false;
                            int tilesTall = y - firstY;

                            AddCollisionRectangle(
                                tileHalfSize * new Vector2(1.0f, tilesTall)
                                , new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y - (float) tilesTall / 2))
                            );
                        }
                    }
                }

                // Create final collision.
                if (hasCollision) {
                    int tilesTall = map.Height - firstY;
                    AddCollisionRectangle(
                        tileHalfSize * new Vector2(1.0f, tilesTall)
                        , new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (map.Height - (float) tilesTall / 2))
                    );
                }
            }

            // Traverse map and create non-solid tile shapes.
            for (int x = 0; x < map.Width; ++x) {
                for (int y = 0; y < map.Height; ++y) {
                    switch (levelCollision[x, y]) {
                        case CollisionType.Solid:
                            // Already handled.
                            break;

                        case CollisionType.SlopeUp: {
                            Vector2 halfsize = UnitConverter.ToSimUnits(tileHalfSize);
                            Vector2 center = UnitConverter.ToSimUnits(new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y + 0.5f)));

                            PolygonShape poly = new PolygonShape();
                            poly.Set(new FarseerPhysics.Common.Vertices(new Vector2[] {
                                center + new Vector2(-halfsize.X, halfsize.Y)
                                , center + new Vector2(halfsize.X, -halfsize.Y)
                                , center + new Vector2(halfsize.X, halfsize.Y)
                            }));
                            WorldBody.CreateFixture(poly);
                            break;
                        }

                        case CollisionType.HalfSlopeUp1: {
                            Vector2 halfsize = UnitConverter.ToSimUnits(tileHalfSize);
                            Vector2 center = UnitConverter.ToSimUnits(new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y + 0.5f)));

                            PolygonShape poly = new PolygonShape();
                            poly.Set(new FarseerPhysics.Common.Vertices(new Vector2[] {
                                center + new Vector2(-halfsize.X, halfsize.Y)
                                , center + new Vector2(halfsize.X, 0.0f)
                                , center + new Vector2(halfsize.X, halfsize.Y)
                            }));
                            Fixture f = WorldBody.CreateFixture(poly);
                            break;
                        }

                        case CollisionType.HalfSlopeUp2: {
                            Vector2 halfsize = UnitConverter.ToSimUnits(tileHalfSize);
                            Vector2 center = UnitConverter.ToSimUnits(new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y + 0.5f)));

                            PolygonShape poly = new PolygonShape();
                            poly.Set(new FarseerPhysics.Common.Vertices(new Vector2[] {
                                center + new Vector2(-halfsize.X, halfsize.Y)
                                , center + new Vector2(-halfsize.X, 0.0f)
                                , center + new Vector2(halfsize.X, -halfsize.Y)
                                , center + new Vector2(halfsize.X, halfsize.Y)
                            }));
                            WorldBody.CreateFixture(poly);
                            break;
                        }

                        case CollisionType.SlopeDown: {
                            Vector2 halfsize = UnitConverter.ToSimUnits(tileHalfSize);
                            Vector2 center = UnitConverter.ToSimUnits(new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y + 0.5f)));

                            PolygonShape poly = new PolygonShape();
                            poly.Set(new FarseerPhysics.Common.Vertices(new Vector2[] {
                                center + new Vector2(-halfsize.X, halfsize.Y)
                                , center + new Vector2(-halfsize.X, -halfsize.Y)
                                , center + new Vector2(halfsize.X, halfsize.Y)
                            }));
                            WorldBody.CreateFixture(poly);
                            break;
                        }

                        case CollisionType.HalfSlopeDown1: {
                            Vector2 halfsize = UnitConverter.ToSimUnits(tileHalfSize);
                            Vector2 center = UnitConverter.ToSimUnits(new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y + 0.5f)));

                            PolygonShape poly = new PolygonShape();
                            poly.Set(new FarseerPhysics.Common.Vertices(new Vector2[] {
                                center + new Vector2(-halfsize.X, halfsize.Y)
                                , center + new Vector2(-halfsize.X, -halfsize.Y)
                                , center + new Vector2(halfsize.X, 0.0f)
                                , center + new Vector2(halfsize.X, halfsize.Y)
                            }));
                            WorldBody.CreateFixture(poly);
                            break;
                        }

                        case CollisionType.HalfSlopeDown2: {
                            Vector2 halfsize = UnitConverter.ToSimUnits(tileHalfSize);
                            Vector2 center = UnitConverter.ToSimUnits(new Vector2(tileSize.X * (x + 0.5f), tileSize.Y * (y + 0.5f)));

                            PolygonShape poly = new PolygonShape();
                            poly.Set(new FarseerPhysics.Common.Vertices(new Vector2[] {
                                center + new Vector2(-halfsize.X, halfsize.Y)
                                , center + new Vector2(-halfsize.X, 0.0f)
                                , center + new Vector2(halfsize.X, halfsize.Y)
                            }));
                            WorldBody.CreateFixture(poly);
                            break;
                        }
                    }
                }
            }

            SpawnController.CreateSpawnPoints(map.ObjectGroups.Values, Vector2.Zero, spawnPlayer);
        }
        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);

                Vertices edge = PolygonTools.CreateEdge(new Vector2(-20.0f, -20.0f), new Vector2(-20.0f, 20.0f));

                PolygonShape shape = new PolygonShape(edge, 0);

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

                // Right vertical
                edge = PolygonTools.CreateEdge(new Vector2(20.0f, -20.0f), new Vector2(20.0f, 20.0f));
                shape.Set(edge);
                ground.CreateFixture(shape);

                // Top horizontal
                edge = PolygonTools.CreateEdge(new Vector2(-20.0f, 20.0f), new Vector2(20.0f, 20.0f));
                shape.Set(edge);
                ground.CreateFixture(shape);

                // Bottom horizontal
                edge = PolygonTools.CreateEdge(new Vector2(-20.0f, -20.0f), new Vector2(20.0f, -20.0f));
                shape.Set(edge);
                ground.CreateFixture(shape);
            }

            {
                Transform xf1 = new Transform();
                xf1.R.Set(0.3524f*Settings.Pi);
                xf1.Position = MathUtils.Multiply(ref xf1.R, new Vector2(1.0f, 0.0f));

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

                PolygonShape poly1 = new PolygonShape(vertices, 4);

                Transform xf2 = new Transform();
                xf2.R.Set(-0.3524f*Settings.Pi);
                xf2.Position = MathUtils.Multiply(ref xf2.R, new Vector2(-1.0f, 0.0f));

                vertices[0] = MathUtils.Multiply(ref xf2, new Vector2(-1.0f, 0.0f));
                vertices[1] = MathUtils.Multiply(ref xf2, new Vector2(1.0f, 0.0f));
                vertices[2] = MathUtils.Multiply(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, Vector2.Zero);
                    jd.CollideConnected = true;
                    jd.MaxForce = mass*gravity;
                    jd.MaxTorque = mass*radius*gravity;

                    World.AddJoint(jd);
                }
            }
        }
        public List<Shape> CreateShapesFromElement(World simulator, PhysicsSprite entity, PhysicsSprite.ShapeTypes shapeType)
        {
            List<Shape> shapeDefs = new List<Shape>();

            switch (shapeType)
            {
                case PhysicsSprite.ShapeTypes.Ellipse:
                    xna.Vector2 worldRadius = ScreenSizeToWorldSize(new SysWin.Size(entity.Width / 2, entity.Width / 2));

                    CircleShape circleDef = new CircleShape(worldRadius.Y, 0.1f);
                    
                    shapeDefs.Add(circleDef);
                    break;
                case PhysicsSprite.ShapeTypes.Rectangle:
                    PolygonShape polygonRect = new PolygonShape(0.1f);
                    SysWin.Rect rect = new SysWin.Rect(0, 0, entity.Width, entity.Height);

                    xna.Vector2 pos = new xna.Vector2(0F, 0F);
                    // does the box have a rotation?
                    double angle = 0;
                    if (entity.RenderTransform is RotateTransform)
                    {
                        angle = (entity.RenderTransform as RotateTransform).Angle;
                    }
                    else
                        if (entity.RenderTransform is CompositeTransform)
                        {
                            angle = (entity.RenderTransform as CompositeTransform).Rotation;
                        }

                    float radAngle = (float)(Math.PI * angle / 180.0);

                    xna.Vector2 worldSize = ScreenSizeToWorldSize(new SysWin.Size(rect.Width / 2, rect.Height / 2));
                    //polygonRect.SetAsBox(worldSize.X, worldSize.Y, new xna.Vector2(0,0), radAngle);
                    polygonRect.SetAsBox(worldSize.X, worldSize.Y, new xna.Vector2(0, 0), 0);
                    shapeDefs.Add(polygonRect);
                    break;
                default:
                    // Polygon via Path
                    Vertices vertices = new Vertices();

                    UIShapes.Path pathBoundary = (entity as Canvas).Children[0] as UIShapes.Path;
                    if (pathBoundary == null)
                    {
                        throw new Exception("The PhysicsSprite " + entity.Name + " has a Polygon ShapeType, but the first element in the PhysicsSprite must be a Path element that depicts the shape. Note you can set the Visibility of this Path to Collapsed if you do not want it shown in the Sprite.");
                    }
                    else
                    {
                        PathGeometry pathGeom = pathBoundary.Data as PathGeometry;

                        if (pathGeom == null)
                        {
                            throw new Exception("The PhysicsSprite " + entity.Name + " contains a Path as the first element, but that Path has no PathGeometry defined.");
                        }
                        else
                        {
#if WINDOWS_PHONE || SILVERLIGHT
                            PathConverter.StringToPathGeometryConverter cnv = new PathConverter.StringToPathGeometryConverter();
                            string geom = pathGeom.ToString();
                            if (geom != string.Empty)
                            {
                                pathGeom = cnv.Convert(geom);
                            }
                            
#endif
                            foreach (PathFigure figure in pathGeom.Figures)
                            {
                                SysWin.Point ptStart = figure.StartPoint;
                                // adjust the position for origin at center
                                ptStart.X = (ptStart.X - ((float)entity.Width / 2));
                                ptStart.Y = (ptStart.Y - ((float)entity.Height / 2));
                                // adjust the position for Canvas Left, Top
                                ptStart.X = ptStart.X + Canvas.GetLeft(pathBoundary);
                                ptStart.Y = ptStart.Y + Canvas.GetTop(pathBoundary);

                                vertices.Add(ScreenSizeToWorldSize(ptStart));

                                foreach (PathSegment segment in figure.Segments)
                                {
                                    if (segment is LineSegment)
                                    {
                                        LineSegment lineSegment = segment as LineSegment;
                                        SysWin.Point ptNext = lineSegment.Point;
                                        // adjust the position for origin at center
                                        ptNext.X = (ptNext.X - ((float)entity.Width / 2));
                                        ptNext.Y = (ptNext.Y - ((float)entity.Height / 2));
                                        // adjust the position for Canvas Left, Top
                                        ptNext.X = ptNext.X + Canvas.GetLeft(pathBoundary);
                                        ptNext.Y = ptNext.Y + Canvas.GetTop(pathBoundary);
                                        vertices.Add(ScreenSizeToWorldSize(ptNext));
                                    }
                                    else
                                        if (segment is BezierSegment)
                                        {
                                            // HACK: This DOES NOT take into account a real Bezier Curve!!
                                            BezierSegment bezSegment = segment as BezierSegment;

                                            SysWin.Point ptNext = bezSegment.Point3;
                                            // adjust the position for origin at center
                                            ptNext.X = (ptNext.X + ((float)entity.Width / 2));
                                            ptNext.Y = (ptNext.Y + ((float)entity.Height / 2));
                                            // adjust the position for Canvas Left, Top
                                            ptNext.X = ptNext.X + Canvas.GetLeft(pathBoundary);
                                            ptNext.Y = ptNext.Y + Canvas.GetTop(pathBoundary);
                                            vertices.Add(ScreenSizeToWorldSize(bezSegment.Point2));

                                        }
                                }
                            }

                            List<Vertices> verticesDecomposed;

                            // DEMO: (2): We need CONVEX shapes, but Decomposers are provided in Farseer.
                            switch (DecomposerType)
                            {
                                case DecomposerTypes.CDT:
                                    verticesDecomposed = CDTDecomposer.ConvexPartition(vertices);
                                    break;
                                case DecomposerTypes.Earclip:
                                    verticesDecomposed = EarclipDecomposer.ConvexPartition(vertices);
                                    break;
                                case DecomposerTypes.Flipcode:
                                    verticesDecomposed = FlipcodeDecomposer.ConvexPartition(vertices);
                                    break;
                                case DecomposerTypes.Melkman:
                                    verticesDecomposed = new List<Vertices>();
                                    verticesDecomposed.Add(Melkman.GetConvexHull(vertices));
                                    break;
                                case DecomposerTypes.Giftwrap:
                                    verticesDecomposed = new List<Vertices>();
                                    verticesDecomposed.Add(GiftWrap.GetConvexHull(vertices));
                                    break;
                                default:
                                    verticesDecomposed = BayazitDecomposer.ConvexPartition(vertices);
                                    break;
                            }


                            foreach (Vertices vertexDecomposed in verticesDecomposed)
                            {
                                if (vertexDecomposed.Count < 3)
                                {
                                    //throw new Exception("The PhysicsSprite " + entity.Name + " contains a Path as the first element, but one of the Decomposed Polygons has " + vertexDecomposed.Count + " vertices. You must have at least 3 vertices for a polygon boundary.");
                                }
                                else
                                {
                                    if (vertexDecomposed.Count > FarseerPhysics.Settings.MaxPolygonVertices)
                                    {
                                        // trim down the # of vertices
                                        double skipNum = (vertexDecomposed.Count - FarseerPhysics.Settings.MaxPolygonVertices);
                                        skipNum = Math.Round(Convert.ToDouble(vertexDecomposed.Count) / skipNum);


                                        for (int i = vertexDecomposed.Count - 1; i >= 0; i -= Convert.ToInt32(skipNum))
                                        {
                                            vertexDecomposed.Remove(vertexDecomposed[i]);
                                        }
                                    }

                                    PolygonShape polygonDef = new PolygonShape(0.1f);
                                    polygonDef.Set(vertexDecomposed);
                                    shapeDefs.Add(polygonDef);
                                }
                            }
                        }
                    }

                    break;
            }


            return shapeDefs;
        }