/// <summary> /// /// </summary> /// <param name="time"></param> /// <param name="quatA"></param> /// <param name="quatB"></param> /// <param name="useShortestPath"></param> /// <returns></returns> public static Quaternion Slerp(float time, Quaternion quatA, Quaternion quatB, bool useShortestPath) { float cos = quatA.Dot(quatB); float angle = MathUtil.ACos(cos); if(MathUtil.Abs(angle) < EPSILON) { return quatA; } float sin = MathUtil.Sin(angle); float inverseSin = 1.0f / sin; float coeff0 = MathUtil.Sin((1.0f - time) * angle) * inverseSin; float coeff1 = MathUtil.Sin(time * angle) * inverseSin; Quaternion result; if(cos < 0.0f && useShortestPath) { coeff0 = -coeff0; // taking the complement requires renormalisation Quaternion t = coeff0 * quatA + coeff1 * quatB; t.Normalize(); result = t; } else { result = (coeff0 * quatA + coeff1 * quatB); } return result; }
/// <summary> /// /// </summary> /// <param name="time"></param> /// <param name="quatA"></param> /// <param name="quatB"></param> /// <param name="useShortestPath"></param> /// <returns></returns> public static Quaternion Nlerp(float time, Quaternion quatA, Quaternion quatB, bool shortestPath) { Quaternion result; float cos = quatA.Dot(quatB); if (cos < 0.0f && shortestPath) { result = quatA + time * ((-1 * quatB) + (-1 * quatA)); } else { result = quatA + time * (quatB + (-1 * quatA)); } result.Normalize(); return result; }