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