/// <summary> /// Initializes a new instance of the HingeJoint class. /// </summary> /// <param name="world">The world class where the constraints get added to.</param> /// <param name="body1">The first body connected to the second one.</param> /// <param name="body2">The second body connected to the first one.</param> /// <param name="position">The position in world space where both bodies get connected.</param> /// <param name="hingeAxis">The axis if the hinge.</param> public LimitedHingeJoint(World world, RigidBody body1, RigidBody body2, JVector position, JVector hingeAxis, float hingeFwdAngle, float hingeBckAngle) : base(world) { // Create the hinge first, two point constraints worldPointConstraint = new PointOnPoint[2]; hingeAxis *= 0.5f; JVector pos1 = position; JVector.Add(ref pos1, ref hingeAxis, out pos1); JVector pos2 = position; JVector.Subtract(ref pos2, ref hingeAxis, out pos2); worldPointConstraint[0] = new PointOnPoint(body1, body2, pos1); worldPointConstraint[1] = new PointOnPoint(body1, body2, pos2); // Now the limit, one max distance constraint hingeAxis.Normalize(); // choose a direction that is perpendicular to the hinge JVector perpDir = JVector.Up; if (JVector.Dot(perpDir, hingeAxis) > 0.1f) perpDir = JVector.Right; // now make it perpendicular to the hinge JVector sideAxis = JVector.Cross(hingeAxis, perpDir); perpDir = JVector.Cross(sideAxis, hingeAxis); perpDir.Normalize(); // the length of the "arm" TODO take this as a parameter? what's // the effect of changing it? float len = 10.0f * 3; // Choose a position using that dir. this will be the anchor point // for body 0. relative to hinge JVector hingeRelAnchorPos0 = perpDir * len; // anchor point for body 2 is chosen to be in the middle of the // angle range. relative to hinge float angleToMiddle = 0.5f * (hingeFwdAngle - hingeBckAngle); JVector hingeRelAnchorPos1 = JVector.Transform(hingeRelAnchorPos0, JMatrix.CreateFromAxisAngle(hingeAxis, -angleToMiddle / 360.0f * 2.0f * JMath.Pi)); // work out the "string" length float hingeHalfAngle = 0.5f * (hingeFwdAngle + hingeBckAngle); float allowedDistance = len * 2.0f * (float)System.Math.Sin(hingeHalfAngle * 0.5f / 360.0f * 2.0f * JMath.Pi); JVector hingePos = body1.Position; JVector relPos0c = hingePos + hingeRelAnchorPos0; JVector relPos1c = hingePos + hingeRelAnchorPos1; distance = new PointPointDistance(body1, body2, relPos0c, relPos1c); distance.Distance = allowedDistance; distance.Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance; }
public PrismaticJoint(World world, RigidBody body1, RigidBody body2,float minimumDistance, float maximumDistance) : base(world) { fixedAngle = new FixedAngle(body1, body2); pointOnLine = new PointOnLine(body1, body2, body1.position, body2.position); minDistance = new PointPointDistance(body1, body2, body1.position, body2.position); minDistance.Behavior = PointPointDistance.DistanceBehavior.LimitMinimumDistance; minDistance.Distance = minimumDistance; maxDistance = new PointPointDistance(body1, body2, body1.position, body2.position); maxDistance.Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance; maxDistance.Distance = maximumDistance; }
private void CreatePointPointDistanceJoint() { JVector anchor1; Vector3D tempVector = ArrayExtensions.GetWithDefault<PropertyType, Vector3D>(Properties, PropertyType.Anchor1); JitterDatatypesMapping.Convert(ref tempVector, out anchor1); JVector anchor2; tempVector = ArrayExtensions.GetWithDefault<PropertyType, Vector3D>(Properties, PropertyType.Anchor2); JitterDatatypesMapping.Convert(ref tempVector, out anchor2); Constraint = new PointPointDistance(RigidBodyA, RigidBodyB, anchor1, anchor2); }
public void BuildRagdoll(World world, JVector position) { // the torso RigidBody torso = new RigidBody(new BoxShape(1.5f, 3, 0.5f)); torso.Position = position; // the head RigidBody head = new RigidBody(new SphereShape(0.5f)); head.Position = position + new JVector(0, 2.1f, 0); // connect head and torso PointPointDistance headTorso = new PointPointDistance(head, torso, position + new JVector(0, 1.6f, 0), position + new JVector(0, 1.5f, 0)); RigidBody arm1 = new RigidBody(new CapsuleShape(0.8f, 0.2f)); arm1.Position = position + new JVector(1.0f, 0.75f, 0); RigidBody arm2 = new RigidBody(new CapsuleShape(0.8f, 0.2f)); arm2.Position = position + new JVector(-1.0f, 0.75f, 0); RigidBody lowerarm1 = new RigidBody(new CapsuleShape(0.6f, 0.2f)); lowerarm1.Position = position + new JVector(1.0f, -0.45f, 0); RigidBody lowerarm2 = new RigidBody(new CapsuleShape(0.6f, 0.2f)); lowerarm2.Position = position + new JVector(-1.0f, -0.45f, 0); PointOnPoint arm1torso = new PointOnPoint(arm1, torso, position + new JVector(0.9f, 1.4f, 0)); PointOnPoint arm2torso = new PointOnPoint(arm2, torso, position + new JVector(-0.9f, 1.4f, 0)); HingeJoint arm1Hinge = new HingeJoint(world, arm1, lowerarm1, position + new JVector(1.0f, 0.05f, 0), JVector.Right); HingeJoint arm2Hinge = new HingeJoint(world, arm2, lowerarm2, position + new JVector(-1.0f, 0.05f, 0), JVector.Right); RigidBody leg1 = new RigidBody(new CapsuleShape(1.0f, 0.3f)); leg1.Position = position + new JVector(-0.5f, -2.4f, 0); RigidBody leg2 = new RigidBody(new CapsuleShape(1.0f, 0.3f)); leg2.Position = position + new JVector(0.5f, -2.4f, 0); PointOnPoint leg1torso = new PointOnPoint(leg1, torso, position + new JVector(-0.5f, -1.6f, 0)); PointOnPoint leg2torso = new PointOnPoint(leg2, torso, position + new JVector(+0.5f, -1.6f, 0)); RigidBody lowerleg1 = new RigidBody(new CapsuleShape(0.8f, 0.3f)); lowerleg1.Position = position + new JVector(-0.5f, -4.0f, 0); RigidBody lowerleg2 = new RigidBody(new CapsuleShape(0.8f, 0.3f)); lowerleg2.Position = position + new JVector(+0.5f, -4.0f, 0); HingeJoint leg1Hinge = new HingeJoint(world, leg1, lowerleg1, position + new JVector(-0.5f, -3.35f, 0), JVector.Right); HingeJoint leg2Hinge = new HingeJoint(world, leg2, lowerleg2, position + new JVector(0.5f, -3.35f, 0), JVector.Right); lowerleg1.IsActive = false; lowerleg2.IsActive = false; leg1.IsActive = false; leg2.IsActive = false; head.IsActive = false; torso.IsActive = false; arm1.IsActive = false; arm2.IsActive = false; lowerarm1.IsActive = false; lowerarm2.IsActive = false; world.AddBody(head); world.AddBody(torso); world.AddBody(arm1); world.AddBody(arm2); world.AddBody(lowerarm1); world.AddBody(lowerarm2); world.AddBody(leg1); world.AddBody(leg2); world.AddBody(lowerleg1); world.AddBody(lowerleg2); arm1Hinge.Activate(); arm2Hinge.Activate(); leg1Hinge.Activate(); leg2Hinge.Activate(); world.AddConstraint(headTorso); world.AddConstraint(arm1torso); world.AddConstraint(arm2torso); world.AddConstraint(leg1torso); world.AddConstraint(leg2torso); }