Example #1
0
    public LookAtIKSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      var modelNode = ContentManager.Load<ModelNode>("Dude/Dude");
      _meshNode = modelNode.GetSubtree().OfType<MeshNode>().First().Clone();
      _meshNode.PoseLocal = new Pose(new Vector3F(0, 0, 0), Matrix33F.CreateRotationY(ConstantsF.Pi));
      SampleHelper.EnablePerPixelLighting(_meshNode);
      GraphicsScreen.Scene.Children.Add(_meshNode);

      var animations = _meshNode.Mesh.Animations;
      var loopingAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
      {
        LoopBehavior = LoopBehavior.Cycle,
        Duration = TimeSpan.MaxValue,
      };
      AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_meshNode.SkeletonPose);

      // Create LookAtIKSolvers for some spine bones, the neck and the head.

      _spine1IK = new LookAtIKSolver
      {
        SkeletonPose = _meshNode.SkeletonPose,
        BoneIndex = 3,

        // The bone space axis that points in look direction.
        Forward = Vector3F.UnitY,

        // The bone space axis that points in up direction
        Up = Vector3F.UnitX,

        // An arbitrary rotation limit.
        Limit = ConstantsF.PiOver4,

        // We use a weight of 1 for the head, and lower weights for all other bones. Thus, most
        // of the looking will be done by the head bone, and the influence on the other bones is
        // smaller.
        Weight = 0.2f,

        // It is important to set the EyeOffsets. If we do not set EyeOffsets, the IK solver 
        // assumes that the eyes are positioned in the origin of the bone. 
        // Approximate EyeOffsets are sufficient.
        EyeOffset = new Vector3F(0.8f, 0, 0),
      };

      _spine2IK = new LookAtIKSolver
      {
        SkeletonPose = _meshNode.SkeletonPose,
        BoneIndex = 4,
        Forward = Vector3F.UnitY,
        Up = Vector3F.UnitX,
        Limit = ConstantsF.PiOver4,
        Weight = 0.2f,
        EyeOffset = new Vector3F(0.64f, 0, 0),
      };

      _spine3IK = new LookAtIKSolver
      {
        SkeletonPose = _meshNode.SkeletonPose,
        BoneIndex = 5,
        Forward = Vector3F.UnitY,
        Up = Vector3F.UnitX,
        Limit = ConstantsF.PiOver4,
        Weight = 0.3f,
        EyeOffset = new Vector3F(0.48f, 0, 0),
      };

      _neckIK = new LookAtIKSolver
      {
        SkeletonPose = _meshNode.SkeletonPose,
        BoneIndex = 6,
        Forward = Vector3F.UnitY,
        Up = Vector3F.UnitX,
        Limit = ConstantsF.PiOver4,
        Weight = 0.4f,
        EyeOffset = new Vector3F(0.32f, 0, 0),
      };

      _headIK = new LookAtIKSolver
      {
        SkeletonPose = _meshNode.SkeletonPose,
        BoneIndex = 7,
        Forward = Vector3F.UnitY,
        Up = Vector3F.UnitX,
        EyeOffset = new Vector3F(0.16f, 0.16f, 0),
        Weight = 1.0f,
        Limit = ConstantsF.PiOver4,
      };
    }
Example #2
0
        protected override void LoadContent()
        {
            // Load model and start a looping animation.
              _model = Game.Content.Load<Model>("Dude");
              var additionalData = (Dictionary<string, object>)_model.Tag;
              var skeleton = (Skeleton)additionalData["Skeleton"];
              _skeletonPose = SkeletonPose.Create(skeleton);
              var animations = (Dictionary<string, SkeletonKeyFrameAnimation>)additionalData["Animations"];
              var loopingAnimation = new AnimationClip<SkeletonPose>(animations.Values.First())
              {
            LoopBehavior = LoopBehavior.Cycle,
            Duration = TimeSpan.MaxValue,
              };
              AnimationService.StartAnimation(loopingAnimation, (IAnimatableProperty)_skeletonPose);

              // Create LookAtIKSolvers for some spine bones, the neck and the head.

              _spine1IK = new LookAtIKSolver
              {
            SkeletonPose = _skeletonPose,
            BoneIndex = 3,

            // The bone space axis that points in look direction.
            Forward = Vector3F.UnitY,

            // The bone space axis that points in up direction
            Up = Vector3F.UnitX,

            // An arbitrary rotation limit.
            Limit = ConstantsF.PiOver4,

            // We use a weight of 1 for the head, and lower weights for all other bones. Thus, most
            // of the looking will be done by the head bone, and the influence on the other bones is
            // smaller.
            Weight = 0.2f,

            // It is important to set the EyeOffsets. If we do not set EyeOffsets, the IK solver
            // assumes that the eyes are positioned in the origin of the bone.
            // Approximate EyeOffsets are sufficient.
            EyeOffset = new Vector3F(0.8f, 0, 0),
              };

              _spine2IK = new LookAtIKSolver
              {
            SkeletonPose = _skeletonPose,
            BoneIndex = 4,
            Forward = Vector3F.UnitY,
            Up = Vector3F.UnitX,
            Limit = ConstantsF.PiOver4,
            Weight = 0.2f,
            EyeOffset = new Vector3F(0.64f, 0, 0),
              };

              _spine3IK = new LookAtIKSolver
              {
            SkeletonPose = _skeletonPose,
            BoneIndex = 5,
            Forward = Vector3F.UnitY,
            Up = Vector3F.UnitX,
            Limit = ConstantsF.PiOver4,
            Weight = 0.3f,
            EyeOffset = new Vector3F(0.48f, 0, 0),
              };

              _neckIK = new LookAtIKSolver
              {
            SkeletonPose = _skeletonPose,
            BoneIndex = 6,
            Forward = Vector3F.UnitY,
            Up = Vector3F.UnitX,
            Limit = ConstantsF.PiOver4,
            Weight = 0.4f,
            EyeOffset = new Vector3F(0.32f, 0, 0),
              };

              _headIK = new LookAtIKSolver
              {
            SkeletonPose = _skeletonPose,
            BoneIndex = 7,
            Forward = Vector3F.UnitY,
            Up = Vector3F.UnitX,
            EyeOffset = new Vector3F(0.16f, 0.16f, 0),
            Weight = 1.0f,
            Limit = ConstantsF.PiOver4,
              };

              base.LoadContent();
        }