private RopeTest() { Body ground; { ground = new Body(World); EdgeShape shape = new EdgeShape(new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f)); ground.CreateFixture(shape); } { Body prevBody = ground; PolygonShape largeShape = new PolygonShape(PolygonTools.CreateRectangle(1.5f, 1.5f), 100); PolygonShape smallShape = new PolygonShape(PolygonTools.CreateRectangle(0.5f, 0.125f), 20); const int N = 10; const float y = 15; for (int i = 0; i < N; ++i) { Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(0.5f + 1.0f * i, y); if (i == N - 1) { Fixture fixture = body.CreateFixture(largeShape); fixture.Friction = 0.2f; fixture.CollisionCategories = Category.Cat2; fixture.CollidesWith = Category.All & ~Category.Cat2; body.Position = new Vector2(1.0f * i, y); body.AngularDamping = 0.4f; } else { Fixture fixture = body.CreateFixture(smallShape); fixture.Friction = 0.2f; fixture.CollisionCategories = Category.Cat1; fixture.CollidesWith = Category.All & ~Category.Cat2; } Vector2 anchor = new Vector2(i, y); RevoluteJoint jd = new RevoluteJoint(prevBody, body, prevBody.GetLocalPoint(ref anchor), body.GetLocalPoint(ref anchor)); jd.CollideConnected = false; World.AddJoint(jd); prevBody = body; } _rj = new RopeJoint(ground, prevBody, new Vector2(0, y), Vector2.Zero); //FPE: The two following lines are actually not needed as FPE sets the MaxLength to a default value const float extraLength = 0.01f; _rj.MaxLength = N - 1.0f + extraLength; World.AddJoint(_rj); } }
private void Simulate() { // SIMULATION for (int i = 0; i < jointCount; i++) { RopeJoint joint = joints[i]; Vector3 positionChange = joint.currentPosition - joint.previousPosition; Vector3 extraPreviousPosition = joint.previousPosition; joint.previousPosition = joint.currentPosition; joint.currentPosition += positionChange + gravityAcceleration * (Time.deltaTime * Time.deltaTime); // collision detection if (Physics.CheckSphere(joint.currentPosition, 0.1f, collidable)) { joint.currentPosition = extraPreviousPosition; } } // CONSTRAINTS for (int i = 0; i < constraintIterations; i++) { ApplyConstraints(); } }
public override void HandleInput() { InputHelper input = game.inputManager.inputHelper; if (input.IsNewButtonPress(MouseButtons.LeftButton)) { Vector2 position = ProjectionHelper.PixelToFarseer(input.MousePosition); List <Fixture> list = game.farseerManager.world.TestPointAll(position); if (list.Count > 0) { if (startBody == null) { startBody = list[0].Body; startBodyLocal = startBody.GetLocalPoint(position); } else { Body endBody = list[0].Body; Vector2 endBodyLocal = endBody.GetLocalPoint(position); RopeJoint j = new RopeJoint(startBody, endBody, startBodyLocal, endBodyLocal); j.CollideConnected = true; game.farseerManager.world.AddJoint(j); FormManager.Property.setSelectedObject(j); startBody = null; } } } }
public static RopeJoint CreateRopeJoint(World world, Body bodyA, Body bodyB, Vector2 anchorA, Vector2 anchorB, bool useWorldCoordinates = false) { var ropeJoint = new RopeJoint(bodyA, bodyB, anchorA, anchorB, useWorldCoordinates); world.addJoint(ropeJoint); return(ropeJoint); }
///// <summary> ///// Creates the fixed revolute joint. ///// </summary> ///// <param name="world">The world.</param> ///// <param name="body">The body.</param> ///// <param name="bodyAnchor">The body anchor.</param> ///// <param name="worldAnchor">The world anchor.</param> ///// <returns></returns> //public static FixedRevoluteJoint CreateFixedRevoluteJoint(World world, Body body, Vector2 bodyAnchor, // Vector2 worldAnchor) //{ // FixedRevoluteJoint fixedRevoluteJoint = new FixedRevoluteJoint(body, bodyAnchor, worldAnchor); // world.AddJoint(fixedRevoluteJoint); // return fixedRevoluteJoint; //} #endregion #region Rope Joint /// <summary> /// Creates a rope joint and adds it to the world /// </summary> public static RopeJoint CreateRopeJoint(World world, Body bodyA, Body bodyB, Vector2 anchorA, Vector2 anchorB) { RopeJoint ropeJoint = new RopeJoint(bodyA, bodyB, anchorA, anchorB); world.AddJoint(ropeJoint); return(ropeJoint); }
public override Joint createJoint() { var joint = new RopeJoint(bodyA, bodyB, ownerBodyAnchor * FSConvert.displayToSim, otherBodyAnchor * FSConvert.displayToSim); joint.collideConnected = collideConnected; joint.maxLength = maxLength * FSConvert.displayToSim; return(joint); }
public override Joint CreateJoint() { var joint = new RopeJoint(BodyA, BodyB, OwnerBodyAnchor * FSConvert.DisplayToSim, OtherBodyAnchor * FSConvert.DisplayToSim); joint.CollideConnected = CollideConnected; joint.MaxLength = MaxLength * FSConvert.DisplayToSim; return(joint); }
protected override Joint CreateJoint(Body bodyA, Body bodyB) { if (bodyA == null || bodyB == null) { return(null); } RopeJoint joint = new RopeJoint(bodyA, bodyB, Vector2.Zero, Vector2.Zero); Scene.PhysicsWorld.AddJoint(joint); return(joint); }
public static PayloadChain Connect(SpaceShip spaceShip, Payload payload, Vector2 payloadTarget) { var dynamicWorld = (DynamicEntityWorld)spaceShip.World; var world = dynamicWorld.PhysicsWorld; AABB spaceShipSize; spaceShip.Body.FixtureList.First().GetAABB(out spaceShipSize, 0); AABB payloadSize; payload.Body.FixtureList.First().GetAABB(out payloadSize, 0); var chainSize = new Vector2(1.0f); var chainSizeSingle = Math.Max(chainSize.X, chainSize.Y); var start = new Vector2(spaceShip.Position.X - spaceShipSize.Extents.Y, spaceShip.Position.Y); var length = payloadTarget.Length(); var targetVector = payloadTarget / length; var chainVector = targetVector * chainSizeSingle; start += chainVector; var chainCount = (int)Math.Ceiling(length / chainSizeSingle); var lastBody = spaceShip.Body; var chain = new PayloadChain(spaceShip.Name + "_Chain"); var elements = new List <ChainElement>(); for (var i = 0; i < chainCount; i++) { var chainBody = BodyFactory.CreateBody(world, start + i * chainVector); chainBody.BodyType = BodyType.Dynamic; var chainFixture = FixtureFactory.AttachRectangle(chainSize.X, chainSize.Y, 0.1f, Vector2.Zero, chainBody); chainFixture.CollidesWith = Category.Cat2; JointFactory.CreateRevoluteJoint(world, lastBody, chainBody, -chainVector / 2.0f); lastBody = chainBody; elements.Add(ChainElement.CreateFor(chain, elements.Count, dynamicWorld, chainBody)); } payload.Position = new Vector3(start + chainCount * chainVector + targetVector * 2.5f, 0.0f); JointFactory.CreateRevoluteJoint(world, lastBody, payload.Body, new Vector2(0.0f, -2.5f)); var ropeJoin = new RopeJoint(spaceShip.Body, payload.Body, new Vector2(0.0f, 3.0f), new Vector2(0.0f, -2.5f)); ropeJoin.CollideConnected = true; world.AddJoint(ropeJoin); return(chain); }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } RopeJoint j = this.joint as RopeJoint; j.LocalAnchorB = GetFarseerPoint(this.BodyB, this.localAnchorB); j.LocalAnchorA = GetFarseerPoint(this.BodyA, this.localAnchorA); j.MaxLength = PhysicsConvert.ToPhysicalUnit(this.maxLength); }
internal override void UpdateJoint() { base.UpdateJoint(); if (this.joint == null) { return; } RopeJoint j = this.joint as RopeJoint; j.LocalAnchorB = GetFarseerPoint(this.OtherBody, this.localAnchorB); j.LocalAnchorA = GetFarseerPoint(this.ParentBody, this.localAnchorA); j.MaxLength = PhysicsUnit.LengthToPhysical * this.maxLength; }
public Rope(Vector2 RopeStart, Vector2 RopeEnd) { path.Add(RopeStart); path.Add(RopeEnd); ropeText = GameLoop.gameInstance.Content.Load <Texture2D>("Sprites/rope"); shape = new PolygonShape(PolygonTools.CreateRectangle(0.05f, 0.1f), 0.6f); chainLinks = PathManager.EvenlyDistributeShapesAlongPath(Level.Physics, path, shape, BodyType.Dynamic, 20); /* * MovingFixture = FixtureFactory.CreateRectangle(Level.Physics, 2, 2, 1); * * MovingFixture.Body.BodyType = BodyType.Static; * MovingFixture.Body.Position = RopeStart; * */ foreach (Body chainLink in chainLinks) { chainLink.LinearDamping = 0.5f; foreach (Fixture f in chainLink.FixtureList) { f.Friction = 2.0f; f.CollidesWith = CollisionCategory.None; } } lastBody = chainLinks[(chainLinks.Count - 1)]; // weld = new WeldJoint(MovingFixture.Body, chainLinks[0], Vector2.Zero, Vector2.Zero); // Level.Physics.AddJoint(weld); RopeJoint rope = new RopeJoint(chainLinks[0], chainLinks[chainLinks.Count - 1], Vector2.Zero, Vector2.Zero); chainLinks[0].BodyType = BodyType.Static; MovingBody = chainLinks[0]; PathManager.AttachBodiesWithRevoluteJoint(Level.Physics, chainLinks, new Vector2(0, -0.1f), new Vector2(0, 0.1f), false, false); }
private void AddBallAndChain(Body body) { // The chain will be divided into several segments along the following path var chainPath = new Path(); chainPath.Add(ConvertUnits.ToSimUnits(332, 332)); chainPath.Add(ConvertUnits.ToSimUnits(332, 452)); // Creates the shape for the chain segments var chainLinkShape = new PolygonShape(PolygonTools.CreateRectangle(ConvertUnits.ToSimUnits(1), ConvertUnits.ToSimUnits(2)), 0.5f); // Creates the bodies for the chain segments _chainBodies = PathManager.EvenlyDistributeShapesAlongPath(World, chainPath, new[] { chainLinkShape }, BodyType.Dynamic, 30); // Connects the chain segments for (var i = 0; i < _chainBodies.Count - 1; i++) { var joint = new RevoluteJoint(_chainBodies[i], _chainBodies[i + 1], Vector2.Zero, Vector2.Zero); World.AddJoint(joint); } // Connects the start of the chain to the ufo var chainStartJoint = new RevoluteJoint(body, _chainBodies.First(), ConvertUnits.ToSimUnits(0, 25), Vector2.Zero); World.AddJoint(chainStartJoint); // Creates the ball at the end of the chain _chainEndBall = BodyFactory.CreateCircle(World, ConvertUnits.ToSimUnits(10), 3f, bodyType: BodyType.Dynamic); _chainEndBall.Position = ConvertUnits.ToSimUnits(332, 452); _chainEndBall.OnCollision += ChainBallOnCollision; // Adds the ball to the chain var chainEndJoint = new RevoluteJoint(_chainBodies.Last(), _chainEndBall, Vector2.Zero, Vector2.Zero); World.AddJoint(chainEndJoint); // Adds a rope join that ensures that the chain won't stretch var ropeJoint = new RopeJoint(body, _chainEndBall, ConvertUnits.ToSimUnits(0, 25), Vector2.Zero) { MaxLength = chainPath.GetLength() }; World.AddJoint(ropeJoint); }
public bool Graple() { Vector2f pos1 = Offset(to2f(character.Body.Position)); Vector2i pos2 = Mouse.GetPosition(window) + new Vector2i(32, 0); float rad = (float)Math.Atan2(pos2.X - pos1.X, pos2.Y - pos1.Y); Vector2 ray = RayCast(25, rad); float len = RayCastDistance(25, rad); if (len < 1) { grapBody = BodyFactory.CreateCircle(PhysConfig.world, 0.1f, 0.0f, ray); grapBody.IsStatic = true; graplingJoint = new RopeJoint(character.Body, grapBody, new Vector2(), new Vector2()); graplingJoint.MaxLength = len * 24.8f; PhysConfig.world.AddJoint(graplingJoint); return(true); } return(false); }
private void ApplyConstraints() { // set first joint to be at position of ropeStart joints[0].currentPosition = ropeStart; // set last joint to be at position of ropeEnd joints[jointCount - 1].currentPosition = ropeEnd; // neighboring points on rope keep a fixed distance apart from each other (this is where the magic happens) for (int i = 0; i < jointCount - 1; i++) { RopeJoint firstJoint = joints[i]; RopeJoint secondJoint = joints[i + 1]; Vector3 firstToSecond = secondJoint.currentPosition - firstJoint.currentPosition; float distance = firstToSecond.magnitude; // current segment length float error = distance - segmentLength; // difference between current and ideal segment length firstToSecond /= distance; // normalize firstToSecond Vector3 correction = firstToSecond * (error * 0.5f); if (i != 0) { firstJoint.currentPosition += correction; } else { secondJoint.currentPosition -= correction; } if (i + 1 != jointCount - 1) { secondJoint.currentPosition -= correction; } else { firstJoint.currentPosition += correction; } } }
private static Joint DeserializeRopeJoint(XElement jointElement, Body bodyA, Body bodyB, World world) { RopeJoint joint = null; Vector2 localAnchorA, localAnchorB; float maxLength = 100.0f; localAnchorA = bodyA.WorldCenter; localAnchorB = bodyB.WorldCenter; foreach (XElement element in jointElement.Elements()) { switch (element.Name.ToString().ToLower()) { case "maxlength": float.TryParse(element.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out maxLength); maxLength = ConvertUnits.ToSimUnits(maxLength); break; case "localanchora": localAnchorA = localAnchorA.DeserializeOffset(element); localAnchorA = ConvertUnits.ToSimUnits(localAnchorA); break; case "localanchorb": localAnchorB = localAnchorB.DeserializeOffset(element); localAnchorB = ConvertUnits.ToSimUnits(localAnchorB); break; } } joint = new RopeJoint(bodyA, bodyB, localAnchorA, localAnchorB); joint.MaxLength = maxLength; world.AddJoint(joint); return(joint); }
void DefaultJoints() { //b.LAnkleDef.body1 = LFoot; //b.LAnkleDef.body2 = LCalf; //b.RAnkleDef.body1 = RFoot; //b.RAnkleDef.body2 = RCalf; { // ankles Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.045f, -.75f); Joints[(int)BipedJointIndex.LAnkle].LocalAnchorA = Joints[(int)BipedJointIndex.RAnkle].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LFoot].Position; Joints[(int)BipedJointIndex.LAnkle].LocalAnchorB = Joints[(int)BipedJointIndex.RAnkle].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LCalf].Position; Joints[(int)BipedJointIndex.LAnkle].ReferenceAngle = Joints[(int)BipedJointIndex.RAnkle].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LAnkle].LowerLimit = Joints[(int)BipedJointIndex.RAnkle].LowerLimit = ReverseAngle(-0.523598776f); Joints[(int)BipedJointIndex.LAnkle].UpperLimit = Joints[(int)BipedJointIndex.RAnkle].UpperLimit = ReverseAngle(0.523598776f); } //b.LKneeDef.body1 = LCalf; //b.LKneeDef.body2 = LThigh; //b.RKneeDef.body1 = RCalf; //b.RKneeDef.body2 = RThigh; { // knees Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.030f, -.355f); Joints[(int)BipedJointIndex.LKnee].LocalAnchorA = Joints[(int)BipedJointIndex.RKnee].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LCalf].Position; Joints[(int)BipedJointIndex.LKnee].LocalAnchorB = Joints[(int)BipedJointIndex.RKnee].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LThigh].Position; Joints[(int)BipedJointIndex.LKnee].ReferenceAngle = Joints[(int)BipedJointIndex.RKnee].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LKnee].LowerLimit = Joints[(int)BipedJointIndex.RKnee].LowerLimit = ReverseAngle(0); Joints[(int)BipedJointIndex.LKnee].UpperLimit = Joints[(int)BipedJointIndex.RKnee].UpperLimit = ReverseAngle(2.61799388f); } //b.LHipDef.body1 = LThigh; //b.LHipDef.body2 = Pelvis; //b.RHipDef.body1 = RThigh; //b.RHipDef.body2 = Pelvis; { // hips Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(.005f, -.045f); Joints[(int)BipedJointIndex.LHip].LocalAnchorA = Joints[(int)BipedJointIndex.RHip].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LThigh].Position; Joints[(int)BipedJointIndex.LHip].LocalAnchorB = Joints[(int)BipedJointIndex.RHip].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.Pelvis].Position; Joints[(int)BipedJointIndex.LHip].ReferenceAngle = Joints[(int)BipedJointIndex.RHip].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LHip].LowerLimit = Joints[(int)BipedJointIndex.RHip].LowerLimit = ReverseAngle(-0.76892803f); Joints[(int)BipedJointIndex.LHip].UpperLimit = Joints[(int)BipedJointIndex.RHip].UpperLimit = 0; } //b.LowerAbsDef.body1 = Pelvis; //b.LowerAbsDef.body2 = Stomach; { // lower abs Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(.035f, .135f); Joints[(int)BipedJointIndex.LowerAbs].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.Pelvis].Position; Joints[(int)BipedJointIndex.LowerAbs].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.Stomach].Position; Joints[(int)BipedJointIndex.LowerAbs].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LowerAbs].LowerLimit = ReverseAngle(-0.523598776f); Joints[(int)BipedJointIndex.LowerAbs].UpperLimit = ReverseAngle(0.523598776f); } //b.UpperAbsDef.body1 = Stomach; //b.UpperAbsDef.body2 = Chest; { // upper abs Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(.045f, .320f); Joints[(int)BipedJointIndex.UpperAbs].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.Stomach].Position; Joints[(int)BipedJointIndex.UpperAbs].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position; Joints[(int)BipedJointIndex.UpperAbs].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.UpperAbs].LowerLimit = ReverseAngle(-0.523598776f); Joints[(int)BipedJointIndex.UpperAbs].UpperLimit = ReverseAngle(0.174532925f); } //b.LowerNeckDef.body1 = Chest; //b.LowerNeckDef.body2 = Neck; { // lower neck Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.015f, .575f); Joints[(int)BipedJointIndex.LowerNeck].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position; Joints[(int)BipedJointIndex.LowerNeck].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.Neck].Position; Joints[(int)BipedJointIndex.LowerNeck].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LowerNeck].LowerLimit = ReverseAngle(-0.174532925f); Joints[(int)BipedJointIndex.LowerNeck].UpperLimit = ReverseAngle(0.174532925f); } //b.UpperNeckDef.body1 = Chest; //b.UpperNeckDef.body2 = Head; { // upper neck Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.005f, .630f); Joints[(int)BipedJointIndex.UpperNeck].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position; Joints[(int)BipedJointIndex.UpperNeck].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.Head].Position; Joints[(int)BipedJointIndex.UpperNeck].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.UpperNeck].LowerLimit = ReverseAngle(-0.610865238f); Joints[(int)BipedJointIndex.UpperNeck].UpperLimit = ReverseAngle(0.785398163f); } //b.LShoulderDef.body1 = Chest; //b.LShoulderDef.body2 = LUpperArm; //b.RShoulderDef.body1 = Chest; //b.RShoulderDef.body2 = RUpperArm; { // shoulders Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.015f, .545f); Joints[(int)BipedJointIndex.LShoulder].LocalAnchorA = Joints[(int)BipedJointIndex.RShoulder].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.Chest].Position; Joints[(int)BipedJointIndex.LShoulder].LocalAnchorB = Joints[(int)BipedJointIndex.RShoulder].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LUpperArm].Position; Joints[(int)BipedJointIndex.LShoulder].ReferenceAngle = Joints[(int)BipedJointIndex.RShoulder].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LShoulder].LowerLimit = Joints[(int)BipedJointIndex.RShoulder].LowerLimit = ReverseAngle(-1.04719755f); Joints[(int)BipedJointIndex.LShoulder].UpperLimit = Joints[(int)BipedJointIndex.RShoulder].UpperLimit = ReverseAngle(3.14159265f); } //b.LElbowDef.body1 = LForearm; //b.LElbowDef.body2 = LUpperArm; //b.RElbowDef.body1 = RForearm; //b.RElbowDef.body2 = RUpperArm; { // elbows Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.005f, .290f); Joints[(int)BipedJointIndex.LElbow].LocalAnchorA = Joints[(int)BipedJointIndex.RElbow].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LForearm].Position; Joints[(int)BipedJointIndex.LElbow].LocalAnchorB = Joints[(int)BipedJointIndex.RElbow].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LUpperArm].Position; Joints[(int)BipedJointIndex.LElbow].ReferenceAngle = Joints[(int)BipedJointIndex.RElbow].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LElbow].LowerLimit = Joints[(int)BipedJointIndex.RElbow].LowerLimit = ReverseAngle(-2.7925268f); Joints[(int)BipedJointIndex.LElbow].UpperLimit = Joints[(int)BipedJointIndex.RElbow].UpperLimit = 0; } //b.LWristDef.body1 = LHand; //b.LWristDef.body2 = LForearm; //b.RWristDef.body1 = RHand; //b.RWristDef.body2 = RForearm; { // wrists Vector2 anchor = new Vector2(xScale, yScale) * new Vector2(-.010f, .045f); Joints[(int)BipedJointIndex.LWrist].LocalAnchorA = Joints[(int)BipedJointIndex.RWrist].LocalAnchorA = anchor - Bodies[(int)BipedFixtureIndex.LHand].Position; Joints[(int)BipedJointIndex.LWrist].LocalAnchorB = Joints[(int)BipedJointIndex.RWrist].LocalAnchorB = anchor - Bodies[(int)BipedFixtureIndex.LForearm].Position; Joints[(int)BipedJointIndex.LWrist].ReferenceAngle = Joints[(int)BipedJointIndex.RWrist].ReferenceAngle = 0.0f; Joints[(int)BipedJointIndex.LWrist].LowerLimit = Joints[(int)BipedJointIndex.RWrist].LowerLimit = ReverseAngle(-0.174532925f); Joints[(int)BipedJointIndex.LWrist].UpperLimit = Joints[(int)BipedJointIndex.RWrist].UpperLimit = ReverseAngle(0.174532925f); } { RopeJoint rj = new RopeJoint(Bodies[(int)BipedFixtureIndex.RUpperArm], Bodies[(int)BipedFixtureIndex.RHand], Vector2.Zero, Vector2.Zero); rj = new RopeJoint(Bodies[(int)BipedFixtureIndex.LUpperArm], Bodies[(int)BipedFixtureIndex.LHand], Vector2.Zero, Vector2.Zero); } if (xScale < 0) { foreach (var j in Joints) { var old = j.UpperLimit; j.UpperLimit = j.LowerLimit; j.LowerLimit = old; } } }
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(); }
public override void Update(float delta) { #if !EDITOR Player playerInstance = Player.Instance; #region Awaken Body // If the body has fallen asleep, we need to wake it if the // level rotates. if (Camera.Instance.IsLevelRotating) { if (_pathBodies[_pathBodies.Count - 1].Awake == false) { this._pathBodies[_pathBodies.Count - 1].Awake = true; } } #endregion if (!_world.JointList.Contains(_ropeJoint)) { if (playerInstance.PlayerState != PlayerState.Dead && InputManager.Instance.Grab(true) && _inRange) { int index = 0; Body playerBody = playerInstance.GetWheelBody(); float smallestDistance = Math.Abs( Vector2.Subtract(playerBody.Position, _touchedRopeFixtures[0].Body.Position).Length()); // Starting it at 3 instead of 1 or 2 because they // shouldn't really be able to grab the top ones for (int i = 3; i < _touchedRopeFixtures.Count; i++) { float distance = Math.Abs( Vector2.Subtract(playerBody.Position, _touchedRopeFixtures[i].Body.Position).Length()); if (distance < smallestDistance) { smallestDistance = distance; this._grabbedIndex = i; } } this._ropePlayerJoint = new RevoluteJoint(_touchedRopeFixtures[index].Body, playerInstance.GetMainBody(), Vector2.Zero, Vector2.Zero); this._world.AddJoint(_ropePlayerJoint); this._ropeJoint = new RopeJoint(_pathBodies[0], playerInstance.GetMainBody(), Vector2.Zero, Vector2.Zero); this._world.AddJoint(_ropeJoint); playerInstance.GrabRope(); } } else { Vector2 ropeDims = _ropeJoint.WorldAnchorB - _ropeJoint.WorldAnchorA; float rotation = (float)Math.Atan2(ropeDims.Y, ropeDims.X); rotation -= MathHelper.PiOver2; playerInstance.SetRotation(rotation); if (InputManager.Instance.Jump(true) || InputManager.Instance.Grab(true) || playerInstance.PlayerState == PlayerState.Dead) { _world.RemoveJoint(_ropeJoint); _world.RemoveJoint(_ropePlayerJoint); if (playerInstance.PlayerState == PlayerState.Swinging) { playerInstance.ForceFall(); } } } #endif }