Pioneer
Loading...
Searching...
No Matches
matrix4x4.h
Go to the documentation of this file.
1// Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#ifndef _MATRIX4X4_H
5#define _MATRIX4X4_H
6
7#include "matrix3x3.h"
8#include "vector3.h"
9#include <math.h>
10#include <stdio.h>
11#include <cassert>
12#include <type_traits>
13
14template <typename T>
15class matrix4x4 {
16private:
17 T cell[16];
18 using other_float_t = typename std::conditional<std::is_same<T, float>::value, double, float>::type;
19
20public:
22 explicit matrix4x4(T val)
23 {
24 cell[0] = cell[1] = cell[2] = cell[3] = cell[4] = cell[5] = cell[6] =
25 cell[7] = cell[8] = cell[9] = cell[10] = cell[11] = cell[12] = cell[13] =
26 cell[14] = cell[15] = val;
27 }
28 explicit matrix4x4(const T *vals)
29 {
30 memcpy(cell, vals, sizeof(T) * 16);
31 }
33 {
35 }
36 matrix4x4(const matrix3x3<T> &m, const vector3<T> &v)
37 {
39 SetTranslate(v);
40 }
42 {
43 for (int i = 0; i < 16; i++)
44 cell[i] = T(m[i]);
45 }
46
47 void SetTranslate(const vector3<T> &v)
48 {
49 cell[12] = v.x;
50 cell[13] = v.y;
51 cell[14] = v.z;
52 }
53 vector3<T> GetTranslate() const { return vector3<T>(cell[12], cell[13], cell[14]); }
55 {
56 for (int i = 0; i < 12; i++)
57 cell[i] = m.cell[i];
58 }
60 {
62 m[0] = cell[0];
63 m[1] = cell[4];
64 m[2] = cell[8];
65 m[3] = cell[1];
66 m[4] = cell[5];
67 m[5] = cell[9];
68 m[6] = cell[2];
69 m[7] = cell[6];
70 m[8] = cell[10];
71 return m;
72 }
73 // row-major 3x3 matrix
74 void LoadFrom3x3Matrix(const T *r)
75 {
76 cell[0] = r[0];
77 cell[4] = r[1];
78 cell[8] = r[2];
79 cell[12] = 0;
80 cell[1] = r[3];
81 cell[5] = r[4];
82 cell[9] = r[5];
83 cell[13] = 0;
84 cell[2] = r[6];
85 cell[6] = r[7];
86 cell[10] = r[8];
87 cell[14] = 0;
88 cell[3] = 0;
89 cell[7] = 0;
90 cell[11] = 0;
91 cell[15] = 1;
92 }
93 // row-major
94 void SaveTo3x3Matrix(T *r) const
95 {
96 r[0] = cell[0];
97 r[1] = cell[4];
98 r[2] = cell[8];
99 r[3] = cell[1];
100 r[4] = cell[5];
101 r[5] = cell[9];
102 r[6] = cell[2];
103 r[7] = cell[6];
104 r[8] = cell[10];
105 }
107 {
108 matrix4x4 m = matrix4x4(0.0);
109 m.cell[0] = m.cell[5] = m.cell[10] = m.cell[15] = 1.0f;
110 return m;
111 }
112 //glscale equivalent
113 void Scale(T x, T y, T z)
114 {
115 *this = (*this) * ScaleMatrix(x, y, z);
116 }
117 void Scale(T s)
118 {
119 *this = (*this) * ScaleMatrix(s, s, s);
120 }
121 static matrix4x4 ScaleMatrix(T x, T y, T z)
122 {
123 matrix4x4 m;
124 m[0] = x;
125 m[1] = m[2] = m[3] = 0;
126 m[5] = y;
127 m[4] = m[6] = m[7] = 0;
128 m[10] = z;
129 m[8] = m[9] = m[11] = 0;
130 m[12] = m[13] = m[14] = 0;
131 m[15] = 1;
132 return m;
133 }
134 static matrix4x4 ScaleMatrix(T scale)
135 {
136 matrix4x4 m;
137 m[0] = scale;
138 m[1] = m[2] = m[3] = 0;
139 m[5] = scale;
140 m[4] = m[6] = m[7] = 0;
141 m[10] = scale;
142 m[8] = m[9] = m[11] = 0;
143 m[12] = m[13] = m[14] = 0;
144 m[15] = 1;
145 return m;
146 }
147 static matrix4x4 MakeRotMatrix(const vector3<T> &rx, const vector3<T> &ry, const vector3<T> &rz)
148 {
149 matrix4x4 m;
150 m[0] = rx.x;
151 m[4] = rx.y;
152 m[8] = rx.z;
153 m[12] = 0;
154 m[1] = ry.x;
155 m[5] = ry.y;
156 m[9] = ry.z;
157 m[13] = 0;
158 m[2] = rz.x;
159 m[6] = rz.y;
160 m[10] = rz.z;
161 m[14] = 0;
162 m[3] = 0;
163 m[7] = 0;
164 m[11] = 0;
165 m[15] = 1;
166 return m;
167 }
168 static matrix4x4 MakeInvRotMatrix(const vector3<T> &rx, const vector3<T> &ry, const vector3<T> &rz)
169 {
170 matrix4x4 m;
171 m[0] = rx.x;
172 m[4] = ry.x;
173 m[8] = rz.x;
174 m[12] = 0;
175 m[1] = rx.y;
176 m[5] = ry.y;
177 m[9] = rz.y;
178 m[13] = 0;
179 m[2] = rx.z;
180 m[6] = ry.z;
181 m[10] = rz.z;
182 m[14] = 0;
183 m[3] = 0;
184 m[7] = 0;
185 m[11] = 0;
186 m[15] = 1;
187 return m;
188 }
189
191 // Matrix Construction Functions
192 // NOTE: all matrix functions here are optimized for reverse-Z depth buffers.
193 // Compared to "standard" DirectX or OpenGL matricies they invert the Z value
194 // so it ranges from 1.0 at the near plane to 0.0 at the far plane.
196
197 // Construct a perspective projection matrix based on arbitrary left/right/top/bottom
198 // plane positions.
199 // This method is slower than the others, but supports view frustrums that are not
200 // aligned with the Z-axis. Unless you know what you're doing, you shouldn't use this.
201 //
202 // @param left - the minimum x-value of the view volume at the near plane
203 // @param right - the maximum x-value of the view volume at the near plane
204 // @param bottom - the maximum y-value of the view volume at the near plane
205 // @param top - the maximum y-value of the view volume at the near plane
206 // @param znear - the near clipping plane
207 // @param zfar - the far clipping plane
208 static matrix4x4 FrustumMatrix(T left, T right, T bottom, T top, T znear, T zfar)
209 {
210 assert((znear > T(0)) && (zfar > T(0)));
211 // these expressions come from the documentation for glFrustum
212 const T sx = (T(2) * znear) / (right - left);
213 const T sy = (T(2) * znear) / (top - bottom);
214 const T A = (right + left) / (right - left);
215 const T B = (top + bottom) / (top - bottom);
216 const T C = (zfar) / (zfar - znear) - 1;
217 const T D = (zfar * znear) / (zfar - znear);
218 matrix4x4 m;
219
220 // http://glprogramming.com/red/appendixf.html
221 // OpenGL 'Red Book' on Perspective Projection
222 // Presented here in row-major notation (because that's what matrix4x4f uses internally)
223 T perspective[16] = {
224 sx, 0, 0, 0,
225 0, sy, 0, 0,
226 A, B, C, -1,
227 0, 0, D, 0
228 };
229 return matrix4x4(&perspective[0]);
230 }
231
232 // Construct a perspective projection matrix based field of view and aspect ratio.
233 // This method is the optimized case when you know your screen aspect ratio and
234 // field of view and aren't interested in fancy math. Use this function or
235 // InfinitePerspectiveMatrix if at all possible.
236 //
237 // @param fovR - the camera FOV in radians
238 // @param aspect - the aspect ratio (width / height) of the viewport
239 // @param znear - the near clipping plane
240 // @param zfar - the far clipping plane
241 // @param fovX - whether the field of view is horizontal or vertical (default)
242 static matrix4x4 PerspectiveMatrix(T fovR, T aspect, T znear, T zfar, bool fovX = false)
243 {
244 assert((znear > T(0)) && (zfar > znear));
245
246 const T e = 1 / tan(fovR / T(2));
247 const T x = fovX ? e : e / aspect;
248 const T y = fovX ? e / aspect : e;
249 const T z = (znear) / (zfar - znear);
250 const T w = (zfar * znear) / (zfar - znear);
251
252 // Based on: http://www.terathon.com/gdc07_lengyel.pdf
253 // Unlike gluProject / FrustumMatrix, this projection matrix can only be
254 // symmetric about the Z axis.
255 // This is what you want in 99% of cases, and simplifies the math a good deal.
256 T perspective[16] = {
257 x, 0, 0, 0,
258 0, y, 0, 0,
259 0, 0, z, -1,
260 0, 0, w, 0
261 };
262
263 return matrix4x4(&perspective[0]);
264 }
265
266 // Construct an infinite far-plane perspective projection matrix.
267 // Unless you specifically want to clip objects beyond a specific distance,
268 // this projection will work for any object at any distance.
269 //
270 // @param fovR - the camera FOV in radians
271 // @param aspect - the aspect ratio (width / height) of the viewport
272 // @param znear - the near clipping plane
273 // @param fovX - whether the field of view is horizontal or vertical (default)
274 static matrix4x4 InfinitePerspectiveMatrix(T fovR, T aspect, T znear, bool fovX = false)
275 {
276 assert(znear > T(0));
277
278 const T e = 1 / tan(fovR / T(2));
279 const T x = fovX ? e : e / aspect;
280 const T y = fovX ? e / aspect : e;
281 const T w = znear;
282
283 // Based on: http://dev.theomader.com/depth-precision/
284 // An 'infinite far-plane' projection matrix. There is no concept of a zFar value,
285 // and it can handle everything up to and including homogeneous coordinates with w=0.
286 T perspective[16] = {
287 x, 0, 0, 0,
288 0, y, 0, 0,
289 0, 0, 0, -1,
290 0, 0, w, 0
291 };
292
293 return matrix4x4(&perspective[0]);
294 }
295
297 // set a orthographic frustum with 6 params similar to glOrtho()
298 // (left, right, bottom, top, near, far)
299 //
300 // Derived from:
301 // [1] https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixorthorh
302 // [2] https://thxforthefish.com/posts/reverse_z/
303 //
304 // Specifically, the `tz` and `c` terms are based on a right-handed DirectX-style
305 // (Z=0..1) matrix [1], multiplied by the given reversing matrix [2].
306 // If looking at the sources, keep in mind that [1] is presented in row-major order
307 // and [2] is presented in column-major order, and thus multiplication occurs in
308 // column-column fashion.
310 static matrix4x4 OrthoFrustum(T left, T right, T bottom, T top, T znear, T zfar)
311 {
312 assert((znear >= T(-1)) && (zfar >= T(0)));
313 T a = T(2) / (right - left);
314 T b = T(2) / (top - bottom);
315 T c = T(1) / (zfar - znear);
316
317 T tx = (right + left) / (left - right);
318 T ty = (top + bottom) / (bottom - top);
319 T tz = (zfar) / (zfar - znear);
320
321 T ortho[16] = {
322 a, 0, 0, 0,
323 0, b, 0, 0,
324 0, 0, c, 0,
325 tx, ty, tz, 1
326 };
327 matrix4x4 m(&ortho[0]);
328 return m;
329 }
330
331 // Optimized form that takes width/height and near/far planes
332 static matrix4x4 OrthoMatrix(T width, T height, T znear, T zfar)
333 {
334 assert((znear >= T(-1)) && (zfar > T(0)));
335 T a = T(2) / width;
336 T b = T(2) / height;
337 T c = T(1) / (zfar - znear);
338
339 T tz = (zfar) / (zfar - znear);
340
341 T ortho[16] = {
342 a, 0, 0, 0,
343 0, b, 0, 0,
344 0, 0, c, 0,
345 0, 0, tz, 1
346 };
347 matrix4x4 m(&ortho[0]);
348 return m;
349 }
350
351 //glRotate equivalent (except radians instead of degrees)
352 void Rotate(T ang, T x, T y, T z)
353 {
354 *this = (*this) * RotateMatrix(ang, x, y, z);
355 }
356 // (x,y,z) must be normalized
357 static matrix4x4 RotateMatrix(T ang, T x, T y, T z)
358 {
359 matrix4x4 m;
360 T c = cos(ang);
361 T s = sin(ang);
362 m[0] = x * x * (1 - c) + c;
363 m[1] = y * x * (1 - c) + z * s;
364 m[2] = x * z * (1 - c) - y * s;
365 m[3] = 0;
366 m[4] = x * y * (1 - c) - z * s;
367 m[5] = y * y * (1 - c) + c;
368 m[6] = y * z * (1 - c) + x * s;
369 m[7] = 0;
370 m[8] = x * z * (1 - c) + y * s;
371 m[9] = y * z * (1 - c) - x * s;
372 m[10] = z * z * (1 - c) + c;
373 m[11] = 0;
374 m[12] = 0;
375 m[13] = 0;
376 m[14] = 0;
377 m[15] = 1;
378 return m;
379 }
380 void RotateZ(T radians) { *this = (*this) * RotateZMatrix(radians); }
381 void RotateY(T radians) { *this = (*this) * RotateYMatrix(radians); }
382 void RotateX(T radians) { *this = (*this) * RotateXMatrix(radians); }
383 static matrix4x4 RotateXMatrix(T radians)
384 {
385 matrix4x4 m;
386 T cos_r = cosf(float(radians));
387 T sin_r = sinf(float(radians));
388 m[0] = 1.0f;
389 m[1] = 0;
390 m[2] = 0;
391 m[3] = 0;
392
393 m[4] = 0;
394 m[5] = cos_r;
395 m[6] = -sin_r;
396 m[7] = 0;
397
398 m[8] = 0;
399 m[9] = sin_r;
400 m[10] = cos_r;
401 m[11] = 0;
402
403 m[12] = 0;
404 m[13] = 0;
405 m[14] = 0;
406 m[15] = 1.0f;
407 return m;
408 }
409 static matrix4x4 RotateYMatrix(T radians)
410 {
411 matrix4x4 m;
412 T cos_r = cosf(float(radians));
413 T sin_r = sinf(float(radians));
414 m[0] = cos_r;
415 m[1] = 0;
416 m[2] = sin_r;
417 m[3] = 0;
418
419 m[4] = 0;
420 m[5] = 1;
421 m[6] = 0;
422 m[7] = 0;
423
424 m[8] = -sin_r;
425 m[9] = 0;
426 m[10] = cos_r;
427 m[11] = 0;
428
429 m[12] = 0;
430 m[13] = 0;
431 m[14] = 0;
432 m[15] = 1.0f;
433 return m;
434 }
435 static matrix4x4 RotateZMatrix(T radians)
436 {
437 matrix4x4 m;
438 T cos_r = cosf(float(radians));
439 T sin_r = sinf(float(radians));
440 m[0] = cos_r;
441 m[1] = -sin_r;
442 m[2] = 0;
443 m[3] = 0;
444
445 m[4] = sin_r;
446 m[5] = cos_r;
447 m[6] = 0;
448 m[7] = 0;
449
450 m[8] = 0;
451 m[9] = 0;
452 m[10] = 1.0f;
453 m[11] = 0;
454
455 m[12] = 0;
456 m[13] = 0;
457 m[14] = 0;
458 m[15] = 1.0f;
459 return m;
460 }
462 {
463 vector3<T> x(cell[0], cell[4], cell[8]);
464 vector3<T> y(cell[1], cell[5], cell[9]);
465 vector3<T> z(cell[2], cell[6], cell[10]);
466 x = x.Normalized();
467 z = x.Cross(y).Normalized();
468 y = z.Cross(x).Normalized();
469 cell[0] = x.x;
470 cell[4] = x.y;
471 cell[8] = x.z;
472 cell[1] = y.x;
473 cell[5] = y.y;
474 cell[9] = y.z;
475 cell[2] = z.x;
476 cell[6] = z.y;
477 cell[10] = z.z;
478 }
480 {
481 cell[12] = 0;
482 cell[13] = 0;
483 cell[14] = 0;
484 }
485 T &operator[](const size_t i) { return cell[i]; }
486 const T &operator[](const size_t i) const { return cell[i]; }
487 const T *Data() const { return cell; }
488 T *Data() { return cell; }
489 friend matrix4x4 operator+(const matrix4x4 &a, const matrix4x4 &b)
490 {
491 matrix4x4 m;
492 for (int i = 0; i < 16; i++)
493 m.cell[i] = a.cell[i] + b.cell[i];
494 return m;
495 }
496 friend matrix4x4 operator-(const matrix4x4 &a, const matrix4x4 &b)
497 {
498 matrix4x4 m;
499 for (int i = 0; i < 16; i++)
500 m.cell[i] = a.cell[i] - b.cell[i];
501 return m;
502 }
504 {
505 matrix4x4 m;
506 for (int i = 0; i < 16; ++i) {
507 m.cell[i] = -a.cell[i];
508 }
509 return m;
510 }
511 friend matrix4x4 operator*(const matrix4x4 &a, const matrix4x4 &b)
512 {
513 matrix4x4 m;
514 m.cell[0] = a.cell[0] * b.cell[0] + a.cell[4] * b.cell[1] + a.cell[8] * b.cell[2] + a.cell[12] * b.cell[3];
515 m.cell[1] = a.cell[1] * b.cell[0] + a.cell[5] * b.cell[1] + a.cell[9] * b.cell[2] + a.cell[13] * b.cell[3];
516 m.cell[2] = a.cell[2] * b.cell[0] + a.cell[6] * b.cell[1] + a.cell[10] * b.cell[2] + a.cell[14] * b.cell[3];
517 m.cell[3] = a.cell[3] * b.cell[0] + a.cell[7] * b.cell[1] + a.cell[11] * b.cell[2] + a.cell[15] * b.cell[3];
518
519 m.cell[4] = a.cell[0] * b.cell[4] + a.cell[4] * b.cell[5] + a.cell[8] * b.cell[6] + a.cell[12] * b.cell[7];
520 m.cell[5] = a.cell[1] * b.cell[4] + a.cell[5] * b.cell[5] + a.cell[9] * b.cell[6] + a.cell[13] * b.cell[7];
521 m.cell[6] = a.cell[2] * b.cell[4] + a.cell[6] * b.cell[5] + a.cell[10] * b.cell[6] + a.cell[14] * b.cell[7];
522 m.cell[7] = a.cell[3] * b.cell[4] + a.cell[7] * b.cell[5] + a.cell[11] * b.cell[6] + a.cell[15] * b.cell[7];
523
524 m.cell[8] = a.cell[0] * b.cell[8] + a.cell[4] * b.cell[9] + a.cell[8] * b.cell[10] + a.cell[12] * b.cell[11];
525 m.cell[9] = a.cell[1] * b.cell[8] + a.cell[5] * b.cell[9] + a.cell[9] * b.cell[10] + a.cell[13] * b.cell[11];
526 m.cell[10] = a.cell[2] * b.cell[8] + a.cell[6] * b.cell[9] + a.cell[10] * b.cell[10] + a.cell[14] * b.cell[11];
527 m.cell[11] = a.cell[3] * b.cell[8] + a.cell[7] * b.cell[9] + a.cell[11] * b.cell[10] + a.cell[15] * b.cell[11];
528
529 m.cell[12] = a.cell[0] * b.cell[12] + a.cell[4] * b.cell[13] + a.cell[8] * b.cell[14] + a.cell[12] * b.cell[15];
530 m.cell[13] = a.cell[1] * b.cell[12] + a.cell[5] * b.cell[13] + a.cell[9] * b.cell[14] + a.cell[13] * b.cell[15];
531 m.cell[14] = a.cell[2] * b.cell[12] + a.cell[6] * b.cell[13] + a.cell[10] * b.cell[14] + a.cell[14] * b.cell[15];
532 m.cell[15] = a.cell[3] * b.cell[12] + a.cell[7] * b.cell[13] + a.cell[11] * b.cell[14] + a.cell[15] * b.cell[15];
533 return m;
534 }
535 friend vector3<T> operator*(const matrix4x4 &a, const vector3<T> &v)
536 {
537 vector3<T> out;
538 out.x = a.cell[0] * v.x + a.cell[4] * v.y + a.cell[8] * v.z + a.cell[12];
539 out.y = a.cell[1] * v.x + a.cell[5] * v.y + a.cell[9] * v.z + a.cell[13];
540 out.z = a.cell[2] * v.x + a.cell[6] * v.y + a.cell[10] * v.z + a.cell[14];
541 return out;
542 }
543 // scam for doing a transpose operation
544 friend vector3<T> operator*(const vector3<T> &v, const matrix4x4 &a)
545 {
546 vector3<T> out;
547 out.x = a.cell[0] * v.x + a.cell[1] * v.y + a.cell[2] * v.z;
548 out.y = a.cell[4] * v.x + a.cell[5] * v.y + a.cell[6] * v.z;
549 out.z = a.cell[8] * v.x + a.cell[9] * v.y + a.cell[10] * v.z;
550 return out;
551 }
552
553 // Transform a vector by the affine inverse of a matrix4x4
554 // internally this does a transpose operation, and thus only works on
555 // Euclidean (translation + rotation) matricies.
557 {
558 // Formula derivation from songho (https://songho.ca/opengl):
559 //
560 // M = [ R | T ]
561 // [ --+-- ] (R denotes 3x3 rotation/reflection matrix)
562 // [ 0 | 1 ] (T denotes 1x3 translation matrix)
563 //
564 // y = M*x -> y = R*x + T -> x = R^-1*(y - T) -> x = R^T*y - R^T*T
565 // (R is orthogonal, R^-1 = R^T)
566
567 // thanks to https://stackoverflow.com/a/2625420
568 // "Depending on your situation, it may be faster to compute the result of
569 // inv(A) * x instead of actually forming inv(A)..."
570 //
571 // inv(A) * [x] = [ inv(M) * (x - b) ]
572 // [1] = [ 1 ]
573 //
574
575 vector3<T> v = inVec - GetTranslate();
576 vector3<T> out;
577 out.x = cell[0] * v.x + cell[1] * v.y + cell[2] * v.z;
578 out.y = cell[4] * v.x + cell[5] * v.y + cell[6] * v.z;
579 out.z = cell[8] * v.x + cell[9] * v.y + cell[10] * v.z;
580 return out;
581 }
582
583 friend matrix4x4 operator*(const matrix4x4 &a, T v)
584 {
585 matrix4x4 m;
586 for (int i = 0; i < 16; i++)
587 m[i] = a.cell[i] * v;
588 return m;
589 }
590 friend matrix4x4 operator*(T v, const matrix4x4 &a)
591 {
592 return (a * v);
593 }
595 {
596 vector3<T> out;
597 out.x = cell[0] * v.x + cell[4] * v.y + cell[8] * v.z;
598 out.y = cell[1] * v.x + cell[5] * v.y + cell[9] * v.z;
599 out.z = cell[2] * v.x + cell[6] * v.y + cell[10] * v.z;
600 return out;
601 }
602 //gltranslate equivalent
603 void Translate(const vector3<T> &t)
604 {
605 Translate(t.x, t.y, t.z);
606 }
607 void Translate(T x, T y, T z)
608 {
609 matrix4x4 m = Identity();
610 m[12] = x;
611 m[13] = y;
612 m[14] = z;
613 *this = (*this) * m;
614 }
616 {
617 return Translation(v.x, v.y, v.z);
618 }
619 static matrix4x4 Translation(T x, T y, T z)
620 {
621 matrix4x4 m = Identity();
622 m[12] = x;
623 m[13] = y;
624 m[14] = z;
625 return m;
626 }
628 {
629 matrix4x4 m;
630 // this only works for matrices containing only rotation and transform
631 m[0] = cell[0];
632 m[1] = cell[4];
633 m[2] = cell[8];
634 m[4] = cell[1];
635 m[5] = cell[5];
636 m[6] = cell[9];
637 m[8] = cell[2];
638 m[9] = cell[6];
639 m[10] = cell[10];
640 m[12] = -(cell[0] * cell[12] + cell[1] * cell[13] + cell[2] * cell[14]);
641 m[13] = -(cell[4] * cell[12] + cell[5] * cell[13] + cell[6] * cell[14]);
642 m[14] = -(cell[8] * cell[12] + cell[9] * cell[13] + cell[10] * cell[14]);
643 m[3] = m[7] = m[11] = 0;
644 m[15] = 1.0f;
645
646 return m;
647 }
649 {
650 matrix4x4 m;
651 m[0] = cell[0];
652 m[1] = cell[4];
653 m[2] = cell[8];
654 m[3] = cell[12];
655 m[4] = cell[1];
656 m[5] = cell[5];
657 m[6] = cell[9];
658 m[7] = cell[13];
659 m[8] = cell[2];
660 m[9] = cell[6];
661 m[10] = cell[10];
662 m[11] = cell[14];
663 m[12] = cell[3];
664 m[13] = cell[7];
665 m[14] = cell[11];
666 m[15] = cell[15];
667 return m;
668 }
669 void Print() const
670 {
671 for (int i = 0; i < 4; i++) {
672 printf("%.12f %.12f %.12f %.12f\n", cell[i], cell[i + 4], cell[i + 8], cell[i + 12]);
673 }
674 printf("\n");
675 }
676
677 //convenience accessors for getting right/up/back vectors
678 //from rotation matrices
680 {
681 return vector3<T>(cell[0], cell[4], cell[8]);
682 }
683
685 {
686 return vector3<T>(cell[1], cell[5], cell[9]);
687 }
688
690 {
691 return vector3<T>(cell[2], cell[6], cell[10]);
692 }
693};
694
697
698static const matrix4x4f matrix4x4fIdentity(matrix4x4f::Identity());
699static const matrix4x4d matrix4x4dIdentity(matrix4x4d::Identity());
700
701#endif /* _MATRIX4X4_H */
double val
Definition PrecalcPath.cpp:40
Definition matrix3x3.h:13
const T * Data() const
Definition matrix3x3.h:38
Definition matrix4x4.h:15
void Translate(const vector3< T > &t)
Definition matrix4x4.h:603
static matrix4x4 OrthoFrustum(T left, T right, T bottom, T top, T znear, T zfar)
Definition matrix4x4.h:310
static matrix4x4 Translation(const vector3< T > &v)
Definition matrix4x4.h:615
static matrix4x4 FrustumMatrix(T left, T right, T bottom, T top, T znear, T zfar)
Definition matrix4x4.h:208
matrix4x4 Inverse() const
Definition matrix4x4.h:627
const T * Data() const
Definition matrix4x4.h:487
matrix4x4()
Definition matrix4x4.h:21
static matrix4x4 PerspectiveMatrix(T fovR, T aspect, T znear, T zfar, bool fovX=false)
Definition matrix4x4.h:242
static matrix4x4 ScaleMatrix(T scale)
Definition matrix4x4.h:134
friend vector3< T > operator*(const vector3< T > &v, const matrix4x4 &a)
Definition matrix4x4.h:544
vector3< T > Back() const
Definition matrix4x4.h:689
static matrix4x4 RotateXMatrix(T radians)
Definition matrix4x4.h:383
void SaveTo3x3Matrix(T *r) const
Definition matrix4x4.h:94
matrix4x4 Transpose() const
Definition matrix4x4.h:648
matrix3x3< T > GetOrient() const
Definition matrix4x4.h:59
friend matrix4x4 operator-(const matrix4x4 &a, const matrix4x4 &b)
Definition matrix4x4.h:496
void Rotate(T ang, T x, T y, T z)
Definition matrix4x4.h:352
static matrix4x4 Translation(T x, T y, T z)
Definition matrix4x4.h:619
vector3< T > Right() const
Definition matrix4x4.h:679
void RotateZ(T radians)
Definition matrix4x4.h:380
T & operator[](const size_t i)
Definition matrix4x4.h:485
void RotateX(T radians)
Definition matrix4x4.h:382
vector3< T > Up() const
Definition matrix4x4.h:684
matrix4x4(const matrix3x3< T > &m, const vector3< T > &v)
Definition matrix4x4.h:36
vector3< T > GetTranslate() const
Definition matrix4x4.h:53
void ClearToRotOnly()
Definition matrix4x4.h:479
void Renormalize()
Definition matrix4x4.h:461
void Scale(T s)
Definition matrix4x4.h:117
T * Data()
Definition matrix4x4.h:488
void RotateY(T radians)
Definition matrix4x4.h:381
static matrix4x4 InfinitePerspectiveMatrix(T fovR, T aspect, T znear, bool fovX=false)
Definition matrix4x4.h:274
static matrix4x4 RotateZMatrix(T radians)
Definition matrix4x4.h:435
friend matrix4x4 operator*(const matrix4x4 &a, T v)
Definition matrix4x4.h:583
friend matrix4x4 operator+(const matrix4x4 &a, const matrix4x4 &b)
Definition matrix4x4.h:489
void LoadFrom3x3Matrix(const T *r)
Definition matrix4x4.h:74
void Translate(T x, T y, T z)
Definition matrix4x4.h:607
friend vector3< T > operator*(const matrix4x4 &a, const vector3< T > &v)
Definition matrix4x4.h:535
void SetRotationOnly(const matrix4x4 &m)
Definition matrix4x4.h:54
static matrix4x4 MakeRotMatrix(const vector3< T > &rx, const vector3< T > &ry, const vector3< T > &rz)
Definition matrix4x4.h:147
static matrix4x4 RotateMatrix(T ang, T x, T y, T z)
Definition matrix4x4.h:357
static matrix4x4 ScaleMatrix(T x, T y, T z)
Definition matrix4x4.h:121
matrix4x4(T val)
Definition matrix4x4.h:22
void SetTranslate(const vector3< T > &v)
Definition matrix4x4.h:47
static matrix4x4 Identity()
Definition matrix4x4.h:106
friend matrix4x4 operator-(const matrix4x4 &a)
Definition matrix4x4.h:503
static matrix4x4 OrthoMatrix(T width, T height, T znear, T zfar)
Definition matrix4x4.h:332
static matrix4x4 RotateYMatrix(T radians)
Definition matrix4x4.h:409
void Print() const
Definition matrix4x4.h:669
void Scale(T x, T y, T z)
Definition matrix4x4.h:113
friend matrix4x4 operator*(T v, const matrix4x4 &a)
Definition matrix4x4.h:590
const T & operator[](const size_t i) const
Definition matrix4x4.h:486
matrix4x4(const matrix3x3< T > &m)
Definition matrix4x4.h:32
friend matrix4x4 operator*(const matrix4x4 &a, const matrix4x4 &b)
Definition matrix4x4.h:511
vector3< T > InvTransform(const vector3< T > &inVec)
Definition matrix4x4.h:556
matrix4x4(const matrix4x4< other_float_t > &m)
Definition matrix4x4.h:41
vector3< T > ApplyRotationOnly(const vector3< T > &v) const
Definition matrix4x4.h:594
matrix4x4(const T *vals)
Definition matrix4x4.h:28
static matrix4x4 MakeInvRotMatrix(const vector3< T > &rx, const vector3< T > &ry, const vector3< T > &rz)
Definition matrix4x4.h:168
Definition vector3.h:16
T y
Definition vector3.h:18
T x
Definition vector3.h:18
T z
Definition vector3.h:18
vector3 Normalized() const
Definition vector3.h:125
vector3 Cross(const vector3 &b) const
Definition vector3.h:117
matrix4x4< double > matrix4x4d
Definition matrix4x4.h:696
matrix4x4< float > matrix4x4f
Definition matrix4x4.h:695
Definition msvc_bug.cpp:33