예제 #1
0
        public bool Setup()
        {
            Curve rotXCurve = objectAnimation.GetCurve(AnimatableProperty.RotationX);

            rotXCurve.GetKeyIndex(firstFrame, out int firstIndex);
            rotXCurve.GetKeyIndex(lastFrame, out int lastIndex);

            if (currentFrame < firstFrame)
            {
                return(false);
            }
            if (currentFrame > lastFrame)
            {
                return(false);
            }

            requiredKeyframe = new List <int>()
            {
                firstFrame, lastFrame
            };
            keyCount = requiredKeyframe.Count;
            int curveCount = curves.Count;

            //number of curve * (in tangent x , in tangent y, out tangent x, out tangent y) * (k- , k+)
            paramCount = curveCount * 4 * 2;

            ds_thetaJob(paramCount, keyCount);

            theta         = new double[paramCount];
            Stiffnes_D    = new double[paramCount, paramCount];
            Continuity_T  = new double[paramCount, paramCount];
            curvesMinMax  = new Vector2[curveCount, 2];
            lowerBound    = new double[paramCount];
            upperBound    = new double[paramCount];
            scale         = new double[paramCount];
            delta_theta_0 = new double[paramCount];

            //Hierarchy rotation curves
            for (int animIndex = 0; animIndex < animationCount; animIndex++)
            {
                for (int curve = 0; curve < 3; curve++)
                {
                    int          curveIndex   = animIndex * 3 + curve;
                    AnimationKey previous1Key = curves[curveIndex].keys[firstIndex];
                    AnimationKey previous2Key = firstIndex > 0 ? curves[curveIndex].keys[firstIndex - 1] : new AnimationKey(previous1Key.frame, previous1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero);
                    AnimationKey next1Key     = curves[curveIndex].keys[lastIndex];
                    AnimationKey next2key     = lastIndex < curves[curveIndex].keys.Count - 1 ? curves[curveIndex].keys[lastIndex + 1] : new AnimationKey(next1Key.frame, next1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero);
                    GetTangents(curveIndex * 8, previous1Key, next1Key);
                    curvesMinMax[curveIndex, 0] = GetMinMax(previous2Key, previous1Key);
                    curvesMinMax[curveIndex, 1] = GetMinMax(next1Key, next2key);

                    float Min = controllers[animIndex].LowerAngleBound[curve];
                    float Max = controllers[animIndex].UpperAngleBound[curve];
                    FillLowerBounds(curveIndex, previous1Key, next1Key, Min, Max);
                    FillUpperBounds(curveIndex, previous1Key, next1Key, previous2Key, next2key, Min, Max);
                    GetContinuity(curveIndex * 8, Min, Max);
                    //k- in x, k- in y, k- out x, k- out y, k+ in x, k+ in y, k+ out x, k+ out y
                    for (int tan = 0; tan < 8; tan++)
                    {
                        int tanIndice = curveIndex * 8 + tan;
                        Stiffnes_D[tanIndice, tanIndice] = animIndex == animationCount - 1 ? 0 : controllers[animIndex].stiffness;
                        scale[tanIndice]         = 1d;
                        delta_theta_0[tanIndice] = 0;
                    }
                }
            }

            //Root position curves
            int aIndex = animationCount;

            for (int curve = 0; curve < 3; curve++)
            {
                int          curveIndex   = aIndex * 3 + curve;
                AnimationKey previous1Key = curves[curveIndex].keys[firstIndex];
                AnimationKey previous2Key = firstIndex > 0 ? curves[curveIndex].keys[firstIndex - 1] : new AnimationKey(previous1Key.frame, previous1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero);
                AnimationKey next1Key     = curves[curveIndex].keys[lastIndex];
                AnimationKey next2Key     = lastIndex < curves[curveIndex].keys.Count - 1 ? curves[curveIndex].keys[lastIndex + 1] : new AnimationKey(next1Key.frame, next1Key.value, inTangent: Vector2.zero, outTangent: Vector2.zero);
                GetTangents(curveIndex * 8, previous1Key, next1Key);
                curvesMinMax[curveIndex, 0] = GetMinMax(previous2Key, previous1Key);
                curvesMinMax[curveIndex, 1] = GetMinMax(next1Key, next2Key);
                GetContinuity(curveIndex * 8);
                for (int tan = 0; tan < 8; tan++)
                {
                    int tanIndice = curveIndex * 8 + tan;
                    Stiffnes_D[tanIndice, tanIndice] = controllers[0].stiffness;
                    lowerBound[tanIndice]            = -10;
                    upperBound[tanIndice]            = 10;
                    scale[tanIndice]         = 1d;
                    delta_theta_0[tanIndice] = 0;
                }
            }
            currentState = GetCurrentState(currentFrame);
            targetState  = new State()
            {
                position = targetPosition,
                rotation = targetRotation,
                time     = currentFrame
            };

            Delta_s_prime = new double[7, 1];
            for (int i = 0; i < 3; i++)
            {
                Delta_s_prime[i, 0] = targetState.position[i] - currentState.position[i];
            }
            if ((currentState.rotation * Quaternion.Inverse(targetState.rotation)).w < 0)
            {
                targetState.rotation = new Quaternion(-targetState.rotation.x, -targetState.rotation.y, -targetState.rotation.z, -targetState.rotation.w);
            }
            for (int i = 0; i < 4; i++)
            {
                Delta_s_prime[i + 3, 0] = targetState.rotation[i] - currentState.rotation[i];
            }

            Theta = Maths.ColumnArrayToArray(theta);
            return(true);
        }