public static PrismaticJoint CreatePrismaticJoint(World world, Body bodyA, Body bodyB, Vector2 anchor, Vector2 axis, bool useWorldCoordinates = false) { PrismaticJoint joint = new PrismaticJoint(bodyA, bodyB, anchor, axis, useWorldCoordinates); world.Add(joint); return(joint); }
private PrismaticTest() { Body ground = BodyFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f)); PolygonShape shape = new PolygonShape(5); shape.Vertices = PolygonTools.CreateRectangle(2.0f, 0.5f); Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(-10.0f, 10.0f); body.Rotation = 0.5f * Settings.Pi; body.CreateFixture(shape); // Bouncy limit Vector2 axis = new Vector2(2.0f, 1.0f); axis.Normalize(); _joint = new PrismaticJoint(ground, body, Vector2.Zero, axis); // Non-bouncy limit //_joint = new PrismaticJoint(ground, body2, body2.Position, new Vector2(-10.0f, 10.0f), new Vector2(1.0f, 0.0f)); _joint.MotorSpeed = 5.0f; _joint.MaxMotorForce = 1000.0f; _joint.MotorEnabled = true; _joint.LowerLimit = -10.0f; _joint.UpperLimit = 20.0f; _joint.LimitEnabled = true; World.AddJoint(_joint); }
public Paddle(PlayerIndex playerIndex, GameplayManager gm, Vector2 position, float width, float height, float maxTranslation, World world) : base(world) { this.playerIndex = playerIndex; this.gm = gm; this.width = width; this.height = height; this.maxTranslation = maxTranslation; startPos = new Vector2(position.X,position.Y) ; body = BodyFactory.CreateRectangle(world, width, height, 1, position); body.BodyType = BodyType.Dynamic; body.CollidesWith = Category.Cat1 | Category.Cat3; body.CollisionCategories = Category.Cat2; body.Restitution = 1.0f; body.Friction = 0.0f; body.UserData = this; ground = BodyFactory.CreateRectangle(world, 1, 1, 1); joint = JointFactory.CreatePrismaticJoint(world, ground, body, position, new Vector2(1, 0),true); joint.LowerLimit = -maxTranslation + width / 2.0f; joint.UpperLimit = maxTranslation - width / 2.0f; joint.LimitEnabled = true; body.LinearDamping = 7.0f; }
private PrismaticTest() { Body ground; { ground = BodyFactory.CreateBody(World); EdgeShape shape3 = new EdgeShape(new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f)); ground.CreateFixture(shape3); } PolygonShape shape = new PolygonShape(5); shape.SetAsBox(2.0f, 0.5f); Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(0.0f, 10.0f); body.CreateFixture(shape); _fixedJoint = new FixedPrismaticJoint(body, body.Position, new Vector2(0.5f, 1.0f)); _fixedJoint.MotorSpeed = 5.0f; _fixedJoint.MaxMotorForce = 1000.0f; _fixedJoint.MotorEnabled = true; _fixedJoint.LowerLimit = -10.0f; _fixedJoint.UpperLimit = 20.0f; _fixedJoint.LimitEnabled = true; World.AddJoint(_fixedJoint); PolygonShape shape2 = new PolygonShape(5); shape2.SetAsBox(2.0f, 0.5f); Body body2 = BodyFactory.CreateBody(World); body2.BodyType = BodyType.Dynamic; body2.Position = new Vector2(10.0f, 10.0f); body2.CreateFixture(shape2); _joint = new PrismaticJoint(ground, body2, ground.GetLocalPoint(body2.Position), Vector2.Zero, new Vector2(0.5f, 1.0f)); _joint.MotorSpeed = 5.0f; _joint.MaxMotorForce = 1000.0f; _joint.MotorEnabled = true; _joint.LowerLimit = -10.0f; _joint.UpperLimit = 20.0f; _joint.LimitEnabled = true; World.AddJoint(_joint); }
public override void InitJoint () { base.InitJoint (); //Microsoft.Xna.Framework.FVector2 angleV = new Microsoft.Xna.Framework.FVector2(BodyB.PhysicsBody.Position.X - BodyA.PhysicsBody.Position.X, BodyB.PhysicsBody.Position.Y - BodyA.PhysicsBody.Position.Y); float ang = Mathf.Atan2(BodyB.PhysicsBody.Position.Y - BodyA.PhysicsBody.Position.Y, BodyB.PhysicsBody.Position.X - BodyA.PhysicsBody.Position.X); Microsoft.Xna.Framework.FVector2 angleV = new Microsoft.Xna.Framework.FVector2(Mathf.Cos(ang), Mathf.Sin(ang)); //angleV.Normalize(); joint = FarseerPhysics.Factories.JointFactory.CreatePrismaticJoint(FSWorldComponent.PhysicsWorld, BodyA.PhysicsBody, BodyB.PhysicsBody, Microsoft.Xna.Framework.FVector2.Zero, angleV); joint.CollideConnected = CollideConnected; //joint.Frequency = Frequency; //joint.DampingRatio = 0.5f; d }
private BodyTypesTest() { //Ground Body ground = BodyFactory.CreateEdge(World, new Vector2(-20.0f, 0.0f), new Vector2(20.0f, 0.0f)); // Define attachment { _attachment = BodyFactory.CreateRectangle(World, 1, 4, 2); _attachment.BodyType = BodyType.Dynamic; _attachment.Position = new Vector2(0.0f, 3.0f); } // Define platform { _platform = BodyFactory.CreateRectangle(World, 8.0f, 1f, 2); _platform.BodyType = BodyType.Dynamic; _platform.Position = new Vector2(0.0f, 5.0f); _platform.Friction = 0.6f; RevoluteJoint rjd = new RevoluteJoint(_attachment, _platform, new Vector2(0, 5), true); rjd.MaxMotorTorque = 50.0f; rjd.MotorEnabled = true; World.AddJoint(rjd); PrismaticJoint pjd = new PrismaticJoint(ground, _platform, new Vector2(0.0f, 5.0f), new Vector2(1.0f, 0.0f), true); pjd.MaxMotorForce = 1000.0f; pjd.MotorEnabled = true; pjd.LowerLimit = -10.0f; pjd.UpperLimit = 10.0f; pjd.LimitEnabled = true; World.AddJoint(pjd); _speed = 3.0f; } // Create a payload { Body body = BodyFactory.CreateRectangle(World, 1.5f, 1.5f, 2); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(0.0f, 8.0f); body.Friction = 0.6f; } }
/// <summary> /// Requires two existing revolute or prismatic joints (any combination will work). /// The provided joints must attach a dynamic body to a static body. /// </summary> /// <param name="jointA">The first joint.</param> /// <param name="jointB">The second joint.</param> /// <param name="ratio">The ratio.</param> public GearJoint(Joint jointA, Joint jointB, float ratio) : base(jointA.BodyA, jointA.BodyB) { JointType = JointType.Gear; JointA = jointA; JointB = jointB; Ratio = ratio; JointType type1 = jointA.JointType; JointType type2 = jointB.JointType; // Make sure its the right kind of joint Debug.Assert(type1 == JointType.Revolute || type1 == JointType.Prismatic || type1 == JointType.FixedRevolute || type1 == JointType.FixedPrismatic); Debug.Assert(type2 == JointType.Revolute || type2 == JointType.Prismatic || type2 == JointType.FixedRevolute || type2 == JointType.FixedPrismatic); // In the case of a prismatic and revolute joint, the first body must be static. if (type1 == JointType.Revolute || type1 == JointType.Prismatic) Debug.Assert(jointA.BodyA.BodyType == BodyType.Static); if (type2 == JointType.Revolute || type2 == JointType.Prismatic) Debug.Assert(jointB.BodyA.BodyType == BodyType.Static); float coordinate1 = 0.0f, coordinate2 = 0.0f; switch (type1) { case JointType.Revolute: BodyA = jointA.BodyB; _revolute1 = (RevoluteJoint)jointA; LocalAnchor1 = _revolute1.LocalAnchorB; coordinate1 = _revolute1.JointAngle; break; case JointType.Prismatic: BodyA = jointA.BodyB; _prismatic1 = (PrismaticJoint)jointA; LocalAnchor1 = _prismatic1.LocalAnchorB; coordinate1 = _prismatic1.JointTranslation; break; case JointType.FixedRevolute: BodyA = jointA.BodyA; _fixedRevolute1 = (FixedRevoluteJoint)jointA; LocalAnchor1 = _fixedRevolute1.LocalAnchorA; coordinate1 = _fixedRevolute1.JointAngle; break; case JointType.FixedPrismatic: BodyA = jointA.BodyA; _fixedPrismatic1 = (FixedPrismaticJoint)jointA; LocalAnchor1 = _fixedPrismatic1.LocalAnchorA; coordinate1 = _fixedPrismatic1.JointTranslation; break; } switch (type2) { case JointType.Revolute: BodyB = jointB.BodyB; _revolute2 = (RevoluteJoint)jointB; LocalAnchor2 = _revolute2.LocalAnchorB; coordinate2 = _revolute2.JointAngle; break; case JointType.Prismatic: BodyB = jointB.BodyB; _prismatic2 = (PrismaticJoint)jointB; LocalAnchor2 = _prismatic2.LocalAnchorB; coordinate2 = _prismatic2.JointTranslation; break; case JointType.FixedRevolute: BodyB = jointB.BodyA; _fixedRevolute2 = (FixedRevoluteJoint)jointB; LocalAnchor2 = _fixedRevolute2.LocalAnchorA; coordinate2 = _fixedRevolute2.JointAngle; break; case JointType.FixedPrismatic: BodyB = jointB.BodyA; _fixedPrismatic2 = (FixedPrismaticJoint)jointB; LocalAnchor2 = _fixedPrismatic2.LocalAnchorA; coordinate2 = _fixedPrismatic2.JointTranslation; break; } _ant = coordinate1 + Ratio * coordinate2; }
public static PrismaticJoint CreatePrismaticJoint(World world, Body bodyA, Body bodyB, Vector2 anchor, Vector2 axis, bool useWorldCoordinates = false) { PrismaticJoint joint = new PrismaticJoint(bodyA, bodyB, anchor, axis, useWorldCoordinates); world.AddJoint(joint); return joint; }
public override Joint createJoint() { var joint = new PrismaticJoint( bodyA, bodyB, ownerBodyAnchor * FSConvert.displayToSim, otherBodyAnchor * FSConvert.displayToSim ); joint.collideConnected = collideConnected; joint.axis = axis; joint.limitEnabled = limitEnabled; joint.lowerLimit = lowerLimit; joint.upperLimit = upperLimit; joint.motorEnabled = motorEnabled; joint.motorSpeed = motorSpeed; joint.maxMotorForce = maxMotorForce; joint.motorImpulse = motorImpulse; return joint; }
private SliderCrankTest() { Body ground; { ground = BodyFactory.CreateBody(World); EdgeShape shape = new EdgeShape(new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f)); ground.CreateFixture(shape); } { Body prevBody = ground; // Define crank. { PolygonShape shape = new PolygonShape(2); shape.Vertices = PolygonTools.CreateRectangle(0.5f, 2.0f); Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(0.0f, 7.0f); body.CreateFixture(shape); _joint1 = new RevoluteJoint(prevBody, body, new Vector2(0f, 5f), true); _joint1.MotorSpeed = 1.0f * Settings.Pi; _joint1.MaxMotorTorque = 10000.0f; _joint1.MotorEnabled = true; World.AddJoint(_joint1); prevBody = body; } // Define follower. { PolygonShape shape = new PolygonShape(2); shape.Vertices = PolygonTools.CreateRectangle(0.5f, 4.0f); Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(0.0f, 13.0f); body.CreateFixture(shape); RevoluteJoint rjd3 = new RevoluteJoint(prevBody, body, new Vector2(0, 9), true); rjd3.MotorEnabled = false; World.AddJoint(rjd3); prevBody = body; } // Define piston { PolygonShape shape = new PolygonShape(2); shape.Vertices = PolygonTools.CreateRectangle(1.5f, 1.5f); Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(0.0f, 17.0f); body.CreateFixture(shape); RevoluteJoint rjd = new RevoluteJoint(prevBody, body, new Vector2(0, 17), true); World.AddJoint(rjd); _joint2 = new PrismaticJoint(ground, body, new Vector2(0.0f, 17.0f), new Vector2(0.0f, 1.0f), true); _joint2.MaxMotorForce = 1000.0f; _joint2.MotorEnabled = true; World.AddJoint(_joint2); } // Create a payload { PolygonShape shape = new PolygonShape(2); shape.Vertices = PolygonTools.CreateRectangle(1.5f, 1.5f); Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(0.0f, 23.0f); body.CreateFixture(shape); } } }
/// <summary> /// Creates a prsimatic joint /// </summary> /// <param name="bodyA"></param> /// <param name="bodyB"></param> /// <param name="localanchorB"></param> /// <param name="axis"></param> /// <returns></returns> public static PrismaticJoint CreatePrismaticJoint(Body bodyA, Body bodyB, Vector2 localanchorB, Vector2 axis) { Vector2 localanchorA = bodyA.GetLocalPoint(bodyB.GetWorldPoint(localanchorB)); PrismaticJoint joint = new PrismaticJoint(bodyA, bodyB, localanchorA, localanchorB, axis); return joint; }
public Player(Vector2 spawn) { // To locomote the player, we're going to create a model like this: // +-----+ // | | // |torso| <-- Rectangle // |/---\| // |legs | <-- circle // \---/ // With the torso having a fixed angle joint, and the legs having a motorized joint. var torsoWidth = playerWidth + 0.25f; var torsoHeight = playerHeight - playerWidth; Torso.Body = BodyFactory.CreateRectangle(PhysicsSubsystem.Instance.World, torsoWidth, playerHeight - playerWidth / 4, 0.1f, spawn); Torso.Body.IgnoreGravity = true; Torso.Body.BodyType = BodyType.Dynamic; Torso.Body.FixedRotation = true; Torso.Body.Friction = 0; Torso.Body.UserData = this; Legs.Body = BodyFactory.CreateCircle(PhysicsSubsystem.Instance.World, playerWidth/2, 4f, new Vector2(spawn.X, spawn.Y + torsoHeight / 2 + playerWidth / 4)); Legs.Body.BodyType = BodyType.Dynamic; Legs.Body.Friction = 1000; Piston.Body = BodyFactory.CreateRectangle(PhysicsSubsystem.Instance.World, playerWidth, playerHeight / 2, 0.5f, spawn); Piston.Body.BodyType = BodyType.Dynamic; axis = JointFactory.CreateRevoluteJoint(PhysicsSubsystem.Instance.World, Torso.Body, Legs.Body, Vector2.Zero); axis.CollideConnected = false; axis.MotorEnabled = true; axis.MaxMotorTorque = 20; //prismatic = JointFactory.CreatePrismaticJoint(PhysicsSubsystem.Instance.World, Piston.Body, Torso.Body, // Vector2.Zero, -Vector2.UnitY); spring = JointFactory.CreateDistanceJoint(PhysicsSubsystem.Instance.World, Piston.Body, Torso.Body); spring.Frequency = 10f; spring.DampingRatio = 1f; spring.CollideConnected = false; prismatic = JointFactory.CreatePrismaticJoint(PhysicsSubsystem.Instance.World, Piston.Body, Torso.Body, Vector2.Zero, Vector2.UnitY); prismatic.CollideConnected = false; Piston.Body.IgnoreCollisionWith(Legs.Body); Graphics.Sprite = new Sprite(Content.Player); Graphics.Animation = standingAnimation; Graphics.FrameSize = new Vector2i(64, 64); Graphics.Sprite.Origin = new Vector2f(32, 40); Slicing = 45; bool jumpInProgress = false, canJump = true, attacking = false, canAttack = true; // 1WEEK // Map the input to the legs Input.NoInput += () => { axis.MotorSpeed = 0; if (!jumpInProgress && !attacking) Graphics.Animation = standingAnimation; }; Input.KeyEvents[Keyboard.Key.A] = (key, mods, time) => { if (attacking) return; if (!jumpInProgress) { axis.MotorSpeed = -playerSpeed; Graphics.Animation = walkingAnimation; } else Legs.Body.ApplyLinearImpulse(new Vector2(-playerAirSpeed * (float)time, 0)); Graphics.Sprite.Scale = new Vector2f(-1, 1); // just flip it }; Input.KeyEvents[Keyboard.Key.D] = (key, mods, time) => { if (attacking) return; if (!jumpInProgress) { axis.MotorSpeed = playerSpeed; Graphics.Animation = walkingAnimation; } else Legs.Body.ApplyLinearImpulse(new Vector2(playerAirSpeed * (float)time, 0)); Graphics.Sprite.Scale = new Vector2f(1, 1); // flip it good }; Input.KeyEvents[Keyboard.Key.W] = (key, mods, time) => { if (canJump)// && !jumpInProgress && !attacking) { jumpInProgress = true; canJump = false; //Legs.Body.ApplyLinearImpulse(new Vector2(0, -playerJumpForce)); //Piston.Body.ApplyLinearImpulse(new Vector2(0, -playerJumpForce)); spring.Length = playerJumpForce; axis.MotorSpeed = 0; Legs.Body.Friction = 0; jumpTimer.Start(); springResetTimer.Start(); } }; Input.MouseInput += (btn) => { Vector2 mousePos, position, direction, endPos; switch (btn) { case Mouse.Button.Left: if (!canAttack) break; canAttack = false; Graphics.Animation = jumpInProgress ? vSwingAerialAnimation : vSwingAnimation; axis.MotorSpeed = 0; attacking = true; attackTimer.Start(); mousePos = new Vector2(ConvertUnits.ToSimUnits(Input.MousePosition.X), ConvertUnits.ToSimUnits(Input.MousePosition.Y)); position = new Vector2(Torso.Position.X, Torso.Position.Y); direction = mousePos - position; direction.Normalize(); endPos = position + (direction * 2.5f); PhysicsSubsystem.Instance.World.RayCast((f, p, n, fr) => { var candy = f.Body.UserData as CandyObject; if (candy != null && candy.HitPoints > 0) { candy.Hit(1, p, direction); return 0; } if (f.Body.UserData is PlatformObject) return 0; return 1; }, position, endPos); break; case Mouse.Button.Middle: break; case Mouse.Button.Right: if (!canAttack || Slicing <= 0) break; canAttack = false; Graphics.Animation = jumpInProgress ? hSwingAerialAnimation : hSwingAnimation; axis.MotorSpeed = 0; attacking = true; attackTimer.Start(); mousePos = new Vector2(ConvertUnits.ToSimUnits(Input.MousePosition.X), ConvertUnits.ToSimUnits(Input.MousePosition.Y)); position = new Vector2(Torso.Position.X, Torso.Position.Y); direction = mousePos - position; direction.Normalize(); direction *= 2.5f; endPos = position + direction; // Find the first thing hit, and if it's a candy, keep track of it. List<Fixture> fixtures = new List<Fixture>(); List<Vector2> entryPoints = new List<Vector2>(); List<Vector2> exitPoints = new List<Vector2>(); //Get the entry points PhysicsSubsystem.Instance.World.RayCast((f, p, n, fr) => { if (f.Body.UserData is PlatformObject) { return 0; } if (f.Body.UserData is CandyObject) { fixtures.Add(f); entryPoints.Add(p); } return 1; }, position, endPos); if (!entryPoints.Any()) return; //Reverse the ray to get the exitpoints PhysicsSubsystem.Instance.World.RayCast((f, p, n, fr) => { if(f.Body.UserData is CandyObject) exitPoints.Add(p); return 1; }, endPos, position); while (fixtures.Count > exitPoints.Count) { fixtures.Remove(fixtures.Last()); entryPoints.Remove(entryPoints.Last()); } GameplayState.Score += fixtures.Count * 500; if (fixtures.Count > 0) Content.SliceSound.Play(); for (int i = 0; i < fixtures.Count; i++) { if (fixtures[i].Body.Mass < 2.5) continue; var originalCandy = fixtures[i].Body.UserData as CandyObject; Debug.Assert(originalCandy != null); Slicing = Math.Max(Slicing - originalCandy.Physics.Body.Mass, 0); originalCandy.Slice(entryPoints[i], exitPoints[i]); } break; } }; #if DEBUG Input.KeyEvents[Keyboard.Key.RShift] = (key, mod) => Framework.Graphics.TakeScreenshot(); #endif Torso.OnFalling += (isFalling) => { if (isFalling) { if (!attacking) Graphics.Animation = fallingAnimation; jumpInProgress = true; } }; Legs.Body.OnCollision += (a, b, c) => { var userData = (a.Body.UserData ?? b.Body.UserData) as WallObject; if (userData == null) { jumpInProgress = false; Legs.Body.Friction = c.Friction = 1000; if (!attacking) Graphics.Animation = standingAnimation; } return true; }; Piston.Body.OnCollision += (a, b, c) => { Graphics.Animation = jumpingAnimation; Content.JumpSound.Play(); return true; }; var swingFinished = new EventHandler((sender, args) => { attacking = false; Graphics.Animation = jumpInProgress ? aerialAnimation : standingAnimation; }); vSwingAnimation.Finished += swingFinished; vSwingAerialAnimation.Finished += swingFinished; hSwingAnimation.Finished += swingFinished; hSwingAerialAnimation.Finished += swingFinished; attackTimer.DingDingDing += (sender, args) => canAttack = true; jumpTimer.DingDingDing += (sender, args) => canJump = true; springResetTimer.DingDingDing += (sender, args) => spring.Length = 0; }
/// <summary> /// Creates a prismatic joint and adds it to the world /// </summary> /// <param name="world"></param> /// <param name="bodyA"></param> /// <param name="bodyB"></param> /// <param name="anchor"></param> /// <param name="axis"></param> /// <returns></returns> public static PrismaticJoint CreatePrismaticJoint(World world, Body bodyA, Body bodyB, Vector2 anchor, Vector2 axis) { PrismaticJoint joint = new PrismaticJoint(bodyA, bodyB, anchor, axis); world.AddJoint(joint); return joint; }
/// <summary> /// Requires two existing revolute or prismatic joints (any combination will work). /// The provided joints must attach a dynamic body to a static body. /// </summary> /// <param name="jointA">The first joint.</param> /// <param name="jointB">The second joint.</param> /// <param name="ratio">The ratio.</param> /// <param name="bodyA">The first body</param> /// <param name="bodyB">The second body</param> public GearJoint(Body bodyA, Body bodyB, Joint jointA, Joint jointB, float ratio = 1f) { JointType = JointType.Gear; BodyA = bodyA; BodyB = bodyB; JointA = jointA; JointB = jointB; Ratio = ratio; _typeA = jointA.JointType; _typeB = jointB.JointType; Debug.Assert(_typeA == JointType.Revolute || _typeA == JointType.Prismatic || _typeA == JointType.FixedRevolute || _typeA == JointType.FixedPrismatic); Debug.Assert(_typeB == JointType.Revolute || _typeB == JointType.Prismatic || _typeB == JointType.FixedRevolute || _typeB == JointType.FixedPrismatic); float coordinateA, coordinateB; // TODO_ERIN there might be some problem with the joint edges in b2Joint. _bodyC = JointA.BodyA; _bodyA = JointA.BodyB; // Get geometry of joint1 Transform xfA = _bodyA._xf; float aA = _bodyA._sweep.A; Transform xfC = _bodyC._xf; float aC = _bodyC._sweep.A; if (_typeA == JointType.Revolute) { RevoluteJoint revolute = (RevoluteJoint)jointA; _localAnchorC = revolute.LocalAnchorA; _localAnchorA = revolute.LocalAnchorB; _referenceAngleA = revolute.ReferenceAngle; _localAxisC = Vector2.Zero; coordinateA = aA - aC - _referenceAngleA; } else { PrismaticJoint prismatic = (PrismaticJoint)jointA; _localAnchorC = prismatic.LocalAnchorA; _localAnchorA = prismatic.LocalAnchorB; _referenceAngleA = prismatic.ReferenceAngle; _localAxisC = prismatic.LocalXAxis; Vector2 pC = _localAnchorC; Vector2 pA = MathUtils.MulT(xfC.q, MathUtils.Mul(xfA.q, _localAnchorA) + (xfA.p - xfC.p)); coordinateA = Vector2.Dot(pA - pC, _localAxisC); } _bodyD = JointB.BodyA; _bodyB = JointB.BodyB; // Get geometry of joint2 Transform xfB = _bodyB._xf; float aB = _bodyB._sweep.A; Transform xfD = _bodyD._xf; float aD = _bodyD._sweep.A; if (_typeB == JointType.Revolute) { RevoluteJoint revolute = (RevoluteJoint)jointB; _localAnchorD = revolute.LocalAnchorA; _localAnchorB = revolute.LocalAnchorB; _referenceAngleB = revolute.ReferenceAngle; _localAxisD = Vector2.Zero; coordinateB = aB - aD - _referenceAngleB; } else { PrismaticJoint prismatic = (PrismaticJoint)jointB; _localAnchorD = prismatic.LocalAnchorA; _localAnchorB = prismatic.LocalAnchorB; _referenceAngleB = prismatic.ReferenceAngle; _localAxisD = prismatic.LocalXAxis; Vector2 pD = _localAnchorD; Vector2 pB = MathUtils.MulT(xfD.q, MathUtils.Mul(xfB.q, _localAnchorB) + (xfB.p - xfD.p)); coordinateB = Vector2.Dot(pB - pD, _localAxisD); } _ratio = ratio; _constant = coordinateA + _ratio * coordinateB; _impulse = 0.0f; }
/// <summary> /// Requires two existing revolute or prismatic joints (any combination will work). /// The provided joints must attach a dynamic body to a static body. /// </summary> /// <param name="jointA">The first joint.</param> /// <param name="jointB">The second joint.</param> /// <param name="ratio">The ratio.</param> public GearJoint(Joint jointA, Joint jointB, float ratio) : base(jointA.BodyA, jointA.BodyB) { JointType = JointType.Gear; JointA = jointA; JointB = jointB; Ratio = ratio; JointType type1 = jointA.JointType; JointType type2 = jointB.JointType; // Make sure its the right kind of joint Debug.Assert(type1 == JointType.Revolute || type1 == JointType.Prismatic || type1 == JointType.FixedRevolute || type1 == JointType.FixedPrismatic); Debug.Assert(type2 == JointType.Revolute || type2 == JointType.Prismatic || type2 == JointType.FixedRevolute || type2 == JointType.FixedPrismatic); // In the case of a prismatic and revolute joint, the first body must be static. if (type1 == JointType.Revolute || type1 == JointType.Prismatic) { Debug.Assert(jointA.BodyA.Type == BodyType.Static); } if (type2 == JointType.Revolute || type2 == JointType.Prismatic) { Debug.Assert(jointB.BodyA.Type == BodyType.Static); } float coordinate1 = 0.0f, coordinate2 = 0.0f; switch (type1) { case JointType.Revolute: BodyA = jointA.BodyB; _revolute1 = (RevoluteJoint)jointA; LocalAnchor1 = _revolute1.LocalAnchorB; coordinate1 = _revolute1.JointAngle; break; case JointType.Prismatic: BodyA = jointA.BodyB; _prismatic1 = (PrismaticJoint)jointA; LocalAnchor1 = _prismatic1.LocalAnchorB; coordinate1 = _prismatic1.JointTranslation; break; case JointType.FixedRevolute: BodyA = jointA.BodyA; _fixedRevolute1 = (FixedRevoluteJoint)jointA; LocalAnchor1 = _fixedRevolute1.LocalAnchorA; coordinate1 = _fixedRevolute1.JointAngle; break; case JointType.FixedPrismatic: BodyA = jointA.BodyA; _fixedPrismatic1 = (FixedPrismaticJoint)jointA; LocalAnchor1 = _fixedPrismatic1.LocalAnchorA; coordinate1 = _fixedPrismatic1.JointTranslation; break; } switch (type2) { case JointType.Revolute: BodyB = jointB.BodyB; _revolute2 = (RevoluteJoint)jointB; LocalAnchor2 = _revolute2.LocalAnchorB; coordinate2 = _revolute2.JointAngle; break; case JointType.Prismatic: BodyB = jointB.BodyB; _prismatic2 = (PrismaticJoint)jointB; LocalAnchor2 = _prismatic2.LocalAnchorB; coordinate2 = _prismatic2.JointTranslation; break; case JointType.FixedRevolute: BodyB = jointB.BodyA; _fixedRevolute2 = (FixedRevoluteJoint)jointB; LocalAnchor2 = _fixedRevolute2.LocalAnchorA; coordinate2 = _fixedRevolute2.JointAngle; break; case JointType.FixedPrismatic: BodyB = jointB.BodyA; _fixedPrismatic2 = (FixedPrismaticJoint)jointB; LocalAnchor2 = _fixedPrismatic2.LocalAnchorA; coordinate2 = _fixedPrismatic2.JointTranslation; break; } _ant = coordinate1 + Ratio * coordinate2; }
private void Resize(float scaleFactor) { width *= scaleFactor; List<Ball> tmpBalls = new List<Ball>(); while (ballAttachments.Count > 0) { tmpBalls.Add(ballAttachments[0].BodyB.UserData as Ball); world.RemoveJoint(ballAttachments[0]); ballAttachments.RemoveAt(0); } world.RemoveJoint(joint); Vector2 pos = body.Position; Vector2 linearVel = body.LinearVelocity; float mass = body.Mass; world.RemoveBody(body); body = BodyFactory.CreateRectangle(world, width, height, 1, pos); body.BodyType = BodyType.Dynamic; body.CollidesWith = Category.Cat1 | Category.Cat3; body.CollisionCategories = Category.Cat2; body.Restitution = 1.0f; body.Friction = 0.0f; body.UserData = this; body.Mass = mass; body.LinearVelocity = linearVel; joint = JointFactory.CreatePrismaticJoint(world, ground, body, startPos, new Vector2(1, 0), true); joint.LowerLimit = -maxTranslation + width / 2.0f + (startPos.X - pos.X); joint.UpperLimit = maxTranslation - width / 2.0f + (startPos.X - pos.X); joint.LimitEnabled = true; body.LinearDamping = 5.0f; foreach (Ball b in tmpBalls) Attach(b); }
public virtual bool OnCollidedWith(Fixture f, UserControlledCharacter character, Fixture charfix, Contact info) { if (!Hanging && character.Physics.LinearVelocity.Y > 0) { character.Physics.ResetDynamics(); character.WheelBody.ResetDynamics(); joint = JointFactory.CreatePrismaticJoint( world, character.WheelBody, Physics, Vector2.Zero, Vector2.UnitX); origLinearDamping = character.Physics.LinearDamping; character.Physics.LinearDamping = 10; Hanging = true; } return true; }
/// <summary> /// Requires two existing revolute or prismatic joints (any combination will work). /// The provided joints must attach a dynamic body to a static body. /// </summary> /// <param name="jointA">The first joint.</param> /// <param name="jointB">The second joint.</param> /// <param name="ratio">The ratio.</param> public GearJoint(FarseerJoint jointA, FarseerJoint jointB, float ratio) : base(jointA.BodyA, jointA.BodyB) { JointType = JointType.Gear; JointA = jointA; JointB = jointB; Ratio = ratio; m_typeA = jointA.JointType; m_typeB = jointB.JointType; // Make sure its the right kind of joint Debug.Assert(m_typeA == JointType.Revolute || m_typeA == JointType.Prismatic || m_typeA == JointType.FixedRevolute || m_typeA == JointType.FixedPrismatic); Debug.Assert(m_typeB == JointType.Revolute || m_typeB == JointType.Prismatic || m_typeB == JointType.FixedRevolute || m_typeB == JointType.FixedPrismatic); float coordinateA = 0.0f, coordinateB = 0.0f; m_bodyC = JointA.BodyA; BodyA = JointA.BodyB; // Get geometry of joint1 Transform xfA = BodyA.Xf; float aA = BodyA.Sweep.A; Transform xfC = m_bodyC.Xf; float aC = m_bodyC.Sweep.A; if (m_typeA == JointType.Revolute) { RevoluteJoint revolute = (RevoluteJoint)jointA; m_localAnchorC = revolute.LocalAnchorA; m_localAnchorA = revolute.LocalAnchorB; m_referenceAngleA = revolute.ReferenceAngle; m_localAxisC = FVector2.Zero; coordinateA = aA - aC - m_referenceAngleA; } else { PrismaticJoint prismatic = (PrismaticJoint)jointA; m_localAnchorC = prismatic.LocalAnchorA; m_localAnchorA = prismatic.LocalAnchorB; m_referenceAngleA = prismatic.ReferenceAngle; m_localAxisC = prismatic.LocalXAxisA; FVector2 pC = m_localAnchorC; FVector2 pA = MathUtils.MulT(xfC.q, MathUtils.Mul(xfA.q, m_localAnchorA) + (xfA.p - xfC.p)); coordinateA = FVector2.Dot(pA - pC, m_localAxisC); } m_bodyD = JointB.BodyA; BodyB = JointB.BodyB; // Get geometry of joint2 Transform xfB = BodyB.Xf; float aB = BodyB.Sweep.A; Transform xfD = m_bodyD.Xf; float aD = m_bodyD.Sweep.A; if (m_typeB == JointType.Revolute) { RevoluteJoint revolute = (RevoluteJoint)jointB; m_localAnchorD = revolute.LocalAnchorA; m_localAnchorB = revolute.LocalAnchorB; m_referenceAngleB = revolute.ReferenceAngle; m_localAxisD = FVector2.Zero; coordinateB = aB - aD - m_referenceAngleB; } else { PrismaticJoint prismatic = (PrismaticJoint)jointB; m_localAnchorD = prismatic.LocalAnchorA; m_localAnchorB = prismatic.LocalAnchorB; m_referenceAngleB = prismatic.ReferenceAngle; m_localAxisD = prismatic.LocalXAxisA; FVector2 pD = m_localAnchorD; FVector2 pB = MathUtils.MulT(xfD.q, MathUtils.Mul(xfB.q, m_localAnchorB) + (xfB.p - xfD.p)); coordinateB = FVector2.Dot(pB - pD, m_localAxisD); } _ratio = ratio; m_constant = coordinateA + _ratio * coordinateB; }
private CollisionFilteringTest() { //Ground BodyFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f)); { // Small triangle Vertices vertices = new Vertices(3); vertices.Add(new Vector2(-1.0f, 0.0f)); vertices.Add(new Vector2(1.0f, 0.0f)); vertices.Add(new Vector2(0.0f, 2.0f)); PolygonShape polygon = new PolygonShape(vertices, 1); Body triangleBody = BodyFactory.CreateBody(World); triangleBody.BodyType = BodyType.Dynamic; triangleBody.Position = new Vector2(-5.0f, 2.0f); Fixture triangleFixture = triangleBody.CreateFixture(polygon); triangleFixture.CollisionGroup = SmallGroup; triangleFixture.CollisionCategories = TriangleCategory; triangleFixture.CollidesWith = TriangleMask; // Large triangle (recycle definitions) vertices[0] *= 2.0f; vertices[1] *= 2.0f; vertices[2] *= 2.0f; polygon.Set(vertices); Body triangleBody2 = BodyFactory.CreateBody(World); triangleBody2.BodyType = BodyType.Dynamic; triangleBody2.Position = new Vector2(-5.0f, 6.0f); triangleBody2.FixedRotation = true; // look at me! Fixture triangleFixture2 = triangleBody2.CreateFixture(polygon); triangleFixture2.CollisionGroup = LargeGroup; triangleFixture2.CollisionCategories = TriangleCategory; triangleFixture2.CollidesWith = TriangleMask; { Body body = BodyFactory.CreateBody(World); body.BodyType = BodyType.Dynamic; body.Position = new Vector2(-5.0f, 10.0f); Vertices box = PolygonTools.CreateRectangle(0.5f, 1.0f); PolygonShape p = new PolygonShape(box, 1); body.CreateFixture(p); PrismaticJoint jd = new PrismaticJoint(triangleBody2, body, triangleBody2.GetLocalPoint(body.Position), Vector2.Zero, new Vector2(0.0f, 1.0f)); jd.LimitEnabled = true; jd.LowerLimit = -1.0f; jd.UpperLimit = 1.0f; World.AddJoint(jd); } // Small box polygon.SetAsBox(1.0f, 0.5f); Body boxBody = BodyFactory.CreateBody(World); boxBody.BodyType = BodyType.Dynamic; boxBody.Position = new Vector2(0.0f, 2.0f); Fixture boxFixture = boxBody.CreateFixture(polygon); boxFixture.Restitution = 0.1f; boxFixture.CollisionGroup = SmallGroup; boxFixture.CollisionCategories = BoxCategory; boxFixture.CollidesWith = BoxMask; // Large box (recycle definitions) polygon.SetAsBox(2, 1); Body boxBody2 = BodyFactory.CreateBody(World); boxBody2.BodyType = BodyType.Dynamic; boxBody2.Position = new Vector2(0.0f, 6.0f); Fixture boxFixture2 = boxBody2.CreateFixture(polygon); boxFixture2.CollisionGroup = LargeGroup; boxFixture2.CollisionCategories = BoxCategory; boxFixture2.CollidesWith = BoxMask; // Small circle CircleShape circle = new CircleShape(1.0f, 1); Body circleBody = BodyFactory.CreateBody(World); circleBody.BodyType = BodyType.Dynamic; circleBody.Position = new Vector2(5.0f, 2.0f); Fixture circleFixture = circleBody.CreateFixture(circle); circleFixture.CollisionGroup = SmallGroup; circleFixture.CollisionCategories = CircleCategory; circleFixture.CollidesWith = CircleMask; // Large circle circle.Radius *= 2.0f; Body circleBody2 = BodyFactory.CreateBody(World); circleBody2.BodyType = BodyType.Dynamic; circleBody2.Position = new Vector2(5.0f, 6.0f); Fixture circleFixture2 = circleBody2.CreateFixture(circle); circleFixture2.CollisionGroup = LargeGroup; circleFixture2.CollisionCategories = CircleCategory; circleFixture2.CollidesWith = CircleMask; // Large circle - Ignore with other large circle Body circleBody3 = BodyFactory.CreateBody(World); circleBody3.BodyType = BodyType.Dynamic; circleBody3.Position = new Vector2(6.0f, 9.0f); //Another large circle. This one uses IgnoreCollisionWith() logic instead of categories. Fixture circleFixture3 = circleBody3.CreateFixture(circle); circleFixture3.CollisionGroup = LargeGroup; circleFixture3.CollisionCategories = CircleCategory; circleFixture3.CollidesWith = CircleMask; circleFixture3.IgnoreCollisionWith(circleFixture2); } }
private GearsTest() { Body ground = BodyFactory.CreateEdge(World, new Vector2(50.0f, 0.0f), new Vector2(-50.0f, 0.0f)); { CircleShape circle1 = new CircleShape(1.0f, 5f); PolygonShape box = new PolygonShape(5f); box.Vertices = PolygonTools.CreateRectangle(0.5f, 5.0f); CircleShape circle2 = new CircleShape(2.0f, 5f); Body body1 = BodyFactory.CreateBody(World, new Vector2(10.0f, 9.0f)); body1.CreateFixture(circle1); Body body2 = BodyFactory.CreateBody(World, new Vector2(10.0f, 8.0f)); body2.BodyType = BodyType.Dynamic; body2.CreateFixture(box); Body body3 = BodyFactory.CreateBody(World, new Vector2(10.0f, 6.0f)); body3.BodyType = BodyType.Dynamic; body3.CreateFixture(circle2); RevoluteJoint joint1 = new RevoluteJoint(body2, body1, body1.Position, true); World.AddJoint(joint1); RevoluteJoint joint2 = new RevoluteJoint(body2, body3, body3.Position, true); World.AddJoint(joint2); GearJoint joint4 = new GearJoint(joint1, joint2, circle2.Radius / circle1.Radius); joint4.BodyA = body1; joint4.BodyB = body3; World.AddJoint(joint4); } { CircleShape circle1 = new CircleShape(1.0f, 5.0f); CircleShape circle2 = new CircleShape(2.0f, 5.0f); PolygonShape box = new PolygonShape(5f); box.Vertices = PolygonTools.CreateRectangle(0.5f, 5.0f); Body body1 = BodyFactory.CreateBody(World, new Vector2(-3.0f, 12.0f)); body1.BodyType = BodyType.Dynamic; body1.CreateFixture(circle1); _joint1 = new RevoluteJoint(ground, body1, body1.Position, true); _joint1.ReferenceAngle = body1.Rotation - ground.Rotation; World.AddJoint(_joint1); Body body2 = BodyFactory.CreateBody(World, new Vector2(0.0f, 12.0f)); body2.BodyType = BodyType.Dynamic; body2.CreateFixture(circle2); _joint2 = new RevoluteJoint(ground, body2, body2.Position, true); World.AddJoint(_joint2); Body body3 = BodyFactory.CreateBody(World, new Vector2(2.5f, 12.0f)); body3.BodyType = BodyType.Dynamic; body3.CreateFixture(box); _joint3 = new PrismaticJoint(ground, body3, body3.Position, new Vector2(0.0f, 1.0f)); _joint3.LowerLimit = -5.0f; _joint3.UpperLimit = 5.0f; _joint3.LimitEnabled = true; World.AddJoint(_joint3); _joint4 = new GearJoint(_joint1, _joint2, circle2.Radius / circle1.Radius); _joint4.BodyA = body1; _joint4.BodyB = body2; World.AddJoint(_joint4); _joint5 = new GearJoint(_joint2, _joint3, -1.0f / circle2.Radius); _joint5.BodyA = body2; _joint5.BodyB = body3; World.AddJoint(_joint5); } }
public void Deserialize(World world, Stream stream) { world.Clear(); XMLFragmentElement root = XMLFragmentParser.LoadFromStream(stream); if (root.Name.ToLower() != "world") throw new Exception(); foreach (XMLFragmentElement main in root.Elements) { if (main.Name.ToLower() == "gravity") { world.Gravity = ReadVector(main); } } foreach (XMLFragmentElement shapeElement in root.Elements) { if (shapeElement.Name.ToLower() == "shapes") { foreach (XMLFragmentElement n in shapeElement.Elements) { if (n.Name.ToLower() != "shape") throw new Exception(); ShapeType type = (ShapeType)Enum.Parse(typeof(ShapeType), n.Attributes[0].Value, true); switch (type) { case ShapeType.Circle: { CircleShape shape = new CircleShape(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "radius": shape.Radius = float.Parse(sn.Value); break; case "position": shape.Position = ReadVector(sn); break; default: throw new Exception(); } } _shapes.Add(shape); } break; case ShapeType.Polygon: { PolygonShape shape = new PolygonShape(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "vertices": { List<Vector2> verts = new List<Vector2>(); foreach (XMLFragmentElement vert in sn.Elements) verts.Add(ReadVector(vert)); shape.Set(new Vertices(verts.ToArray())); } break; case "centroid": shape.MassData.Centroid = ReadVector(sn); break; } } _shapes.Add(shape); } break; case ShapeType.Edge: { EdgeShape shape = new EdgeShape(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "hasvertex0": shape.HasVertex0 = bool.Parse(sn.Value); break; case "hasvertex3": shape.HasVertex0 = bool.Parse(sn.Value); break; case "vertex0": shape.Vertex0 = ReadVector(sn); break; case "vertex1": shape.Vertex1 = ReadVector(sn); break; case "vertex2": shape.Vertex2 = ReadVector(sn); break; case "vertex3": shape.Vertex3 = ReadVector(sn); break; default: throw new Exception(); } } _shapes.Add(shape); } break; } } } } foreach (XMLFragmentElement fixtureElement in root.Elements) { if (fixtureElement.Name.ToLower() == "fixtures") { foreach (XMLFragmentElement n in fixtureElement.Elements) { Fixture fixture = new Fixture(); if (n.Name.ToLower() != "fixture") throw new Exception(); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "shape": fixture.Shape = _shapes[int.Parse(sn.Value)]; break; case "density": fixture.Shape.Density = float.Parse(sn.Value); break; case "filterdata": foreach (XMLFragmentElement ssn in sn.Elements) { switch (ssn.Name.ToLower()) { case "categorybits": fixture._collisionCategories = (Category)int.Parse(ssn.Value); break; case "maskbits": fixture._collidesWith = (Category)int.Parse(ssn.Value); break; case "groupindex": fixture._collisionGroup = short.Parse(ssn.Value); break; } } break; case "friction": fixture.Friction = float.Parse(sn.Value); break; case "issensor": fixture.IsSensor = bool.Parse(sn.Value); break; case "restitution": fixture.Restitution = float.Parse(sn.Value); break; case "userdata": fixture.UserData = ReadSimpleType(sn, null, false); break; } } _fixtures.Add(fixture); } } } foreach (XMLFragmentElement bodyElement in root.Elements) { if (bodyElement.Name.ToLower() == "bodies") { foreach (XMLFragmentElement n in bodyElement.Elements) { Body body = new Body(world); if (n.Name.ToLower() != "body") throw new Exception(); body.BodyType = (BodyType)Enum.Parse(typeof(BodyType), n.Attributes[0].Value, true); foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "active": if (bool.Parse(sn.Value)) body.Flags |= BodyFlags.Enabled; else body.Flags &= ~BodyFlags.Enabled; break; case "allowsleep": body.SleepingAllowed = bool.Parse(sn.Value); break; case "angle": { Vector2 position = body.Position; body.SetTransformIgnoreContacts(ref position, float.Parse(sn.Value)); } break; case "angulardamping": body.AngularDamping = float.Parse(sn.Value); break; case "angularvelocity": body.AngularVelocity = float.Parse(sn.Value); break; case "awake": body.Awake = bool.Parse(sn.Value); break; case "bullet": body.IsBullet = bool.Parse(sn.Value); break; case "fixedrotation": body.FixedRotation = bool.Parse(sn.Value); break; case "lineardamping": body.LinearDamping = float.Parse(sn.Value); break; case "linearvelocity": body.LinearVelocity = ReadVector(sn); break; case "position": { float rotation = body.Rotation; Vector2 position = ReadVector(sn); body.SetTransformIgnoreContacts(ref position, rotation); } break; case "userdata": body.UserData = ReadSimpleType(sn, null, false); break; case "fixtures": { foreach (XMLFragmentElement v in sn.Elements) { Fixture blueprint = _fixtures[int.Parse(v.Value)]; Fixture f = new Fixture(body, blueprint.Shape, blueprint.CollisionCategories); f.Restitution = blueprint.Restitution; f.UserData = blueprint.UserData; f.Friction = blueprint.Friction; f.CollidesWith = blueprint.CollidesWith; f.CollisionGroup = blueprint.CollisionGroup; } break; } } } _bodies.Add(body); } } } foreach (XMLFragmentElement jointElement in root.Elements) { if (jointElement.Name.ToLower() == "joints") { foreach (XMLFragmentElement n in jointElement.Elements) { Joint joint; if (n.Name.ToLower() != "joint") throw new Exception(); JointType type = (JointType)Enum.Parse(typeof(JointType), n.Attributes[0].Value, true); int bodyAIndex = -1, bodyBIndex = -1; bool collideConnected = false; object userData = null; foreach (XMLFragmentElement sn in n.Elements) { switch (sn.Name.ToLower()) { case "bodya": bodyAIndex = int.Parse(sn.Value); break; case "bodyb": bodyBIndex = int.Parse(sn.Value); break; case "collideconnected": collideConnected = bool.Parse(sn.Value); break; case "userdata": userData = ReadSimpleType(sn, null, false); break; } } Body bodyA = _bodies[bodyAIndex]; Body bodyB = _bodies[bodyBIndex]; switch (type) { case JointType.Distance: joint = new DistanceJoint(); break; case JointType.Friction: joint = new FrictionJoint(); break; case JointType.Line: joint = new LineJoint(); break; case JointType.Prismatic: joint = new PrismaticJoint(); break; case JointType.Pulley: joint = new PulleyJoint(); break; case JointType.Revolute: joint = new RevoluteJoint(); break; case JointType.Weld: joint = new WeldJoint(); break; case JointType.Rope: joint = new RopeJoint(); break; case JointType.Angle: joint = new AngleJoint(); break; case JointType.Slider: joint = new SliderJoint(); break; case JointType.Gear: throw new Exception("GearJoint is not supported."); default: throw new Exception("Invalid or unsupported joint."); } joint.CollideConnected = collideConnected; joint.UserData = userData; joint.BodyA = bodyA; joint.BodyB = bodyB; _joints.Add(joint); world.AddJoint(joint); foreach (XMLFragmentElement sn in n.Elements) { // check for specific nodes switch (type) { case JointType.Distance: { switch (sn.Name.ToLower()) { case "dampingratio": ((DistanceJoint)joint).DampingRatio = float.Parse(sn.Value); break; case "frequencyhz": ((DistanceJoint)joint).Frequency = float.Parse(sn.Value); break; case "length": ((DistanceJoint)joint).Length = float.Parse(sn.Value); break; case "localanchora": ((DistanceJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((DistanceJoint)joint).LocalAnchorB = ReadVector(sn); break; } } break; case JointType.Friction: { switch (sn.Name.ToLower()) { case "localanchora": ((FrictionJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((FrictionJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxforce": ((FrictionJoint)joint).MaxForce = float.Parse(sn.Value); break; case "maxtorque": ((FrictionJoint)joint).MaxTorque = float.Parse(sn.Value); break; } } break; case JointType.Line: { switch (sn.Name.ToLower()) { case "enablemotor": ((LineJoint)joint).MotorEnabled = bool.Parse(sn.Value); break; case "localanchora": ((LineJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((LineJoint)joint).LocalAnchorB = ReadVector(sn); break; case "motorspeed": ((LineJoint)joint).MotorSpeed = float.Parse(sn.Value); break; case "dampingratio": ((LineJoint)joint).DampingRatio = float.Parse(sn.Value); break; case "maxmotortorque": ((LineJoint)joint).MaxMotorTorque = float.Parse(sn.Value); break; case "frequencyhz": ((LineJoint)joint).Frequency = float.Parse(sn.Value); break; case "localxaxis": ((LineJoint)joint).LocalXAxis = ReadVector(sn); break; } } break; case JointType.Prismatic: { switch (sn.Name.ToLower()) { case "enablelimit": ((PrismaticJoint)joint).LimitEnabled = bool.Parse(sn.Value); break; case "enablemotor": ((PrismaticJoint)joint).MotorEnabled = bool.Parse(sn.Value); break; case "localanchora": ((PrismaticJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((PrismaticJoint)joint).LocalAnchorB = ReadVector(sn); break; case "local1axis1": ((PrismaticJoint)joint).LocalXAxis1 = ReadVector(sn); break; case "maxmotorforce": ((PrismaticJoint)joint).MaxMotorForce = float.Parse(sn.Value); break; case "motorspeed": ((PrismaticJoint)joint).MotorSpeed = float.Parse(sn.Value); break; case "lowertranslation": ((PrismaticJoint)joint).LowerLimit = float.Parse(sn.Value); break; case "uppertranslation": ((PrismaticJoint)joint).UpperLimit = float.Parse(sn.Value); break; case "referenceangle": ((PrismaticJoint)joint).ReferenceAngle = float.Parse(sn.Value); break; } } break; case JointType.Pulley: { switch (sn.Name.ToLower()) { case "groundanchora": ((PulleyJoint)joint).GroundAnchorA = ReadVector(sn); break; case "groundanchorb": ((PulleyJoint)joint).GroundAnchorB = ReadVector(sn); break; case "lengtha": ((PulleyJoint)joint).LengthA = float.Parse(sn.Value); break; case "lengthb": ((PulleyJoint)joint).LengthB = float.Parse(sn.Value); break; case "localanchora": ((PulleyJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((PulleyJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxlengtha": ((PulleyJoint)joint).MaxLengthA = float.Parse(sn.Value); break; case "maxlengthb": ((PulleyJoint)joint).MaxLengthB = float.Parse(sn.Value); break; case "ratio": ((PulleyJoint)joint).Ratio = float.Parse(sn.Value); break; } } break; case JointType.Revolute: { switch (sn.Name.ToLower()) { case "enablelimit": ((RevoluteJoint)joint).LimitEnabled = bool.Parse(sn.Value); break; case "enablemotor": ((RevoluteJoint)joint).MotorEnabled = bool.Parse(sn.Value); break; case "localanchora": ((RevoluteJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((RevoluteJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxmotortorque": ((RevoluteJoint)joint).MaxMotorTorque = float.Parse(sn.Value); break; case "motorspeed": ((RevoluteJoint)joint).MotorSpeed = float.Parse(sn.Value); break; case "lowerangle": ((RevoluteJoint)joint).LowerLimit = float.Parse(sn.Value); break; case "upperangle": ((RevoluteJoint)joint).UpperLimit = float.Parse(sn.Value); break; case "referenceangle": ((RevoluteJoint)joint).ReferenceAngle = float.Parse(sn.Value); break; } } break; case JointType.Weld: { switch (sn.Name.ToLower()) { case "localanchora": ((WeldJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((WeldJoint)joint).LocalAnchorB = ReadVector(sn); break; } } break; case JointType.Rope: { switch (sn.Name.ToLower()) { case "localanchora": ((RopeJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((RopeJoint)joint).LocalAnchorB = ReadVector(sn); break; case "maxlength": ((RopeJoint)joint).MaxLength = float.Parse(sn.Value); break; } } break; case JointType.Gear: throw new Exception("Gear joint is unsupported"); case JointType.Angle: { switch (sn.Name.ToLower()) { case "biasfactor": ((AngleJoint)joint).BiasFactor = float.Parse(sn.Value); break; case "maximpulse": ((AngleJoint)joint).MaxImpulse = float.Parse(sn.Value); break; case "softness": ((AngleJoint)joint).Softness = float.Parse(sn.Value); break; case "targetangle": ((AngleJoint)joint).TargetAngle = float.Parse(sn.Value); break; } } break; case JointType.Slider: { switch (sn.Name.ToLower()) { case "dampingratio": ((SliderJoint)joint).DampingRatio = float.Parse(sn.Value); break; case "frequencyhz": ((SliderJoint)joint).Frequency = float.Parse(sn.Value); break; case "maxlength": ((SliderJoint)joint).MaxLength = float.Parse(sn.Value); break; case "minlength": ((SliderJoint)joint).MinLength = float.Parse(sn.Value); break; case "localanchora": ((SliderJoint)joint).LocalAnchorA = ReadVector(sn); break; case "localanchorb": ((SliderJoint)joint).LocalAnchorB = ReadVector(sn); break; } } break; } } } } } }
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 FixedAngleJoint(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.Line: 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.LocalXAxis1; 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).LocalXAxis1 = pJoint.LocalXAxis1; 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; }