コード例 #1
0
        private static double InterpolateCamera(
            int keyFrameIndex,
            double time,
            IList <SetCameraData.CameraKeys> keyFrames,
            SetCameraData.CameraKeys prevKey)
        {
            const double N            = 1.0 / 512.0;
            var          curKeyFrame  = keyFrames[keyFrameIndex];
            var          nextKeyFrame = keyFrames[keyFrameIndex + 1];

            if (prevKey != null)
            {
                prevKey.TangentEaseOut = curKeyFrame.TangentEaseOut;
            }

            var t  = time - curKeyFrame.KeyFrame * N;
            var tx = (nextKeyFrame.KeyFrame - curKeyFrame.KeyFrame) * N;

            switch (curKeyFrame.Interpolation)
            {
            case Kh2.Motion.Interpolation.Nearest:
                return(curKeyFrame.Value);

            case Kh2.Motion.Interpolation.Linear:
                return(curKeyFrame.Value + ((nextKeyFrame.Value - curKeyFrame.Value) * t / tx));

            case Kh2.Motion.Interpolation.Hermite:
            case (Kh2.Motion.Interpolation) 3:
            case (Kh2.Motion.Interpolation) 4:
                var itx = 1.0 / tx;
                // Perform a cubic hermite interpolation
                var p0 = curKeyFrame.Value;
                var p1 = nextKeyFrame.Value;
                var m0 = curKeyFrame.TangentEaseOut;
                var m1 = nextKeyFrame.TangentEaseIn;
                var t2 = t * t * itx;
                var t3 = t * t * t * itx * itx;
                return(p0 * (2 * t3 * itx - 3 * t2 * itx + 1) +
                       m0 * (t3 - 2 * t2 + t) +
                       p1 * (-2 * t3 * itx + 3 * t2 * itx) +
                       m1 * (t3 - t2));

            default:
                return(0);
            }
        }
コード例 #2
0
        private static double GetCameraValue(
            double time,
            IList <SetCameraData.CameraKeys> keyFrames,
            SetCameraData.CameraKeys prevKey)
        {
            if (keyFrames.Count == 0)
            {
                return(0.0);
            }

            if (keyFrames.Count == 1)
            {
                return(keyFrames[0].Value);
            }

            const int First = 0;
            var       Last  = keyFrames.Count - 1;

            var m = time + 1.0 / 60.0;
            var currentFrameIndex = (int)(m * 512.0);

            if (currentFrameIndex > keyFrames[First].KeyFrame - 0x10000000)
            {
                if (currentFrameIndex < keyFrames[Last].KeyFrame)
                {
                    // Do a binary search through all the key frames
                    var left  = First;
                    var right = Last;
                    if (right <= 1)
                    {
                        return(InterpolateCamera(right - 1, m, keyFrames, prevKey));
                    }

                    while (true)
                    {
                        var mid = (left + right) / 2;
                        if (currentFrameIndex >= keyFrames[mid].KeyFrame)
                        {
                            if (currentFrameIndex <= keyFrames[mid].KeyFrame)
                            {
                                return(keyFrames[mid].Value);
                            }
                            left = mid;
                        }
                        else
                        {
                            right = mid;
                        }

                        if (right - left <= 1)
                        {
                            return(InterpolateCamera(right - 1, m, keyFrames, prevKey));
                        }
                    }
                }

                double tangent;
                var    keyFrameDistance = keyFrames[Last].KeyFrame - keyFrames[Last - 1].KeyFrame;
                if (keyFrames[Last].Interpolation != Kh2.Motion.Interpolation.Linear || keyFrameDistance == 0)
                {
                    tangent = keyFrames[Last].TangentEaseOut;
                }
                else
                {
                    tangent = (keyFrames[Last].Value - keyFrames[Last - 1].Value) / keyFrameDistance;
                }
                return(((currentFrameIndex - (keyFrames[Last].KeyFrame + 0x10000000) + 0x10000000) * tangent) + keyFrames[Last].Value);
            }
            else
            {
                double tangent;
                var    keyFrameDistance = keyFrames[First + 1].KeyFrame - keyFrames[First].KeyFrame;
                if (keyFrames[First].Interpolation != Kh2.Motion.Interpolation.Linear || keyFrameDistance == 0)
                {
                    tangent = keyFrames[First].TangentEaseIn;
                }
                else
                {
                    tangent = (keyFrames[First + 1].Value - keyFrames[First].Value) / keyFrameDistance;
                }
                return(-(((keyFrames[First].KeyFrame - currentFrameIndex - 0x10000000) * tangent) - keyFrames[First].Value));
            }
        }