Fixed corner cases in exp and log functions for quaternions #199

This commit is contained in:
Christophe Riccio 2014-06-21 15:38:49 +02:00
parent 08ff93925f
commit 9b6eecc739
2 changed files with 19 additions and 12 deletions

View File

@ -8,6 +8,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
#include <limits> #include <limits>
#include "../gtc/constants.hpp"
namespace glm namespace glm
{ {
@ -62,7 +63,10 @@ namespace glm
) )
{ {
detail::tvec3<T, P> u(q.x, q.y, q.z); detail::tvec3<T, P> u(q.x, q.y, q.z);
float Angle = glm::length(u); T Angle = glm::length(u);
if (Angle < epsilon<T>())
return detail::tquat<T, P>();
detail::tvec3<T, P> v(u / Angle); detail::tvec3<T, P> v(u / Angle);
return detail::tquat<T, P>(cos(Angle), sin(Angle) * v); return detail::tquat<T, P>(cos(Angle), sin(Angle) * v);
} }
@ -73,18 +77,20 @@ namespace glm
detail::tquat<T, P> const & q detail::tquat<T, P> const & q
) )
{ {
if((q.x == static_cast<T>(0)) && (q.y == static_cast<T>(0)) && (q.z == static_cast<T>(0))) detail::tvec3<T, P> u(q.x, q.y, q.z);
T Vec3Len = length(u);
if (Vec3Len < epsilon<T>())
{ {
if(q.w > T(0)) if(q.w > static_cast<T>(0))
return detail::tquat<T, P>(log(q.w), T(0), T(0), T(0)); return detail::tquat<T, P>(log(q.w), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
else if(q.w < T(0)) else if(q.w < static_cast<T>(0))
return detail::tquat<T, P>(log(-q.w), T(3.1415926535897932384626433832795), T(0),T(0)); return detail::tquat<T, P>(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
else else
return detail::tquat<T, P>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity()); return detail::tquat<T, P>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
} }
else else
{ {
T Vec3Len = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w); T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w);
T t = atan(Vec3Len, T(q.w)) / Vec3Len; T t = atan(Vec3Len, T(q.w)) / Vec3Len;
return detail::tquat<T, P>(log(QuatLen), t * q.x, t * q.y, t * q.z); return detail::tquat<T, P>(log(QuatLen), t * q.x, t * q.y, t * q.z);
@ -98,11 +104,11 @@ namespace glm
T const & y T const & y
) )
{ {
if(abs(x.w) > T(0.9999)) if(abs(x.w) > (static_cast<T>(1) - epsilon<T>()))
return x; return x;
float Angle = acos(y); T Angle = acos(y);
float NewAngle = Angle * y; T NewAngle = Angle * y;
float Div = sin(NewAngle) / sin(Angle); T Div = sin(NewAngle) / sin(Angle);
return detail::tquat<T, P>( return detail::tquat<T, P>(
cos(NewAngle), cos(NewAngle),
x.x * Div, x.x * Div,

View File

@ -37,7 +37,7 @@ More informations in GLM manual:
http://glm.g-truc.net/glm.pdf http://glm.g-truc.net/glm.pdf
================================================================================ ================================================================================
GLM 0.9.5.4: 2014-0X-XX GLM 0.9.5.4: 2014-06-21
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
- Fixed non-utf8 character #196 - Fixed non-utf8 character #196
- Added FindGLM install for CMake #189 - Added FindGLM install for CMake #189
@ -56,6 +56,7 @@ GLM 0.9.5.4: 2014-0X-XX
- Fixed std::copy and std::vector with GLM types #214 - Fixed std::copy and std::vector with GLM types #214
- Fixed strict aliasing issues #212, #152 - Fixed strict aliasing issues #212, #152
- Fixed std::nextafter not supported with C++11 on Android #213 - Fixed std::nextafter not supported with C++11 on Android #213
- Fixed corner cases in exp and log functions for quaternions #199
================================================================================ ================================================================================
GLM 0.9.5.3: 2014-04-02 GLM 0.9.5.3: 2014-04-02