Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TMatrix4.ipp
Go to the documentation of this file.
1#pragma once
2
3#include "Math/TMatrix4.h"
4#include "Math/TVector3.h"
5#include "Math/TQuaternion.h"
6
7#include <Common/assertion.h>
8
9#include <cmath>
10
11namespace ph::math
12{
13
14template<typename T>
20template<typename T>
21inline TMatrix4<T>::TMatrix4(const T value)
22{
23 for(std::size_t i = 0; i < 4; ++i)
24 {
25 for(std::size_t j = 0; j < 4; ++j)
26 {
27 m[i][j] = value;
28 }
29 }
30}
31
32template<typename T>
33inline TMatrix4<T>::TMatrix4(const Elements& elements) :
34 m(elements)
35{}
37template<typename T>
38template<typename U>
41 for(std::size_t i = 0; i < 4; ++i)
42 {
43 for(std::size_t j = 0; j < 4; ++j)
44 {
45 m[i][j] = static_cast<T>(other.m[i][j]);
46 }
47 }
50template<typename T>
53 m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
54 m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
55 m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
56 m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
58 return *this;
59}
60
61template<typename T>
62inline TMatrix4<T>& TMatrix4<T>::initTranslation(const T x, const T y, const T z)
63{
64 m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = x;
65 m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = y;
66 m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = z;
67 m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
68
69 return *this;
70}
71
72template<typename T>
74{
75 return initTranslation(value.x(), value.y(), value.z());
76}
77
78template<typename T>
80{
81 m[0][0] = 1 - 2 * (rot.y() * rot.y() + rot.z() * rot.z());
82 m[0][1] = 2 * (rot.x() * rot.y() - rot.z() * rot.w());
83 m[0][2] = 2 * (rot.y() * rot.w() + rot.x() * rot.z());
84 m[0][3] = 0;
85
86 m[1][0] = 2 * (rot.x() * rot.y() + rot.z() * rot.w());
87 m[1][1] = 1 - 2 * (rot.x() * rot.x() + rot.z() * rot.z());
88 m[1][2] = 2 * (rot.y() * rot.z() - rot.x() * rot.w());
89 m[1][3] = 0;
90
91 m[2][0] = 2 * (rot.x() * rot.z() - rot.y() * rot.w());
92 m[2][1] = 2 * (rot.y() * rot.z() + rot.x() * rot.w());
93 m[2][2] = 1 - 2 * (rot.x() * rot.x() + rot.y() * rot.y());
94 m[2][3] = 0;
95
96 m[3][0] = 0;
97 m[3][1] = 0;
98 m[3][2] = 0;
99 m[3][3] = 1;
100
101 return *this;
102}
103
104template<typename T>
105inline TMatrix4<T>& TMatrix4<T>::initRotation(const TVector3<T>& orthBasisX, const TVector3<T>& orthBasisY, const TVector3<T>& orthBasisZ)
106{
107 m[0][0] = orthBasisX.x(); m[0][1] = orthBasisY.x(); m[0][2] = orthBasisZ.x(); m[0][3] = 0;
108 m[1][0] = orthBasisX.y(); m[1][1] = orthBasisY.y(); m[1][2] = orthBasisZ.y(); m[1][3] = 0;
109 m[2][0] = orthBasisX.z(); m[2][1] = orthBasisY.z(); m[2][2] = orthBasisZ.z(); m[2][3] = 0;
110 m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
111
112 return *this;
113}
114
115template<typename T>
116inline TMatrix4<T>& TMatrix4<T>::initScale(const T x, const T y, const T z)
117{
118 m[0][0] = x; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
119 m[1][0] = 0; m[1][1] = y; m[1][2] = 0; m[1][3] = 0;
120 m[2][0] = 0; m[2][1] = 0; m[2][2] = z; m[2][3] = 0;
121 m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
122
123 return *this;
124}
125
126template<typename T>
128{
129 return initScale(scale.x(), scale.y(), scale.z());
130}
131
132template<typename T>
134 const T aspectRatio,
135 const T zNear,
136 const T zFar)
137{
138 const T tanHalfFov = std::tan(fov / 2);
139 const T zRange = zNear - zFar;
140
141 m[0][0] = 1.0f / tanHalfFov; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
142 m[1][0] = 0; m[1][1] = aspectRatio / tanHalfFov; m[1][2] = 0; m[1][3] = 0;
143 m[2][0] = 0; m[2][1] = 0; m[2][2] = (zNear + zFar) / zRange; m[2][3] = 2 * zFar * zNear / zRange;
144 m[3][0] = 0; m[3][1] = 0; m[3][2] = -1.0f; m[3][3] = 0;
145
146 return *this;
147}
148
149template<typename T>
150inline TMatrix4<T> TMatrix4<T>::mul(const TMatrix4& rhs) const
151{
152 TMatrix4 res;
153
154 for(std::size_t i = 0; i < 4; ++i)
155 {
156 for(std::size_t j = 0; j < 4; ++j)
157 {
158 res.m[i][j] = m[i][0] * rhs.m[0][j] +
159 m[i][1] * rhs.m[1][j] +
160 m[i][2] * rhs.m[2][j] +
161 m[i][3] * rhs.m[3][j];
162 }
163 }
164
165 return res;
166}
167
168template<typename T>
169inline void TMatrix4<T>::mul(const TMatrix4& rhs, TMatrix4* const out_result) const
170{
171 PH_ASSERT(out_result != nullptr && out_result != this);
172
173 for(std::size_t i = 0; i < 4; ++i)
174 {
175 for(std::size_t j = 0; j < 4; ++j)
176 {
177 out_result->m[i][j] = m[i][0] * rhs.m[0][j]
178 + m[i][1] * rhs.m[1][j]
179 + m[i][2] * rhs.m[2][j]
180 + m[i][3] * rhs.m[3][j];
181 }
182 }
183}
184
185template<typename T>
186inline void TMatrix4<T>::mul(const TVector3<T>& rhsXYZ, const T rhsW, TVector3<T>* const out_result) const
187{
188 PH_ASSERT(out_result != nullptr && out_result != &rhsXYZ);
189
190 out_result->x() = m[0][0] * rhsXYZ.x() + m[0][1] * rhsXYZ.y() + m[0][2] * rhsXYZ.z() + m[0][3] * rhsW;
191 out_result->y() = m[1][0] * rhsXYZ.x() + m[1][1] * rhsXYZ.y() + m[1][2] * rhsXYZ.z() + m[1][3] * rhsW;
192 out_result->z() = m[2][0] * rhsXYZ.x() + m[2][1] * rhsXYZ.y() + m[2][2] * rhsXYZ.z() + m[2][3] * rhsW;
193}
194
195template<typename T>
197{
198 m[0][0] *= rhs;
199 m[0][1] *= rhs;
200 m[0][2] *= rhs;
201 m[0][3] *= rhs;
202
203 m[1][0] *= rhs;
204 m[1][1] *= rhs;
205 m[1][2] *= rhs;
206 m[1][3] *= rhs;
207
208 m[2][0] *= rhs;
209 m[2][1] *= rhs;
210 m[2][2] *= rhs;
211 m[2][3] *= rhs;
212
213 m[3][0] *= rhs;
214 m[3][1] *= rhs;
215 m[3][2] *= rhs;
216 m[3][3] *= rhs;
217
218 return *this;
219}
220
221template<typename T>
222inline TMatrix4<T>& TMatrix4<T>::inverse(TMatrix4* const out_result) const
223{
224 PH_ASSERT(out_result != nullptr && out_result != this);
225
226 out_result->m[0][0] = m[1][2] * m[2][3] * m[3][1] - m[1][3] * m[2][2] * m[3][1] + m[1][3] * m[2][1] * m[3][2]
227 - m[1][1] * m[2][3] * m[3][2] - m[1][2] * m[2][1] * m[3][3] + m[1][1] * m[2][2] * m[3][3];
228 out_result->m[0][1] = m[0][3] * m[2][2] * m[3][1] - m[0][2] * m[2][3] * m[3][1] - m[0][3] * m[2][1] * m[3][2]
229 + m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] - m[0][1] * m[2][2] * m[3][3];
230 out_result->m[0][2] = m[0][2] * m[1][3] * m[3][1] - m[0][3] * m[1][2] * m[3][1] + m[0][3] * m[1][1] * m[3][2]
231 - m[0][1] * m[1][3] * m[3][2] - m[0][2] * m[1][1] * m[3][3] + m[0][1] * m[1][2] * m[3][3];
232 out_result->m[0][3] = m[0][3] * m[1][2] * m[2][1] - m[0][2] * m[1][3] * m[2][1] - m[0][3] * m[1][1] * m[2][2]
233 + m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] - m[0][1] * m[1][2] * m[2][3];
234
235 out_result->m[1][0] = m[1][3] * m[2][2] * m[3][0] - m[1][2] * m[2][3] * m[3][0] - m[1][3] * m[2][0] * m[3][2]
236 + m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] - m[1][0] * m[2][2] * m[3][3];
237 out_result->m[1][1] = m[0][2] * m[2][3] * m[3][0] - m[0][3] * m[2][2] * m[3][0] + m[0][3] * m[2][0] * m[3][2]
238 - m[0][0] * m[2][3] * m[3][2] - m[0][2] * m[2][0] * m[3][3] + m[0][0] * m[2][2] * m[3][3];
239 out_result->m[1][2] = m[0][3] * m[1][2] * m[3][0] - m[0][2] * m[1][3] * m[3][0] - m[0][3] * m[1][0] * m[3][2]
240 + m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] - m[0][0] * m[1][2] * m[3][3];
241 out_result->m[1][3] = m[0][2] * m[1][3] * m[2][0] - m[0][3] * m[1][2] * m[2][0] + m[0][3] * m[1][0] * m[2][2]
242 - m[0][0] * m[1][3] * m[2][2] - m[0][2] * m[1][0] * m[2][3] + m[0][0] * m[1][2] * m[2][3];
243
244 out_result->m[2][0] = m[1][1] * m[2][3] * m[3][0] - m[1][3] * m[2][1] * m[3][0] + m[1][3] * m[2][0] * m[3][1]
245 - m[1][0] * m[2][3] * m[3][1] - m[1][1] * m[2][0] * m[3][3] + m[1][0] * m[2][1] * m[3][3];
246 out_result->m[2][1] = m[0][3] * m[2][1] * m[3][0] - m[0][1] * m[2][3] * m[3][0] - m[0][3] * m[2][0] * m[3][1]
247 + m[0][0] * m[2][3] * m[3][1] + m[0][1] * m[2][0] * m[3][3] - m[0][0] * m[2][1] * m[3][3];
248 out_result->m[2][2] = m[0][1] * m[1][3] * m[3][0] - m[0][3] * m[1][1] * m[3][0] + m[0][3] * m[1][0] * m[3][1]
249 - m[0][0] * m[1][3] * m[3][1] - m[0][1] * m[1][0] * m[3][3] + m[0][0] * m[1][1] * m[3][3];
250 out_result->m[2][3] = m[0][3] * m[1][1] * m[2][0] - m[0][1] * m[1][3] * m[2][0] - m[0][3] * m[1][0] * m[2][1]
251 + m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] - m[0][0] * m[1][1] * m[2][3];
252
253 out_result->m[3][0] = m[1][2] * m[2][1] * m[3][0] - m[1][1] * m[2][2] * m[3][0] - m[1][2] * m[2][0] * m[3][1]
254 + m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] - m[1][0] * m[2][1] * m[3][2];
255 out_result->m[3][1] = m[0][1] * m[2][2] * m[3][0] - m[0][2] * m[2][1] * m[3][0] + m[0][2] * m[2][0] * m[3][1]
256 - m[0][0] * m[2][2] * m[3][1] - m[0][1] * m[2][0] * m[3][2] + m[0][0] * m[2][1] * m[3][2];
257 out_result->m[3][2] = m[0][2] * m[1][1] * m[3][0] - m[0][1] * m[1][2] * m[3][0] - m[0][2] * m[1][0] * m[3][1]
258 + m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] - m[0][0] * m[1][1] * m[3][2];
259 out_result->m[3][3] = m[0][1] * m[1][2] * m[2][0] - m[0][2] * m[1][1] * m[2][0] + m[0][2] * m[1][0] * m[2][1]
260 - m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] + m[0][0] * m[1][1] * m[2][2];
261
262 return out_result->mulLocal(1 / determinant());
263}
264
265template<typename T>
267{
268 TMatrix4 result;
269 for(std::size_t i = 0; i < 4; ++i)
270 {
271 for(std::size_t j = 0; j < 4; ++j)
272 {
273 result.m[j][i] = m[i][j];
274 }
275 }
276
277 return result;
278}
279
280template<typename T>
282{
283 T value;
284
285 value = m[0][3] * m[1][2] * m[2][1] * m[3][0] - m[0][2] * m[1][3] * m[2][1] * m[3][0]
286 - m[0][3] * m[1][1] * m[2][2] * m[3][0] + m[0][1] * m[1][3] * m[2][2] * m[3][0]
287 + m[0][2] * m[1][1] * m[2][3] * m[3][0] - m[0][1] * m[1][2] * m[2][3] * m[3][0]
288 - m[0][3] * m[1][2] * m[2][0] * m[3][1] + m[0][2] * m[1][3] * m[2][0] * m[3][1]
289 + m[0][3] * m[1][0] * m[2][2] * m[3][1] - m[0][0] * m[1][3] * m[2][2] * m[3][1]
290 - m[0][2] * m[1][0] * m[2][3] * m[3][1] + m[0][0] * m[1][2] * m[2][3] * m[3][1]
291 + m[0][3] * m[1][1] * m[2][0] * m[3][2] - m[0][1] * m[1][3] * m[2][0] * m[3][2]
292 - m[0][3] * m[1][0] * m[2][1] * m[3][2] + m[0][0] * m[1][3] * m[2][1] * m[3][2]
293 + m[0][1] * m[1][0] * m[2][3] * m[3][2] - m[0][0] * m[1][1] * m[2][3] * m[3][2]
294 - m[0][2] * m[1][1] * m[2][0] * m[3][3] + m[0][1] * m[1][2] * m[2][0] * m[3][3]
295 + m[0][2] * m[1][0] * m[2][1] * m[3][3] - m[0][0] * m[1][2] * m[2][1] * m[3][3]
296 - m[0][1] * m[1][0] * m[2][2] * m[3][3] + m[0][0] * m[1][1] * m[2][2] * m[3][3];
297
298 return value;
299}
300
301template<typename T>
302inline bool TMatrix4<T>::isEqual(const TMatrix4& other) const
303{
304 // TODO: branchless?
305
306 for(std::size_t i = 0; i < 4; ++i)
307 {
308 for(std::size_t j = 0; j < 4; ++j)
309 {
310 if(m[i][j] != other.m[i][j])
311 {
312 return false;
313 }
314 }
315 }
316
317 return true;
318}
319
320template<typename T>
321inline std::string TMatrix4<T>::toString() const
322{
323 std::string result;
324
325 result += '[' + std::to_string(m[0][0]) + ", "
326 + std::to_string(m[0][1]) + ", "
327 + std::to_string(m[0][2]) + ", "
328 + std::to_string(m[0][3]) + "]\n";
329
330 result += '[' + std::to_string(m[1][0]) + ", "
331 + std::to_string(m[1][1]) + ", "
332 + std::to_string(m[1][2]) + ", "
333 + std::to_string(m[1][3]) + "]\n";
334
335 result += '[' + std::to_string(m[2][0]) + ", "
336 + std::to_string(m[2][1]) + ", "
337 + std::to_string(m[2][2]) + ", "
338 + std::to_string(m[2][3]) + "]\n";
339
340 result += '[' + std::to_string(m[3][0]) + ", "
341 + std::to_string(m[3][1]) + ", "
342 + std::to_string(m[3][2]) + ", "
343 + std::to_string(m[3][3]) + "]";
344
345 return result;
346}
347
348}// end namespace ph::math
Represents a 4x4 matrix.
Definition TMatrix4.h:17
static TMatrix4 makeIdentity()
Definition TMatrix4.ipp:15
TMatrix4 mul(const TMatrix4 &rhs) const
Definition TMatrix4.ipp:150
TMatrix4 & initRotation(const TQuaternion< T > &rot)
Definition TMatrix4.ipp:79
TMatrix4 & mulLocal(T rhs)
Definition TMatrix4.ipp:196
std::string toString() const
Definition TMatrix4.ipp:321
std::array< std::array< T, 4 >, 4 > Elements
Definition TMatrix4.h:22
TMatrix4 & initScale(T x, T y, T z)
Definition TMatrix4.ipp:116
bool isEqual(const TMatrix4 &other) const
Definition TMatrix4.ipp:302
T determinant() const
Definition TMatrix4.ipp:281
TMatrix4 & initTranslation(T x, T y, T z)
Definition TMatrix4.ipp:62
Elements m
Definition TMatrix4.h:24
TMatrix4 & initPerspectiveProjection(T fov, T aspectRatio, T zNear, T zFar)
Definition TMatrix4.ipp:133
TMatrix4 & initIdentity()
Definition TMatrix4.ipp:51
TMatrix4 & inverse(TMatrix4 *out_result) const
Definition TMatrix4.ipp:222
TMatrix4 transpose() const
Definition TMatrix4.ipp:266
Represents a quaternion.
Definition TQuaternion.h:17
T & x()
Definition TQuaternion.ipp:95
T & z()
Definition TQuaternion.ipp:107
T & w()
Definition TQuaternion.ipp:113
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
Math functions and utilities.
Definition TransformInfo.h:10