private void test_playAnimation(int frameIndex, MotionClipData motionClipData)
 {
     if (MotionName == motionClipData.Name)
     {
         NextFrame.Value = motionClipData.MotionFrames[frameIndex];
     }
     else
     {
         timer           = 0;
         NextFrame.Value = motionClipData.MotionFrames[0];
     }
 }
    public void GetNextFrame()
    {
        var            calCulateCost       = new CalculateCost();
        float          bestScore           = float.MaxValue;
        int            bestScoreClipIndex  = 0;
        int            bestScoreFrameIndex = 0;
        float          normalizedTime      = 0;
        MotionClipData motionClipData      = MotionClips[0];
        int            frameIndex          = 0;

        GetPlayerMotion(PlayerInput, timer);

        for (int i = 0; i < MotionClips.Count; i++)
        {
            //var normalizedTime = (timer % MotionClips[i].MotionClipLengthInMilliseconds) / MotionClips[i].MotionClipLengthInMilliseconds;
            if (MotionClips[i].ClipType != NowClipType)
            {
                continue;
            }

            for (int j = 0; j < MotionClips[i].MotionFrames.Length; j++)
            {
                var thisMotionScore = calCulateCost.CalculateAllCost(MotionClips[i].MotionFrames[j],
                                                                     PlayerMotionFrame,
                                                                     playerSetting);


                if (thisMotionScore < Mathf.Epsilon)// Mathf.Epsilon
                {
                    continue;
                }
                if (thisMotionScore < bestScore)
                {
                    bestScore           = thisMotionScore;
                    bestScoreClipIndex  = i;
                    bestScoreFrameIndex = j;
                    normalizedTime      = (timer % MotionClips[i].MotionClipLengthInMilliseconds) / MotionClips[i].MotionClipLengthInMilliseconds;
                    frameIndex          = Mathf.FloorToInt(MotionClips[i].MotionFrames.Length * normalizedTime);
                    motionClipData      = MotionClips[i];
                }
            }
        }
        // Debug.Log("best frame");
        // Debug.Log(bestScoreFrameIndex);
        //PlayerMotionFrame = MotionClips[bestScoreClipIndex].MotionFrames[bestScoreFrameIndex];
        // NextFrame.Value = MotionClips[bestScoreClipIndex].MotionFrames[bestScoreFrameIndex];
        test_playAnimation(frameIndex, motionClipData);
        MotionName = motionClipData.Name;
    }
    private MotionFrame GetBakedMotionFrame(PlayerInput playerInput,
                                            float timer)//, MotionClipType motionClipType)
    {
        //does motionFrame have cliptype?
        MotionFrame motionFrame = null;

        for (int i = 0; i < MotionClips.Count; i++)
        {
            MotionClipData motionClipData = MotionClips[i];
            var            normalizedTime = (timer % motionClipData.MotionClipLengthInMilliseconds) / motionClipData.MotionClipLengthInMilliseconds;
            if (isJump || isDash)
            {
                if (isJump && motionClipData.Name.Contains("jump"))
                {
                    MotionName  = motionClipData.Name;
                    motionFrame = motionClipData.MotionFrames[0];
                    NowClipType = motionClipData.ClipType;
                    break;
                }
                if (isDash && motionClipData.Name.Contains("dash"))
                {
                    MotionName  = motionClipData.Name;
                    motionFrame = motionClipData.MotionFrames[0];
                    NowClipType = motionClipData.ClipType;
                    break;
                }
            }
            else if (motionClipData.Name == MotionName)
            {
                int frame = Mathf.FloorToInt(motionClipData.MotionFrames.Length * normalizedTime);
                motionFrame = motionClipData.MotionFrames[frame];//PlayerMotionFrame;
                NowClipType = motionClipData.ClipType;
                break;
            }
        }
        return(motionFrame);

        /*
         * else if (playerInput.Crouch && motionClipData.Name.Contains("crouch"))
         * {
         *  MotionName = motionClipData.Name;
         *  motionFrame = motionClipData.MotionFrames[0];
         *  break;
         * }
         */
    }
 // Start is called before the first frame update
 void Start()
 {
     ClipToPlay = MotionManager.MotionClips.First();
     StartCoroutine(Play());
 }
    /*
     * private MotionFrame GetBakedMotionFrame(string motionName, float normalizedTime, MotionClipType clipType)
     * {
     *  for (int i = 0; i < MotionClips.Count; i++) {
     *      var clip = MotionClips[i];
     *
     *      if (clipType != null) {
     *          if (clipType == clip.ClipType) {
     *              return clip.MotionFrames[0];
     *          }
     *      } else if (clip.Name.Equals(motionName)) {
     *          int frameBasedOnTime = Mathf.FloorToInt(clip.MotionFrames.Length * normalizedTime);
     *
     *          return clip.MotionFrames[frameBasedOnTime];
     *      }
     *  }
     *
     *  return null;
     * }
     */

    public void ExtractMotionClips(AnimClip animationClip)
    {
        var motionClip = new MotionClipData();

        motionClip.Name = animationClip.name;
        //motionClip.MotionClipLengthInMilliseconds = animationClip.ClipLengthInMilliseconds; //no value for animationClip.ClipLengthInMilliseconds
        motionClip.ClipType     = animationClip.ClipType;
        motionClip.MotionFrames = new MotionFrame[animationClip.Frames.Count - 10];

        // The very first frame
        var firstMotionFrame        = new MotionFrame();
        var firstFrame              = animationClip.Frames[0];
        var stubAnimationjointPoint = new AnimationJointPoint {
            Position = Vector3.zero
        };

        firstMotionFrame.Joints = (from jp in firstFrame.JointPoints
                                   select MakeMotionJoint(jp, stubAnimationjointPoint)).ToArray();
        foreach (var jt in firstMotionFrame.Joints)
        {
            jt.BaseRotation = jt.Rotation;
        }

        var rootMotionJoint = firstMotionFrame.Joints.First(x => x.Name.Equals(RootName));

        firstMotionFrame.AngularVelocity = Vector3.Angle(Vector3.forward, rootMotionJoint.Velocity) / 180f;
        firstMotionFrame.Velocity        = rootMotionJoint.Velocity.sqrMagnitude;
        firstMotionFrame.Direction       = rootMotionJoint.Velocity.normalized;
        firstMotionFrame.Time            = firstFrame.Time;
        GetClipTrajectoryData(firstMotionFrame);

        //motionClip.MotionFrames[0] = firstMotionFrame;

        // All the other ones
        for (int i = 10; i < animationClip.Frames.Count; i++)
        {
            var frame       = animationClip.Frames[i];
            var lastFrame   = animationClip.Frames[i - 1];
            var motionFrame = new MotionFrame();

            motionFrame.Time = frame.Time;

            var joints = (from jp in frame.JointPoints
                          from jp2 in lastFrame.JointPoints
                          where jp.Name.Equals(jp2.Name)
                          select MakeMotionJoint(jp, jp2)).ToArray();

            foreach (var jt in joints)
            {
                var firstJt = firstMotionFrame.Joints.First(x => x.Name.Equals(jt.Name));
                jt.BaseRotation = firstJt.Rotation;
            }

            motionFrame.Joints = joints;

            var root = joints.First(x => x.Name.Equals(RootName));
            motionFrame.AngularVelocity = Vector3.Angle(Vector3.forward, root.Velocity) / 180f;
            motionFrame.Velocity        = root.Velocity.sqrMagnitude;
            motionFrame.Direction       = root.Velocity.normalized;
            GetClipTrajectoryData(motionFrame);

            motionClip.MotionFrames[i - 10] = motionFrame;
        }

        motionClip.MotionClipLengthInMilliseconds = animationClip.Frames.Last().Time;

        MotionClips.Add(motionClip);
    }