Constraint which attempts to restrict the relative angular motion of two entities. Can use a target relative orientation to apply additional force.
Inheritance: BEPUphysics.Constraints.TwoEntity.Motors.Motor, I3DImpulseConstraintWithError, I3DJacobianConstraint
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public MoreConstraintsTestDemo(DemosGame game)
            : base(game)
        {
            Box boxA = new Box(new Vector3(0, 5, 0), 1, 2, 1, 10);
            Box boxB = new Box(new Vector3(0, 8, 0), 1, 2, 1, 10);
            boxA.Orientation = Quaternion.CreateFromYawPitchRoll(0, MathHelper.PiOver4, 0);
            boxB.Orientation = Quaternion.CreateFromYawPitchRoll(MathHelper.PiOver4, 0, 0);

            WeldJoint weld = new WeldJoint(boxA, boxB);

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(weld);

            boxA = new Box(new Vector3(3, 5, 0), 1, 2, 1, 10);
            boxB = new Box(new Vector3(3, 8, 0), 1, 2, 1, 10);
            boxA.Orientation = Quaternion.CreateFromYawPitchRoll(0, MathHelper.PiOver4, 0);
            boxB.Orientation = Quaternion.CreateFromYawPitchRoll(MathHelper.PiOver4, 0, 0);

            BallSocketJoint ballSocket = new BallSocketJoint(boxA, boxB, (boxA.Position + boxB.Position) / 2);
            AngularMotor angularMotor = new AngularMotor(boxA, boxB);
            angularMotor.Settings.Mode = MotorMode.Servomechanism;

            Space.Add(boxA);
            Space.Add(boxB);
            Space.Add(ballSocket);
            Space.Add(angularMotor);

            Box ground = new Box(new Vector3(0, 0, 0), 10, 1, 10);

            Space.Add(ground);

            game.Camera.Position = new Vector3(0, 6, 15);
        }
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public ActionFigureDemo(DemosGame game)
            : base(game)
        {
            //Make a simple, poseable action figure.  This isn't a full featured 'ragdoll' really;
            //ragdolls usually have specific joint limits and appropriate kinds of joints rather than all
            //ball socket joints.  This demo could be modified into a 'proper' ragdoll.
            Entity body = new Box(new Vector3(0, 5, 0), 1.5f, 2, 1, 10);
            Space.Add(body);

            Entity head = new Sphere(body.Position + new Vector3(0, 2, 0), .5f, 5);
            Space.Add(head);

            //Connect the head to the body.
            Space.Add(new BallSocketJoint(body, head, head.Position + new Vector3(0, -.9f, 0)));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            var angularMotor = new AngularMotor(body, head);
            angularMotor.Settings.MaximumForce = 150; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Make the first arm.
            var upperLimb = new Box(body.Position + new Vector3(-1.6f, .8f, 0), 1, .5f, .5f, 5);
            Space.Add(upperLimb);

            var lowerLimb = new Box(upperLimb.Position + new Vector3(-1.4f, 0, 0), 1, .5f, .5f, 5);
            Space.Add(lowerLimb);

            //Connect the body to the upper arm.
            Space.Add(new BallSocketJoint(body, upperLimb, upperLimb.Position + new Vector3(.7f, 0, 0)));
            angularMotor = new AngularMotor(body, upperLimb);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Connect the upper arm to the lower arm.
            Space.Add(new BallSocketJoint(upperLimb, lowerLimb, upperLimb.Position + new Vector3(-.7f, 0, 0)));
            angularMotor = new AngularMotor(upperLimb, lowerLimb);
            angularMotor.Settings.MaximumForce = 150;
            Space.Add(angularMotor);

            //Make the second arm.
            upperLimb = new Box(body.Position + new Vector3(1.6f, .8f, 0), 1, .5f, .5f, 5);
            Space.Add(upperLimb);

            lowerLimb = new Box(upperLimb.Position + new Vector3(1.4f, 0, 0), 1, .5f, .5f, 5);
            Space.Add(lowerLimb);

            //Connect the body to the upper arm.
            Space.Add(new BallSocketJoint(body, upperLimb, upperLimb.Position + new Vector3(-.7f, 0, 0)));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            angularMotor = new AngularMotor(body, upperLimb);
            angularMotor.Settings.MaximumForce = 250; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Connect the upper arm to the lower arm.
            Space.Add(new BallSocketJoint(upperLimb, lowerLimb, upperLimb.Position + new Vector3(.7f, 0, 0)));
            angularMotor = new AngularMotor(upperLimb, lowerLimb);
            angularMotor.Settings.MaximumForce = 150;
            Space.Add(angularMotor);

            //Make the first leg.
            upperLimb = new Box(body.Position + new Vector3(-.6f, -2.1f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(upperLimb);

            lowerLimb = new Box(upperLimb.Position + new Vector3(0, -1.7f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(lowerLimb);

            //Connect the body to the upper leg.
            Space.Add(new BallSocketJoint(body, upperLimb, upperLimb.Position + new Vector3(0, .9f, 0)));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            angularMotor = new AngularMotor(body, upperLimb);
            angularMotor.Settings.MaximumForce = 350; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Connect the upper leg to the lower leg.
            Space.Add(new BallSocketJoint(upperLimb, lowerLimb, upperLimb.Position + new Vector3(0, -.9f, 0)));
            angularMotor = new AngularMotor(upperLimb, lowerLimb);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Make the second leg.
            upperLimb = new Box(body.Position + new Vector3(.6f, -2.1f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(upperLimb);

            lowerLimb = new Box(upperLimb.Position + new Vector3(0, -1.7f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(lowerLimb);

            //Connect the body to the upper leg.
            Space.Add(new BallSocketJoint(body, upperLimb, upperLimb.Position + new Vector3(0, .9f, 0)));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            angularMotor = new AngularMotor(body, upperLimb);
            angularMotor.Settings.MaximumForce = 350; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Connect the upper leg to the lower leg.
            Space.Add(new BallSocketJoint(upperLimb, lowerLimb, upperLimb.Position + new Vector3(0, -.9f, 0)));
            angularMotor = new AngularMotor(upperLimb, lowerLimb);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Add some ground.
            Space.Add(new Box(new Vector3(0, -3.5f, 0), 40f, 1, 40f));

            game.Camera.Position = new Vector3(0, 5, 25);
        }
        void BuildRoboArmThing(Vector3 position)
        {
            //Make the IK representation
            Bone baseBone = new Bone(position, Quaternion.Identity, 1, 3);
            Bone upperArm = new Bone(baseBone.Position + new Vector3(0, 1.5f + 2, 0), Quaternion.Identity, .4f, 4);
            Bone lowerArm = new Bone(upperArm.Position + new Vector3(0, 2 + 1, 0), Quaternion.Identity, .7f, 2);
            Bone bonkDevice = new Bone(lowerArm.Position + new Vector3(0, 5, 0), Quaternion.Identity, .6f, 1.2f);

            joints.Add(new IKBallSocketJoint(baseBone, upperArm, baseBone.Position + new Vector3(0, 1.5f, 0)));
            joints.Add(new IKSwingLimit(baseBone, upperArm, Vector3.Up, Vector3.Up, MathHelper.PiOver4));
            joints.Add(new IKBallSocketJoint(upperArm, lowerArm, upperArm.Position + new Vector3(0, 2f, 0)));
            joints.Add(new IKRevoluteJoint(upperArm, lowerArm, Vector3.Forward));
            joints.Add(new IKSwingLimit(upperArm, lowerArm, Vector3.Up, Vector3.Up, MathHelper.PiOver4));
            joints.Add(new IKPointOnLineJoint(lowerArm, bonkDevice, lowerArm.Position, Vector3.Up, bonkDevice.Position));
            joints.Add(new IKAngularJoint(lowerArm, bonkDevice));
            joints.Add(new IKLinearAxisLimit(lowerArm, bonkDevice, lowerArm.Position, Vector3.Up, bonkDevice.Position, 1.6f, 5));

            //Make the dynamics representation
            Entity baseEntity = new Cylinder(baseBone.Position, baseBone.Height, baseBone.Radius, 10);
            Entity upperArmEntity = new Cylinder(upperArm.Position, upperArm.Height, upperArm.Radius, 7);
            Entity lowerArmEntity = new Cylinder(lowerArm.Position, lowerArm.Height, lowerArm.Radius, 5);
            Entity bonkDeviceEntity = new Cylinder(bonkDevice.Position, bonkDevice.Height, bonkDevice.Radius, 3);
            bonkDeviceEntity.Orientation = bonkDevice.Orientation;

            Space.Add(baseEntity);
            Space.Add(upperArmEntity);
            Space.Add(lowerArmEntity);
            Space.Add(bonkDeviceEntity);

            Space.Add(new BallSocketJoint(baseEntity, upperArmEntity, baseBone.Position + new Vector3(0, 1.5f, 0)));
            Space.Add(new SwingLimit(baseEntity, upperArmEntity, Vector3.Up, Vector3.Up, MathHelper.PiOver4));
            Space.Add(new BallSocketJoint(upperArmEntity, lowerArmEntity, upperArm.Position + new Vector3(0, 2f, 0)));
            Space.Add(new RevoluteAngularJoint(upperArmEntity, lowerArmEntity, Vector3.Forward));
            Space.Add(new SwingLimit(upperArmEntity, lowerArmEntity, Vector3.Up, Vector3.Up, MathHelper.PiOver4));
            Space.Add(new PointOnLineJoint(lowerArmEntity, bonkDeviceEntity, lowerArm.Position, Vector3.Up, bonkDevice.Position));
            var motor = new AngularMotor(lowerArmEntity, bonkDeviceEntity);
            motor.Settings.Mode = MotorMode.Servomechanism;
            Space.Add(motor);
            Space.Add(new LinearAxisLimit(lowerArmEntity, bonkDeviceEntity, lowerArm.Position, bonkDevice.Position, Vector3.Up, 1.6f, 5));

            CollisionRules.AddRule(baseEntity, upperArmEntity, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(upperArmEntity, lowerArmEntity, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerArmEntity, bonkDeviceEntity, CollisionRule.NoBroadPhase);

            //Relate the two!
            bones.Add(new BoneRelationship(baseBone, baseEntity));
            bones.Add(new BoneRelationship(upperArm, upperArmEntity));
            bones.Add(new BoneRelationship(lowerArm, lowerArmEntity));
            bones.Add(new BoneRelationship(bonkDevice, bonkDeviceEntity));
        }
        void BuildChain(Vector3 position)
        {
            //Set up a bone chain.
            int linkCount = 100;
            var previousBoneEntity = new Cylinder(position, 1, .2f, 10);
            var previousBone = new Bone(previousBoneEntity.Position, previousBoneEntity.Orientation, previousBoneEntity.Radius, previousBoneEntity.Height);
            bones.Add(new BoneRelationship(previousBone, previousBoneEntity));
            Space.Add(previousBoneEntity);

            for (int i = 1; i < linkCount; i++)
            {
                var boneEntity = new Cylinder(previousBone.Position + new Vector3(0, 1, 0), 1, .2f, 10);
                var bone = new Bone(boneEntity.Position, boneEntity.Orientation, boneEntity.Radius, boneEntity.Height);
                bones.Add(new BoneRelationship(bone, boneEntity));
                Space.Add(boneEntity);

                //Make a relationship between the two bones and entities.
                CollisionRules.AddRule(previousBoneEntity, boneEntity, CollisionRule.NoBroadPhase);
                Vector3 anchor = (previousBoneEntity.Position + boneEntity.Position) / 2;
                var dynamicsBallSocketJoint = new BallSocketJoint(previousBoneEntity, boneEntity, anchor);
                var dynamicsAngularFriction = new AngularMotor(previousBoneEntity, boneEntity);
                dynamicsAngularFriction.Settings.Mode = MotorMode.VelocityMotor;
                dynamicsAngularFriction.Settings.MaximumForce = 200;
                Space.Add(dynamicsBallSocketJoint);
                Space.Add(dynamicsAngularFriction);
                var ikBallSocketJoint = new IKBallSocketJoint(previousBone, bone, anchor); //(the joint is auto-added to the bones; no solver-add is needed)
                joints.Add(ikBallSocketJoint);

                previousBone = bone;
                previousBoneEntity = boneEntity;
            }
        }
        void BuildActionFigure(Vector3 position)
        {
            //Make a simple, poseable action figure, like the ActionFigureDemo.
            Entity body = new Box(position, 1.5f, 2, 1, 10);
            Space.Add(body);

            Entity head = new Sphere(body.Position + new Vector3(0, 2, 0), .5f, 5);
            Space.Add(head);

            //Connect the head to the body.
            var headBodyBallSocketAnchor = head.Position + new Vector3(0, -.75f, 0);
            Space.Add(new BallSocketJoint(body, head, headBodyBallSocketAnchor));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            var angularMotor = new AngularMotor(body, head);
            angularMotor.Settings.MaximumForce = 150; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Make the first arm.
            var upperLeftArm = new Box(body.Position + new Vector3(-1.6f, .8f, 0), 1, .5f, .5f, 5);
            Space.Add(upperLeftArm);

            var lowerLeftArm = new Box(upperLeftArm.Position + new Vector3(-1.4f, 0, 0), 1, .5f, .5f, 5);
            Space.Add(lowerLeftArm);

            var leftHand = new Box(lowerLeftArm.Position + new Vector3(-.8f, 0, 0), 0.5f, 0.3f, 0.5f, 4);
            Space.Add(leftHand);

            //Connect the body to the upper arm.
            var bodyUpperLeftArmBallSocketAnchor = upperLeftArm.Position + new Vector3(.7f, 0, 0);
            Space.Add(new BallSocketJoint(body, upperLeftArm, bodyUpperLeftArmBallSocketAnchor));
            angularMotor = new AngularMotor(body, upperLeftArm);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Connect the upper arm to the lower arm.
            var upperLeftArmLowerLeftArmBallSocketAnchor = upperLeftArm.Position + new Vector3(-.7f, 0, 0);
            Space.Add(new BallSocketJoint(upperLeftArm, lowerLeftArm, upperLeftArmLowerLeftArmBallSocketAnchor));
            angularMotor = new AngularMotor(upperLeftArm, lowerLeftArm);
            angularMotor.Settings.MaximumForce = 150;
            Space.Add(angularMotor);

            //Connect the lower arm to the hand.
            var lowerLeftArmLeftHandBallSocketAnchor = lowerLeftArm.Position + new Vector3(-.5f, 0, 0);
            Space.Add(new BallSocketJoint(lowerLeftArm, leftHand, lowerLeftArmLeftHandBallSocketAnchor));
            angularMotor = new AngularMotor(lowerLeftArm, leftHand);
            angularMotor.Settings.MaximumForce = 150;
            Space.Add(angularMotor);

            //Make the second arm.
            var upperRightArm = new Box(body.Position + new Vector3(1.6f, .8f, 0), 1, .5f, .5f, 5);
            Space.Add(upperRightArm);

            var lowerRightArm = new Box(upperRightArm.Position + new Vector3(1.4f, 0, 0), 1, .5f, .5f, 5);
            Space.Add(lowerRightArm);

            var rightHand = new Box(lowerRightArm.Position + new Vector3(.8f, 0, 0), 0.5f, 0.3f, 0.5f, 4);
            Space.Add(rightHand);

            //Connect the body to the upper arm.
            var bodyUpperRightArmBallSocketAnchor = upperRightArm.Position + new Vector3(-.7f, 0, 0);
            Space.Add(new BallSocketJoint(body, upperRightArm, bodyUpperRightArmBallSocketAnchor));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            angularMotor = new AngularMotor(body, upperRightArm);
            angularMotor.Settings.MaximumForce = 250; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Connect the upper arm to the lower arm.
            var upperRightArmLowerRightArmBallSocketAnchor = upperRightArm.Position + new Vector3(.7f, 0, 0);
            Space.Add(new BallSocketJoint(upperRightArm, lowerRightArm, upperRightArmLowerRightArmBallSocketAnchor));
            angularMotor = new AngularMotor(upperRightArm, lowerRightArm);
            angularMotor.Settings.MaximumForce = 150;
            Space.Add(angularMotor);

            //Connect the lower arm to the hand.
            var lowerRightArmRightHandBallSocketAnchor = lowerRightArm.Position + new Vector3(.5f, 0, 0);
            Space.Add(new BallSocketJoint(lowerRightArm, rightHand, lowerRightArmRightHandBallSocketAnchor));
            angularMotor = new AngularMotor(lowerRightArm, rightHand);
            angularMotor.Settings.MaximumForce = 150;
            Space.Add(angularMotor);

            //Make the first leg.
            var upperLeftLeg = new Box(body.Position + new Vector3(-.6f, -2.1f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(upperLeftLeg);

            var lowerLeftLeg = new Box(upperLeftLeg.Position + new Vector3(0, -1.7f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(lowerLeftLeg);

            var leftFoot = new Box(lowerLeftLeg.Position + new Vector3(0, -.25f - 0.65f, 0.25f), .5f, .4f, 1, 8);
            Space.Add(leftFoot);

            //Connect the body to the upper leg.
            var bodyUpperLeftLegBallSocketAnchor = upperLeftLeg.Position + new Vector3(0, .9f, 0);
            Space.Add(new BallSocketJoint(body, upperLeftLeg, bodyUpperLeftLegBallSocketAnchor));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            angularMotor = new AngularMotor(body, upperLeftLeg);
            angularMotor.Settings.MaximumForce = 350; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Connect the upper leg to the lower leg.
            var upperLeftLegLowerLeftLegBallSocketAnchor = upperLeftLeg.Position + new Vector3(0, -.9f, 0);
            Space.Add(new BallSocketJoint(upperLeftLeg, lowerLeftLeg, upperLeftLegLowerLeftLegBallSocketAnchor));
            angularMotor = new AngularMotor(upperLeftLeg, lowerLeftLeg);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Connect the lower leg to the foot.
            var lowerLeftLegLeftFootBallSocketAnchor = lowerLeftLeg.Position + new Vector3(0, -.65f, 0);
            Space.Add(new BallSocketJoint(lowerLeftLeg, leftFoot, lowerLeftLegLeftFootBallSocketAnchor));
            angularMotor = new AngularMotor(lowerLeftLeg, leftFoot);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Make the second leg.
            var upperRightLeg = new Box(body.Position + new Vector3(.6f, -2.1f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(upperRightLeg);

            var lowerRightLeg = new Box(upperRightLeg.Position + new Vector3(0, -1.7f, 0), .5f, 1.3f, .5f, 8);
            Space.Add(lowerRightLeg);

            var rightFoot = new Box(lowerRightLeg.Position + new Vector3(0, -.25f - 0.65f, 0.25f), .5f, .4f, 1, 8);
            Space.Add(rightFoot);

            //Connect the body to the upper leg.
            var bodyUpperRightLegBallSocketAnchor = upperRightLeg.Position + new Vector3(0, .9f, 0);
            Space.Add(new BallSocketJoint(body, upperRightLeg, bodyUpperRightLegBallSocketAnchor));
            //Angular motors can be used to simulate friction when their goal velocity is 0.
            angularMotor = new AngularMotor(body, upperRightLeg);
            angularMotor.Settings.MaximumForce = 350; //The maximum force of 'friction' in this joint.
            Space.Add(angularMotor);

            //Connect the upper leg to the lower leg.
            var upperRightLegLowerRightLegBallSocketAnchor = upperRightLeg.Position + new Vector3(0, -.9f, 0);
            Space.Add(new BallSocketJoint(upperRightLeg, lowerRightLeg, upperRightLegLowerRightLegBallSocketAnchor));
            angularMotor = new AngularMotor(upperRightLeg, lowerRightLeg);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Connect the lower leg to the foot.
            var lowerRightLegRightFootBallSocketAnchor = lowerRightLeg.Position + new Vector3(0, -.65f, 0);
            Space.Add(new BallSocketJoint(lowerRightLeg, rightFoot, lowerRightLegRightFootBallSocketAnchor));
            angularMotor = new AngularMotor(lowerRightLeg, rightFoot);
            angularMotor.Settings.MaximumForce = 250;
            Space.Add(angularMotor);

            //Set up collision rules.
            CollisionRules.AddRule(head, body, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(body, upperLeftArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(upperLeftArm, lowerLeftArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerLeftArm, leftHand, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(body, upperRightArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(upperRightArm, lowerRightArm, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerRightArm, rightHand, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(body, upperLeftLeg, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(upperLeftLeg, lowerLeftLeg, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerLeftLeg, leftFoot, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(body, upperRightLeg, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(upperRightLeg, lowerRightLeg, CollisionRule.NoBroadPhase);
            CollisionRules.AddRule(lowerRightLeg, rightFoot, CollisionRule.NoBroadPhase);

            //IK version!
            Bone bodyBone = new Bone(body.Position, Quaternion.Identity, .75f, 2);
            Bone headBone = new Bone(head.Position, Quaternion.Identity, .4f, .8f);
            Bone upperLeftArmBone = new Bone(upperLeftArm.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), .25f, 1);
            Bone lowerLeftArmBone = new Bone(lowerLeftArm.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), .25f, 1);
            Bone upperRightArmBone = new Bone(upperRightArm.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), .25f, 1);
            Bone lowerRightArmBone = new Bone(lowerRightArm.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), .25f, 1);
            Bone leftHandBone = new Bone(leftHand.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), .2f, .5f);
            Bone rightHandBone = new Bone(rightHand.Position, Quaternion.CreateFromAxisAngle(new Vector3(0, 0, 1), MathHelper.PiOver2), .2f, .5f);
            Bone upperLeftLegBone = new Bone(upperLeftLeg.Position, Quaternion.Identity, .25f, 1.3f);
            Bone lowerLeftLegBone = new Bone(lowerLeftLeg.Position, Quaternion.Identity, .25f, 1.3f);
            Bone leftFootBone = new Bone(leftFoot.Position, Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathHelper.PiOver2), .25f, 1);
            Bone upperRightLegBone = new Bone(upperRightLeg.Position, Quaternion.Identity, .25f, 1.3f);
            Bone lowerRightLegBone = new Bone(lowerRightLeg.Position, Quaternion.Identity, .25f, 1.3f);
            Bone rightFootBone = new Bone(rightFoot.Position, Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathHelper.PiOver2), .25f, 1);

            bones.Add(new BoneRelationship(bodyBone, body));
            bones.Add(new BoneRelationship(headBone, head));
            bones.Add(new BoneRelationship(upperLeftArmBone, upperLeftArm));
            bones.Add(new BoneRelationship(lowerLeftArmBone, lowerLeftArm));
            bones.Add(new BoneRelationship(upperRightArmBone, upperRightArm));
            bones.Add(new BoneRelationship(lowerRightArmBone, lowerRightArm));
            bones.Add(new BoneRelationship(leftHandBone, leftHand));
            bones.Add(new BoneRelationship(rightHandBone, rightHand));
            bones.Add(new BoneRelationship(upperLeftLegBone, upperLeftLeg));
            bones.Add(new BoneRelationship(lowerLeftLegBone, lowerLeftLeg));
            bones.Add(new BoneRelationship(leftFootBone, leftFoot));
            bones.Add(new BoneRelationship(upperRightLegBone, upperRightLeg));
            bones.Add(new BoneRelationship(lowerRightLegBone, lowerRightLeg));
            bones.Add(new BoneRelationship(rightFootBone, rightFoot));

            //[We don't care about the return values here. A bit weird, but the constructor puts the reference where it needs to go.]
            joints.Add(new IKBallSocketJoint(bodyBone, headBone, headBodyBallSocketAnchor));
            joints.Add(new IKSwingLimit(bodyBone, headBone, Vector3.Up, Vector3.Up, MathHelper.PiOver2));
            joints.Add(new IKTwistLimit(bodyBone, headBone, Vector3.Up, Vector3.Up, MathHelper.PiOver2));

            //Left arm
            joints.Add(new IKBallSocketJoint(bodyBone, upperLeftArmBone, bodyUpperLeftArmBallSocketAnchor));
            joints.Add(new IKSwingLimit(bodyBone, upperLeftArmBone, Vector3.Normalize(new Vector3(-1, 0, .3f)), Vector3.Left, MathHelper.Pi * .65f));
            joints.Add(new IKTwistLimit(bodyBone, upperLeftArmBone, Vector3.Left, Vector3.Left, MathHelper.PiOver2) { Rigidity = 0.08f });
            joints.Add(new IKBallSocketJoint(upperLeftArmBone, lowerLeftArmBone, upperLeftArmLowerLeftArmBallSocketAnchor));
            joints.Add(new IKSwivelHingeJoint(upperLeftArmBone, lowerLeftArmBone, Vector3.Up, Vector3.Left));
            joints.Add(new IKSwingLimit(upperLeftArmBone, lowerLeftArmBone, Vector3.Normalize(new Vector3(-0.23f, 0, .97f)), Vector3.Left, MathHelper.Pi * 0.435f));
            joints.Add(new IKTwistLimit(upperLeftArmBone, lowerLeftArmBone, Vector3.Left, Vector3.Left, MathHelper.PiOver4) { Rigidity = 0.08f });
            joints.Add(new IKBallSocketJoint(lowerLeftArmBone, leftHandBone, lowerLeftArmLeftHandBallSocketAnchor));
            joints.Add(new IKSwingLimit(lowerLeftArmBone, leftHandBone, Vector3.Left, Vector3.Left, MathHelper.PiOver2));
            joints.Add(new IKTwistLimit(lowerLeftArmBone, leftHandBone, Vector3.Left, Vector3.Left, MathHelper.PiOver4) { Rigidity = 0.08f });

            //Right arm
            joints.Add(new IKBallSocketJoint(bodyBone, upperRightArmBone, bodyUpperRightArmBallSocketAnchor));
            joints.Add(new IKSwingLimit(bodyBone, upperRightArmBone, Vector3.Normalize(new Vector3(1, 0, .3f)), Vector3.Right, MathHelper.Pi * .65f));
            joints.Add(new IKTwistLimit(bodyBone, upperRightArmBone, Vector3.Right, Vector3.Right, MathHelper.PiOver2) { Rigidity = 0.08f });
            joints.Add(new IKBallSocketJoint(upperRightArmBone, lowerRightArmBone, upperRightArmLowerRightArmBallSocketAnchor));
            joints.Add(new IKSwivelHingeJoint(upperRightArmBone, lowerRightArmBone, Vector3.Up, Vector3.Right));
            joints.Add(new IKSwingLimit(upperRightArmBone, lowerRightArmBone, Vector3.Normalize(new Vector3(0.23f, 0, .97f)), Vector3.Right, MathHelper.Pi * 0.435f));
            joints.Add(new IKTwistLimit(upperRightArmBone, lowerRightArmBone, Vector3.Right, Vector3.Right, MathHelper.PiOver4) { Rigidity = 0.08f });
            joints.Add(new IKBallSocketJoint(lowerRightArmBone, rightHandBone, lowerRightArmRightHandBallSocketAnchor));
            joints.Add(new IKSwingLimit(lowerRightArmBone, rightHandBone, Vector3.Right, Vector3.Right, MathHelper.PiOver2));
            joints.Add(new IKTwistLimit(lowerRightArmBone, rightHandBone, Vector3.Right, Vector3.Right, MathHelper.PiOver4) { Rigidity = 0.08f });

            //Left Leg
            joints.Add(new IKBallSocketJoint(bodyBone, upperLeftLegBone, bodyUpperLeftLegBallSocketAnchor));
            joints.Add(new IKSwingLimit(bodyBone, upperLeftLegBone, Vector3.Normalize(new Vector3(-.3f, -1, .6f)), Vector3.Down, MathHelper.Pi * 0.6f));
            joints.Add(new IKTwistLimit(bodyBone, upperLeftLegBone, Vector3.Up, Vector3.Up, MathHelper.PiOver4) { MeasurementAxisA = Vector3.Normalize(new Vector3(-1, 0, 1)), Rigidity = 0.08f });
            joints.Add(new IKBallSocketJoint(upperLeftLegBone, lowerLeftLegBone, upperLeftLegLowerLeftLegBallSocketAnchor));
            joints.Add(new IKSwivelHingeJoint(upperLeftLegBone, lowerLeftLegBone, Vector3.Left, Vector3.Down));
            joints.Add(new IKTwistLimit(upperLeftLegBone, lowerLeftLegBone, Vector3.Up, Vector3.Up, MathHelper.Pi * .1f) { Rigidity = 0.08f });
            joints.Add(new IKSwingLimit(upperLeftLegBone, lowerLeftLegBone, Vector3.Normalize(new Vector3(0, -.23f, -.97f)), Vector3.Down, MathHelper.Pi * 0.435f));
            joints.Add(new IKBallSocketJoint(lowerLeftLegBone, leftFootBone, lowerLeftLegLeftFootBallSocketAnchor));
            joints.Add(new IKTwistJoint(lowerLeftLegBone, leftFootBone, Vector3.Down, Vector3.Down) { Rigidity = 0.08f });
            joints.Add(new IKSwingLimit(lowerLeftLegBone, leftFootBone, Vector3.Normalize(new Vector3(0, -1, -.3f)), Vector3.Down, MathHelper.Pi * 0.22f));

            //Right leg
            joints.Add(new IKBallSocketJoint(bodyBone, upperRightLegBone, bodyUpperRightLegBallSocketAnchor));
            joints.Add(new IKSwingLimit(bodyBone, upperRightLegBone, Vector3.Normalize(new Vector3(.3f, -1, .6f)), Vector3.Down, MathHelper.Pi * 0.6f));
            joints.Add(new IKTwistLimit(bodyBone, upperRightLegBone, Vector3.Up, Vector3.Up, MathHelper.PiOver4) { MeasurementAxisA = Vector3.Normalize(new Vector3(1, 0, 1)), Rigidity = 0.08f });
            joints.Add(new IKBallSocketJoint(upperRightLegBone, lowerRightLegBone, upperRightLegLowerRightLegBallSocketAnchor));
            joints.Add(new IKSwivelHingeJoint(upperRightLegBone, lowerRightLegBone, Vector3.Right, Vector3.Down));
            joints.Add(new IKTwistLimit(upperRightLegBone, lowerRightLegBone, Vector3.Up, Vector3.Up, MathHelper.Pi * .1f) { Rigidity = 0.08f });
            joints.Add(new IKSwingLimit(upperRightLegBone, lowerRightLegBone, Vector3.Normalize(new Vector3(0, -.23f, -.97f)), Vector3.Down, MathHelper.Pi * 0.435f));
            joints.Add(new IKBallSocketJoint(lowerRightLegBone, rightFootBone, lowerRightLegRightFootBallSocketAnchor));
            joints.Add(new IKTwistJoint(lowerRightLegBone, rightFootBone, Vector3.Down, Vector3.Down) { Rigidity = 0.08f });
            joints.Add(new IKSwingLimit(lowerRightLegBone, rightFootBone, Vector3.Normalize(new Vector3(0, -1, -.3f)), Vector3.Down, MathHelper.Pi * 0.22f));
        }
Beispiel #6
0
        public override void InitializeComponents()
        {
            Component shade;
            Light shadeLight;

            var toplink = new Component(Position, Quaternion.Identity, scalevec / 32.0f);
            toplink.Mesh = new LPPMesh(segmentModel);
            toplink.SetCollision(segmentPhys, true);

            Components.Add(toplink);

            Vector3 yVec = new Vector3(0.0f, scalevec.Y, 0.0f);

            var lastlink = toplink;

            for (int i = 0; i < numSegments; i++)
            {
                var link = new Component(Position - (yVec * (float)i * linklength), Quaternion.Identity, scalevec / 32.0f);
                link.Mesh = new LPPMesh(segmentModel);
                link.SetCollision(segmentPhys, false);
                CollisionRules.AddRule(lastlink.Entity, link.Entity, CollisionRule.NoBroadPhase);
                var joint = new DistanceJoint(lastlink.Entity, link.Entity, link.Position, link.Position);

                joint.SpringSettings.Advanced.UseAdvancedSettings = true;
                joint.SpringSettings.Advanced.ErrorReductionFactor = 0.99f;
                joint.SpringSettings.Advanced.Softness = 0.1f;

                Components.Add(link);
                Components.Add(new DummyComponent(joint));
                lastlink = link;
            }

            shade = new Component(Position - (yVec * ((numSegments * linklength) + 0.25f)), Quaternion.Identity, scalevec / 32.0f);
            shade.Mesh = new LPPMesh(lampModel);

            shadeLight = new Light();
            shadeLight.LocalTransform = Matrix.CreateTranslation(yVec * -0.3f);
            shadeLight.Shadow = true;
            shadeLight.LightType = "BakedShadow";
            shadeLight.Radius = 12.5f;
            shadeLight.Intensity = 0.75f;
            shadeLight.Color = lightColor;
            PhysicsInfo PI = new PhysicsInfo(lampPhys);
            PI.Density /= scalevec.Length() / Vector3.One.Length();
            shade.SetCollision(PI, false);
            shade.Lights.Add(shadeLight);
            shade.Entity.Tag = new EntityTag(this, shade);

            shadeLight = new Light();
            shadeLight.Color = lightColor;
            shadeLight.LocalTransform = Matrix.CreateTranslation(yVec);
            shadeLight.Radius = 11.9f;
            shadeLight.Intensity = 0.75f;
            shadeLight.Shadow = false;
            shade.Lights.Add(shadeLight);

            shadeLight = new Light();
            shadeLight.Intensity = 1.0f;
            shadeLight.Radius = 0.5f;
            shade.Lights.Add(shadeLight);
            Components.Add(shade);

            CollisionRules.AddRule(shade.Entity, lastlink.Entity, CollisionRule.NoBroadPhase);
            var joint1 = new DistanceJoint(lastlink.Entity, shade.Entity, shade.Position, lastlink.Position);
            joint1.SpringSettings.DampingConstant = 1000000f;
            joint1.SpringSettings.StiffnessConstant = 600000f;
            var angularMotor1 = new AngularMotor(lastlink.Entity, shade.Entity);
            angularMotor1.Settings.MaximumForce = 50f;
            Components.Add(new DummyComponent(joint1));
            Components.Add(new DummyComponent(angularMotor1));
            base.InitializeComponents();
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        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
        }