public BasicFCurve()
 {
     KeyFrames = null ;
     DimCount = 0 ;
     KeyCount = 0 ;
     InterpType = BasicFCurveInterpType.Constant ;
     TargetType = BasicFCurveTargetType.None ;
     ChannelType = BasicFCurveChannelType.None ;
     TargetIndex = -1 ;
 }
Beispiel #2
0
        void EvalFCurve(BasicFCurve fcurve, float frame, float[] result)
        {
            float[] data          = fcurve.KeyFrames;
            int     lower         = 0;
            int     upper         = fcurve.KeyCount - 1;
            int     elementStride = fcurveElementStrides[(int)fcurve.InterpType];
            int     stride        = elementStride * fcurve.DimCount + 1;

            while (upper - lower > 1)
            {
                int   center = (upper + lower) / 2;
                float frame2 = data[stride * center];
                if (frame < frame2)
                {
                    upper = center;
                }
                else
                {
                    lower = center;
                }
            }
            int   k1 = stride * lower;
            int   k2 = stride * upper;
            float f1 = data[k1++];
            float f2 = data[k2++];
            float t  = f2 - f1;

            if (t != 0.0f)
            {
                t = (frame - f1) / t;
            }

            BasicFCurveInterpType interp = fcurve.InterpType;

            if (t <= 0.0f)
            {
                interp = BasicFCurveInterpType.Constant;
            }
            if (t >= 1.0f)
            {
                interp = BasicFCurveInterpType.Constant;
                k1     = k2;
            }
            switch (interp)
            {
            case BasicFCurveInterpType.Constant:
                for (int i = 0; i < fcurve.DimCount; i++)
                {
                    result[i] = data[k1];
                    k1       += elementStride;
                }
                break;

            case BasicFCurveInterpType.Linear:
                for (int i = 0; i < fcurve.DimCount; i++)
                {
                    float v1 = data[k1++];
                    float v2 = data[k2++];
                    result[i] = (v2 - v1) * t + v1;
                }
                break;

            case BasicFCurveInterpType.Hermite:
                float s  = 1.0f - t;
                float b1 = s * s * t * 3.0f;
                float b2 = t * t * s * 3.0f;
                float b0 = s * s * s + b1;
                float b3 = t * t * t + b2;
                for (int i = 0; i < fcurve.DimCount; i++)
                {
                    result[i] = data[k1] * b0 + data[k1 + 2] * b1 + data[k2 + 1] * b2 + data[k2] * b3;
                    k1       += 3;
                    k2       += 3;
                }
                break;

            case BasicFCurveInterpType.Cubic:
                for (int i = 0; i < fcurve.DimCount; i++)
                {
                    float fa = f1 + data[k1 + 3];
                    float fb = f2 + data[k2 + 1];
                    float u  = FindCubicRoot(f1, fa, fb, f2, frame);
                    float v  = 1.0f - u;
                    float c1 = v * v * u * 3.0f;
                    float c2 = u * u * v * 3.0f;
                    float c0 = v * v * v + c1;
                    float c3 = u * u * u + c2;
                    result[i] = data[k1] * c0 + data[k1 + 4] * c1 + data[k2 + 2] * c2 + data[k2] * c3;
                    k1       += 5;
                    k2       += 5;
                }
                break;

            case BasicFCurveInterpType.Spherical:
                var q1 = new Quaternion(data[k1 + 0], data[k1 + 1], data[k1 + 2], data[k1 + 3]);
                var q2 = new Quaternion(data[k2 + 0], data[k2 + 1], data[k2 + 2], data[k2 + 3]);
                // [note] 旧API
                // var q3 = Quaternion.Slerp( q1, q2, t, 0.0f ) ;
                var q3 = q1.Slerp(q2, t);
                result[0] = q3.X;
                result[1] = q3.Y;
                result[2] = q3.Z;
                result[3] = q3.W;
                break;
            }
        }