private static void SmoothLocalInterpolation(BezierKeyframe previous, float previousTime, ref BezierKeyframe current, BezierKeyframe next, float nextTime)
 {
     if (next.HasValue() && previous.HasValue())
     {
         var inHandle             = (current.value - previous.value) / 3f;
         var outHandle            = (next.value - current.value) / 3f;
         var bothSegmentsDuration = nextTime - previousTime;
         var inRatio  = (current.time - previousTime) / bothSegmentsDuration;
         var outRatio = (nextTime - current.time) / bothSegmentsDuration;
         var avg      = inHandle * inRatio + outHandle * outRatio;
         if (inRatio > outRatio)
         {
             current.controlPointIn  = current.value - avg;
             current.controlPointOut = current.value + avg * outRatio;
         }
         else
         {
             current.controlPointIn  = current.value - avg * inRatio;
             current.controlPointOut = current.value + avg;
         }
     }
     else if (previous.IsNull())
     {
         current.controlPointIn  = current.value;
         current.controlPointOut = current.value + (next.value - current.value) / 3f;
     }
     else if (next.IsNull())
     {
         current.controlPointIn  = current.value - (current.value - previous.value) / 3f;
         current.controlPointOut = current.value;
     }
 }
        public static float ComputeValue(BezierKeyframe current, BezierKeyframe next, float time)
        {
            if (next.IsNull())
            {
                return(current.value);
            }
            var t = (time - current.time) / (next.time - current.time);

            switch (current.curveType)
            {
            case CurveTypeValues.Constant:
                return(current.value);

            case CurveTypeValues.Linear:
            case CurveTypeValues.FlatLinear:
            {
                return(current.value + (next.value - current.value) * t);
            }
            }

            var w0 = current.value;
            var w1 = current.controlPointOut;
            var w2 = next.controlPointIn;
            var w3 = next.value;

            // See https://pomax.github.io/bezierinfo/#how-to-implement-the-weighted-basis-function
            var mt  = 1f - t;
            var mt2 = mt * mt;
            var mt3 = mt2 * mt;
            var t2  = t * t;
            var t3  = t2 * t;

            return(w0 * mt3 + 3f * w1 * mt2 * t + 3f * w2 * mt * t2 + w3 * t3);
        }
示例#3
0
        private static void SmoothLocalInterpolation(BezierKeyframe previous, float previousTime, ref BezierKeyframe current, BezierKeyframe next, float nextTime)
        {
            if (next.HasValue() && previous.HasValue())
            {
                var inHandle             = (current.value - previous.value) / 3f;
                var outHandle            = (next.value - current.value) / 3f;
                var bothSegmentsDuration = nextTime - previousTime;
                var inRatio  = (current.time - previousTime) / bothSegmentsDuration;
                var outRatio = (nextTime - current.time) / bothSegmentsDuration;

                /* // SMOOTH
                 * // The larger the incoming curve, the weaker the effect on the other side
                 * var weightedAvg = inHandle * outRatio + outHandle * inRatio;
                 * if (inRatio > outRatio)
                 * {
                 *  current.controlPointIn = current.value - weightedAvg * (inRatio / outRatio);
                 *  current.controlPointOut = current.value + weightedAvg;
                 * }
                 * else
                 * {
                 *  current.controlPointIn = current.value - weightedAvg;
                 *  current.controlPointOut = current.value + weightedAvg * (outRatio / inRatio);
                 * }
                 */
                // NO_OVERSHOOT
                // The larger the incoming curve, the stronger the effect on the other side
                var weightedAvg = inHandle * inRatio + outHandle * outRatio;
                if (inRatio > outRatio)
                {
                    current.controlPointIn  = current.value - weightedAvg;
                    current.controlPointOut = current.value + weightedAvg * (outRatio / inRatio);
                }
                else
                {
                    current.controlPointIn  = current.value - weightedAvg * (inRatio / outRatio);
                    current.controlPointOut = current.value + weightedAvg;
                }
            }
            else if (previous.IsNull())
            {
                current.controlPointIn  = current.value;
                current.controlPointOut = current.value + (next.value - current.value) / 3f;
            }
            else if (next.IsNull())
            {
                current.controlPointIn  = current.value - (current.value - previous.value) / 3f;
                current.controlPointOut = current.value;
            }
        }