예제 #1
0
            private AnimKeyFrame[] GetTranslationArray(int start, int count, int type)
            {
                AnimKeyFrame[] dat = new AnimKeyFrame[count];//array of keyframes

                int ptr = start;
                int c   = 0;

                while (c < count)
                {
                    dat[c] = new AnimKeyFrame();
                    if (count > 1)
                    {
                        dat[c].time        = translations[ptr++];
                        dat[c].value       = translations[ptr++];
                        dat[c].tangent_in  = translations[ptr++];
                        dat[c].tangent_out = (type == 0 ? translations[ptr - 1] : translations[ptr++]);
                    }
                    else
                    {
                        dat[c].value = translations[ptr++];
                    }
                    c++;
                }
                return(dat);
            }
예제 #2
0
            private AnimKeyFrame[] GetRotationArray(int start, int count, int type)
            {
                int size = (type == 0 ? 3 : 4);

                AnimKeyFrame[] dat = new AnimKeyFrame[count];

                int ptr = start;
                int c   = 0;

                while (c < count)
                {
                    dat[c] = new AnimKeyFrame();
                    if (count > 1)
                    {
                        dat[c].time        = rotations[ptr++];
                        dat[c].value       = rotations[ptr++] * anglescale;
                        dat[c].tangent_in  = rotations[ptr++];
                        dat[c].tangent_out = (type == 0 ? rotations[ptr - 1] : rotations[ptr++]);
                    }
                    else
                    {
                        dat[c].value = rotations[ptr++];
                    }
                    c++;
                }
                return(dat);
            }
예제 #3
0
                private static float GetDurationOfKeyFrameList(List <AnimKeyFrame> list)
                {
                    AnimKeyFrame prev = new AnimKeyFrame();

                    for (int i = 0; i < list.Count; i++)
                    {
                        if (list[i].time >= prev.time)
                        {
                            prev = list[i];
                        }
                    }
                    return(prev.time);
                }
예제 #4
0
                private static float InterpolateKeyFrameList(List <AnimKeyFrame> list, float time, InterpolationType type = InterpolationType.Linear)
                {
                    AnimKeyFrame prev  = null;
                    AnimKeyFrame after = null;

                    for (int i = 0; i < list.Count; i++)
                    {
                        if ((prev == null || list[i].time >= prev.time) && list[i].time <= time)
                        {
                            prev = list[i];
                        }
                        if ((after == null || list[i].time <= after.time) && list[i].time >= time)
                        {
                            after = list[i];
                            //We can't break here; the list isn't necessarily ordered by time.
                        }
                    }

                    if (after == null && prev == null)//this shouldn't happen
                    {
                        after = prev = new AnimKeyFrame();
                    }
                    else if (after == null)
                    {
                        after = prev;
                    }
                    else if (prev == null)
                    {
                        prev = after;
                    }

                    switch (type)
                    {
                    case InterpolationType.Linear:
                        if (prev.time != after.time)
                        {
                            float fracx = (time - prev.time) / (after.time - prev.time);
                            return(((1 - fracx) * prev.value) + (fracx * after.value));
                        }
                        else
                        {
                            return(prev.value);
                        }

                    case InterpolationType.Cubic:
                        if (prev.time != after.time)
                        {
                            float FramesBetweenKeys = prev.time - after.time;
                            float fracx             = (time - prev.time) / FramesBetweenKeys;
                            return((2 * prev.value - 2 * after.value + prev.tangent_out * FramesBetweenKeys + after.tangent_in * FramesBetweenKeys) * fracx * fracx * fracx
                                   + (3 * after.value - 3 * prev.value - after.tangent_in * FramesBetweenKeys - 2 * prev.tangent_out * FramesBetweenKeys) * fracx * fracx
                                   + (prev.tangent_out * FramesBetweenKeys) * fracx
                                   + prev.value);//hermite in one step. It's jank but it works so whatevs. This curve is created over the domain 0,1 hence why we scale the derivatives and use fracx.
                        }
                        else
                        {
                            return(prev.value);
                        }

                    default:
                        throw new Exception("Bck: Unknown interpolation type");
                    }
                }