public static FrictionJoint CreateFrictionJoint(World world, Body bodyA, Body bodyB, Vector2 anchor, bool useWorldCoordinates = false) { var frictionJoint = new FrictionJoint(bodyA, bodyB, anchor, useWorldCoordinates); world.addJoint(frictionJoint); return(frictionJoint); }
//public static FixedDistanceJoint CreateFixedDistanceJoint(World world, Body body, Vector2 localAnchor, // Vector2 worldAnchor) //{ // FixedDistanceJoint distanceJoint = new FixedDistanceJoint(body, localAnchor, worldAnchor); // world.AddJoint(distanceJoint); // return distanceJoint; //} #endregion #region Friction Joint public static FrictionJoint CreateFrictionJoint(World world, Body bodyA, Body bodyB, Vector2 anchor) { FrictionJoint frictionJoint = new FrictionJoint(bodyA, bodyB, anchor); world.AddJoint(frictionJoint); return(frictionJoint); }
public override Joint CreateJoint() { var joint = new FrictionJoint(BodyA, BodyB, Anchor); joint.CollideConnected = CollideConnected; joint.MaxForce = MaxForce; joint.MaxTorque = MaxTorque; return(joint); }
public override Joint createJoint() { var joint = new FrictionJoint(bodyA, bodyB, anchor); joint.collideConnected = collideConnected; joint.maxForce = maxForce; joint.maxTorque = maxTorque; return(joint); }
public override Joint CreateJoint() { FrictionJoint joint = new FrictionJoint(BodyA, BodyB, Anchor) { CollideConnected = CollideConnected, MaxForce = MaxForce, MaxTorque = MaxTorque }; return(joint); }
protected override void LoadContent() { // Initialize camera controls _view = Matrix.Identity; _cameraPosition = Vector2.Zero; _screenCenter = new Vector2(_graphics.GraphicsDevice.Viewport.Width / 2f, _graphics.GraphicsDevice.Viewport.Height / 2f); _batch = new SpriteBatch(_graphics.GraphicsDevice); _font = Content.Load <SpriteFont>("font"); // Load sprites _circleSprite = Content.Load <Texture2D>("CircleSprite"); // 96px x 96px => 1.5m x 1.5m // _groundSprite = Content.Load<Texture2D>("GroundSprite"); // 512px x 64px => 8m x 1m /* We need XNA to draw the ground and circle at the center of the shapes */ // _groundOrigin = new Vector2(_groundSprite.Width / 2f, _groundSprite.Height / 2f); _circleOrigin = new Vector2(_circleSprite.Width / 2f, _circleSprite.Height / 2f); // Velcro Physics expects objects to be scaled to MKS (meters, kilos, seconds) // 1 meters equals 64 pixels here ConvertUnits.SetDisplayUnitToSimUnitRatio(64f); /* Circle */ // Convert screen center from pixels to meters Vector2 circlePosition = ConvertUnits.ToSimUnits(_screenCenter) + new Vector2(0, -1.5f); // Create the circle fixture _circleBody = BodyFactory.CreateCircle(_world, ConvertUnits.ToSimUnits(96 / 2f), 1f, circlePosition, BodyType.Dynamic); // Give it some bounce and friction _circleBody.Restitution = 0.3f; _circleBody.Friction = 0.5f; /* Ground */ // Vector2 groundPosition = ConvertUnits.ToSimUnits(_screenCenter) + new Vector2(0, 1.25f); // Create the ground fixture // _groundBody = BodyFactory.CreateRectangle(_world, ConvertUnits.ToSimUnits(512f), ConvertUnits.ToSimUnits(64f), 1f, groundPosition); // _groundBody.BodyType = BodyType.Static; // _groundBody.Restitution = 0.3f; // _groundBody.Friction = 0.5f; var floor = BodyFactory.CreateBody(_world); _joint = JointFactory.CreateFrictionJoint(_world, floor, _circleBody); _joint.MaxForce = 5; _joint.MaxTorque = 5; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } FrictionJoint j = this.joint as FrictionJoint; j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA); j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB); j.MaxForce = PhysicsConvert.ToPhysicalUnit(this.maxForce) / Time.SPFMult; j.MaxTorque = PhysicsConvert.ToPhysicalUnit(this.maxTorque) / Time.SPFMult; }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } FrictionJoint j = this.joint as FrictionJoint; j.LocalAnchorA = GetFarseerPoint(this.ParentBody, this.localAnchorA); j.LocalAnchorB = GetFarseerPoint(this.OtherBody, this.localAnchorB); j.MaxForce = PhysicsUnit.ForceToPhysical * this.maxForce; j.MaxTorque = PhysicsUnit.TorqueToPhysical * this.maxTorque; }
private ApplyForceTest() { World.Gravity = Vector2.Zero; const float restitution = 0.4f; Body ground; { ground = BodyFactory.CreateBody(World); ground.Position = new Vector2(0.0f, 20.0f); EdgeShape shape = new EdgeShape(new Vector2(-20.0f, -20.0f), new Vector2(-20.0f, 20.0f)); // Left vertical Fixture fixture = ground.CreateFixture(shape); fixture.Restitution = restitution; // Right vertical shape = new EdgeShape(new Vector2(20.0f, -20.0f), new Vector2(20.0f, 20.0f)); ground.CreateFixture(shape); // Top horizontal shape = new EdgeShape(new Vector2(-20.0f, 20.0f), new Vector2(20.0f, 20.0f)); ground.CreateFixture(shape); // Bottom horizontal shape = new EdgeShape(new Vector2(-20.0f, -20.0f), new Vector2(20.0f, -20.0f)); ground.CreateFixture(shape); } { Transform xf1 = new Transform(); xf1.q.Set(0.3524f * Settings.Pi); xf1.p = MathUtils.Mul(ref xf1.q, new Vector2(1.0f, 0.0f)); Vertices vertices = new Vertices(3); vertices.Add(MathUtils.Mul(ref xf1, new Vector2(-1.0f, 0.0f))); vertices.Add(MathUtils.Mul(ref xf1, new Vector2(1.0f, 0.0f))); vertices.Add(MathUtils.Mul(ref xf1, new Vector2(0.0f, 0.5f))); PolygonShape poly1 = new PolygonShape(vertices, 4); Transform xf2 = new Transform(); xf2.q.Set(-0.3524f * Settings.Pi); xf2.p = MathUtils.Mul(ref xf2.q, new Vector2(-1.0f, 0.0f)); vertices[0] = MathUtils.Mul(ref xf2, new Vector2(-1.0f, 0.0f)); vertices[1] = MathUtils.Mul(ref xf2, new Vector2(1.0f, 0.0f)); vertices[2] = MathUtils.Mul(ref xf2, new Vector2(0.0f, 0.5f)); PolygonShape poly2 = new PolygonShape(vertices, 2); _body = BodyFactory.CreateBody(World); _body.BodyType = BodyType.Dynamic; _body.Position = new Vector2(0.0f, 2.0f); _body.Rotation = Settings.Pi; _body.AngularDamping = 5.0f; _body.LinearDamping = 0.8f; _body.SleepingAllowed = true; _body.CreateFixture(poly1); _body.CreateFixture(poly2); } { Vertices box = PolygonUtils.CreateRectangle(0.5f, 0.5f); PolygonShape shape = new PolygonShape(box, 1); for (int i = 0; i < 10; ++i) { Body body = BodyFactory.CreateBody(World); body.Position = new Vector2(0.0f, 5.0f + 1.54f * i); body.BodyType = BodyType.Dynamic; Fixture fixture = body.CreateFixture(shape); fixture.Friction = 0.3f; const float gravity = 10.0f; float I = body.Inertia; float mass = body.Mass; // For a circle: I = 0.5 * m * r * r ==> r = sqrt(2 * I / m) float radius = (float)Math.Sqrt(2.0 * (I / mass)); FrictionJoint jd = new FrictionJoint(ground, body, Vector2.Zero); jd.CollideConnected = true; jd.MaxForce = mass * gravity; jd.MaxTorque = mass * radius * gravity; World.AddJoint(jd); } } }
private SerializationTest() { Body ground = BodyFactory.CreateEdge(World, new Vector2(-20, 0), new Vector2(20, 0)); //Friction and distance joint { Body bodyA = BodyFactory.CreateCircle(World, 1, 1.5f, new Vector2(10, 25)); bodyA.BodyType = BodyType.Dynamic; Body bodyB = BodyFactory.CreateRectangle(World, 1, 1, 1, new Vector2(-1, 25)); bodyB.BodyType = BodyType.Dynamic; FrictionJoint frictionJoint = JointFactory.CreateFrictionJoint(World, bodyB, ground, Vector2.Zero); frictionJoint.CollideConnected = true; frictionJoint.MaxForce = 100; JointFactory.CreateDistanceJoint(World, bodyA, bodyB); } //Wheel joint { Vertices vertices = new Vertices(6); vertices.Add(new Vector2(-1.5f, -0.5f)); vertices.Add(new Vector2(1.5f, -0.5f)); vertices.Add(new Vector2(1.5f, 0.0f)); vertices.Add(new Vector2(0.0f, 0.9f)); vertices.Add(new Vector2(-1.15f, 0.9f)); vertices.Add(new Vector2(-1.5f, 0.2f)); Body carBody = BodyFactory.CreatePolygon(World, vertices, 1, new Vector2(0, 1)); carBody.BodyType = BodyType.Dynamic; Body wheel1 = BodyFactory.CreateCircle(World, 0.4f, 1, new Vector2(-1.0f, 0.35f)); wheel1.BodyType = BodyType.Dynamic; wheel1.Friction = 0.9f; Body wheel2 = BodyFactory.CreateCircle(World, 0.4f, 1, new Vector2(1.0f, 0.4f)); wheel2.BodyType = BodyType.Dynamic; wheel2.Friction = 0.9f; Vector2 axis = new Vector2(0.0f, 1.0f); WheelJoint spring1 = JointFactory.CreateWheelJoint(World, carBody, wheel1, axis); spring1.MotorSpeed = 0.0f; spring1.MaxMotorTorque = 20.0f; spring1.MotorEnabled = true; spring1.Frequency = 4; spring1.DampingRatio = 0.7f; WheelJoint spring2 = JointFactory.CreateWheelJoint(World, carBody, wheel2, axis); spring2.MotorSpeed = 0.0f; spring2.MaxMotorTorque = 10.0f; spring2.MotorEnabled = false; spring2.Frequency = 4; spring2.DampingRatio = 0.7f; } //Prismatic joint { Body body = BodyFactory.CreateRectangle(World, 2, 2, 5, new Vector2(-10.0f, 10.0f)); body.BodyType = BodyType.Dynamic; body.Rotation = 0.5f * Settings.Pi; Vector2 axis = new Vector2(2.0f, 1.0f); axis.Normalize(); PrismaticJoint joint = JointFactory.CreatePrismaticJoint(World, ground, body, Vector2.Zero, axis); joint.MotorSpeed = 5.0f; joint.MaxMotorForce = 1000.0f; joint.MotorEnabled = true; joint.LowerLimit = -10.0f; joint.UpperLimit = 20.0f; joint.LimitEnabled = true; } // Pulley joint { Body body1 = BodyFactory.CreateRectangle(World, 2, 4, 5, new Vector2(-10.0f, 16.0f)); body1.BodyType = BodyType.Dynamic; Body body2 = BodyFactory.CreateRectangle(World, 2, 4, 5, new Vector2(10.0f, 16.0f)); body2.BodyType = BodyType.Dynamic; Vector2 anchor1 = new Vector2(-10.0f, 16.0f + 2.0f); Vector2 anchor2 = new Vector2(10.0f, 16.0f + 2.0f); Vector2 worldAnchor1 = new Vector2(-10.0f, 16.0f + 2.0f + 12.0f); Vector2 worldAnchor2 = new Vector2(10.0f, 16.0f + 2.0f + 12.0f); JointFactory.CreatePulleyJoint(World, body1, body2, anchor1, anchor2, worldAnchor1, worldAnchor2, 1.5f, true); } //Revolute joint { Body ball = BodyFactory.CreateCircle(World, 3.0f, 5.0f, new Vector2(5.0f, 30.0f)); ball.BodyType = BodyType.Dynamic; Body polygonBody = BodyFactory.CreateRectangle(World, 20, 0.4f, 2, new Vector2(10, 10)); polygonBody.BodyType = BodyType.Dynamic; polygonBody.IsBullet = true; RevoluteJoint joint = JointFactory.CreateRevoluteJoint(World, ground, polygonBody, new Vector2(10, 0)); joint.LowerLimit = -0.25f * Settings.Pi; joint.UpperLimit = 0.0f * Settings.Pi; joint.LimitEnabled = true; } //Weld joint { PolygonShape shape = new PolygonShape(PolygonUtils.CreateRectangle(0.5f, 0.125f), 20); Body prevBody = ground; for (int i = 0; i < 10; ++i) { Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(-14.5f + 1.0f * i, 5.0f); body.CreateFixture(shape); Vector2 anchor = new Vector2(0.5f, 0); if (i == 0) { anchor = new Vector2(-15f, 5); } JointFactory.CreateWeldJoint(World, prevBody, body, anchor, new Vector2(-0.5f, 0)); prevBody = body; } } //Rope joint { LinkFactory.CreateChain(World, new Vector2(-10, 10), new Vector2(-20, 10), 0.1f, 0.5f, 10, 0.1f, true); } //Angle joint { Body fA = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(-5, 4)); fA.BodyType = BodyType.Dynamic; fA.Rotation = (float)(Math.PI / 3); Body fB = BodyFactory.CreateRectangle(World, 4, 4, 1, new Vector2(5, 4)); fB.BodyType = BodyType.Dynamic; AngleJoint joint = new AngleJoint(fA, fB); joint.TargetAngle = (float)Math.PI / 2; World.AddJoint(joint); } //Motor joint { Body body = BodyFactory.CreateRectangle(World, 4, 1, 2, new Vector2(0, 35)); body.BodyType = BodyType.Dynamic; body.Friction = 0.6f; MotorJoint motorJoint = JointFactory.CreateMotorJoint(World, ground, body); motorJoint.MaxForce = 1000.0f; motorJoint.MaxTorque = 1000.0f; motorJoint.LinearOffset = new Vector2(0, 35); motorJoint.AngularOffset = (float)(Math.PI / 3f); } }
//private static Joint DeserializeSliderJoint(XElement jointElement, Body bodyA, Body bodyB, World world) //{ // SliderJoint joint = null; // Vector2 localAnchorA, localAnchorB; // float minLength = 0.0f, maxLength = 100.0f, dampingRatio = 0.0f, frequency = 0.0f; // localAnchorA = bodyA.WorldCenter; // localAnchorB = bodyB.WorldCenter; // foreach (XElement element in jointElement.Elements()) // { // switch (element.Name.ToString().ToLower()) // { // case "minlength": // float.TryParse(element.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out minLength); // break; // case "maxlength": // float.TryParse(element.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out maxLength); // break; // case "dampingratio": // float.TryParse(element.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out dampingRatio); // break; // case "frequency": // float.TryParse(element.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out frequency); // break; // case "localanchora": // localAnchorA = localAnchorA.DeserializeOffset(element); // localAnchorA = ConvertUnits.ToSimUnits(localAnchorA); // break; // case "localanchorb": // localAnchorB = localAnchorB.DeserializeOffset(element); // localAnchorB = ConvertUnits.ToSimUnits(localAnchorB); // break; // } // } // joint = JointFactory.CreateSliderJoint(world, bodyA, bodyB, localAnchorA, localAnchorB, minLength, maxLength); // joint.DampingRatio = dampingRatio; // joint.Frequency = frequency; // return joint; //} #endregion #endregion public static Joint CopyJoint(Joint joint, Body bodyA, Body bodyB, World world) { Joint newJoint = null; switch (joint.JointType) { case JointType.Angle: newJoint = JointFactory.CreateAngleJoint(world, bodyA, bodyB); break; case JointType.Distance: newJoint = new DistanceJoint(bodyA, bodyB, bodyA.WorldCenter, bodyB.WorldCenter); break; /*case JointType.FixedAngle: * newJoint = new FarseerPhysics.Factories.JointFactory().(bodyA); * break; * case JointType.FixedDistance: * newJoint = new FixedDistanceJoint(bodyA, bodyA.WorldCenter, Vector2.Zero); * break; * case JointType.FixedFriction: * newJoint = new FixedFrictionJoint(bodyA, bodyA.WorldCenter); * break; * case JointType.FixedPrismatic: * var fpJoint = joint as FixedPrismaticJoint; * var fpAxis = fpJoint.LocalXAxis1; * newJoint = new FixedPrismaticJoint(bodyA, bodyA.WorldCenter, fpAxis); * break; * case JointType.FixedRevolute: * newJoint = new FixedRevoluteJoint(bodyA, bodyA.WorldCenter, Vector2.Zero); * break;*/ case JointType.Friction: newJoint = new FrictionJoint(bodyA, bodyB, bodyA.WorldCenter /*, bodyB.WorldCenter*/); break; /*case JointType.FixedLine: * var lineJoint = joint as LineJoint; * var axis = lineJoint.LocalXAxis; * newJoint = new LineJoint(bodyA, bodyB, bodyA.WorldCenter, axis); * break; */ case JointType.Prismatic: var pJoint = joint as PrismaticJoint; var pAxis = pJoint.LocalXAxis; newJoint = new PrismaticJoint(bodyA, bodyB, bodyA.WorldCenter, bodyB.WorldCenter, pAxis); ((PrismaticJoint)newJoint).LimitEnabled = pJoint.LimitEnabled; ((PrismaticJoint)newJoint).MotorEnabled = pJoint.MotorEnabled; ((PrismaticJoint)newJoint).MaxMotorForce = pJoint.MaxMotorForce; ((PrismaticJoint)newJoint).MotorSpeed = pJoint.MotorSpeed; ((PrismaticJoint)newJoint).LowerLimit = pJoint.LowerLimit; ((PrismaticJoint)newJoint).UpperLimit = pJoint.UpperLimit; ((PrismaticJoint)newJoint).ReferenceAngle = pJoint.ReferenceAngle; //((PrismaticJoint)newJoint).LocalXAxis = pJoint.LocalXAxis; break; case JointType.Pulley: var pulleyJoint = joint as PulleyJoint; var ratio = pulleyJoint.Ratio; newJoint = new PulleyJoint(bodyA, bodyB, Vector2.Zero, Vector2.Zero, bodyA.WorldCenter, bodyB.WorldCenter, ratio); break; case JointType.Revolute: newJoint = new RevoluteJoint(bodyA, bodyB, bodyA.WorldCenter, bodyB.WorldCenter); break; /*case JointType.Slider: * var sliderJoint = joint as SliderJoint; * var minLength = sliderJoint.MinLength; * var maxLength = sliderJoint.MaxLength; * newJoint = new SliderJoint(bodyA, bodyB, bodyA.WorldCenter, bodyB.WorldCenter, minLength, maxLength); * break; */ case JointType.Weld: newJoint = new WeldJoint(bodyA, bodyB, bodyA.WorldCenter, bodyB.WorldCenter); break; } var data = new FarseerJointUserData(); data.BodyAName = ((FarseerJointUserData)joint.UserData).BodyAName; data.BodyBName = ((FarseerJointUserData)joint.UserData).BodyBName; joint.UserData = data; return(newJoint); }
private static void Deserialize(World world, Stream stream) { List <Body> bodies = new List <Body>(); List <Fixture> fixtures = new List <Fixture>(); List <Joint> joints = new List <Joint>(); List <Shape> shapes = new List <Shape>(); XMLFragmentElement root = XMLFragmentParser.LoadFromStream(stream); if (root.Name.ToLower() != "world") { throw new Exception(); } //Read gravity foreach (XMLFragmentElement element in root.Elements) { if (element.Name.ToLower() == "gravity") { world.Gravity = ReadVector(element); break; } } //Read shapes foreach (XMLFragmentElement shapeElement in root.Elements) { if (shapeElement.Name.ToLower() == "shapes") { foreach (XMLFragmentElement element in shapeElement.Elements) { if (element.Name.ToLower() != "shape") { throw new Exception(); } ShapeType type = (ShapeType)Enum.Parse(typeof(ShapeType), element.Attributes[0].Value, true); float density = float.Parse(element.Attributes[1].Value); switch (type) { case ShapeType.Circle: { CircleShape shape = new CircleShape(); shape._density = density; foreach (XMLFragmentElement sn in element.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(); shape._density = density; foreach (XMLFragmentElement sn in element.Elements) { switch (sn.Name.ToLower()) { case "vertices": { List <Vector2> verts = new List <Vector2>(sn.Elements.Count); foreach (XMLFragmentElement vert in sn.Elements) { verts.Add(ReadVector(vert)); } shape.Vertices = new Vertices(verts); } break; case "centroid": shape.MassData.Centroid = ReadVector(sn); break; } } shapes.Add(shape); } break; case ShapeType.Edge: { EdgeShape shape = new EdgeShape(); shape._density = density; foreach (XMLFragmentElement sn in element.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; case ShapeType.Chain: { ChainShape shape = new ChainShape(); shape._density = density; foreach (XMLFragmentElement sn in element.Elements) { switch (sn.Name.ToLower()) { case "vertices": { List <Vector2> verts = new List <Vector2>(sn.Elements.Count); foreach (XMLFragmentElement vert in sn.Elements) { verts.Add(ReadVector(vert)); } shape.Vertices = new Vertices(verts); } break; case "nextvertex": shape.NextVertex = ReadVector(sn); break; case "prevvertex": shape.PrevVertex = ReadVector(sn); break; default: throw new Exception(); } } shapes.Add(shape); } break; } } } } //Read fixtures foreach (XMLFragmentElement fixtureElement in root.Elements) { if (fixtureElement.Name.ToLower() == "fixtures") { foreach (XMLFragmentElement element in fixtureElement.Elements) { Fixture fixture = new Fixture(); if (element.Name.ToLower() != "fixture") { throw new Exception(); } fixture.FixtureId = int.Parse(element.Attributes[0].Value); foreach (XMLFragmentElement sn in element.Elements) { switch (sn.Name.ToLower()) { 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; case "CollisionIgnores": string[] split = ssn.Value.Split('|'); foreach (string s in split) { fixture._collisionIgnores.Add(int.Parse(s)); } 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); } } } //Read bodies foreach (XMLFragmentElement bodyElement in root.Elements) { if (bodyElement.Name.ToLower() == "bodies") { foreach (XMLFragmentElement element in bodyElement.Elements) { Body body = new Body(world); if (element.Name.ToLower() != "body") { throw new Exception(); } body.BodyType = (BodyType)Enum.Parse(typeof(BodyType), element.Attributes[0].Value, true); foreach (XMLFragmentElement sn in element.Elements) { switch (sn.Name.ToLower()) { case "active": bool enabled = bool.Parse(sn.Value); if (enabled) { 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 "bindings": { foreach (XMLFragmentElement pair in sn.Elements) { Fixture fix = fixtures[int.Parse(pair.Attributes[0].Value)]; fix.Shape = shapes[int.Parse(pair.Attributes[1].Value)].Clone(); fix.CloneOnto(body); } break; } } } bodies.Add(body); } } } //Read joints 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.FixedMouse: // joint = new FixedMouseJoint(); // break; //case JointType.FixedRevolute: // break; //case JointType.FixedDistance: // break; //case JointType.FixedLine: // break; //case JointType.FixedPrismatic: // break; //case JointType.FixedAngle: // break; //case JointType.FixedFriction: // break; case JointType.Distance: joint = new DistanceJoint(); break; case JointType.Friction: joint = new FrictionJoint(); break; case JointType.Wheel: joint = new WheelJoint(); 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.Motor: joint = new MotorJoint(); 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.Wheel: { switch (sn.Name.ToLower()) { case "enablemotor": ((WheelJoint)joint).MotorEnabled = bool.Parse(sn.Value); break; case "localanchora": ((WheelJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((WheelJoint)joint).LocalAnchorB = ReadVector(sn); break; case "motorspeed": ((WheelJoint)joint).MotorSpeed = float.Parse(sn.Value); break; case "dampingratio": ((WheelJoint)joint).DampingRatio = float.Parse(sn.Value); break; case "maxmotortorque": ((WheelJoint)joint).MaxMotorTorque = float.Parse(sn.Value); break; case "frequencyhz": ((WheelJoint)joint).Frequency = float.Parse(sn.Value); break; case "axis": ((WheelJoint)joint).Axis = 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 "axis": ((PrismaticJoint)joint).Axis = 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 "worldanchora": ((PulleyJoint)joint).WorldAnchorA = ReadVector(sn); break; case "worldanchorb": ((PulleyJoint)joint).WorldAnchorB = 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 "ratio": ((PulleyJoint)joint).Ratio = float.Parse(sn.Value); break; case "constant": ((PulleyJoint)joint).Constant = 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.Motor: switch (sn.Name.ToLower()) { case "angularoffset": ((MotorJoint)joint).AngularOffset = float.Parse(sn.Value); break; case "linearoffset": ((MotorJoint)joint).LinearOffset = ReadVector(sn); break; case "maxforce": ((MotorJoint)joint).MaxForce = float.Parse(sn.Value); break; case "maxtorque": ((MotorJoint)joint).MaxTorque = float.Parse(sn.Value); break; case "correctionfactor": ((MotorJoint)joint).CorrectionFactor = float.Parse(sn.Value); break; } break; } } } } } world.ProcessChanges(); }
private static void SerializeJoint(List <Body> bodies, Joint joint) { _writer.WriteStartElement("Joint"); _writer.WriteAttributeString("Type", joint.JointType.ToString()); WriteElement("BodyA", FindIndex(bodies, joint.BodyA)); WriteElement("BodyB", FindIndex(bodies, joint.BodyB)); WriteElement("CollideConnected", joint.CollideConnected); WriteElement("Breakpoint", joint.Breakpoint); if (joint.UserData != null) { _writer.WriteStartElement("UserData"); WriteDynamicType(joint.UserData.GetType(), joint.UserData); _writer.WriteEndElement(); } switch (joint.JointType) { case JointType.Distance: { DistanceJoint distanceJoint = (DistanceJoint)joint; WriteElement("DampingRatio", distanceJoint.DampingRatio); WriteElement("FrequencyHz", distanceJoint.Frequency); WriteElement("Length", distanceJoint.Length); WriteElement("LocalAnchorA", distanceJoint.LocalAnchorA); WriteElement("LocalAnchorB", distanceJoint.LocalAnchorB); } break; case JointType.Friction: { FrictionJoint frictionJoint = (FrictionJoint)joint; WriteElement("LocalAnchorA", frictionJoint.LocalAnchorA); WriteElement("LocalAnchorB", frictionJoint.LocalAnchorB); WriteElement("MaxForce", frictionJoint.MaxForce); WriteElement("MaxTorque", frictionJoint.MaxTorque); } break; case JointType.Gear: throw new Exception("Gear joint not supported by serialization"); case JointType.Wheel: { WheelJoint wheelJoint = (WheelJoint)joint; WriteElement("EnableMotor", wheelJoint.MotorEnabled); WriteElement("LocalAnchorA", wheelJoint.LocalAnchorA); WriteElement("LocalAnchorB", wheelJoint.LocalAnchorB); WriteElement("MotorSpeed", wheelJoint.MotorSpeed); WriteElement("DampingRatio", wheelJoint.DampingRatio); WriteElement("MaxMotorTorque", wheelJoint.MaxMotorTorque); WriteElement("FrequencyHz", wheelJoint.Frequency); WriteElement("Axis", wheelJoint.Axis); } break; case JointType.Prismatic: { //NOTE: Does not conform with Box2DScene PrismaticJoint prismaticJoint = (PrismaticJoint)joint; WriteElement("EnableLimit", prismaticJoint.LimitEnabled); WriteElement("EnableMotor", prismaticJoint.MotorEnabled); WriteElement("LocalAnchorA", prismaticJoint.LocalAnchorA); WriteElement("LocalAnchorB", prismaticJoint.LocalAnchorB); WriteElement("Axis", prismaticJoint.Axis); WriteElement("LowerTranslation", prismaticJoint.LowerLimit); WriteElement("UpperTranslation", prismaticJoint.UpperLimit); WriteElement("MaxMotorForce", prismaticJoint.MaxMotorForce); WriteElement("MotorSpeed", prismaticJoint.MotorSpeed); } break; case JointType.Pulley: { PulleyJoint pulleyJoint = (PulleyJoint)joint; WriteElement("WorldAnchorA", pulleyJoint.WorldAnchorA); WriteElement("WorldAnchorB", pulleyJoint.WorldAnchorB); WriteElement("LengthA", pulleyJoint.LengthA); WriteElement("LengthB", pulleyJoint.LengthB); WriteElement("LocalAnchorA", pulleyJoint.LocalAnchorA); WriteElement("LocalAnchorB", pulleyJoint.LocalAnchorB); WriteElement("Ratio", pulleyJoint.Ratio); WriteElement("Constant", pulleyJoint.Constant); } break; case JointType.Revolute: { RevoluteJoint revoluteJoint = (RevoluteJoint)joint; WriteElement("EnableLimit", revoluteJoint.LimitEnabled); WriteElement("EnableMotor", revoluteJoint.MotorEnabled); WriteElement("LocalAnchorA", revoluteJoint.LocalAnchorA); WriteElement("LocalAnchorB", revoluteJoint.LocalAnchorB); WriteElement("LowerAngle", revoluteJoint.LowerLimit); WriteElement("MaxMotorTorque", revoluteJoint.MaxMotorTorque); WriteElement("MotorSpeed", revoluteJoint.MotorSpeed); WriteElement("ReferenceAngle", revoluteJoint.ReferenceAngle); WriteElement("UpperAngle", revoluteJoint.UpperLimit); } break; case JointType.Weld: { WeldJoint weldJoint = (WeldJoint)joint; WriteElement("LocalAnchorA", weldJoint.LocalAnchorA); WriteElement("LocalAnchorB", weldJoint.LocalAnchorB); } break; // // Not part of Box2DScene // case JointType.Rope: { RopeJoint ropeJoint = (RopeJoint)joint; WriteElement("LocalAnchorA", ropeJoint.LocalAnchorA); WriteElement("LocalAnchorB", ropeJoint.LocalAnchorB); WriteElement("MaxLength", ropeJoint.MaxLength); } break; case JointType.Angle: { AngleJoint angleJoint = (AngleJoint)joint; WriteElement("BiasFactor", angleJoint.BiasFactor); WriteElement("MaxImpulse", angleJoint.MaxImpulse); WriteElement("Softness", angleJoint.Softness); WriteElement("TargetAngle", angleJoint.TargetAngle); } break; case JointType.Motor: { MotorJoint motorJoint = (MotorJoint)joint; WriteElement("AngularOffset", motorJoint.AngularOffset); WriteElement("LinearOffset", motorJoint.LinearOffset); WriteElement("MaxForce", motorJoint.MaxForce); WriteElement("MaxTorque", motorJoint.MaxTorque); WriteElement("CorrectionFactor", motorJoint.CorrectionFactor); } break; default: throw new Exception("Joint not supported"); } _writer.WriteEndElement(); }