public static Vector3 SlerpWithReferenceUp(Vector3 vA, Vector3 vB, float t, Vector3 up) { float magnitude = vA.magnitude; float magnitude2 = vB.magnitude; if (magnitude < 0.0001f || magnitude2 < 0.0001f) { return(Vector3.Lerp(vA, vB, t)); } Vector3 forward = vA / magnitude; Vector3 forward2 = vB / magnitude2; Quaternion qA = Quaternion.LookRotation(forward, up); Quaternion qB = Quaternion.LookRotation(forward2, up); return(UnityQuaternionExtensions.SlerpWithReferenceUp(qA, qB, t, up) * Vector3.forward * Mathf.Lerp(magnitude, magnitude2, t)); }
/// <summary>This is a slerp that mimics a camera operator's movement in that /// it chooses a path that avoids the lower hemisphere, as defined by /// the up param</summary> /// <param name="vA">First direction</param> /// <param name="vB">Second direction</param> /// <param name="t">Interpolation amoun t</param> /// <param name="up">Defines the up direction</param> public static Vector3 SlerpWithReferenceUp( Vector3 vA, Vector3 vB, float t, Vector3 up) { float dA = vA.magnitude; float dB = vB.magnitude; if (dA < Epsilon || dB < Epsilon) { return(Vector3.Lerp(vA, vB, t)); } Vector3 dirA = vA / dA; Vector3 dirB = vB / dB; Quaternion qA = Quaternion.LookRotation(dirA, up); Quaternion qB = Quaternion.LookRotation(dirB, up); Quaternion q = UnityQuaternionExtensions.SlerpWithReferenceUp(qA, qB, t, up); Vector3 dir = q * Vector3.forward; return(dir * Mathf.Lerp(dA, dB, t)); }