static void FindIndicesForSampling(float time, ref KeyframeCurveAccessor curve, out int lhs, out int rhs) { var actualSize = curve.Length; // Fall back to using binary search // upper bound (first value larger than curveT) var length = actualSize; int half; int middle; int first = 0; while (length > 0) { half = length >> 1; middle = first + half; if (time < curve.GetKeyframe(middle).Time) { length = half; } else { first = middle; ++first; length = length - half - 1; } } // If not within range, we pick the last element twice lhs = first - 1; rhs = math.min(actualSize - 1, first); }
public static float Evaluate(float time, KeyframeCurveAccessor curve) { if (curve.Length == 1) { return(curve.GetKeyframe(0).Value); } // Wrap time time = math.clamp(time, curve.GetKeyframe(0).Time, curve.GetKeyframe(curve.Length - 1).Time); FindIndicesForSampling(time, ref curve, out int lhs, out int rhs); var leftKey = curve.GetKeyframe(lhs); var rightKey = curve.GetKeyframe(rhs); if (math.isinf(leftKey.OutTangent) || math.isinf(rightKey.InTangent)) { return(leftKey.Value); } var output = HermiteInterpolate(time, leftKey, rightKey); return(output); }