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