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); }
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); }
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); }
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"); } }