Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TQuaternion.ipp
Go to the documentation of this file.
1#pragma once
2
3#include "Math/TQuaternion.h"
4#include "Math/TVector3.h"
5#include "Math/TMatrix4.h"
6#include "Math/math.h"
7
8#include <Common/assertion.h>
9
10namespace ph::math
11{
12
13template<typename T>
15{
16 return TQuaternion(0, 0, 0, 1);
17}
18
19template<typename T>
20inline TQuaternion<T>::TQuaternion(const T vx, const T vy, const T vz, const T vw)
21 : Base(std::array<T, 4>{vx, vy, vz, vw})
22{}
23
24template<typename T>
25template<typename U>
28 static_cast<T>(other.x()),
29 static_cast<T>(other.y()),
30 static_cast<T>(other.z()),
31 static_cast<T>(other.w()))
32{}
33
34template<typename T>
35template<typename U>
36inline TQuaternion<T>::TQuaternion(const std::array<U, 4>& xyzwValues)
38 TQuaternion<U>(xyzwValues[0], xyzwValues[1], xyzwValues[2], xyzwValues[3]))
39{}
41template<typename T>
42inline TQuaternion<T>::TQuaternion(const TVector3<T>& normalizedAxis, const T radians)
45 setRot(normalizedAxis, radians);
48template<typename T>
49inline TQuaternion<T>::TQuaternion(const TMatrix4<T>& rotationMatrix)
51{
52 const TMatrix4<T>& m = rotationMatrix;
53
54 const T trace = m.m[0][0] + m.m[1][1] + m.m[2][2];
55 if(trace > 0)
56 {
57 const T s = static_cast<T>(0.5) / std::sqrt(trace + 1);
58 x() = (m.m[2][1] - m.m[1][2]) * s;
59 y() = (m.m[0][2] - m.m[2][0]) * s;
60 z() = (m.m[1][0] - m.m[0][1]) * s;
61 w() = static_cast<T>(0.25) / s;
62 }
63 else
64 {
65 if(m.m[0][0] > m.m[1][1] && m.m[0][0] > m.m[2][2])
66 {
67 const T s = static_cast<T>(0.5) / std::sqrt(1 + m.m[0][0] - m.m[1][1] - m.m[2][2]);
68 x() = static_cast<T>(0.25) / s;
69 y() = (m.m[0][1] + m.m[1][0]) * s;
70 z() = (m.m[0][2] + m.m[2][0]) * s;
71 w() = (m.m[2][1] - m.m[1][2]) * s;
72 }
73 else if(m.m[1][1] > m.m[2][2])
74 {
75 const T s = static_cast<T>(0.5) / std::sqrt(1 + m.m[1][1] - m.m[0][0] - m.m[2][2]);
76 x() = (m.m[0][1] + m.m[1][0]) * s;
77 y() = static_cast<T>(0.25) / s;
78 z() = (m.m[1][2] + m.m[2][1]) * s;
79 w() = (m.m[0][2] - m.m[2][0]) * s;
80 }
81 else
82 {
83 const T s = static_cast<T>(0.5) / std::sqrt(1 + m.m[2][2] - m.m[0][0] - m.m[1][1]);
84 x() = (m.m[0][2] + m.m[2][0]) * s;
85 y() = (m.m[1][2] + m.m[2][1]) * s;
86 z() = static_cast<T>(0.25) / s;
87 w() = (m.m[1][0] - m.m[0][1]) * s;
88 }
89 }
90
91 normalizeLocal();
92}
93
94template<typename T>
96{
97 return m[0];
98}
99
100template<typename T>
102{
103 return m[1];
104}
105
106template<typename T>
108{
109 return m[2];
110}
111
112template<typename T>
114{
115 return m[3];
116}
117
118template<typename T>
119inline const T& TQuaternion<T>::x() const
120{
121 return m[0];
122}
123
124template<typename T>
125inline const T& TQuaternion<T>::y() const
126{
127 return m[1];
128}
129
130template<typename T>
131inline const T& TQuaternion<T>::z() const
132{
133 return m[2];
134}
135
136template<typename T>
137inline const T& TQuaternion<T>::w() const
138{
139 return m[3];
140}
141
142template<typename T>
144{
145 // Acting like `xyz`'s w component is 0
146 return TQuaternion(w() * xyz.x() + y() * xyz.z() - z() * xyz.y(),
147 w() * xyz.y() - x() * xyz.z() + z() * xyz.x(),
148 w() * xyz.z() + x() * xyz.y() - y() * xyz.x(),
149 -x() * xyz.x() - y() * xyz.y() - z() * xyz.z());
150}
151
152template<typename T>
154{
155 return TQuaternion(*this).normalizeLocal();
156}
157
158template<typename T>
160{
162
163 return *this;
164}
165
166template<typename T>
168{
169 return ::ph::math::length(m);
170}
171
172template<typename T>
174{
175 return TQuaternion(*this).conjugateLocal();
176}
177
178template<typename T>
179inline void TQuaternion<T>::conjugate(TQuaternion* const out_result) const
180{
181 PH_ASSERT(out_result);
182
183 *out_result = *this;
184 out_result->conjugateLocal();
185}
186
187template<typename T>
189{
190 x() *= -1;
191 y() *= -1;
192 z() *= -1;
193
194 return *this;
195}
196
197template<typename T>
199{
200 return TQuaternion(*this).mulLocal(rhs);
201}
202
203template<typename T>
205{
206 const T _x = w() * rhs.x() + x() * rhs.w() + y() * rhs.z() - z() * rhs.y();
207 const T _y = w() * rhs.y() - x() * rhs.z() + y() * rhs.w() + z() * rhs.x();
208 const T _z = w() * rhs.z() + x() * rhs.y() - y() * rhs.x() + z() * rhs.w();
209 const T _w = w() * rhs.w() - x() * rhs.x() - y() * rhs.y() - z() * rhs.z();
210
211 x() = _x;
212 y() = _y;
213 z() = _z;
214 w() = _w;
215
216 return *this;
217}
218
219template<typename T>
220inline TQuaternion<T> TQuaternion<T>::mul(const T rhs) const
221{
222 return TQuaternion(x() * rhs, y() * rhs, z() * rhs, w() * rhs);
223}
224
225template<typename T>
227{
228 return TQuaternion(x() - rhs.x(), y() - rhs.y(), z() - rhs.z(), w() - rhs.w());
229}
230
231template<typename T>
233{
234 return TQuaternion(x() + rhs.x(), y() + rhs.y(), z() + rhs.z(), w() + rhs.w());
235}
236
237template<typename T>
238inline T TQuaternion<T>::dot(const TQuaternion& rhs) const
239{
240 return ::ph::math::dot_product(m, rhs.m);
241}
242
243template<typename T>
244inline void TQuaternion<T>::setRot(const TVector3<T>& normalizedAxis, const T radians)
245{
246 const T sinHalfAngle = std::sin(radians / 2);
247 const T cosHalfAngle = std::cos(radians / 2);
248
249 x() = normalizedAxis.x() * sinHalfAngle;
250 y() = normalizedAxis.y() * sinHalfAngle;
251 z() = normalizedAxis.z() * sinHalfAngle;
252 w() = cosHalfAngle;
253}
254
255template<typename T>
256inline void TQuaternion<T>::toRotationMatrix(TMatrix4<T>* const out_result) const
257{
258 PH_ASSERT(out_result);
259
260 out_result->m[0][0] = 1 - 2 * (y() * y() + z() * z());
261 out_result->m[0][1] = 2 * (x() * y() - z() * w());
262 out_result->m[0][2] = 2 * (y() * w() + x() * z());
263 out_result->m[0][3] = 0;
264
265 out_result->m[1][0] = 2 * (x() * y() + z() * w());
266 out_result->m[1][1] = 1 - 2 * (x() * x() + z() * z());
267 out_result->m[1][2] = 2 * (y() * z() - x() * w());
268 out_result->m[1][3] = 0;
269
270 out_result->m[2][0] = 2 * (x() * z() - y() * w());
271 out_result->m[2][1] = 2 * (y() * z() + x() * w());
272 out_result->m[2][2] = 1 - 2 * (x() * x() + y() * y());
273 out_result->m[2][3] = 0;
274
275 out_result->m[3][0] = 0;
276 out_result->m[3][1] = 0;
277 out_result->m[3][2] = 0;
278 out_result->m[3][3] = 1;
279}
280
281}// end namespace ph::math
std::array< T, N > m
Definition TArithmeticArrayBase.h:217
Represents a 4x4 matrix.
Definition TMatrix4.h:17
Elements m
Definition TMatrix4.h:24
Represents a quaternion.
Definition TQuaternion.h:17
void toRotationMatrix(TMatrix4< T > *out_result) const
Definition TQuaternion.ipp:256
TQuaternion conjugate() const
Definition TQuaternion.ipp:173
T & x()
Definition TQuaternion.ipp:95
TQuaternion add(const TQuaternion &rhs) const
Definition TQuaternion.ipp:232
TQuaternion & mulLocal(const TQuaternion &rhs)
Definition TQuaternion.ipp:204
T & z()
Definition TQuaternion.ipp:107
T & w()
Definition TQuaternion.ipp:113
T length() const
Definition TQuaternion.ipp:167
T dot(const TQuaternion &rhs) const
Definition TQuaternion.ipp:238
void setRot(const TVector3< T > &normalizedAxis, T radians)
Definition TQuaternion.ipp:244
TQuaternion sub(const TQuaternion &rhs) const
Definition TQuaternion.ipp:226
TQuaternion & conjugateLocal()
Definition TQuaternion.ipp:188
TQuaternion normalize() const
Definition TQuaternion.ipp:153
TQuaternion & normalizeLocal()
Definition TQuaternion.ipp:159
TQuaternion(T vx, T vy, T vz, T vw)
Definition TQuaternion.ipp:20
static TQuaternion makeNoRotation()
Definition TQuaternion.ipp:14
TQuaternion mul(const TVector3< T > &xyz) const
Quaternion multiplication (treating the input's w component as 0).
Definition TQuaternion.ipp:143
T & y()
Definition TQuaternion.ipp:101
Represents a 3-D vector.
Definition TVector3.h:17
T & y()
Definition TVector3.ipp:189
T & z()
Definition TVector3.ipp:195
T & x()
Definition TVector3.ipp:183
Miscellaneous math utilities.
Math functions and utilities.
Definition TransformInfo.h:10
void normalize(std::array< T, N > &vec)
Treating input values as a vector and normalize it. Notice that normalizing a integer typed vector wi...
Definition math.ipp:142
Definition TAABB2D.h:96