Added slerp, lerp and mix functions for quaternions. Added, fixed and clarified documentation.

This commit is contained in:
Christophe Riccio 2012-12-21 23:05:10 +01:00
parent 6f22430bbc
commit 912d1b1e81
3 changed files with 76 additions and 3 deletions

View File

@ -88,7 +88,7 @@ namespace glm
/// @param m Input matrix multiplied by this rotation matrix. /// @param m Input matrix multiplied by this rotation matrix.
/// @param angle Rotation angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise. /// @param angle Rotation angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
/// @param axis Rotation axis, recommanded to be normalized. /// @param axis Rotation axis, recommanded to be normalized.
/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double. /// @tparam T Value type used to build the matrix. Supported: half, float or double.
/// @see gtc_matrix_transform /// @see gtc_matrix_transform
/// @see gtx_transform /// @see gtx_transform
/// @see - rotate(T angle, T x, T y, T z) /// @see - rotate(T angle, T x, T y, T z)

View File

@ -171,15 +171,48 @@ namespace detail
detail::tquat<T> const & q1, detail::tquat<T> const & q1,
detail::tquat<T> const & q2); detail::tquat<T> const & q2);
/// Returns a SLERP interpolated quaternion of x and y according a. /// Spherical linear interpolation of two quaternions.
/// The interpolation is oriented and the rotation is performed at constant speed.
/// ///
/// @param x A quaternion
/// @param y A quaternion
/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
/// @see gtc_quaternion /// @see gtc_quaternion
template <typename T> template <typename T>
detail::tquat<T> mix( detail::tquat<T> mix(
detail::tquat<T> const & x, detail::tquat<T> const & x,
detail::tquat<T> const & y, detail::tquat<T> const & y,
T const & a); T const & a);
/// Linear interpolation of two quaternions.
/// The interpolation is oriented.
///
/// @param x A quaternion
/// @param y A quaternion
/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
/// @see gtc_quaternion
template <typename T>
detail::tquat<T> lerp(
detail::tquat<T> const & x,
detail::tquat<T> const & y,
T const & a);
/// Spherical linear interpolation of two quaternions.
/// The interpolation always take the short path and the rotation is performed at constant speed.
///
/// @param x A quaternion
/// @param y A quaternion
/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
/// @see gtc_quaternion
template <typename T>
detail::tquat<T> slerp(
detail::tquat<T> const & x,
detail::tquat<T> const & y,
T const & a);
/// Returns the q conjugate. /// Returns the q conjugate.
/// ///
/// @see gtc_quaternion /// @see gtc_quaternion

View File

@ -443,6 +443,7 @@ namespace detail
return normalize(beta * x + alpha * y); return normalize(beta * x + alpha * y);
} }
*/ */
template <typename T> template <typename T>
GLM_FUNC_QUALIFIER detail::tquat<T> mix GLM_FUNC_QUALIFIER detail::tquat<T> mix
( (
@ -450,6 +451,45 @@ namespace detail
detail::tquat<T> const & y, detail::tquat<T> const & y,
T const & a T const & a
) )
{
T cosTheta = dot(x, y);
// Perform a linear interpolation when cosTheta is close to 1 to avoid side effect of sin(angle) becoming a zero denominator
if(cosTheta > T(1) - epsilon<T>())
{
// Linear interpolation
return detail::tquat<T>(
mix(x.w, y.w, a),
mix(x.x, y.x, a),
mix(x.y, y.y, a),
mix(x.z, y.z, a));
}
else
{
// Essential Mathematics, page 467
T angle = acos(cosTheta);
return (sin((T(1) - a) * angle) * x + sin(a * angle) * z) / sin(angle);
}
}
template <typename T>
GLM_FUNC_QUALIFIER detail::tquat<T> lerp
(
detail::tquat<T> const & x,
detail::tquat<T> const & y,
T const & a
)
{
return x * (T(1) - a) + (y * a);
}
template <typename T>
GLM_FUNC_QUALIFIER detail::tquat<T> slerp
(
detail::tquat<T> const & x,
detail::tquat<T> const & y,
T const & a
)
{ {
detail::tquat<T> z = y; detail::tquat<T> z = y;