TDME2 1.9.121
Matrix4x4.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4
5#include <tdme/tdme.h>
7#include <tdme/math/Math.h>
8#include <tdme/math/Vector3.h>
9#include <tdme/math/Vector4.h>
10
11using std::array;
12
17
18/**
19 * 4x4 3D Matrix class
20 * @author Andreas Drewke, Song Ho Ahn <song.ahn@gmail.com>
21 * @version $Id$
22 */
24{
25private:
26 array<float, 16> data;
27
28public:
29 /**
30 * Public constructor
31 */
32 inline Matrix4x4() {
33 data.fill(0.0f);
34 }
35
36 /**
37 * Public constructor
38 * @param m matrix as float values
39 */
40 inline Matrix4x4(const array<float, 16>& m) {
41 data = m;
42 }
43
44 /**
45 * Public constructor
46 * @param matrix matrix
47 */
48 inline Matrix4x4(const Matrix4x4& matrix) {
49 data = matrix.data;
50 }
51
52 /**
53 * Public constructor
54 * @param r0c0 r0c0
55 * @param r1c0 r1c0
56 * @param r2c0 r2c0
57 * @param r3c0 r3c0
58 * @param r0c1 r0c1
59 * @param r1c1 r1c1
60 * @param r2c1 r2c1
61 * @param r3c1 r3c1
62 * @param r0c2 r0c2
63 * @param r1c2 r1c2
64 * @param r2c2 r2c2
65 * @param r3c2 r3c2
66 * @param r0c3 r0c3
67 * @param r1c3 r1c3
68 * @param r2c3 r2c3
69 * @param r3c3 r3c3
70 */
71 inline Matrix4x4(float r0c0, float r1c0, float r2c0, float r3c0, float r0c1, float r1c1, float r2c1, float r3c1, float r0c2, float r1c2, float r2c2, float r3c2, float r0c3, float r1c3, float r2c3, float r3c3) {
72 set(r0c0, r1c0, r2c0, r3c0, r0c1, r1c1, r2c1, r3c1, r0c2, r1c2, r2c2, r3c2, r0c3, r1c3, r2c3, r3c3);
73 }
74
75 /**
76 * Set up matrix by values
77 * @param r0c0 row 0, column 0
78 * @param r1c0 row 1, column 0
79 * @param r2c0 row 2, column 0
80 * @param r3c0 row 3, column 0
81 * @param r0c1 row 0, column 1
82 * @param r1c1 row 1, column 1
83 * @param r2c1 row 2, column 1
84 * @param r3c1 row 3, column 1
85 * @param r0c2 row 0, column 2
86 * @param r1c2 row 1, column 2
87 * @param r2c2 row 2, column 2
88 * @param r3c2 row 3, column 2
89 * @param r0c3 row 0, column 3
90 * @param r1c3 row 1, column 3
91 * @param r2c3 row 2, column 3
92 * @param r3c3 row 3, column 3
93 * @return this matrix
94 */
95 inline Matrix4x4& set(float r0c0, float r1c0, float r2c0, float r3c0, float r0c1, float r1c1, float r2c1, float r3c1, float r0c2, float r1c2, float r2c2, float r3c2, float r0c3, float r1c3, float r2c3, float r3c3) {
96 data[0] = r0c0;
97 data[1] = r1c0;
98 data[2] = r2c0;
99 data[3] = r3c0;
100 data[4] = r0c1;
101 data[5] = r1c1;
102 data[6] = r2c1;
103 data[7] = r3c1;
104 data[8] = r0c2;
105 data[9] = r1c2;
106 data[10] = r2c2;
107 data[11] = r3c2;
108 data[12] = r0c3;
109 data[13] = r1c3;
110 data[14] = r2c3;
111 data[15] = r3c3;
112 return *this;
113 }
114
115 /**
116 * Sets up this matrix by matrix m
117 * @param m m
118 * @return this matrix
119 */
120 inline Matrix4x4& set(const array<float, 16>& m) {
121 data = m;
122 return *this;
123 }
124
125 /**
126 * Sets up this matrix by matrix m
127 * @param m m
128 * @return
129 */
130 inline Matrix4x4& set(const Matrix4x4& m) {
131 data = m.data;
132 return *this;
133 }
134
135 /**
136 * Array access operator
137 * @param i index
138 * @return vector3 component
139 */
140 inline float& operator[](int i) {
141 return data[i];
142 }
143
144 /**
145 * Const array access operator
146 * @param i index
147 * @return vector3 component
148 */
149 inline const float& operator[](int i) const {
150 return data[i];
151 }
152
153 /**
154 * Operator * (float)
155 * @param f value to multiply by
156 * @return new matrix (this * f)
157 */
158 inline Matrix4x4 operator *(const float f) const {
159 auto r = this->clone().scale(f);
160 return r;
161 }
162
163 /**
164 * Operator * (Matrix4x4&)
165 * @param m matrix to multiply by
166 * @return new matrix (this * m)
167 */
168 inline Matrix4x4 operator *(const Matrix4x4& m) const {
169 auto r = this->clone().multiply(m);
170 return r;
171 }
172
173 /**
174 * Operator * (Vector3&)
175 * @param v vector to multiply by
176 * @return new vector (this * v)
177 */
178 inline Vector3 operator *(const Vector3& v) const {
179 return this->multiply(v);
180 }
181
182 /**
183 * Operator * (Vector4&)
184 * @param v vector to multiply by
185 * @return new vector (this * v)
186 */
187 inline Vector4 operator *(const Vector4& v) const {
188 return this->multiply(v);
189 }
190
191 /*
192 * Operator *=
193 * @param m matrix to multiply by
194 * @return this matrix multiplied by m
195 */
196 inline Matrix4x4& operator *=(const Matrix4x4 m) {
197 return this->multiply(m);
198 }
199
200 /**
201 * Equality comparison operator
202 * @param m matrix to compare to
203 * @return equality
204 */
205
206 inline bool operator ==(const Matrix4x4& m) const {
207 return this->equals(m);
208 }
209
210 /**
211 * Non equality comparison operator
212 * @param m matrix to compare to
213 * @return non equality
214 */
215
216 inline bool operator !=(const Matrix4x4& m) const {
217 return this->equals(m) == false;
218 }
219
220 /**
221 * Get coordinate system axes
222 * @param xAxis x axis
223 * @param yAxis y axis
224 * @param zAxis z axis
225 * @return this matrix
226 */
227 inline void getAxes(Vector3& xAxis, Vector3& yAxis, Vector3& zAxis) const {
228 xAxis.set(data[0], data[1], data[2]);
229 yAxis.set(data[4], data[5], data[6]);
230 zAxis.set(data[8], data[9], data[10]);
231 }
232
233 /**
234 * Set coordinate system axes
235 * @param xAxis x axis
236 * @param yAxis y axis
237 * @param zAxis z axis
238 * @return this matrix
239 */
240 inline Matrix4x4& setAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis) {
241 data[0] = xAxis.data[0];
242 data[1] = xAxis.data[1];
243 data[2] = xAxis.data[2];
244 data[3] = 0.0f;
245 data[4] = yAxis.data[0];
246 data[5] = yAxis.data[1];
247 data[6] = yAxis.data[2];
248 data[7] = 0.0f;
249 data[8] = zAxis.data[0];
250 data[9] = zAxis.data[1];
251 data[10] = zAxis.data[2];
252 data[11] = 0.0f;
253 return *this;
254 }
255
256 /**
257 * Get translation
258 * @param translation translation
259 * @return this matrix
260 */
261 inline void getTranslation(Vector3& translation) const {
262 translation.set(data[12], data[13], data[14]);
263 }
264
265 /**
266 * Set translation
267 * @param translation translation
268 * @return this matrix
269 */
270 inline Matrix4x4& setTranslation(const Vector3& translation) {
271 data[12] = translation.data[0];
272 data[13] = translation.data[1];
273 data[14] = translation.data[2];
274 return *this;
275 }
276
277 /**
278 * Get scale
279 * @param scale scale
280 * @return this matrix
281 */
282 inline void getScale(Vector3& scale) const {
283 // x axis
284 scale.data[0] = Vector3(data[0], data[1], data[2]).computeLength();
285 // y axis
286 scale.data[1] = Vector3(data[4], data[5], data[6]).computeLength();
287 // z axis
288 scale.data[2] = Vector3(data[8], data[9], data[10]).computeLength();
289 }
290
291 /**
292 * Get scale
293 * @param scale scale
294 * @return this matrix
295 */
296 inline Matrix4x4& setScale(const Vector3& scale) {
297 Vector3 axisVector;
298 // x axis
299 axisVector.set(data[0], data[1], data[2]);
300 axisVector.normalize();
301 axisVector.scale(scale.data[0]);
302 data[0] = axisVector.data[0];
303 data[1] = axisVector.data[1];
304 data[2] = axisVector.data[2];
305 // y axis
306 axisVector.set(data[4], data[5], data[6]);
307 axisVector.normalize();
308 axisVector.scale(scale.data[1]);
309 data[4] = axisVector.data[0];
310 data[5] = axisVector.data[1];
311 data[6] = axisVector.data[2];
312 // z axis
313 axisVector.set(data[8], data[9], data[10]);
314 axisVector.normalize();
315 axisVector.scale(scale.data[2]);
316 data[8] = axisVector.data[0];
317 data[9] = axisVector.data[1];
318 data[10] = axisVector.data[2];
319 return *this;
320 }
321
322 /**
323 * Setup identity matrix
324 * @return this matrix
325 */
326 inline Matrix4x4& identity() {
327 data[0] = 1.0f;
328 data[1] = 0.0f;
329 data[2] = 0.0f;
330 data[3] = 0.0f;
331 data[4] = 0.0f;
332 data[5] = 1.0f;
333 data[6] = 0.0f;
334 data[7] = 0.0f;
335 data[8] = 0.0f;
336 data[9] = 0.0f;
337 data[10] = 1.0f;
338 data[11] = 0.0f;
339 data[12] = 0.0f;
340 data[13] = 0.0f;
341 data[14] = 0.0f;
342 data[15] = 1.0f;
343 return *this;
344 }
345
346 /**
347 * Multiplies a vector3 with this matrix into destination vector
348 * @param v vector 3
349 * @return resulting vector 3
350 */
351 inline Vector3 multiply(const Vector3& v) const {
352 return Vector3(
353 v.data[0] * data[0] + v.data[1] * data[4] + v.data[2] * data[8] + data[12],
354 v.data[0] * data[1] + v.data[1] * data[5] + v.data[2] * data[9] + data[13],
355 v.data[0] * data[2] + v.data[1] * data[6] + v.data[2] * data[10] + data[14]
356 );
357 }
358
359 /**
360 * Multiplies a vector3 with this matrix ignoring translation
361 * @param v vector 3
362 * @return resulting vector 3
363 */
364 inline Vector3 multiplyNoTranslation(const Vector3& v) const {
365 return Vector3(
366 v.data[0] * data[0] + v.data[1] * data[4] + v.data[2] * data[8],
367 v.data[0] * data[1] + v.data[1] * data[5] + v.data[2] * data[9],
368 v.data[0] * data[2] + v.data[1] * data[6] + v.data[2] * data[10]
369 );
370 }
371
372 /**
373 * Multiplies a vector4 with this matrix into destination vector
374 * @param v vector 4
375 * @return resulting vector 4
376 */
377 inline Vector4 multiply(const Vector4& v) const {
378 return Vector4(
379 v.data[0] * data[0] + v.data[1] * data[4] + v.data[2] * data[8] + v.data[3] * data[12],
380 v.data[0] * data[1] + v.data[1] * data[5] + v.data[2] * data[9] + v.data[3] * data[13],
381 v.data[0] * data[2] + v.data[1] * data[6] + v.data[2] * data[10] + v.data[3] * data[14],
382 v.data[0] * data[3] + v.data[1] * data[7] + v.data[2] * data[11] + v.data[3] * data[15]
383 );
384 }
385
386 /**
387 * Multiplies this matrix with another matrix
388 * @param m m
389 * @return this matrix
390 */
391 inline Matrix4x4& multiply(const Matrix4x4& m) {
392 array<float, 16> _data;
393 _data[0] = data[0] * m.data[0] + data[1] * m.data[4] + data[2] * m.data[8] + data[3] * m.data[12];
394 _data[1] = data[0] * m.data[1] + data[1] * m.data[5] + data[2] * m.data[9] + data[3] * m.data[13];
395 _data[2] = data[0] * m.data[2] + data[1] * m.data[6] + data[2] * m.data[10] + data[3] * m.data[14];
396 _data[3] = data[0] * m.data[3] + data[1] * m.data[7] + data[2] * m.data[11] + data[3] * m.data[15];
397 _data[4] = data[4] * m.data[0] + data[5] * m.data[4] + data[6] * m.data[8] + data[7] * m.data[12];
398 _data[5] = data[4] * m.data[1] + data[5] * m.data[5] + data[6] * m.data[9] + data[7] * m.data[13];
399 _data[6] = data[4] * m.data[2] + data[5] * m.data[6] + data[6] * m.data[10] + data[7] * m.data[14];
400 _data[7] = data[4] * m.data[3] + data[5] * m.data[7] + data[6] * m.data[11] + data[7] * m.data[15];
401 _data[8] = data[8] * m.data[0] + data[9] * m.data[4] + data[10] * m.data[8] + data[11] * m.data[12];
402 _data[9] = data[8] * m.data[1] + data[9] * m.data[5] + data[10] * m.data[9] + data[11] * m.data[13];
403 _data[10] = data[8] * m.data[2] + data[9] * m.data[6] + data[10] * m.data[10] + data[11] * m.data[14];
404 _data[11] = data[8] * m.data[3] + data[9] * m.data[7] + data[10] * m.data[11] + data[11] * m.data[15];
405 _data[12] = data[12] * m.data[0] + data[13] * m.data[4] + data[14] * m.data[8] + data[15] * m.data[12];
406 _data[13] = data[12] * m.data[1] + data[13] * m.data[5] + data[14] * m.data[9] + data[15] * m.data[13];
407 _data[14] = data[12] * m.data[2] + data[13] * m.data[6] + data[14] * m.data[10] + data[15] * m.data[14];
408 _data[15] = data[12] * m.data[3] + data[13] * m.data[7] + data[14] * m.data[11] + data[15] * m.data[15];
409 data = _data;
410 return *this;
411 }
412
413 /**
414 * Scales this matrix
415 * @param s s
416 * @returns this matrix
417 */
418 inline Matrix4x4& scale(float s) {
419 data[0] *= s;
420 data[1] *= s;
421 data[2] *= s;
422 data[3] *= s;
423 data[4] *= s;
424 data[5] *= s;
425 data[6] *= s;
426 data[7] *= s;
427 data[8] *= s;
428 data[9] *= s;
429 data[10] *= s;
430 data[11] *= s;
431 return *this;
432 }
433
434 /**
435 * Scales this matrix by given vector
436 * @param v v
437 * @return this matrix
438 */
439 inline Matrix4x4& scale(const Vector3& v) {
440 data[0] *= v.data[0];
441 data[1] *= v.data[0];
442 data[2] *= v.data[0];
443 data[3] *= v.data[0];
444 data[4] *= v.data[1];
445 data[5] *= v.data[1];
446 data[6] *= v.data[1];
447 data[7] *= v.data[1];
448 data[8] *= v.data[2];
449 data[9] *= v.data[2];
450 data[10] *= v.data[2];
451 data[11] *= v.data[2];
452 return *this;
453 }
454
455 /**
456 * Sets up a translation matrix
457 * @param v v
458 * @return this matrix
459 */
460 inline Matrix4x4& translate(const Vector3& v) {
461 data[12] += v.data[0] * data[0] + v.data[1] * data[4] + v.data[2] * data[8];
462 data[13] += v.data[0] * data[1] + v.data[1] * data[5] + v.data[2] * data[9];
463 data[14] += v.data[0] * data[2] + v.data[1] * data[6] + v.data[2] * data[10];
464 return *this;
465 }
466
467 /**
468 * Creates a rotation matrix
469 * @param axis axis
470 * @param angle angle
471 * @return this matrix
472 */
473 inline Matrix4x4& rotate(const Vector3& axis, float angle) {
474 // see: http://www.songho.ca/opengl/gl_matrix.html
475 auto& vXYZ = axis.getArray();
476 float c = Math::cos(angle * Math::DEG2RAD); // cosine
477 float s = Math::sin(angle * Math::DEG2RAD); // sine
478 float c1 = 1.0f - c; // 1 - c
479 float m0 = data[0], m4 = data[4], m8 = data[8], m12= data[12],
480 m1 = data[1], m5 = data[5], m9 = data[9], m13= data[13],
481 m2 = data[2], m6 = data[6], m10= data[10], m14= data[14];
482 float r0 = vXYZ[0] * vXYZ[0] * c1 + c;
483 float r1 = vXYZ[0] * vXYZ[1] * c1 + vXYZ[2] * s;
484 float r2 = vXYZ[0] * vXYZ[2] * c1 - vXYZ[1] * s;
485 float r4 = vXYZ[0] * vXYZ[1] * c1 - vXYZ[2] * s;
486 float r5 = vXYZ[1] * vXYZ[1] * c1 + c;
487 float r6 = vXYZ[1] * vXYZ[2] * c1 + vXYZ[0] * s;
488 float r8 = vXYZ[0] * vXYZ[2] * c1 + vXYZ[1] * s;
489 float r9 = vXYZ[1] * vXYZ[2] * c1 - vXYZ[0] * s;
490 float r10= vXYZ[2] * vXYZ[2] * c1 + c;
491 data[0] = r0 * m0 + r4 * m1 + r8 * m2;
492 data[1] = r1 * m0 + r5 * m1 + r9 * m2;
493 data[2] = r2 * m0 + r6 * m1 + r10* m2;
494 data[4] = r0 * m4 + r4 * m5 + r8 * m6;
495 data[5] = r1 * m4 + r5 * m5 + r9 * m6;
496 data[6] = r2 * m4 + r6 * m5 + r10* m6;
497 data[8] = r0 * m8 + r4 * m9 + r8 * m10;
498 data[9] = r1 * m8 + r5 * m9 + r9 * m10;
499 data[10]= r2 * m8 + r6 * m9 + r10* m10;
500 data[12]= r0 * m12+ r4 * m13+ r8 * m14;
501 data[13]= r1 * m12+ r5 * m13+ r9 * m14;
502 data[14]= r2 * m12+ r6 * m13+ r10* m14;
503 return *this;
504 }
505
506 /**
507 * Transposes this matrix
508 * @return this matrix
509 */
511 array <float, 16> _data;
512 _data[0] = data[0];
513 _data[1] = data[4];
514 _data[2] = data[8];
515 _data[3] = data[12];
516 _data[4] = data[1];
517 _data[5] = data[5];
518 _data[6] = data[9];
519 _data[7] = data[13];
520 _data[8] = data[2];
521 _data[9] = data[6];
522 _data[10] = data[10];
523 _data[11] = data[14];
524 _data[12] = data[3];
525 _data[13] = data[7];
526 _data[14] = data[11];
527 _data[15] = data[15];
528 data = _data;
529 return *this;
530 }
531
532 /**
533 * Inverts the matrix
534 * @return this matrix
535 */
536 inline Matrix4x4& invert() {
537 /*
538 Taken from MESA GLU implementation
539 Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
540 Permission is hereby granted, free of charge, to any person obtaining a
541 copy of this software and associated documentation files (the "Software"),
542 to deal in the Software without restriction, including without limitation
543 the rights to use, copy, modify, merge, publish, distribute, sublicense,
544 and/or sell copies of the Software, and to permit persons to whom the
545 Software is furnished to do so, subject to the following conditions:
546 The above copyright notice and this permission notice shall be included
547 in all copies or substantial portions of the Software.
548 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
549 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
550 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
551 BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
552 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
553 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
554 */
555 array <float, 16> _data;
556 _data[0] = data[5] * data[10] * data[15] - data[5] * data[11] * data[14] - data[9] * data[6] * data[15] + data[9] * data[7] * data[14] + data[13] * data[6] * data[11] - data[13] * data[7] * data[10];
557 _data[4] = -data[4] * data[10] * data[15] + data[4] * data[11] * data[14] + data[8] * data[6] * data[15] - data[8] * data[7] * data[14] - data[12] * data[6] * data[11] + data[12] * data[7] * data[10];
558 _data[8] = data[4] * data[9] * data[15] - data[4] * data[11] * data[13] - data[8] * data[5] * data[15] + data[8] * data[7] * data[13] + data[12] * data[5] * data[11] - data[12] * data[7] * data[9];
559 _data[12] = -data[4] * data[9] * data[14] + data[4] * data[10] * data[13] + data[8] * data[5] * data[14] - data[8] * data[6] * data[13] - data[12] * data[5] * data[10] + data[12] * data[6] * data[9];
560 _data[1] = -data[1] * data[10] * data[15] + data[1] * data[11] * data[14] + data[9] * data[2] * data[15] - data[9] * data[3] * data[14] - data[13] * data[2] * data[11] + data[13] * data[3] * data[10];
561 _data[5] = data[0] * data[10] * data[15] - data[0] * data[11] * data[14] - data[8] * data[2] * data[15] + data[8] * data[3] * data[14] + data[12] * data[2] * data[11] - data[12] * data[3] * data[10];
562 _data[9] = -data[0] * data[9] * data[15] + data[0] * data[11] * data[13] + data[8] * data[1] * data[15] - data[8] * data[3] * data[13] - data[12] * data[1] * data[11] + data[12] * data[3] * data[9];
563 _data[13] = data[0] * data[9] * data[14] - data[0] * data[10] * data[13] - data[8] * data[1] * data[14] + data[8] * data[2] * data[13] + data[12] * data[1] * data[10] - data[12] * data[2] * data[9];
564 _data[2] = data[1] * data[6] * data[15] - data[1] * data[7] * data[14] - data[5] * data[2] * data[15] + data[5] * data[3] * data[14] + data[13] * data[2] * data[7] - data[13] * data[3] * data[6];
565 _data[6] = -data[0] * data[6] * data[15] + data[0] * data[7] * data[14] + data[4] * data[2] * data[15] - data[4] * data[3] * data[14] - data[12] * data[2] * data[7] + data[12] * data[3] * data[6];
566 _data[10] = data[0] * data[5] * data[15] - data[0] * data[7] * data[13] - data[4] * data[1] * data[15] + data[4] * data[3] * data[13] + data[12] * data[1] * data[7] - data[12] * data[3] * data[5];
567 _data[14] = -data[0] * data[5] * data[14] + data[0] * data[6] * data[13] + data[4] * data[1] * data[14] - data[4] * data[2] * data[13] - data[12] * data[1] * data[6] + data[12] * data[2] * data[5];
568 _data[3] = -data[1] * data[6] * data[11] + data[1] * data[7] * data[10] + data[5] * data[2] * data[11] - data[5] * data[3] * data[10] - data[9] * data[2] * data[7] + data[9] * data[3] * data[6];
569 _data[7] = data[0] * data[6] * data[11] - data[0] * data[7] * data[10] - data[4] * data[2] * data[11] + data[4] * data[3] * data[10] + data[8] * data[2] * data[7] - data[8] * data[3] * data[6];
570 _data[11] = -data[0] * data[5] * data[11] + data[0] * data[7] * data[9] + data[4] * data[1] * data[11] - data[4] * data[3] * data[9] - data[8] * data[1] * data[7] + data[8] * data[3] * data[5];
571 _data[15] = data[0] * data[5] * data[10] - data[0] * data[6] * data[9] - data[4] * data[1] * data[10] + data[4] * data[2] * data[9] + data[8] * data[1] * data[6] - data[8] * data[2] * data[5];
572 auto determinant = data[0] * _data[0] + data[1] * _data[4] + data[2] * _data[8] + data[3] * _data[12];
573 if (determinant == 0.0f) {
574 identity();
575 return *this;
576 }
577 determinant = 1.0f / determinant;
578 for (auto i = 0; i < _data.size(); i++)
579 _data[i] = _data[i] * determinant;
580 data = _data;
581 return *this;
582 }
583
584 /**
585 * Returns if this matrix equals m
586 * @param m m
587 * @return equals
588 */
589 inline bool equals(const Matrix4x4& m) const {
590 return
591 (this == &m) ||
592 (
593 Math::abs(data[0] - m.data[0]) < Math::EPSILON &&
594 Math::abs(data[1] - m.data[1]) < Math::EPSILON &&
595 Math::abs(data[2] - m.data[2]) < Math::EPSILON &&
596 Math::abs(data[3] - m.data[3]) < Math::EPSILON &&
597 Math::abs(data[4] - m.data[4]) < Math::EPSILON &&
598 Math::abs(data[5] - m.data[5]) < Math::EPSILON &&
599 Math::abs(data[6] - m.data[6]) < Math::EPSILON &&
600 Math::abs(data[7] - m.data[7]) < Math::EPSILON &&
601 Math::abs(data[8] - m.data[8]) < Math::EPSILON &&
602 Math::abs(data[9] - m.data[9]) < Math::EPSILON &&
603 Math::abs(data[10] - m.data[10]) < Math::EPSILON &&
604 Math::abs(data[11] - m.data[11]) < Math::EPSILON &&
605 Math::abs(data[12] - m.data[12]) < Math::EPSILON &&
606 Math::abs(data[13] - m.data[13]) < Math::EPSILON &&
607 Math::abs(data[14] - m.data[14]) < Math::EPSILON &&
608 Math::abs(data[15] - m.data[15]) < Math::EPSILON
609 );
610 }
611
612 /**
613 * Returns array data
614 * @return array data
615 */
616 inline array<float, 16>& getArray() const {
617 return (array<float, 16>&)data;
618 }
619
620 /**
621 * Clones this matrix
622 * @return new cloned matrix
623 */
624 inline Matrix4x4 clone() {
625 Matrix4x4 clonedMatrix(*this);
626 return clonedMatrix;
627 }
628
629 /**
630 * Interpolates between matrix 1 and matrix 2 by 0f<=t<=1f linearly
631 * @param m1 matrix 1
632 * @param m2 matrix 2
633 * @param t t
634 * @return interpolated matrix
635 */
636 inline static Matrix4x4 interpolateLinear(const Matrix4x4& m1, const Matrix4x4& m2, float t) {
637 return Matrix4x4(
638 (m2.data[0] * t) + ((1.0f - t) * m1.data[0]),
639 (m2.data[1] * t) + ((1.0f - t) * m1.data[1]),
640 (m2.data[2] * t) + ((1.0f - t) * m1.data[2]),
641 (m2.data[3] * t) + ((1.0f - t) * m1.data[3]),
642 (m2.data[4] * t) + ((1.0f - t) * m1.data[4]),
643 (m2.data[5] * t) + ((1.0f - t) * m1.data[5]),
644 (m2.data[6] * t) + ((1.0f - t) * m1.data[6]),
645 (m2.data[7] * t) + ((1.0f - t) * m1.data[7]),
646 (m2.data[8] * t) + ((1.0f - t) * m1.data[8]),
647 (m2.data[9] * t) + ((1.0f - t) * m1.data[9]),
648 (m2.data[10] * t) + ((1.0f - t) * m1.data[10]),
649 (m2.data[11] * t) + ((1.0f - t) * m1.data[11]),
650 (m2.data[12] * t) + ((1.0f - t) * m1.data[12]),
651 (m2.data[13] * t) + ((1.0f - t) * m1.data[13]),
652 (m2.data[14] * t) + ((1.0f - t) * m1.data[14]),
653 (m2.data[15] * t) + ((1.0f - t) * m1.data[15])
654 );
655 }
656
657 /**
658 * Compute Euler angles (rotation around x, y, z axes)
659 * @return vector 3 containing euler angles
660 */
662 /*
663 see https://github.com/erich666/GraphicsGems/tree/master/gemsiv/euler_angle
664
665 This code repository predates the concept of Open Source, and predates most licenses along such lines.
666 As such, the official license truly is:
667 EULA: The Graphics Gems code is copyright-protected.
668 In other words, you cannot claim the text of the code as your own and resell it.
669 Using the code is permitted in any program, product, or library, non-commercial or commercial.
670 Giving credit is not required, though is a nice gesture.
671 The code comes as-is, and if there are any flaws or problems with any Gems code,
672 nobody involved with Gems - authors, editors, publishers, or webmasters - are to be held responsible.
673 Basically, don't be a jerk, and remember that anything free comes with no guarantee.
674 */
675 Vector3 euler;
676 auto axis0 = 0;
677 auto axis1 = 1;
678 auto axis2 = 2;
679 auto cy = static_cast<float>(Math::sqrt(data[axis0 + 4 * axis0] * data[axis0 + 4 * axis0] + data[axis1 + 4 * axis0] * data[axis1 + 4 * axis0]));
680 if (cy > 16.0f * Math::EPSILON) {
681 euler[0] = static_cast<float>((Math::atan2(data[axis2 + 4 * axis1], data[axis2 + 4 * axis2])));
682 euler[1] = static_cast<float>((Math::atan2(-data[axis2 + 4 * axis0], cy)));
683 euler[2] = static_cast<float>((Math::atan2(data[axis1 + 4 * axis0], data[axis0 + 4 * axis0])));
684 } else {
685 euler[0] = static_cast<float>((Math::atan2(-data[axis1 + 4 * axis2], data[axis1 + 4 * axis1])));
686 euler[1] = static_cast<float>((Math::atan2(-data[axis2 + 4 * axis0], cy)));
687 euler[2] = 0.0f;
688 }
689 euler.scale(static_cast<float>((180.0 / Math::PI)));
690 return euler;
691 }
692
693 /**
694 * Clones this matrix
695 * @return new cloned matrix
696 */
697 inline Matrix4x4 clone() const {
698 return Matrix4x4(data);
699 }
700
701};
Standard math functions.
Definition: Math.h:21
static float sqrt(float value)
Returns the square of given value.
Definition: Math.h:289
static float cos(float value)
Returns the cosine of an angle.
Definition: Math.h:165
static constexpr float EPSILON
Definition: Math.h:25
static int32_t abs(int32_t value)
Returns absolute value.
Definition: Math.h:91
static float atan2(float y, float x)
Returns the angle from the conversion of rectangular coordinates to polar coordinates.
Definition: Math.h:147
static constexpr float PI
Definition: Math.h:24
static constexpr float DEG2RAD
Definition: Math.h:26
static float sin(float value)
Returns the sine of an angle.
Definition: Math.h:280
4x4 3D Matrix class
Definition: Matrix4x4.h:24
Matrix4x4(const Matrix4x4 &matrix)
Public constructor.
Definition: Matrix4x4.h:48
Vector4 multiply(const Vector4 &v) const
Multiplies a vector4 with this matrix into destination vector.
Definition: Matrix4x4.h:377
Matrix4x4(const array< float, 16 > &m)
Public constructor.
Definition: Matrix4x4.h:40
Matrix4x4 clone() const
Clones this matrix.
Definition: Matrix4x4.h:697
Matrix4x4 & set(const array< float, 16 > &m)
Sets up this matrix by matrix m.
Definition: Matrix4x4.h:120
void getAxes(Vector3 &xAxis, Vector3 &yAxis, Vector3 &zAxis) const
Get coordinate system axes.
Definition: Matrix4x4.h:227
static Matrix4x4 interpolateLinear(const Matrix4x4 &m1, const Matrix4x4 &m2, float t)
Interpolates between matrix 1 and matrix 2 by 0f<=t<=1f linearly.
Definition: Matrix4x4.h:636
Matrix4x4 & multiply(const Matrix4x4 &m)
Multiplies this matrix with another matrix.
Definition: Matrix4x4.h:391
Vector3 computeEulerAngles() const
Compute Euler angles (rotation around x, y, z axes)
Definition: Matrix4x4.h:661
Matrix4x4()
Public constructor.
Definition: Matrix4x4.h:32
Matrix4x4 & identity()
Setup identity matrix.
Definition: Matrix4x4.h:326
Matrix4x4 & rotate(const Vector3 &axis, float angle)
Creates a rotation matrix.
Definition: Matrix4x4.h:473
Matrix4x4 & set(float r0c0, float r1c0, float r2c0, float r3c0, float r0c1, float r1c1, float r2c1, float r3c1, float r0c2, float r1c2, float r2c2, float r3c2, float r0c3, float r1c3, float r2c3, float r3c3)
Set up matrix by values.
Definition: Matrix4x4.h:95
Matrix4x4 & scale(const Vector3 &v)
Scales this matrix by given vector.
Definition: Matrix4x4.h:439
Matrix4x4 & transpose()
Transposes this matrix.
Definition: Matrix4x4.h:510
Matrix4x4 & setTranslation(const Vector3 &translation)
Set translation.
Definition: Matrix4x4.h:270
bool operator==(const Matrix4x4 &m) const
Equality comparison operator.
Definition: Matrix4x4.h:206
Matrix4x4 & setScale(const Vector3 &scale)
Get scale.
Definition: Matrix4x4.h:296
Matrix4x4(float r0c0, float r1c0, float r2c0, float r3c0, float r0c1, float r1c1, float r2c1, float r3c1, float r0c2, float r1c2, float r2c2, float r3c2, float r0c3, float r1c3, float r2c3, float r3c3)
Public constructor.
Definition: Matrix4x4.h:71
const float & operator[](int i) const
Const array access operator.
Definition: Matrix4x4.h:149
Matrix4x4 & operator*=(const Matrix4x4 m)
Definition: Matrix4x4.h:196
Vector3 multiplyNoTranslation(const Vector3 &v) const
Multiplies a vector3 with this matrix ignoring translation.
Definition: Matrix4x4.h:364
float & operator[](int i)
Array access operator.
Definition: Matrix4x4.h:140
void getScale(Vector3 &scale) const
Get scale.
Definition: Matrix4x4.h:282
Matrix4x4 & translate(const Vector3 &v)
Sets up a translation matrix.
Definition: Matrix4x4.h:460
Matrix4x4 operator*(const float f) const
Operator * (float)
Definition: Matrix4x4.h:158
Matrix4x4 clone()
Clones this matrix.
Definition: Matrix4x4.h:624
Matrix4x4 & invert()
Inverts the matrix.
Definition: Matrix4x4.h:536
Matrix4x4 & setAxes(const Vector3 &xAxis, const Vector3 &yAxis, const Vector3 &zAxis)
Set coordinate system axes.
Definition: Matrix4x4.h:240
void getTranslation(Vector3 &translation) const
Get translation.
Definition: Matrix4x4.h:261
Matrix4x4 & scale(float s)
Scales this matrix.
Definition: Matrix4x4.h:418
Matrix4x4 & set(const Matrix4x4 &m)
Sets up this matrix by matrix m.
Definition: Matrix4x4.h:130
Vector3 multiply(const Vector3 &v) const
Multiplies a vector3 with this matrix into destination vector.
Definition: Matrix4x4.h:351
array< float, 16 > & getArray() const
Returns array data.
Definition: Matrix4x4.h:616
bool equals(const Matrix4x4 &m) const
Returns if this matrix equals m.
Definition: Matrix4x4.h:589
bool operator!=(const Matrix4x4 &m) const
Non equality comparison operator.
Definition: Matrix4x4.h:216
array< float, 16 > data
Definition: Matrix4x4.h:26
3D vector 3 class
Definition: Vector3.h:22
float computeLength() const
Definition: Vector3.h:202
Vector3 & normalize()
Normalize the vector.
Definition: Vector3.h:288
Vector3 & set(float x, float y, float z)
Set up vector.
Definition: Vector3.h:73
array< float, 3 > data
Definition: Vector3.h:28
Vector3 & scale(float scale)
Scale this vector.
Definition: Vector3.h:349
array< float, 3 > & getArray() const
Definition: Vector3.h:171
3D vector 4 class
Definition: Vector4.h:19
array< float, 4 > data
Definition: Vector4.h:24