private void SerializeJoint(FarseerJoint joint) { if (joint.IsFixedType()) return; _writer.WriteStartElement("Joint"); _writer.WriteAttributeString("Type", joint.JointType.ToString()); WriteElement("BodyA", FindBodyIndex(joint.BodyA)); WriteElement("BodyB", FindBodyIndex(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 djd = (DistanceJoint)joint; WriteElement("DampingRatio", djd.DampingRatio); WriteElement("FrequencyHz", djd.Frequency); WriteElement("Length", djd.Length); WriteElement("LocalAnchorA", djd.LocalAnchorA); WriteElement("LocalAnchorB", djd.LocalAnchorB); } break; case JointType.Friction: { FrictionJoint fjd = (FrictionJoint)joint; WriteElement("LocalAnchorA", fjd.LocalAnchorA); WriteElement("LocalAnchorB", fjd.LocalAnchorB); WriteElement("MaxForce", fjd.MaxForce); WriteElement("MaxTorque", fjd.MaxTorque); } break; case JointType.Gear: throw new Exception("Gear joint not supported by serialization"); //case JointType.Wheel: // { // WheelJoint ljd = (WheelJoint)joint; // WriteElement("EnableMotor", ljd.MotorEnabled); // WriteElement("LocalAnchorA", ljd.LocalAnchorA); // WriteElement("LocalAnchorB", ljd.LocalAnchorB); // WriteElement("MotorSpeed", ljd.MotorSpeed); // WriteElement("DampingRatio", ljd.DampingRatio); // WriteElement("MaxMotorTorque", ljd.MaxMotorTorque); // WriteElement("FrequencyHz", ljd.Frequency); // WriteElement("LocalXAxis", ljd.LocalXAxis); // } // break; case JointType.Prismatic: { PrismaticJoint pjd = (PrismaticJoint)joint; //NOTE: Does not conform with Box2DScene WriteElement("EnableLimit", pjd.LimitEnabled); WriteElement("EnableMotor", pjd.MotorEnabled); WriteElement("LocalAnchorA", pjd.LocalAnchorA); WriteElement("LocalAnchorB", pjd.LocalAnchorB); WriteElement("LocalXAxis1", pjd.LocalXAxisA); WriteElement("LowerTranslation", pjd.LowerLimit); WriteElement("UpperTranslation", pjd.UpperLimit); WriteElement("MaxMotorForce", pjd.MaxMotorForce); WriteElement("MotorSpeed", pjd.MotorSpeed); } break; //case JointType.Pulley: // { // PulleyJoint pjd = (PulleyJoint)joint; // WriteElement("GroundAnchorA", pjd.GroundAnchorA); // WriteElement("GroundAnchorB", pjd.GroundAnchorB); // WriteElement("LengthA", pjd.LengthA); // WriteElement("LengthB", pjd.LengthB); // WriteElement("LocalAnchorA", pjd.LocalAnchorA); // WriteElement("LocalAnchorB", pjd.LocalAnchorB); // WriteElement("MaxLengthA", pjd.MaxLengthA); // WriteElement("MaxLengthB", pjd.MaxLengthB); // WriteElement("Ratio", pjd.Ratio); // } // break; case JointType.Revolute: { RevoluteJoint rjd = (RevoluteJoint)joint; WriteElement("EnableLimit", rjd.LimitEnabled); WriteElement("EnableMotor", rjd.MotorEnabled); WriteElement("LocalAnchorA", rjd.LocalAnchorA); WriteElement("LocalAnchorB", rjd.LocalAnchorB); WriteElement("LowerAngle", rjd.LowerLimit); WriteElement("MaxMotorTorque", rjd.MaxMotorTorque); WriteElement("MotorSpeed", rjd.MotorSpeed); WriteElement("ReferenceAngle", rjd.ReferenceAngle); WriteElement("UpperAngle", rjd.UpperLimit); } break; case JointType.Weld: { WeldJoint wjd = (WeldJoint)joint; WriteElement("LocalAnchorA", wjd.LocalAnchorA); WriteElement("LocalAnchorB", wjd.LocalAnchorB); } break; // // Not part of Box2DScene // case JointType.Rope: { RopeJoint rjd = (RopeJoint)joint; WriteElement("LocalAnchorA", rjd.LocalAnchorA); WriteElement("LocalAnchorB", rjd.LocalAnchorB); WriteElement("MaxLength", rjd.MaxLength); } break; case JointType.Angle: { AngleJoint aj = (AngleJoint)joint; WriteElement("BiasFactor", aj.BiasFactor); WriteElement("MaxImpulse", aj.MaxImpulse); WriteElement("Softness", aj.Softness); WriteElement("TargetAngle", aj.TargetAngle); } break; case JointType.Slider: { SliderJoint sliderJoint = (SliderJoint)joint; WriteElement("DampingRatio", sliderJoint.DampingRatio); WriteElement("FrequencyHz", sliderJoint.Frequency); WriteElement("MaxLength", sliderJoint.MaxLength); WriteElement("MinLength", sliderJoint.MinLength); WriteElement("LocalAnchorA", sliderJoint.LocalAnchorA); WriteElement("LocalAnchorB", sliderJoint.LocalAnchorB); } break; default: throw new Exception("Joint not supported"); } _writer.WriteEndElement(); }
/// <summary> /// Destroy a joint. This may cause the connected bodies to begin colliding. /// </summary> /// <param name="joint">The joint.</param> public void RemoveJoint(FarseerJoint joint) { RemoveJoint(joint, true); }
public static FSGearJoint CreateGearJoint(FSWorld world, FarseerJoint jointA, FarseerJoint jointB, float ratio) { FSGearJoint gearJoint = new FSGearJoint(jointA, jointB, ratio); world.AddJoint(gearJoint); return gearJoint; }
private void RemoveJoint(FarseerJoint joint, bool doCheck) { if (doCheck) { Debug.Assert(!_jointRemoveList.Contains(joint), "The joint is already marked for removal. You are removing the joint more than once."); } if (!_jointRemoveList.Contains(joint)) _jointRemoveList.Add(joint); }
/// <summary> /// Create a joint to constrain bodies together. This may cause the connected bodies to cease colliding. /// </summary> /// <param name="joint">The joint.</param> public void AddJoint(FarseerJoint joint) { Debug.Assert(!_jointAddList.Contains(joint), "You are adding the same joint more than once."); if (!_jointAddList.Contains(joint)) _jointAddList.Add(joint); }
public void Add(FarseerJoint joint) { Debug.Assert(JointCount < JointCapacity); _joints[JointCount++] = 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> 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; }
/// <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; }