Esempio n. 1
0
 public AnimationCurveTpl(IReadOnlyList <KeyframeTpl <T> > keyframes, CurveLoopTypes preInfinity, CurveLoopTypes postInfinity)
 {
     PreInfinity   = preInfinity;
     PostInfinity  = postInfinity;
     RotationOrder = RotationOrder.OrderZXY;
     m_curve       = new KeyframeTpl <T> [keyframes.Count];
     for (int i = 0; i < keyframes.Count; i++)
     {
         m_curve[i] = keyframes[i];
     }
 }
Esempio n. 2
0
        /// <summary>
        /// Sets post-infinity to the given CurveLoopTypes for the selected curves</summary>
        /// <param name="infType">CurveLoopTypes to be set</param>
        public void SetPostInfinity(CurveLoopTypes infType)
        {
            if (m_selectedCurves.Length == 0)
                return;

            m_transactionContext.DoTransaction(delegate
            {
                foreach (ICurve curve in m_selectedCurves)
                    curve.PostInfinity = infType;
            }, "Edit Post-Infinity".Localize());
            Invalidate();

        }
Esempio n. 3
0
        /// <summary>
        /// Evaluates point on curve</summary>
        /// <param name="x">X-coordinate for which y-coordinate is calculated</param>
        /// <returns>Y-coordinate on curve corresponding to given x-coordinate</returns>
        /// <remarks>Calculates y-coordinate from x-coordinate using appropriate interpolation for a curve</remarks>
        public float Evaluate(float x)
        {
            if (m_points.Count == 0)
            {
                return(0.0f);
            }

            if (m_points.Count == 1)
            {
                return(m_points[0].Y);
            }

            IControlPoint firstPt = m_points[0];
            IControlPoint lastPt  = m_points[m_points.Count - 1];
            float         offset  = 0.0f;

            if (x < firstPt.X) // pre-infiniy.
            {
                CurveLoopTypes loop = m_curve.PreInfinity;
                if (loop == CurveLoopTypes.Constant)
                {
                    return(firstPt.Y);
                }
                if (loop == CurveLoopTypes.Linear)
                {
                    return(firstPt.Y - ((firstPt.TangentIn.Y / firstPt.TangentIn.X) * (firstPt.X - x)));
                }
                float firstX   = firstPt.X;
                float lastX    = lastPt.X;
                float rangeX   = lastX - firstX;
                float numcycle = (int)((firstX - x) / rangeX);
                float nx       = ((firstX - x) - numcycle * rangeX);
                if (loop == CurveLoopTypes.Cycle)
                {
                    x = lastX - nx;
                }
                else if (loop == CurveLoopTypes.CycleWithOffset)
                {
                    x      = lastX - nx;
                    offset = -((numcycle + 1) * (lastPt.Y - firstPt.Y));
                }
                else if (loop == CurveLoopTypes.Oscillate)
                {
                    x = (((int)numcycle & 1) == 0) ? firstX + nx : lastX - nx;
                }
            }
            else if (x > lastPt.X) // post-infinity.
            {
                CurveLoopTypes loop = m_curve.PostInfinity;
                if (loop == CurveLoopTypes.Constant)
                {
                    return(lastPt.Y);
                }
                if (loop == CurveLoopTypes.Linear)
                {
                    return(lastPt.Y + ((lastPt.TangentOut.Y / lastPt.TangentOut.X) * (x - lastPt.X)));
                }

                float firstX   = firstPt.X;
                float lastX    = lastPt.X;
                float rangeX   = lastX - firstX;
                float numcycle = (int)((x - lastX) / rangeX);
                float nx       = (x - lastX) - numcycle * rangeX;
                if (loop == CurveLoopTypes.Cycle)
                {
                    x = firstX + nx;
                }
                else if (loop == CurveLoopTypes.CycleWithOffset)
                {
                    x      = firstX + nx;
                    offset = (numcycle + 1) * (lastPt.Y - firstPt.Y);
                }
                else if (loop == CurveLoopTypes.Oscillate)
                {
                    x = (((int)numcycle & 1) == 0)? lastX - nx : firstX + nx;
                }
            }

            bool exactMatch;
            int  index = FindIndex(x, out exactMatch);

            if (exactMatch)
            {
                return(m_points[index].Y + offset);
            }

            IControlPoint p1 = m_points[index];
            IControlPoint p2 = m_points[index + 1];

            if (p1.TangentOut.X == 0 && p1.TangentOut.Y == 0)
            {// step
                return(p1.Y + offset);
            }
            else if (p1.TangentOut.X == float.MaxValue && p1.TangentOut.Y == float.MaxValue)
            {// step-next
                return(p2.Y + offset);
            }
            else
            {// hermite eval.
                if (m_lastP1 != p1)
                {
                    // compute coeff.
                    ComputeHermiteCoeff(p1, p2, m_coeff);
                    m_lastP1 = p1;
                }
                return(CubicPolyEval(p1.X, x, m_coeff) + offset);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Evaluates point on curve</summary>
        /// <param name="x">X-coordinate for which y-coordinate is calculated</param>
        /// <returns>Y-coordinate on curve corresponding to given x-coordinate</returns>
        /// <remarks>Calculates y-coordinate from x-coordinate using appropriate interpolation for a curve</remarks>
        public float Evaluate(float x)
        {
            if (m_points.Count == 0)
            {
                return(0.0f);
            }

            if (m_points.Count == 1)
            {
                return(m_points[0].Y);
            }

            IControlPoint firstPt = m_points[0];
            IControlPoint lastPt  = m_points[m_points.Count - 1];
            float         offset  = 0.0f;

            if (x < firstPt.X) // pre-infiniy.
            {
                CurveLoopTypes loop = m_curve.PreInfinity;
                if (loop == CurveLoopTypes.Constant)
                {
                    return(firstPt.Y);
                }
                if (loop == CurveLoopTypes.Linear)
                {
                    IControlPoint secondPt = m_points[1];
                    float         slope    = (secondPt.Y - firstPt.Y) / (secondPt.X - firstPt.X);
                    return(firstPt.Y - slope * (firstPt.X - x));
                }
                float firstX   = firstPt.X;
                float lastX    = lastPt.X;
                float rangeX   = lastX - firstX;
                float numcycle = (int)((firstX - x) / rangeX);
                float nx       = ((firstX - x) - numcycle * rangeX);
                if (loop == CurveLoopTypes.Cycle)
                {
                    x = lastX - nx;
                }
                else if (loop == CurveLoopTypes.CycleWithOffset)
                {
                    x      = lastX - nx;
                    offset = -((numcycle + 1) * (lastPt.Y - firstPt.Y));
                }
                else if (loop == CurveLoopTypes.Oscillate)
                {
                    x = (((int)numcycle & 1) == 0) ? firstX + nx : lastX - nx;
                }
            }
            else if (x > lastPt.X) // post-infinity.
            {
                CurveLoopTypes loop = m_curve.PostInfinity;
                if (loop == CurveLoopTypes.Constant)
                {
                    return(lastPt.Y);
                }
                if (loop == CurveLoopTypes.Linear)
                {
                    IControlPoint beforeLastPt = m_points[m_points.Count - 2];
                    float         slope        = (lastPt.Y - beforeLastPt.Y) / (lastPt.X - beforeLastPt.X);
                    return(lastPt.Y + slope * (x - lastPt.X));
                }

                float firstX   = firstPt.X;
                float lastX    = lastPt.X;
                float rangeX   = lastX - firstX;
                float numcycle = (int)((x - lastX) / rangeX);
                float nx       = (x - lastX) - numcycle * rangeX;
                if (loop == CurveLoopTypes.Cycle)
                {
                    x = firstX + nx;
                }
                else if (loop == CurveLoopTypes.CycleWithOffset)
                {
                    x      = firstX + nx;
                    offset = (numcycle + 1) * (lastPt.Y - firstPt.Y);
                }
                else if (loop == CurveLoopTypes.Oscillate)
                {
                    x = (((int)numcycle & 1) == 0)? lastX - nx : firstX + nx;
                }
            }

            bool exactMatch;
            int  index = FindIndex(x, out exactMatch);

            if (exactMatch)
            {
                return(m_points[index].Y + offset);
            }

            IControlPoint p1 = m_points[index];
            IControlPoint p2 = m_points[index + 1];

            if (m_lastP1 != p1)
            {
                // compute slope and y intercept
                m        = (p2.Y - p1.Y) / (p2.X - p1.X);
                b        = p1.Y - m * p1.X;
                m_lastP1 = p1;
            }
            // y = mx + b
            // offset is computed from post and pre infinities.
            return(m * x + b + offset);
        }
Esempio n. 5
0
        /// <summary>
        /// Sets post-infinity to the given CurveLoopTypes for the selected curves</summary>
        /// <param name="infType">CurveLoopTypes to be set</param>
        public void SetPostInfinity(CurveLoopTypes infType)
        {
            if (m_editSet.Count == 0 && m_selectedCurves.Length == 0)
                return;
            IEnumerable<ICurve> curves = m_editSet.Count > 0 ? (IEnumerable<ICurve>)m_editSet : m_selectedCurves;
            m_transactionContext.DoTransaction(delegate
            {
                foreach (ICurve curve in curves)
                    curve.PostInfinity = infType;
            }, "Edit Post-Infinity".Localize());
            Invalidate();

        }