|
|
|
@ -1,3 +1,5 @@ |
|
|
|
|
#include "scalar_constants.hpp" |
|
|
|
|
|
|
|
|
|
namespace glm |
|
|
|
|
{ |
|
|
|
|
template<typename T, qualifier Q> |
|
|
|
@ -46,16 +48,30 @@ namespace glm |
|
|
|
|
//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); |
|
|
|
|
|
|
|
|
|
T Angle; |
|
|
|
|
if(abs(x.w / magnitude) > cos_one_over_two<T>()) |
|
|
|
|
{ |
|
|
|
|
//Scalar component is close to 1; using it to recover angle would lose precision |
|
|
|
|
//Instead, we use the non-scalar components since sin() is accurate around 0 |
|
|
|
|
|
|
|
|
|
//Prevent a division by 0 error later on |
|
|
|
|
T VectorMagnitude = x.x * x.x + x.y * x.y + x.z * x.z; |
|
|
|
|
if (glm::abs(VectorMagnitude - static_cast<T>(0)) < glm::epsilon<T>()) { |
|
|
|
|
//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<T>(1) - epsilon<T>() && abs(x.w / magnitude) < static_cast<T>(1) + epsilon<T>()) |
|
|
|
|
return qua<T, Q>(pow(x.w, y), 0, 0, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Angle = asin(sqrt(VectorMagnitude) / magnitude); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
//Scalar component is small, shouldn't cause loss of precision |
|
|
|
|
Angle = acos(x.w / magnitude); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
T Angle = acos(x.w / magnitude); |
|
|
|
|
T NewAngle = Angle * y; |
|
|
|
|
T Div = sin(NewAngle) / sin(Angle); |
|
|
|
|
T Mag = pow(magnitude, y - static_cast<T>(1)); |
|
|
|
|
|
|
|
|
|
return qua<T, Q>(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|