/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public RobotArmDemo(DemosGame game) : base(game) { //Since this is not a "StandardDemo" derived class, we need to set our own gravity. Space.ForceUpdater.Gravity = new Vector3(0, -9.81f, 0); Entity ground = new Box(Vector3.Zero, 30, 1, 30); Space.Add(ground); var armBase = new Cylinder(new Vector3(0, 2, 0), 2.5f, 1, 40); Space.Add(armBase); //The arm base can rotate around the Y axis. //Rotation is controlled by user input. groundToBaseJoint = new RevoluteJoint(ground, armBase, Vector3.Zero, Vector3.Up); groundToBaseJoint.Motor.IsActive = true; groundToBaseJoint.Motor.Settings.Mode = MotorMode.Servomechanism; groundToBaseJoint.Motor.Settings.MaximumForce = 3500; Space.Add(groundToBaseJoint); Entity lowerArm = new Box(armBase.Position + new Vector3(0, 2, 0), 1, 3, .5f, 10); Space.Add(lowerArm); shoulder = new RevoluteJoint(armBase, lowerArm, armBase.Position, Vector3.Forward); shoulder.Motor.IsActive = true; shoulder.Motor.Settings.Mode = MotorMode.Servomechanism; shoulder.Motor.Settings.MaximumForce = 2500; //Don't want it to rotate too far; this keeps the whole contraption off the ground. shoulder.Limit.IsActive = true; shoulder.Limit.MinimumAngle = -MathHelper.PiOver4; shoulder.Limit.MaximumAngle = MathHelper.PiOver4; Space.Add(shoulder); //Make the next piece of the arm. Entity upperArm = new Cylinder(lowerArm.Position + new Vector3(0, 3, 0), 3, .25f, 10); Space.Add(upperArm); //Swivel hinges allow motion around two axes. Imagine a tablet PC's monitor hinge. elbow = new SwivelHingeJoint(lowerArm, upperArm, lowerArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward); elbow.TwistMotor.IsActive = true; elbow.TwistMotor.Settings.Mode = MotorMode.Servomechanism; elbow.TwistMotor.Settings.MaximumForce = 1000; elbow.HingeMotor.IsActive = true; elbow.HingeMotor.Settings.Mode = MotorMode.Servomechanism; elbow.HingeMotor.Settings.MaximumForce = 1250; //Keep it from rotating too much. elbow.HingeLimit.IsActive = true; elbow.HingeLimit.MinimumAngle = -MathHelper.PiOver2; elbow.HingeLimit.MaximumAngle = MathHelper.PiOver2; Space.Add(elbow); //Add a menacing claw at the end. var lowerPosition = upperArm.Position + new Vector3(-.65f, 1.6f, 0); CollisionRules clawPart1ARules = new CollisionRules(); var bodies = new List<CompoundChildData>() { new CompoundChildData() { Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1ARules }, new CompoundChildData() { Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(-.375f, .4f, 0), 3), Material = new Material(2,2,0) } }; var claw = new CompoundBody(bodies, 6); Space.Add(claw); clawHingeA = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward); clawHingeA.Motor.IsActive = true; clawHingeA.Motor.Settings.Mode = MotorMode.Servomechanism; clawHingeA.Motor.Settings.Servo.Goal = -MathHelper.PiOver2; //Weaken the claw to prevent it from crushing the boxes. clawHingeA.Motor.Settings.Servo.SpringSettings.DampingConstant /= 100; clawHingeA.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 100; clawHingeA.Limit.IsActive = true; clawHingeA.Limit.MinimumAngle = -MathHelper.PiOver2; clawHingeA.Limit.MaximumAngle = -MathHelper.Pi / 6; Space.Add(clawHingeA); //Add one more claw to complete the contraption. lowerPosition = upperArm.Position + new Vector3(.65f, 1.6f, 0); CollisionRules clawPart1BRules = new CollisionRules(); bodies = new List<CompoundChildData>() { new CompoundChildData() { Entry = new CompoundShapeEntry(new BoxShape(1, .25f, .25f), lowerPosition, 3), CollisionRules = clawPart1BRules }, new CompoundChildData() { Entry = new CompoundShapeEntry(new ConeShape(1, .125f), lowerPosition + new Vector3(.375f, .4f, 0), 3), Material = new Material(2,2,0) } }; claw = new CompoundBody(bodies, 6); Space.Add(claw); clawHingeB = new RevoluteJoint(upperArm, claw, upperArm.Position + new Vector3(0, 1.5f, 0), Vector3.Forward); clawHingeB.Motor.IsActive = true; clawHingeB.Motor.Settings.Mode = MotorMode.Servomechanism; clawHingeB.Motor.Settings.Servo.Goal = MathHelper.PiOver2; //Weaken the claw to prevent it from crushing the boxes. clawHingeB.Motor.Settings.Servo.SpringSettings.DampingConstant /= 100; clawHingeB.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 100; clawHingeB.Limit.IsActive = true; clawHingeB.Limit.MinimumAngle = MathHelper.Pi / 6; clawHingeB.Limit.MaximumAngle = MathHelper.PiOver2; Space.Add(clawHingeB); //Keep the pieces of the robot from interacting with each other. //The CollisionRules.AddRule method is just a convenience method that adds items to the 'specific' dictionary. //Sometimes, it's a little unwieldy to reference the collision rules, //so the convenience method just takes the owners and hides the ugly syntax. CollisionRules.AddRule(armBase, lowerArm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(clawPart1ARules, upperArm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(clawPart1BRules, upperArm, CollisionRule.NoBroadPhase); //Here's an example without a convenience method. Since they are both direct CollisionRules references, it's pretty clean. clawPart1BRules.Specific.Add(clawPart1ARules, CollisionRule.NoBroadPhase); //Put some boxes on the ground to try to pick up. for (double k = 0; k < Math.PI * 2; k += Math.PI / 6) { Space.Add(new Box(new Vector3((float)Math.Cos(k) * 5.5f, 2, (float)Math.Sin(k) * 5.5f), 1, 1, 1, 10)); } game.Camera.Position = new Vector3(0, 5, 13); }
/// <summary> /// Constructs a new demo. /// </summary> /// <param name="game">Game owning this demo.</param> public UnfortunateGuyDemo(DemosGame game) : base(game) { Entity ground = new Box(Vector3.Zero, 10, 1, 10); Space.Add(ground); //Rather than add basically redundant code for every limb, this demo //focuses on a single arm, showing some extra details and limits. //Make the torso. var bodies = new List<CompoundShapeEntry>() { new CompoundShapeEntry(new BoxShape(2, 1.5f, 1), new Vector3(-1, 3, 0), 50), new CompoundShapeEntry(new SphereShape(.45f), new Vector3(.4f, 3, 0), 1), new CompoundShapeEntry(new SphereShape(.25f), new Vector3(-1.9f, 3.5f, 0), 1), new CompoundShapeEntry(new SphereShape(.25f), new Vector3(-1.9f, 2.5f, 0), 1), new CompoundShapeEntry(new SphereShape(.25f), new Vector3(-.3f, 2.3f, 0), 1) }; var torso = new CompoundBody(bodies, 54); Space.Add(torso); //Make the upper arm. Entity upperArm = new Box(torso.Position + new Vector3(1, 1.4f, 0), .4f, 1.2f, .4f, 8); Space.Add(upperArm); //A ball socket joint will handle the linear degrees of freedom between the two entities. var ballSocketJoint = new BallSocketJoint(torso, upperArm, torso.Position + new Vector3(1, .7f, 0)); Space.Add(ballSocketJoint); //Shoulders don't have a simple limit. The EllipseSwingLimit allows angles within an ellipse, which is closer to how some joints function //than just flat planes (like two RevoluteLimits) or a single angle (like SwingLimits). var swingLimit = new EllipseSwingLimit(torso, upperArm, Vector3.Up, MathHelper.PiOver2, MathHelper.PiOver4 * 3); Space.Add(swingLimit); //Upper arms can't spin around forever. var twistLimit = new TwistLimit(torso, upperArm, Vector3.Up, Vector3.Up, -MathHelper.PiOver4 / 2, MathHelper.PiOver4); twistLimit.SpringSettings.StiffnessConstant = 100; twistLimit.SpringSettings.DampingConstant = 100; Space.Add(twistLimit); //Make the lower arm. Entity lowerArm = new Box(upperArm.Position + new Vector3(0, 1.4f, 0), .35f, 1.3f, .35f, 8); Space.Add(lowerArm); var elbow = new SwivelHingeJoint(upperArm, lowerArm, upperArm.Position + new Vector3(0, .6f, 0), Vector3.Forward); //Forearm can twist a little. elbow.TwistLimit.IsActive = true; elbow.TwistLimit.MinimumAngle = -MathHelper.PiOver4 / 2; elbow.TwistLimit.MaximumAngle = MathHelper.PiOver4 / 2; elbow.TwistLimit.SpringSettings.DampingConstant = 100; elbow.TwistLimit.SpringSettings.StiffnessConstant = 100; //The elbow is like a hinge, but it can't hyperflex. elbow.HingeLimit.IsActive = true; elbow.HingeLimit.MinimumAngle = 0; elbow.HingeLimit.MaximumAngle = MathHelper.Pi * .7f; Space.Add(elbow); Entity hand = new Box(lowerArm.Position + new Vector3(0, .9f, 0), .4f, .55f, .25f, 3); Space.Add(hand); ballSocketJoint = new BallSocketJoint(lowerArm, hand, lowerArm.Position + new Vector3(0, .7f, 0)); Space.Add(ballSocketJoint); //Wrists can use an ellipse limit too. swingLimit = new EllipseSwingLimit(lowerArm, hand, Vector3.Up, MathHelper.PiOver4, MathHelper.PiOver2); Space.Add(swingLimit); //Allow a little extra twist beyond the forearm. twistLimit = new TwistLimit(lowerArm, hand, Vector3.Up, Vector3.Up, -MathHelper.PiOver4 / 2, MathHelper.PiOver4 / 2); twistLimit.SpringSettings.StiffnessConstant = 100; twistLimit.SpringSettings.DampingConstant = 100; Space.Add(twistLimit); //The hand is pretty floppy without some damping. var angularMotor = new AngularMotor(lowerArm, hand); angularMotor.Settings.VelocityMotor.Softness = .5f; Space.Add(angularMotor); //Make sure the parts of the arm don't collide. CollisionRules.AddRule(torso, upperArm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(lowerArm, upperArm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(lowerArm, hand, CollisionRule.NoBroadPhase); game.Camera.Position = new Vector3(0, 4, 20); }
public Joints(SoundEffect hn, SoundEffect rotv, seeSaw ss, HelicopterBase hb, HelicopterRotor hr, HelicopterSkid hs, HelicopterTail ht, HelicopterTailRotor htr, HelicopterClawHolder hch, HelicopterClawHinge hchinge, HelicopterClawItemHolder hcih) { engineOn = false; // Set the engine to off hBase = hb; hRotor = hr; hSkid = hs; hTail = ht; hTailRotor = htr; hClawHolder = hch; hClawHinge = hchinge; hClawItemHolder = hcih; seeSaw = ss; helicopterNoise = hn; hnInstance = helicopterNoise.CreateInstance(); // New instance of sound effect hnInstance.Volume = 0.6f; hnInstance.IsLooped = true; rideOfTheValkyries = rotv; rotvInstance = rideOfTheValkyries.CreateInstance(); // New instance of sound effect rotvInstance.Volume = 0.6f; rotvInstance.IsLooped = true; hBaseRotorJoint = new RevoluteJoint(hBase.helicopter.body, hRotor.rotor.body, hBase.helicopter.body.Position, Vector3.Up); // Joint for rotor on top of helicopter hBaseRotorJoint.Motor.Settings.MaximumForce = 200; hBaseRotorJoint.Motor.IsActive = false; // Well joints for skids on bottom of helicopter and tail, attach each entity to the helicopter hTailJoint = new WeldJoint(hTail.tail.body, hBase.helicopter.body); hSkidJoint1 = new WeldJoint(hSkid.skid1.body, hBase.helicopter.body); hSkidJoint2 = new WeldJoint(hSkid.skid2.body, hBase.helicopter.body); hTailRotorJoint = new RevoluteJoint(hTailRotor.tailRotor.body, hTail.tail.body, hTailRotor.tailRotor.body.Position, Vector3.Right); // Joint for rotor on tail of the helicopter hTailRotorJoint.Motor.Settings.MaximumForce = 180; hTailRotorJoint.Motor.IsActive = false; hClawHolderJoint = new SwivelHingeJoint(hBase.helicopter.body, hClawHolder.clawHolder.body, hBase.helicopter.body.Position, Vector3.Right); // Joint for claw holder below helicopter hClawHolderJoint.HingeLimit.IsActive = true; hClawHolderJoint.HingeLimit.MinimumAngle = -MathHelper.Pi / 45; hClawHolderJoint.HingeLimit.MaximumAngle = MathHelper.Pi / 45; // 4 similar joints for hinge joints between the claw holder and a part of the claw // The hinges code was created with help from the examuse ple Bepu Physics demo available from the website hClawHingeJoint1 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge1.body, hClawHolder.clawHolder.body.Position, Vector3.Forward); hClawHingeJoint1.Motor.IsActive = true; hClawHingeJoint1.Motor.Settings.Mode = MotorMode.Servomechanism; hClawHingeJoint1.Motor.Settings.Servo.Goal = -MathHelper.PiOver2; hClawHingeJoint1.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20; // Damping to quicken the claw contracting hClawHingeJoint1.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20; // Stop the claw from over moving on the axis hClawHingeJoint1.Limit.IsActive = true; hClawHingeJoint1.Limit.MinimumAngle = -MathHelper.TwoPi; hClawHingeJoint1.Limit.MaximumAngle = MathHelper.PiOver4; hClawHingeJoint2 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge2.body, hClawHolder.clawHolder.body.Position, Vector3.Backward); hClawHingeJoint2.Motor.IsActive = true; hClawHingeJoint2.Motor.Settings.Mode = MotorMode.Servomechanism; hClawHingeJoint2.Motor.Settings.Servo.Goal = -MathHelper.PiOver2; hClawHingeJoint2.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20; hClawHingeJoint2.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20; hClawHingeJoint2.Limit.IsActive = true; hClawHingeJoint2.Limit.MinimumAngle = -MathHelper.TwoPi; hClawHingeJoint2.Limit.MaximumAngle = MathHelper.PiOver4; hClawHingeJoint3 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge3.body, hClawHolder.clawHolder.body.Position, Vector3.Right); hClawHingeJoint3.Motor.IsActive = true; hClawHingeJoint3.Motor.Settings.Mode = MotorMode.Servomechanism; hClawHingeJoint3.Motor.Settings.Servo.Goal = -MathHelper.PiOver2; hClawHingeJoint3.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20; hClawHingeJoint3.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20; hClawHingeJoint3.Limit.IsActive = true; hClawHingeJoint3.Limit.MinimumAngle = -MathHelper.TwoPi; hClawHingeJoint3.Limit.MaximumAngle = MathHelper.PiOver4; hClawHingeJoint4 = new RevoluteJoint(hClawHolder.clawHolder.body, hClawHinge.clawHinge4.body, hClawHolder.clawHolder.body.Position, Vector3.Left); hClawHingeJoint4.Motor.IsActive = true; hClawHingeJoint4.Motor.Settings.Mode = MotorMode.Servomechanism; hClawHingeJoint4.Motor.Settings.Servo.Goal = -MathHelper.PiOver2; hClawHingeJoint4.Motor.Settings.Servo.SpringSettings.DampingConstant /= 20; hClawHingeJoint4.Motor.Settings.Servo.SpringSettings.StiffnessConstant /= 20; hClawHingeJoint4.Limit.IsActive = true; hClawHingeJoint4.Limit.MinimumAngle = -MathHelper.TwoPi; hClawHingeJoint4.Limit.MaximumAngle = MathHelper.PiOver4; // More weld joints as the claw pieces are made up off two different sections hClawItemHolderJoint1 = new WeldJoint(hClawHinge.clawHinge1.body, hClawItemHolder.clawItemHolder1.body); hClawItemHolderJoint2 = new WeldJoint(hClawHinge.clawHinge2.body, hClawItemHolder.clawItemHolder2.body); hClawItemHolderJoint3 = new WeldJoint(hClawHinge.clawHinge3.body, hClawItemHolder.clawItemHolder3.body); hClawItemHolderJoint4 = new WeldJoint(hClawHinge.clawHinge4.body, hClawItemHolder.clawItemHolder4.body); // Joint for the seesaw with the ball located on it seeSawJoint = new RevoluteJoint(seeSaw.seeSawHolder.body, seeSaw.seeSawBoard.body, seeSaw.seeSawHolder.body.Position, Vector3.Forward); revoluteJoints.Add(hBaseRotorJoint); revoluteJoints.Add(hTailRotorJoint); revoluteJoints.Add(hClawHingeJoint1); revoluteJoints.Add(hClawHingeJoint2); revoluteJoints.Add(hClawHingeJoint3); revoluteJoints.Add(hClawHingeJoint4); revoluteJoints.Add(seeSawJoint); weldJoints.Add(hTailJoint); weldJoints.Add(hSkidJoint1); weldJoints.Add(hSkidJoint2); weldJoints.Add(hClawItemHolderJoint1); weldJoints.Add(hClawItemHolderJoint2); weldJoints.Add(hClawItemHolderJoint3); weldJoints.Add(hClawItemHolderJoint4); entities.Add(hBase.helicopter); entities.Add(hRotor.rotor); entities.Add(hSkid.skid1); entities.Add(hSkid.skid2); entities.Add(hTail.tail); entities.Add(hTailRotor.tailRotor); entities.Add(hClawHolder.clawHolder); entities.Add(hClawHinge.clawHinge1); entities.Add(hClawHinge.clawHinge2); entities.Add(hClawHinge.clawHinge3); entities.Add(hClawHinge.clawHinge4); entities.Add(hClawItemHolder.clawItemHolder1); entities.Add(hClawItemHolder.clawItemHolder2); entities.Add(hClawItemHolder.clawItemHolder3); entities.Add(hClawItemHolder.clawItemHolder4); for (int i = 0; i < revoluteJoints.Count; i++) // Add all the revolute joints to the space { Game1.Instance.Space.Add(revoluteJoints.ElementAt(i)); } for (int i = 0; i < weldJoints.Count; i++) // Add all the weld joints to the space { Game1.Instance.Space.Add(weldJoints.ElementAt(i)); } Game1.Instance.Space.Add(hClawHolderJoint); // Add the swivel hinge joint to the space }
public Ragdoll() { #region Ragdoll Entities //Create the ragdoll's bones. var pelvis = new Box(Vector3.Zero, .5f, .28f, .33f, 20); var torsoBottom = new Box(pelvis.Position + new Vector3(0, .3f, 0), .42f, .48f, .3f, 15); var torsoTop = new Box(torsoBottom.Position + new Vector3(0, .3f, 0), .5f, .38f, .32f, 20); var neck = new Box(torsoTop.Position + new Vector3(0, .2f, .04f), .19f, .24f, .2f, 5); var head = new Sphere(neck.Position + new Vector3(0, .22f, -.04f), .19f, 7); var leftUpperArm = new Box(torsoTop.Position + new Vector3(-.46f, .1f, 0), .52f, .19f, .19f, 6); var leftForearm = new Box(leftUpperArm.Position + new Vector3(-.5f, 0, 0), .52f, .18f, .18f, 5); var leftHand = new Box(leftForearm.Position + new Vector3(-.35f, 0, 0), .28f, .13f, .22f, 4); var rightUpperArm = new Box(torsoTop.Position + new Vector3(.46f, .1f, 0), .52f, .19f, .19f, 6); var rightForearm = new Box(rightUpperArm.Position + new Vector3(.5f, 0, 0), .52f, .18f, .18f, 5); var rightHand = new Box(rightForearm.Position + new Vector3(.35f, 0, 0), .28f, .13f, .22f, 4); var leftThigh = new Box(pelvis.Position + new Vector3(-.15f, -.4f, 0), .23f, .63f, .23f, 10); var leftShin = new Box(leftThigh.Position + new Vector3(0, -.6f, 0), .21f, .63f, .21f, 7); var leftFoot = new Box(leftShin.Position + new Vector3(0, -.35f, -.1f), .23f, .15f, .43f, 5); var rightThigh = new Box(pelvis.Position + new Vector3(.15f, -.4f, 0), .23f, .63f, .23f, 10); var rightShin = new Box(rightThigh.Position + new Vector3(0, -.6f, 0), .21f, .63f, .21f, 7); var rightFoot = new Box(rightShin.Position + new Vector3(0, -.35f, -.1f), .23f, .15f, .43f, 5); #endregion #region Bone List //Make a convenient list of all of the bones. bones.Add(pelvis); bones.Add(torsoBottom); bones.Add(torsoTop); bones.Add(neck); bones.Add(head); bones.Add(leftUpperArm); bones.Add(leftForearm); bones.Add(leftHand); bones.Add(rightUpperArm); bones.Add(rightForearm); bones.Add(rightHand); bones.Add(leftThigh); bones.Add(leftShin); bones.Add(leftFoot); bones.Add(rightThigh); bones.Add(rightShin); bones.Add(rightFoot); #endregion #region Collision Rules //Prevent adjacent limbs from colliding. CollisionRules.AddRule(pelvis, torsoBottom, CollisionRule.NoBroadPhase); CollisionRules.AddRule(torsoBottom, torsoTop, CollisionRule.NoBroadPhase); CollisionRules.AddRule(torsoTop, neck, CollisionRule.NoBroadPhase); CollisionRules.AddRule(neck, head, CollisionRule.NoBroadPhase); CollisionRules.AddRule(head, torsoTop, CollisionRule.NoBroadPhase); CollisionRules.AddRule(torsoTop, leftUpperArm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(leftUpperArm, leftForearm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(leftForearm, leftHand, CollisionRule.NoBroadPhase); CollisionRules.AddRule(torsoTop, rightUpperArm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(rightUpperArm, rightForearm, CollisionRule.NoBroadPhase); CollisionRules.AddRule(rightForearm, rightHand, CollisionRule.NoBroadPhase); CollisionRules.AddRule(pelvis, leftThigh, CollisionRule.NoBroadPhase); CollisionRules.AddRule(leftThigh, leftShin, CollisionRule.NoBroadPhase); CollisionRules.AddRule(leftThigh, torsoBottom, CollisionRule.NoBroadPhase); CollisionRules.AddRule(leftShin, leftFoot, CollisionRule.NoBroadPhase); CollisionRules.AddRule(pelvis, rightThigh, CollisionRule.NoBroadPhase); CollisionRules.AddRule(rightThigh, rightShin, CollisionRule.NoBroadPhase); CollisionRules.AddRule(rightThigh, torsoBottom, CollisionRule.NoBroadPhase); CollisionRules.AddRule(rightShin, rightFoot, CollisionRule.NoBroadPhase); #endregion //Create the constraints between the bones. #region Pelvis up to Head Constraints var pelvisToTorsoBottomBallSocketJoint = new BallSocketJoint(pelvis, torsoBottom, pelvis.Position + new Vector3(0, .1f, 0)); var pelvisToTorsoBottomTwistLimit = new TwistLimit(pelvis, torsoBottom, Vector3.Up, Vector3.Up, -MathHelper.Pi / 6, MathHelper.Pi / 6); var pelvisToTorsoBottomSwingLimit = new SwingLimit(pelvis, torsoBottom, Vector3.Up, Vector3.Up, MathHelper.Pi / 6); var pelvisToTorsoBottomMotor = new AngularMotor(pelvis, torsoBottom); pelvisToTorsoBottomMotor.Settings.VelocityMotor.Softness = .05f; var torsoBottomToTorsoTopBallSocketJoint = new BallSocketJoint(torsoBottom, torsoTop, torsoBottom.Position + new Vector3(0, .25f, 0)); var torsoBottomToTorsoTopSwingLimit = new SwingLimit(torsoBottom, torsoTop, Vector3.Up, Vector3.Up, MathHelper.Pi / 6); var torsoBottomToTorsoTopTwistLimit = new TwistLimit(torsoBottom, torsoTop, Vector3.Up, Vector3.Up, -MathHelper.Pi / 6, MathHelper.Pi / 6); var torsoBottomToTorsoTopMotor = new AngularMotor(torsoBottom, torsoTop); torsoBottomToTorsoTopMotor.Settings.VelocityMotor.Softness = .05f; var torsoTopToNeckBallSocketJoint = new BallSocketJoint(torsoTop, neck, torsoTop.Position + new Vector3(0, .15f, .05f)); var torsoTopToNeckSwingLimit = new SwingLimit(torsoTop, neck, Vector3.Up, Vector3.Up, MathHelper.Pi / 6); var torsoTopToNeckTwistLimit = new TwistLimit(torsoTop, neck, Vector3.Up, Vector3.Up, -MathHelper.Pi / 8, MathHelper.Pi / 8); var torsoTopToNeckMotor = new AngularMotor(torsoTop, neck); torsoTopToNeckMotor.Settings.VelocityMotor.Softness = .1f; var neckToHeadBallSocketJoint = new BallSocketJoint(neck, head, neck.Position + new Vector3(0, .1f, .05f)); var neckToHeadTwistLimit = new TwistLimit(neck, head, Vector3.Up, Vector3.Up, -MathHelper.Pi / 8, MathHelper.Pi / 8); var neckToHeadSwingLimit = new SwingLimit(neck, head, Vector3.Up, Vector3.Up, MathHelper.Pi / 6); var neckToHeadMotor = new AngularMotor(neck, head); neckToHeadMotor.Settings.VelocityMotor.Softness = .1f; #endregion #region Left Arm var torsoTopToLeftArmBallSocketJoint = new BallSocketJoint(torsoTop, leftUpperArm, torsoTop.Position + new Vector3(-.3f, .1f, 0)); var torsoTopToLeftArmEllipseLimit = new EllipseSwingLimit(torsoTop, leftUpperArm, Vector3.Left, MathHelper.Pi * .75f, MathHelper.PiOver2); var torsoTopToLeftArmTwistLimit = new TwistLimit(torsoTop, leftUpperArm, Vector3.Left, Vector3.Left, -MathHelper.PiOver2, MathHelper.PiOver2); var torsoTopToLeftArmMotor = new AngularMotor(torsoTop, leftUpperArm); torsoTopToLeftArmMotor.Settings.VelocityMotor.Softness = .2f; var leftUpperArmToLeftForearmSwivelHingeJoint = new SwivelHingeJoint(leftUpperArm, leftForearm, leftUpperArm.Position + new Vector3(-.28f, 0, 0), Vector3.Up); leftUpperArmToLeftForearmSwivelHingeJoint.HingeLimit.IsActive = true; leftUpperArmToLeftForearmSwivelHingeJoint.TwistLimit.IsActive = true; leftUpperArmToLeftForearmSwivelHingeJoint.TwistLimit.MinimumAngle = -MathHelper.Pi / 8; leftUpperArmToLeftForearmSwivelHingeJoint.TwistLimit.MaximumAngle = MathHelper.Pi / 8; leftUpperArmToLeftForearmSwivelHingeJoint.HingeLimit.MinimumAngle = -MathHelper.Pi * .8f; leftUpperArmToLeftForearmSwivelHingeJoint.HingeLimit.MaximumAngle = 0; //The SwivelHingeJoint has motors, but they are separately defined for twist/bending. //The AngularMotor covers all degrees of freedom. var leftUpperArmToLeftForearmMotor = new AngularMotor(leftUpperArm, leftForearm); leftUpperArmToLeftForearmMotor.Settings.VelocityMotor.Softness = .3f; var leftForearmToLeftHandBallSocketJoint = new BallSocketJoint(leftForearm, leftHand, leftForearm.Position + new Vector3(-.2f, 0, 0)); var leftForearmToLeftHandEllipseSwingLimit = new EllipseSwingLimit(leftForearm, leftHand, Vector3.Left, MathHelper.PiOver2, MathHelper.Pi / 6); var leftForearmToLeftHandTwistLimit = new TwistLimit(leftForearm, leftHand, Vector3.Left, Vector3.Left, -MathHelper.Pi / 6, MathHelper.Pi / 6); var leftForearmToLeftHandMotor = new AngularMotor(leftForearm, leftHand); leftForearmToLeftHandMotor.Settings.VelocityMotor.Softness = .4f; #endregion #region Right Arm var torsoTopToRightArmBallSocketJoint = new BallSocketJoint(torsoTop, rightUpperArm, torsoTop.Position + new Vector3(.3f, .1f, 0)); var torsoTopToRightArmEllipseLimit = new EllipseSwingLimit(torsoTop, rightUpperArm, Vector3.Right, MathHelper.Pi * .75f, MathHelper.PiOver2); var torsoTopToRightArmTwistLimit = new TwistLimit(torsoTop, rightUpperArm, Vector3.Right, Vector3.Right, -MathHelper.PiOver2, MathHelper.PiOver2); var torsoTopToRightArmMotor = new AngularMotor(torsoTop, rightUpperArm); torsoTopToRightArmMotor.Settings.VelocityMotor.Softness = .2f; var rightUpperArmToRightForearmSwivelHingeJoint = new SwivelHingeJoint(rightUpperArm, rightForearm, rightUpperArm.Position + new Vector3(.28f, 0, 0), Vector3.Up); rightUpperArmToRightForearmSwivelHingeJoint.HingeLimit.IsActive = true; rightUpperArmToRightForearmSwivelHingeJoint.TwistLimit.IsActive = true; rightUpperArmToRightForearmSwivelHingeJoint.TwistLimit.MinimumAngle = -MathHelper.Pi / 8; rightUpperArmToRightForearmSwivelHingeJoint.TwistLimit.MaximumAngle = MathHelper.Pi / 8; rightUpperArmToRightForearmSwivelHingeJoint.HingeLimit.MinimumAngle = 0; rightUpperArmToRightForearmSwivelHingeJoint.HingeLimit.MaximumAngle = MathHelper.Pi * .8f; //The SwivelHingeJoint has motors, but they are separately defined for twist/bending. //The AngularMotor covers all degrees of freedom. var rightUpperArmToRightForearmMotor = new AngularMotor(rightUpperArm, rightForearm); rightUpperArmToRightForearmMotor.Settings.VelocityMotor.Softness = .3f; var rightForearmToRightHandBallSocketJoint = new BallSocketJoint(rightForearm, rightHand, rightForearm.Position + new Vector3(.2f, 0, 0)); var rightForearmToRightHandEllipseSwingLimit = new EllipseSwingLimit(rightForearm, rightHand, Vector3.Right, MathHelper.PiOver2, MathHelper.Pi / 6); var rightForearmToRightHandTwistLimit = new TwistLimit(rightForearm, rightHand, Vector3.Right, Vector3.Right, -MathHelper.Pi / 6, MathHelper.Pi / 6); var rightForearmToRightHandMotor = new AngularMotor(rightForearm, rightHand); rightForearmToRightHandMotor.Settings.VelocityMotor.Softness = .4f; #endregion #region Left Leg var pelvisToLeftThighBallSocketJoint = new BallSocketJoint(pelvis, leftThigh, pelvis.Position + new Vector3(-.15f, -.1f, 0)); var pelvisToLeftThighEllipseSwingLimit = new EllipseSwingLimit(pelvis, leftThigh, Vector3.Normalize(new Vector3(-.2f, -1, -.6f)), MathHelper.Pi * .7f, MathHelper.PiOver4); pelvisToLeftThighEllipseSwingLimit.LocalTwistAxisB = Vector3.Down; var pelvisToLeftThighTwistLimit = new TwistLimit(pelvis, leftThigh, Vector3.Down, Vector3.Down, -MathHelper.Pi / 6, MathHelper.Pi / 6); var pelvisToLeftThighMotor = new AngularMotor(pelvis, leftThigh); pelvisToLeftThighMotor.Settings.VelocityMotor.Softness = .1f; var leftThighToLeftShinRevoluteJoint = new RevoluteJoint(leftThigh, leftShin, leftThigh.Position + new Vector3(0, -.3f, 0), Vector3.Right); leftThighToLeftShinRevoluteJoint.Limit.IsActive = true; leftThighToLeftShinRevoluteJoint.Limit.MinimumAngle = -MathHelper.Pi * .8f; leftThighToLeftShinRevoluteJoint.Limit.MaximumAngle = 0; leftThighToLeftShinRevoluteJoint.Motor.IsActive = true; leftThighToLeftShinRevoluteJoint.Motor.Settings.VelocityMotor.Softness = .2f; var leftShinToLeftFootBallSocketJoint = new BallSocketJoint(leftShin, leftFoot, leftShin.Position + new Vector3(0, -.3f, 0)); var leftShinToLeftFootSwingLimit = new SwingLimit(leftShin, leftFoot, Vector3.Forward, Vector3.Forward, MathHelper.Pi / 8); var leftShinToLeftFootTwistLimit = new TwistLimit(leftShin, leftFoot, Vector3.Down, Vector3.Forward, -MathHelper.Pi / 8, MathHelper.Pi / 8); var leftShinToLeftFootMotor = new AngularMotor(leftShin, leftFoot); leftShinToLeftFootMotor.Settings.VelocityMotor.Softness = .2f; #endregion #region Right Leg var pelvisToRightThighBallSocketJoint = new BallSocketJoint(pelvis, rightThigh, pelvis.Position + new Vector3(.15f, -.1f, 0)); var pelvisToRightThighEllipseSwingLimit = new EllipseSwingLimit(pelvis, rightThigh, Vector3.Normalize(new Vector3(.2f, -1, -.6f)), MathHelper.Pi * .7f, MathHelper.PiOver4); pelvisToRightThighEllipseSwingLimit.LocalTwistAxisB = Vector3.Down; var pelvisToRightThighTwistLimit = new TwistLimit(pelvis, rightThigh, Vector3.Down, Vector3.Down, -MathHelper.Pi / 6, MathHelper.Pi / 6); var pelvisToRightThighMotor = new AngularMotor(pelvis, rightThigh); pelvisToRightThighMotor.Settings.VelocityMotor.Softness = .1f; var rightThighToRightShinRevoluteJoint = new RevoluteJoint(rightThigh, rightShin, rightThigh.Position + new Vector3(0, -.3f, 0), Vector3.Right); rightThighToRightShinRevoluteJoint.Limit.IsActive = true; rightThighToRightShinRevoluteJoint.Limit.MinimumAngle = -MathHelper.Pi * .8f; rightThighToRightShinRevoluteJoint.Limit.MaximumAngle = 0; rightThighToRightShinRevoluteJoint.Motor.IsActive = true; rightThighToRightShinRevoluteJoint.Motor.Settings.VelocityMotor.Softness = .2f; var rightShinToRightFootBallSocketJoint = new BallSocketJoint(rightShin, rightFoot, rightShin.Position + new Vector3(0, -.3f, 0)); var rightShinToRightFootSwingLimit = new SwingLimit(rightShin, rightFoot, Vector3.Forward, Vector3.Forward, MathHelper.Pi / 8); var rightShinToRightFootTwistLimit = new TwistLimit(rightShin, rightFoot, Vector3.Down, Vector3.Forward, -MathHelper.Pi / 8, MathHelper.Pi / 8); var rightShinToRightFootMotor = new AngularMotor(rightShin, rightFoot); rightShinToRightFootMotor.Settings.VelocityMotor.Softness = .2f; #endregion #region Joint List //Collect the joints. joints.Add(pelvisToTorsoBottomBallSocketJoint); joints.Add(pelvisToTorsoBottomTwistLimit); joints.Add(pelvisToTorsoBottomSwingLimit); joints.Add(pelvisToTorsoBottomMotor); joints.Add(torsoBottomToTorsoTopBallSocketJoint); joints.Add(torsoBottomToTorsoTopTwistLimit); joints.Add(torsoBottomToTorsoTopSwingLimit); joints.Add(torsoBottomToTorsoTopMotor); joints.Add(torsoTopToNeckBallSocketJoint); joints.Add(torsoTopToNeckTwistLimit); joints.Add(torsoTopToNeckSwingLimit); joints.Add(torsoTopToNeckMotor); joints.Add(neckToHeadBallSocketJoint); joints.Add(neckToHeadTwistLimit); joints.Add(neckToHeadSwingLimit); joints.Add(neckToHeadMotor); joints.Add(torsoTopToLeftArmBallSocketJoint); joints.Add(torsoTopToLeftArmEllipseLimit); joints.Add(torsoTopToLeftArmTwistLimit); joints.Add(torsoTopToLeftArmMotor); joints.Add(leftUpperArmToLeftForearmSwivelHingeJoint); joints.Add(leftUpperArmToLeftForearmMotor); joints.Add(leftForearmToLeftHandBallSocketJoint); joints.Add(leftForearmToLeftHandEllipseSwingLimit); joints.Add(leftForearmToLeftHandTwistLimit); joints.Add(leftForearmToLeftHandMotor); joints.Add(torsoTopToRightArmBallSocketJoint); joints.Add(torsoTopToRightArmEllipseLimit); joints.Add(torsoTopToRightArmTwistLimit); joints.Add(torsoTopToRightArmMotor); joints.Add(rightUpperArmToRightForearmSwivelHingeJoint); joints.Add(rightUpperArmToRightForearmMotor); joints.Add(rightForearmToRightHandBallSocketJoint); joints.Add(rightForearmToRightHandEllipseSwingLimit); joints.Add(rightForearmToRightHandTwistLimit); joints.Add(rightForearmToRightHandMotor); joints.Add(pelvisToLeftThighBallSocketJoint); joints.Add(pelvisToLeftThighEllipseSwingLimit); joints.Add(pelvisToLeftThighTwistLimit); joints.Add(pelvisToLeftThighMotor); joints.Add(leftThighToLeftShinRevoluteJoint); joints.Add(leftShinToLeftFootBallSocketJoint); joints.Add(leftShinToLeftFootSwingLimit); joints.Add(leftShinToLeftFootTwistLimit); joints.Add(leftShinToLeftFootMotor); joints.Add(pelvisToRightThighBallSocketJoint); joints.Add(pelvisToRightThighEllipseSwingLimit); joints.Add(pelvisToRightThighTwistLimit); joints.Add(pelvisToRightThighMotor); joints.Add(rightThighToRightShinRevoluteJoint); joints.Add(rightShinToRightFootBallSocketJoint); joints.Add(rightShinToRightFootSwingLimit); joints.Add(rightShinToRightFootTwistLimit); joints.Add(rightShinToRightFootMotor); #endregion }