Exemplo n.º 1
0
 public static FrictionJoint CreateFrictionJoint(PhysicsWorld world, PhysicsBody bodyA, PhysicsBody bodyB, Vector2 anchorA,
                                                 Vector2 anchorB)
 {
     FrictionJoint frictionJoint = new FrictionJoint(bodyA, bodyB, anchorA, anchorB);
     world.AddJoint(frictionJoint);
     return frictionJoint;
 }
Exemplo n.º 2
0
        public void Deserialize(PhysicsWorld 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)
                    {
                        PhysicsBody body = new PhysicsBody(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);
                                            f.Restitution = blueprint.Restitution;
                                            f.UserData = blueprint.UserData;
                                            f.Friction = blueprint.Friction;
                                            f.CollidesWith = blueprint.CollidesWith;
                                            f.CollisionCategories = blueprint.CollisionCategories;
                                            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)
                    {
                        PhysicsJoint 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;
                            }
                        }

                        PhysicsBody bodyA = _bodies[bodyAIndex];
                        PhysicsBody 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;
                            }
                        }
                    }
                }
            }
        }