Clutter Engine 0.0.1
Loading...
Searching...
No Matches
quaternion_exponential.inl
2
3namespace glm
4{
5 template<typename T, qualifier Q>
6 GLM_FUNC_QUALIFIER qua<T, Q> exp(qua<T, Q> const& q)
7 {
8 vec<3, T, Q> u(q.x, q.y, q.z);
9 T const Angle = glm::length(u);
10 if (Angle < epsilon<T>())
11 return qua<T, Q>();
12
13 vec<3, T, Q> const v(u / Angle);
14 return qua<T, Q>(cos(Angle), sin(Angle) * v);
15 }
16
17 template<typename T, qualifier Q>
18 GLM_FUNC_QUALIFIER qua<T, Q> log(qua<T, Q> const& q)
19 {
20 vec<3, T, Q> u(q.x, q.y, q.z);
21 T Vec3Len = length(u);
22
23 if (Vec3Len < epsilon<T>())
24 {
25 if(q.w > static_cast<T>(0))
26 return qua<T, Q>(log(q.w), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
27 else if(q.w < static_cast<T>(0))
28 return qua<T, Q>(log(-q.w), pi<T>(), static_cast<T>(0), static_cast<T>(0));
29 else
30 return qua<T, Q>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
31 }
32 else
33 {
34 T t = atan(Vec3Len, T(q.w)) / Vec3Len;
35 T QuatLen2 = Vec3Len * Vec3Len + q.w * q.w;
36 return qua<T, Q>(static_cast<T>(0.5) * log(QuatLen2), t * q.x, t * q.y, t * q.z);
37 }
38 }
39
40 template<typename T, qualifier Q>
41 GLM_FUNC_QUALIFIER qua<T, Q> pow(qua<T, Q> const& x, T y)
42 {
43 //Raising to the power of 0 should yield 1
44 //Needed to prevent a division by 0 error later on
45 if(y > -epsilon<T>() && y < epsilon<T>())
46 return qua<T, Q>(1,0,0,0);
47
48 //To deal with non-unit quaternions
49 T magnitude = sqrt(x.x * x.x + x.y * x.y + x.z * x.z + x.w *x.w);
50
51 T Angle;
52 if(abs(x.w / magnitude) > cos_one_over_two<T>())
53 {
54 //Scalar component is close to 1; using it to recover angle would lose precision
55 //Instead, we use the non-scalar components since sin() is accurate around 0
56
57 //Prevent a division by 0 error later on
58 T VectorMagnitude = x.x * x.x + x.y * x.y + x.z * x.z;
59 if (glm::abs(VectorMagnitude - static_cast<T>(0)) < glm::epsilon<T>()) {
60 //Equivalent to raising a real number to a power
61 return qua<T, Q>(pow(x.w, y), 0, 0, 0);
62 }
63
64 Angle = asin(sqrt(VectorMagnitude) / magnitude);
65 }
66 else
67 {
68 //Scalar component is small, shouldn't cause loss of precision
69 Angle = acos(x.w / magnitude);
70 }
71
72 T NewAngle = Angle * y;
73 T Div = sin(NewAngle) / sin(Angle);
74 T Mag = pow(magnitude, y - static_cast<T>(1));
75 return qua<T, Q>(cos(NewAngle) * magnitude * Mag, x.x * Div * Mag, x.y * Div * Mag, x.z * Div * Mag);
76 }
77
78 template<typename T, qualifier Q>
79 GLM_FUNC_QUALIFIER qua<T, Q> sqrt(qua<T, Q> const& x)
80 {
81 return pow(x, static_cast<T>(0.5));
82 }
83}//namespace glm
84
85
GLM_FUNC_DECL GLM_CONSTEXPR genType abs(genType x)
GLM_FUNC_QUALIFIER vec< L, T, Q > sqrt(vec< L, T, Q > const &x)
Definition func_exponential.inl:128
GLM_FUNC_QUALIFIER vec< L, T, Q > pow(vec< L, T, Q > const &base, vec< L, T, Q > const &exponent)
Definition func_exponential.inl:72
GLM_FUNC_QUALIFIER vec< L, T, Q > log(vec< L, T, Q > const &x)
Definition func_exponential.inl:88
GLM_FUNC_QUALIFIER vec< L, T, Q > exp(vec< L, T, Q > const &x)
Definition func_exponential.inl:80
GLM_FUNC_QUALIFIER vec< L, T, Q > sin(vec< L, T, Q > const &v)
Definition func_trigonometric.inl:41
GLM_FUNC_QUALIFIER vec< L, T, Q > cos(vec< L, T, Q > const &v)
Definition func_trigonometric.inl:50
GLM_FUNC_QUALIFIER vec< L, T, Q > asin(vec< L, T, Q > const &v)
Definition func_trigonometric.inl:68
GLM_FUNC_QUALIFIER vec< L, T, Q > acos(vec< L, T, Q > const &v)
Definition func_trigonometric.inl:77
GLM_FUNC_DECL GLM_CONSTEXPR genType epsilon()
Return the epsilon constant for floating point types.
Definition scalar_constants.inl:6
GLM_FUNC_DECL GLM_CONSTEXPR genType pi()
Return the pi constant for floating point types.
Definition scalar_constants.inl:13
GLM_FUNC_DECL GLM_CONSTEXPR genType cos_one_over_two()
Return the value of cos(1 / 2) for floating point types.
Definition scalar_constants.inl:20
Core features
Definition common.hpp:21
Definition type_quat.hpp:20
Definition qualifier.hpp:35