diff --git a/include/cglm/quat.h b/include/cglm/quat.h index 8560ec8..97b27ed 100644 --- a/include/cglm/quat.h +++ b/include/cglm/quat.h @@ -38,6 +38,7 @@ CGLM_INLINE void glm_quat_lerp(versor from, versor to, float t, versor dest); CGLM_INLINE void glm_quat_lerpc(versor from, versor to, float t, versor dest); CGLM_INLINE void glm_quat_slerp(versor q, versor r, float t, versor dest); + CGLM_INLINE void glm_quat_nlerp(versor q, versor r, float t, versor dest); CGLM_INLINE void glm_quat_look(vec3 eye, versor ori, mat4 dest); CGLM_INLINE void glm_quat_for(vec3 dir, vec3 fwd, vec3 up, versor dest); CGLM_INLINE void glm_quat_forp(vec3 from, @@ -628,6 +629,29 @@ glm_quat_lerpc(versor from, versor to, float t, versor dest) { glm_vec4_lerpc(from, to, t, dest); } +/*! + * @brief interpolates between two quaternions + * taking the shortest rotation path using + * normalized linear interpolation (NLERP) + * + * @param[in] from from + * @param[in] to to + * @param[in] t interpolant (amount) + * @param[out] dest result quaternion + */ +CGLM_INLINE +void +glm_quat_nlerp(versor from, versor to, float t, versor dest) { + float dot = glm_vec4_dot(from, to); + versor target; + if (dot >= 0) + glm_quat_copy(to, target); + else + glm_vec4_negate_to(to, target); + glm_quat_lerp(from, target, t, dest); + glm_quat_normalize(dest); +} + /*! * @brief interpolates between two quaternions * using spherical linear interpolation (SLERP)