示例#1
0
        private float GetCurvePosition(float position)
        {
            CurveKey curveKey1 = this.keys[0];

            for (int index = 1; index < this.keys.Count; ++index)
            {
                CurveKey curveKey2 = this.Keys[index];
                if ((double)curveKey2.Position >= (double)position)
                {
                    if (curveKey1.Continuity == CurveContinuity.Step)
                    {
                        if ((double)position >= 1.0)
                        {
                            return(curveKey2.Value);
                        }
                        else
                        {
                            return(curveKey1.Value);
                        }
                    }
                    else
                    {
                        float num1 = (float)(((double)position - (double)curveKey1.Position) / ((double)curveKey2.Position - (double)curveKey1.Position));
                        float num2 = num1 * num1;
                        float num3 = num2 * num1;
                        return((float)((2.0 * (double)num3 - 3.0 * (double)num2 + 1.0) * (double)curveKey1.Value + ((double)num3 - 2.0 * (double)num2 + (double)num1) * (double)curveKey1.TangentOut + (3.0 * (double)num2 - 2.0 * (double)num3) * (double)curveKey2.Value + ((double)num3 - (double)num2) * (double)curveKey2.TangentIn));
                    }
                }
                else
                {
                    curveKey1 = curveKey2;
                }
            }
            return(0.0f);
        }
示例#2
0
        private float GetCurvePosition(float position)
        {
            //only for position in curve
            CurveKey prev = this.keys[0];
            CurveKey next;

            for (int i = 1; i < this.keys.Count; i++)
            {
                next = this.Keys[i];
                if (next.Position >= position)
                {
                    if (prev.Continuity == CurveContinuity.Step)
                    {
                        if (position >= 1f)
                        {
                            return(next.Value);
                        }
                        return(prev.Value);
                    }
                    float t   = (position - prev.Position) / (next.Position - prev.Position);//to have t in [0,1]
                    float ts  = t * t;
                    float tss = ts * t;
                    //After a lot of search on internet I have found all about spline function
                    // and bezier (phi'sss ancien) but finaly use hermite curve
                    //http://en.wikipedia.org/wiki/Cubic_Hermite_spline
                    //P(t) = (2*t^3 - 3t^2 + 1)*P0 + (t^3 - 2t^2 + t)m0 + (-2t^3 + 3t^2)P1 + (t^3-t^2)m1
                    //with P0.value = prev.value , m0 = prev.tangentOut, P1= next.value, m1 = next.TangentIn
                    return((2 * tss - 3 * ts + 1f) * prev.Value + (tss - 2 * ts + t) * prev.TangentOut + (3 * ts - 2 * tss) * next.Value + (tss - ts) * next.TangentIn);
                }
                prev = next;
            }
            return(0f);
        }
示例#3
0
        public float Evaluate(float position)
        {
            CurveKey curveKey1 = this.keys[0];
            CurveKey curveKey2 = this.keys[this.keys.Count - 1];

            if ((double)position < (double)curveKey1.Position)
            {
                switch (this.PreLoop)
                {
                case CurveLoopType.Constant:
                    return(curveKey1.Value);

                case CurveLoopType.Cycle:
                    int numberOfCycle1 = this.GetNumberOfCycle(position);
                    return(this.GetCurvePosition(position - (float)numberOfCycle1 * (curveKey2.Position - curveKey1.Position)));

                case CurveLoopType.CycleOffset:
                    int numberOfCycle2 = this.GetNumberOfCycle(position);
                    return(this.GetCurvePosition(position - (float)numberOfCycle2 * (curveKey2.Position - curveKey1.Position)) + (float)numberOfCycle2 * (curveKey2.Value - curveKey1.Value));

                case CurveLoopType.Oscillate:
                    int numberOfCycle3 = this.GetNumberOfCycle(position);
                    return(this.GetCurvePosition(0.0 != (double)numberOfCycle3 % 2.0 ? (float)((double)curveKey2.Position - (double)position + (double)curveKey1.Position + (double)numberOfCycle3 * ((double)curveKey2.Position - (double)curveKey1.Position)) : position - (float)numberOfCycle3 * (curveKey2.Position - curveKey1.Position)));

                case CurveLoopType.Linear:
                    return(curveKey1.Value - curveKey1.TangentIn * (curveKey1.Position - position));
                }
            }
            else if ((double)position > (double)curveKey2.Position)
            {
                switch (this.PostLoop)
                {
                case CurveLoopType.Constant:
                    return(curveKey2.Value);

                case CurveLoopType.Cycle:
                    int numberOfCycle4 = this.GetNumberOfCycle(position);
                    return(this.GetCurvePosition(position - (float)numberOfCycle4 * (curveKey2.Position - curveKey1.Position)));

                case CurveLoopType.CycleOffset:
                    int numberOfCycle5 = this.GetNumberOfCycle(position);
                    return(this.GetCurvePosition(position - (float)numberOfCycle5 * (curveKey2.Position - curveKey1.Position)) + (float)numberOfCycle5 * (curveKey2.Value - curveKey1.Value));

                case CurveLoopType.Oscillate:
                    int   numberOfCycle6 = this.GetNumberOfCycle(position);
                    float num            = position - (float)numberOfCycle6 * (curveKey2.Position - curveKey1.Position);
                    return(this.GetCurvePosition(0.0 != (double)numberOfCycle6 % 2.0 ? (float)((double)curveKey2.Position - (double)position + (double)curveKey1.Position + (double)numberOfCycle6 * ((double)curveKey2.Position - (double)curveKey1.Position)) : position - (float)numberOfCycle6 * (curveKey2.Position - curveKey1.Position)));

                case CurveLoopType.Linear:
                    return(curveKey2.Value + curveKey1.TangentOut * (position - curveKey2.Position));
                }
            }
            return(this.GetCurvePosition(position));
        }
示例#4
0
        private float GetCurvePosition(float position)
        {
            // Only for position in curve.
            CurveKey prev = Keys[0];
            CurveKey next;

            for (int i = 1; i < Keys.Count; i += 1)
            {
                next = Keys[i];
                if (next.Position >= position)
                {
                    if (prev.Continuity == CurveContinuity.Step)
                    {
                        if (position >= 1f)
                        {
                            return(next.Value);
                        }
                        return(prev.Value);
                    }
                    // To have t in [0,1]
                    float t = (
                        (position - prev.Position) /
                        (next.Position - prev.Position)
                        );
                    float ts  = t * t;
                    float tss = ts * t;

                    /* After a lot of search on internet I have found all about
                     * spline function and bezier (phi'sss ancien) but finally
                     * used hermite curve:
                     * http://en.wikipedia.org/wiki/Cubic_Hermite_spline
                     * P(t) = (2*t^3 - 3t^2 + 1)*P0 + (t^3 - 2t^2 + t)m0 +
                     *        (-2t^3 + 3t^2)P1 + (t^3-t^2)m1
                     * with P0.value = prev.value , m0 = prev.tangentOut,
                     *      P1= next.value, m1 = next.TangentIn.
                     */
                    return(
                        (2 * tss - 3 * ts + 1f) * prev.Value +
                        (tss - 2 * ts + t) * prev.TangentOut +
                        (3 * ts - 2 * tss) * next.Value +
                        (tss - ts) * next.TangentIn
                        );
                }
                prev = next;
            }
            return(0f);
        }
示例#5
0
        private FP GetCurvePosition(FP position)
        {
            CurveKey curveKey = this.keys[0];
            FP       result;

            for (int i = 1; i < this.keys.Count; i++)
            {
                CurveKey curveKey2 = this.Keys[i];
                bool     flag      = curveKey2.Position >= position;
                if (flag)
                {
                    bool flag2 = curveKey.Continuity == CurveContinuity.Step;
                    if (flag2)
                    {
                        bool flag3 = position >= 1f;
                        if (flag3)
                        {
                            result = curveKey2.Value;
                        }
                        else
                        {
                            result = curveKey.Value;
                        }
                    }
                    else
                    {
                        FP fP  = (position - curveKey.Position) / (curveKey2.Position - curveKey.Position);
                        FP fP2 = fP * fP;
                        FP fP3 = fP2 * fP;
                        result = (2 * fP3 - 3 * fP2 + 1f) * curveKey.Value + (fP3 - 2 * fP2 + fP) * curveKey.TangentOut + (3 * fP2 - 2 * fP3) * curveKey2.Value + (fP3 - fP2) * curveKey2.TangentIn;
                    }
                    return(result);
                }
                curveKey = curveKey2;
            }
            result = 0f;
            return(result);
        }
示例#6
0
        public float Evaluate(float position)
        {
            CurveKey first = keys[0];
            CurveKey last  = keys[keys.Count - 1];

            if (position < first.Position)
            {
                switch (this.PreLoop)
                {
                case CurveLoopType.Constant:
                    //constant
                    return(first.Value);

                case CurveLoopType.Linear:
                    // linear y = a*x +b with a tangeant of last point
                    return(first.Value - first.TangentIn * (first.Position - position));

                case CurveLoopType.Cycle:
                    //start -> end / start -> end
                    int   cycle      = GetNumberOfCycle(position);
                    float virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos));

                case CurveLoopType.CycleOffset:
                    //make the curve continue (with no step) so must up the curve each cycle of delta(value)
                    cycle      = GetNumberOfCycle(position);
                    virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value));

                case CurveLoopType.Oscillate:
                    //go back on curve from end and target start
                    // start-> end / end -> start
                    cycle = GetNumberOfCycle(position);
                    if (0 == cycle % 2f)    //if pair
                    {
                        virtualPos = position - (cycle * (last.Position - first.Position));
                    }
                    else
                    {
                        virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position));
                    }
                    return(GetCurvePosition(virtualPos));
                }
            }
            else if (position > last.Position)
            {
                int cycle;
                switch (this.PostLoop)
                {
                case CurveLoopType.Constant:
                    //constant
                    return(last.Value);

                case CurveLoopType.Linear:
                    // linear y = a*x +b with a tangeant of last point
                    return(last.Value + first.TangentOut * (position - last.Position));

                case CurveLoopType.Cycle:
                    //start -> end / start -> end
                    cycle = GetNumberOfCycle(position);
                    float virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos));

                case CurveLoopType.CycleOffset:
                    //make the curve continue (with no step) so must up the curve each cycle of delta(value)
                    cycle      = GetNumberOfCycle(position);
                    virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value));

                case CurveLoopType.Oscillate:
                    //go back on curve from end and target start
                    // start-> end / end -> start
                    cycle      = GetNumberOfCycle(position);
                    virtualPos = position - (cycle * (last.Position - first.Position));
                    if (0 == cycle % 2f)    //if pair
                    {
                        virtualPos = position - (cycle * (last.Position - first.Position));
                    }
                    else
                    {
                        virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position));
                    }
                    return(GetCurvePosition(virtualPos));
                }
            }

            //in curve
            return(GetCurvePosition(position));
        }
示例#7
0
        /// <summary>
        /// Computes tangent for the specific key in the collection.
        /// </summary>
        /// <param name="keyIndex">The index of key in the collection.</param>
        /// <param name="tangentInType">The tangent in-type. <see cref="CurveKey.TangentIn"/> for more details.</param>
        /// <param name="tangentOutType">The tangent out-type. <see cref="CurveKey.TangentOut"/> for more details.</param>
        public void ComputeTangent(
            int keyIndex,
            CurveTangent tangentInType,
            CurveTangent tangentOutType
            )
        {
            // See http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.curvetangent.aspx

            CurveKey key = Keys[keyIndex];

            float p0, p, p1;

            p0 = p = p1 = key.Position;

            float v0, v, v1;

            v0 = v = v1 = key.Value;

            if (keyIndex > 0)
            {
                p0 = Keys[keyIndex - 1].Position;
                v0 = Keys[keyIndex - 1].Value;
            }

            if (keyIndex < Keys.Count - 1)
            {
                p1 = Keys[keyIndex + 1].Position;
                v1 = Keys[keyIndex + 1].Value;
            }

            switch (tangentInType)
            {
            case CurveTangent.Flat:
                key.TangentIn = 0;
                break;

            case CurveTangent.Linear:
                key.TangentIn = v - v0;
                break;

            case CurveTangent.Smooth:
                float pn = p1 - p0;
                if (MathHelper.WithinEpsilon(pn, 0.0f))
                {
                    key.TangentIn = 0;
                }
                else
                {
                    key.TangentIn = (v1 - v0) * ((p - p0) / pn);
                }
                break;
            }

            switch (tangentOutType)
            {
            case CurveTangent.Flat:
                key.TangentOut = 0;
                break;

            case CurveTangent.Linear:
                key.TangentOut = v1 - v;
                break;

            case CurveTangent.Smooth:
                float pn = p1 - p0;
                if (Math.Abs(pn) < float.Epsilon)
                {
                    key.TangentOut = 0;
                }
                else
                {
                    key.TangentOut = (v1 - v0) * ((p1 - p) / pn);
                }
                break;
            }
        }
示例#8
0
        /// <summary>
        /// Evaluate the value at a position of this <see cref="Curve"/>.
        /// </summary>
        /// <param name="position">The position on this <see cref="Curve"/>.</param>
        /// <returns>Value at the position on this <see cref="Curve"/>.</returns>
        public float Evaluate(float position)
        {
            if (Keys.Count == 0)
            {
                return(0.0f);
            }
            if (Keys.Count == 1)
            {
                return(Keys[0].Value);
            }

            CurveKey first = Keys[0];
            CurveKey last  = Keys[Keys.Count - 1];

            if (position < first.Position)
            {
                switch (this.PreLoop)
                {
                case CurveLoopType.Constant:
                    return(first.Value);

                case CurveLoopType.Linear:
                    // Linear y = a*x +b with a tangent of last point.
                    return(first.Value - first.TangentIn * (first.Position - position));

                case CurveLoopType.Cycle:
                    // Start -> end / start -> end...
                    int   cycle      = GetNumberOfCycle(position);
                    float virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos));

                case CurveLoopType.CycleOffset:
                    /* Make the curve continue (with no step) so must up
                     * the curve each cycle of delta(value).
                     */
                    cycle      = GetNumberOfCycle(position);
                    virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value));

                case CurveLoopType.Oscillate:
                    /* Go back on curve from end and target start
                     * Start-> end / end -> start...
                     */
                    cycle = GetNumberOfCycle(position);

                    if (0 == cycle % 2f)
                    {
                        virtualPos = position - (cycle * (last.Position - first.Position));
                    }
                    else
                    {
                        virtualPos = last.Position - position + first.Position + (cycle * (last.Position - first.Position));
                    }
                    return(GetCurvePosition(virtualPos));
                }
            }
            else if (position > last.Position)
            {
                int cycle;
                switch (this.PostLoop)
                {
                case CurveLoopType.Constant:
                    return(last.Value);

                case CurveLoopType.Linear:
                    // Linear y = a*x +b with a tangent of last point.
                    return(last.Value + first.TangentOut * (position - last.Position));

                case CurveLoopType.Cycle:
                    // Start -> end / start -> end...
                    cycle = GetNumberOfCycle(position);
                    float virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos));

                case CurveLoopType.CycleOffset:
                    /* Make the curve continue (with no step) so must up
                     * the curve each cycle of delta(value).
                     */
                    cycle      = GetNumberOfCycle(position);
                    virtualPos = position - (cycle * (last.Position - first.Position));
                    return(GetCurvePosition(virtualPos) + cycle * (last.Value - first.Value));

                case CurveLoopType.Oscillate:
                    /* Go back on curve from end and target start.
                     * Start-> end / end -> start...
                     */
                    cycle      = GetNumberOfCycle(position);
                    virtualPos = position - (cycle * (last.Position - first.Position));

                    if (0 == cycle % 2f)
                    {
                        virtualPos = position - (cycle * (last.Position - first.Position));
                    }
                    else
                    {
                        virtualPos =
                            last.Position - position + first.Position +
                            (cycle * (last.Position - first.Position)
                            );
                    }
                    return(GetCurvePosition(virtualPos));
                }
            }

            // In curve.
            return(GetCurvePosition(position));
        }
示例#9
0
        public void ComputeTangent(int keyIndex, CurveTangent tangentInType, CurveTangent tangentOutType)
        {
            CurveKey curveKey = this.keys[keyIndex];
            double   num1;
            float    num2 = (float)(num1 = (double)curveKey.Position);
            float    num3 = (float)num1;
            float    num4 = (float)num1;
            double   num5;
            float    num6 = (float)(num5 = (double)curveKey.Value);
            float    num7 = (float)num5;
            float    num8 = (float)num5;

            if (keyIndex > 0)
            {
                num4 = this.keys[keyIndex - 1].Position;
                num8 = this.keys[keyIndex - 1].Value;
            }
            if (keyIndex < this.keys.Count - 1)
            {
                num2 = this.keys[keyIndex + 1].Position;
                num6 = this.keys[keyIndex + 1].Value;
            }
            switch (tangentInType)
            {
            case CurveTangent.Flat:
                curveKey.TangentIn = 0.0f;
                break;

            case CurveTangent.Linear:
                curveKey.TangentIn = num7 - num8;
                break;

            case CurveTangent.Smooth:
                float num9 = num2 - num4;
                curveKey.TangentIn = (double)Math.Abs(num9) >= 1.40129846432482E-45 ? (float)(((double)num6 - (double)num8) * (((double)num3 - (double)num4) / (double)num9)) : 0.0f;
                break;
            }
            switch (tangentOutType)
            {
            case CurveTangent.Flat:
                curveKey.TangentOut = 0.0f;
                break;

            case CurveTangent.Linear:
                curveKey.TangentOut = num6 - num7;
                break;

            case CurveTangent.Smooth:
                float num10 = num2 - num4;
                if ((double)Math.Abs(num10) < 1.40129846432482E-45)
                {
                    curveKey.TangentOut = 0.0f;
                    break;
                }
                else
                {
                    curveKey.TangentOut = (float)(((double)num6 - (double)num8) * (((double)num2 - (double)num3) / (double)num10));
                    break;
                }
            }
        }
示例#10
0
        public FP Evaluate(FP position)
        {
            CurveKey curveKey  = this.keys[0];
            CurveKey curveKey2 = this.keys[this.keys.Count - 1];
            bool     flag      = position < curveKey.Position;
            FP       result;

            if (flag)
            {
                switch (this.PreLoop)
                {
                case CurveLoopType.Constant:
                    result = curveKey.Value;
                    return(result);

                case CurveLoopType.Cycle:
                {
                    int numberOfCycle = this.GetNumberOfCycle(position);
                    FP  position2     = position - numberOfCycle * (curveKey2.Position - curveKey.Position);
                    result = this.GetCurvePosition(position2);
                    return(result);
                }

                case CurveLoopType.CycleOffset:
                {
                    int numberOfCycle = this.GetNumberOfCycle(position);
                    FP  position2     = position - numberOfCycle * (curveKey2.Position - curveKey.Position);
                    result = this.GetCurvePosition(position2) + numberOfCycle * (curveKey2.Value - curveKey.Value);
                    return(result);
                }

                case CurveLoopType.Oscillate:
                {
                    int  numberOfCycle = this.GetNumberOfCycle(position);
                    bool flag2         = 0f == (float)numberOfCycle % 2f;
                    FP   position2;
                    if (flag2)
                    {
                        position2 = position - numberOfCycle * (curveKey2.Position - curveKey.Position);
                    }
                    else
                    {
                        position2 = curveKey2.Position - position + curveKey.Position + numberOfCycle * (curveKey2.Position - curveKey.Position);
                    }
                    result = this.GetCurvePosition(position2);
                    return(result);
                }

                case CurveLoopType.Linear:
                    result = curveKey.Value - curveKey.TangentIn * (curveKey.Position - position);
                    return(result);
                }
            }
            else
            {
                bool flag3 = position > curveKey2.Position;
                if (flag3)
                {
                    switch (this.PostLoop)
                    {
                    case CurveLoopType.Constant:
                        result = curveKey2.Value;
                        return(result);

                    case CurveLoopType.Cycle:
                    {
                        int numberOfCycle2 = this.GetNumberOfCycle(position);
                        FP  position3      = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position);
                        result = this.GetCurvePosition(position3);
                        return(result);
                    }

                    case CurveLoopType.CycleOffset:
                    {
                        int numberOfCycle2 = this.GetNumberOfCycle(position);
                        FP  position3      = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position);
                        result = this.GetCurvePosition(position3) + numberOfCycle2 * (curveKey2.Value - curveKey.Value);
                        return(result);
                    }

                    case CurveLoopType.Oscillate:
                    {
                        int  numberOfCycle2 = this.GetNumberOfCycle(position);
                        FP   position3      = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position);
                        bool flag4          = 0f == (float)numberOfCycle2 % 2f;
                        if (flag4)
                        {
                            position3 = position - numberOfCycle2 * (curveKey2.Position - curveKey.Position);
                        }
                        else
                        {
                            position3 = curveKey2.Position - position + curveKey.Position + numberOfCycle2 * (curveKey2.Position - curveKey.Position);
                        }
                        result = this.GetCurvePosition(position3);
                        return(result);
                    }

                    case CurveLoopType.Linear:
                        result = curveKey2.Value + curveKey.TangentOut * (position - curveKey2.Position);
                        return(result);
                    }
                }
            }
            result = this.GetCurvePosition(position);
            return(result);
        }