diff --git a/glm/gtx/quaternion.inl b/glm/gtx/quaternion.inl index 4c5b3d66..7467b42d 100644 --- a/glm/gtx/quaternion.inl +++ b/glm/gtx/quaternion.inl @@ -121,33 +121,28 @@ namespace glm } template - GLM_FUNC_QUALIFIER tquat pow - ( - tquat const & x, - T const & y - ) + GLM_FUNC_QUALIFIER tquat pow(tquat const & x, T const & y) { - if(abs(x.w) > (static_cast(1) - epsilon())) - return x; - T Angle = acos(y); + //Raising to the power of 0 should yield 1 + //Needed to prevent a division by 0 error later on + if(y > -epsilon() && y < epsilon()) + return tquat(1,0,0,0); + + //To deal with non-unit quaternions + T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w); + + //Equivalent to raising a real number to a power + //Needed to prevent a division by 0 error later on + if(abs(x.w / magnitude) > static_cast(1) - epsilon() && abs(x.w / magnitude) < static_cast(1) + epsilon()) + return tquat(pow(x.w, y),0,0,0); + + T Angle = acos(x.w / magnitude); T NewAngle = Angle * y; T Div = sin(NewAngle) / sin(Angle); - return tquat( - cos(NewAngle), - x.x * Div, - x.y * Div, - x.z * Div); - } + T Mag = pow(magnitude, y-1); - //template - //GLM_FUNC_QUALIFIER tquat sqrt - //( - // tquat const & q - //) - //{ - // T q0 = static_cast(1) - dot(q, q); - // return T(2) * (T(1) + q0) * q; - //} + return tquat(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag); + } template GLM_FUNC_QUALIFIER tvec3 rotate diff --git a/readme.md b/readme.md index 96a131eb..83ff6f8e 100644 --- a/readme.md +++ b/readme.md @@ -78,6 +78,7 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate) - Fixed isfinite with C++98 compilers #343 - Fixed Intel compiler build error on Linux #354 - Fixed use of libstdc++ with Clang #351 +- Fixed quaternion pow #346 ##### Deprecation: - Removed integer specification for 'mod' in GTC_integer #308