16 #ifndef MATHFU_MATRIX_H_
17 #define MATHFU_MATRIX_H_
43 #pragma warning(disable : 4127) // conditional expression is constant
44 #pragma warning(disable : 4789) // buffer overrun
45 #if _MSC_VER >= 1900 // MSVC 2015
46 #pragma warning(disable : 4456) // allow shadowing in unrolled loops
47 #pragma warning(disable : 4723) // suppress "potential divide by 0" warning
48 #endif // _MSC_VER >= 1900
53 #define MATHFU_VECTOR_STRIDE_FLOATS(vector) (sizeof(vector) / sizeof(float))
58 #define MATHFU_MAT_OPERATION(OP) MATHFU_UNROLLED_LOOP(i, columns, OP)
63 #define MATHFU_MAT_OPERATOR(OP) \
65 Matrix<T, rows, columns> result; \
66 MATHFU_MAT_OPERATION(result.data_[i] = (OP)); \
73 #define MATHFU_MAT_SELF_OPERATOR(OP) \
75 MATHFU_MAT_OPERATION(OP); \
83 #define MATHFU_MATRIX_4X4_DOT(data1, data2, r) \
84 ((data1)[r] * (data2)[0] + (data1)[(r) + 4] * (data2)[1] + \
85 (data1)[(r) + 8] * (data2)[2] + (data1)[(r) + 12] * (data2)[3])
89 #define MATHFU_MATRIX_3X3_DOT(data1, data2, r, size) \
90 ((data1)[r] * (data2)[0] + (data1)[(r) + (size)] * (data2)[1] + \
91 (data1)[(r) + 2 * (size)] * (data2)[2])
97 template <
class T,
int rows,
int columns = rows>
99 template <
class T,
int rows,
int columns>
100 inline Matrix<T, rows, columns> IdentityHelper();
101 template <
bool check_invertible,
class T,
int rows,
int columns>
102 inline bool InverseHelper(
const Matrix<T, rows, columns>& m,
103 Matrix<T, rows, columns>*
const inverse);
104 template <
class T,
int rows,
int columns>
105 inline void TimesHelper(
const Matrix<T, rows, columns>& m1,
106 const Matrix<T, rows, columns>& m2,
107 Matrix<T, rows, columns>* out_m);
108 template <
class T,
int rows,
int columns>
109 static inline Matrix<T, rows, columns> OuterProductHelper(
110 const Vector<T, rows>& v1,
const Vector<T, columns>& v2);
112 inline Matrix<T, 4, 4> PerspectiveHelper(T fovy, T aspect, T znear, T zfar,
115 static inline Matrix<T, 4, 4> OrthoHelper(T left, T right, T bottom, T top,
116 T znear, T zfar, T handedness);
118 static inline Matrix<T, 4, 4> LookAtHelper(
const Vector<T, 3>& at,
119 const Vector<T, 3>& eye,
120 const Vector<T, 3>& up,
123 static inline bool UnProjectHelper(
const Vector<T, 3>& window_coord,
124 const Matrix<T, 4, 4>& model_view,
125 const Matrix<T, 4, 4>& projection,
126 const float window_width,
127 const float window_height,
128 Vector<T, 3>& result);
130 template <
typename T,
int rows,
int columns,
typename CompatibleT>
131 static inline Matrix<T, rows, columns> FromTypeHelper(
const CompatibleT& compatible);
133 template <
typename T,
int rows,
int columns,
typename CompatibleT>
134 static inline CompatibleT ToTypeHelper(
const Matrix<T, rows, columns>& m);
146 template <
class T,
int rows,
int columns>
156 MATHFU_MAT_OPERATION(data_[i] = m.data_[i]);
174 inline Matrix(
const T& s00,
const T& s10,
const T& s01,
const T& s11) {
193 inline Matrix(
const T& s00,
const T& s10,
const T& s20,
const T& s01,
194 const T& s11,
const T& s21,
const T& s02,
const T& s12,
219 inline Matrix(
const T& s00,
const T& s10,
const T& s20,
const T& s30,
220 const T& s01,
const T& s11,
const T& s21,
const T& s31,
221 const T& s02,
const T& s12,
const T& s22,
const T& s32) {
248 inline Matrix(
const T& s00,
const T& s10,
const T& s20,
const T& s30,
249 const T& s01,
const T& s11,
const T& s21,
const T& s31,
250 const T& s02,
const T& s12,
const T& s22,
const T& s32,
251 const T& s03,
const T& s13,
const T& s23,
const T& s33) {
279 explicit inline Matrix(
const T*
const a) {
296 inline const T&
operator()(
const int row,
const int column)
const {
297 return data_[column][row];
306 return data_[column][row];
338 #if defined(MATHFU_COMPILE_WITH_PADDING)
342 const int row = i % rows;
343 const int col = i / rows;
344 return data_[col][row];
346 return reinterpret_cast<T*
>(data_)[i];
349 return reinterpret_cast<T*
>(data_)[i];
350 #endif // defined(MATHFU_COMPILE_WITH_PADDING)
358 MATHFU_MAT_OPERATION(GetColumn(i).
Pack(&vector[i]));
372 inline const Vector<T, rows>& GetColumn(
const int i)
const {
381 MATHFU_MAT_OPERATOR(-data_[i]);
390 MATHFU_MAT_OPERATOR(data_[i] + m.data_[i]);
399 MATHFU_MAT_OPERATOR(data_[i] - m.data_[i]);
407 MATHFU_MAT_OPERATOR(data_[i] + s);
415 MATHFU_MAT_OPERATOR(data_[i] - s);
423 MATHFU_MAT_OPERATOR(data_[i] * s);
431 return (*
this) * (1 / s);
441 TimesHelper(*
this, m, &result);
451 MATHFU_MAT_SELF_OPERATOR(data_[i] += m.data_[i]);
460 MATHFU_MAT_SELF_OPERATOR(data_[i] -= m.data_[i]);
468 MATHFU_MAT_SELF_OPERATOR(data_[i] += s);
476 MATHFU_MAT_SELF_OPERATOR(data_[i] -= s);
484 MATHFU_MAT_SELF_OPERATOR(data_[i] *= s);
492 return (*
this) *= (1 / s);
502 TimesHelper(copy_of_this, m,
this);
513 InverseHelper<false>(*
this, &inverse);
534 return InverseHelper<true>(*
this, inverse);
542 MATHFU_UNROLLED_LOOP(
543 i, columns, MATHFU_UNROLLED_LOOP(
544 j, rows, transpose.GetColumn(j)[i] = GetColumn(i)[j]))
565 return Vector<T, 3>(data_[3][0], data_[3][1], data_[3][2]);
584 template <
typename CompatibleT>
586 return FromTypeHelper<T, rows, columns, CompatibleT>(compatible);
601 template <
typename CompatibleT>
603 return ToTypeHelper<T, rows, columns, CompatibleT>(m);
611 return OuterProductHelper(v1, v2);
621 MATHFU_MAT_OPERATOR(m1[i] * m2[i]);
628 return IdentityHelper<T, rows, columns>();
648 return Matrix<T, 4>(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, v[0], v[1], v[2],
665 for (
int i = 0; i < rows - 1; ++i) return_matrix(i, i) = v[i];
666 return return_matrix;
676 return Matrix<T, 4>(m[0], m[1], m[2], 0, m[3], m[4], m[5], 0, m[6], m[7],
677 m[8], 0, 0, 0, 0, 1);
688 return Matrix<T, 3>(m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9],
698 return Matrix<T, 4>(affine[0], affine[4], affine[8],
static_cast<T
>(0),
699 affine[1], affine[5], affine[9], static_cast<T>(0),
700 affine[2], affine[6], affine[10],
static_cast<T
>(0),
701 affine[3], affine[7], affine[11], static_cast<T>(1));
712 return Matrix<T, 4, 3>(m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13],
713 m[2], m[6], m[10], m[14]);
722 return Matrix<T, 3>(1, 0, 0, 0, v.x, v.y, 0, -v.y, v.x);
731 return Matrix<T, 3>(v.x, 0, -v.y, 0, 1, 0, v.y, 0, v.x);
740 return Matrix<T, 3>(v.x, v.y, 0, -v.y, v.x, 0, 0, 0, 1);
780 return PerspectiveHelper(fovy, aspect, znear, zfar, handedness);
794 T zfar, T handedness = 1) {
795 return OrthoHelper(left, right, bottom, top, znear, zfar, handedness);
811 return LookAtHelper(at, eye, up, handedness);
828 const float window_width,
829 const float window_height) {
831 UnProjectHelper(window_coord, model_view, projection, window_width,
832 window_height, result);
843 const int d = columns;
875 template <
class T,
int rows,
int columns>
892 template <
class T,
int rows,
int columns>
897 for (
int column = 0; column < columns; column++) {
898 for (
int row = 0; row < rows; row++) {
899 result[row] += m[offset + row] * v[column];
909 return Vector<T, 2>(m[0] * v[0] + m[2] * v[1], m[1] * v[0] + m[3] * v[1]);
915 inline Vector<T, 3>
operator*(
const Matrix<T, 3, 3>& m,
const Vector<T, 3>& v) {
916 return Vector<T, 3>(MATHFU_MATRIX_3X3_DOT(&m[0], v, 0, 3),
917 MATHFU_MATRIX_3X3_DOT(&m[0], v, 1, 3),
918 MATHFU_MATRIX_3X3_DOT(&m[0], v, 2, 3));
924 inline Vector<float, 3>
operator*(
const Matrix<float, 3, 3>& m,
925 const Vector<float, 3>& v) {
926 return Vector<float, 3>(
927 MATHFU_MATRIX_3X3_DOT(&m[0], v, 0, MATHFU_VECTOR_STRIDE_FLOATS(v)),
928 MATHFU_MATRIX_3X3_DOT(&m[0], v, 1, MATHFU_VECTOR_STRIDE_FLOATS(v)),
929 MATHFU_MATRIX_3X3_DOT(&m[0], v, 2, MATHFU_VECTOR_STRIDE_FLOATS(v)));
935 inline Vector<T, 4>
operator*(
const Matrix<T, 4, 4>& m,
const Vector<T, 4>& v) {
937 MATHFU_MATRIX_4X4_DOT(&m[0], v, 0), MATHFU_MATRIX_4X4_DOT(&m[0], v, 1),
938 MATHFU_MATRIX_4X4_DOT(&m[0], v, 2), MATHFU_MATRIX_4X4_DOT(&m[0], v, 3));
956 return Vector<T, 3>(v4[0] / v4[3], v4[1] / v4[3], v4[2] / v4[3]);
974 template <
class T,
int size1,
int size2,
int size3>
978 for (
int i = 0; i < size1; i++) {
979 for (
int j = 0; j < size3; j++) {
981 for (
int k = 0; k < size2; k++) {
984 (*out_m)(i, j) = Vector<T, size2>::DotProduct(m2.GetColumn(j), row);
992 inline void TimesHelper(
const Matrix<T, 2, 2>& m1,
const Matrix<T, 2, 2>& m2,
993 Matrix<T, 2, 2>* out_m) {
994 Matrix<T, 2, 2>& out = *out_m;
995 out[0] = m1[0] * m2[0] + m1[2] * m2[1];
996 out[1] = m1[1] * m2[0] + m1[3] * m2[1];
997 out[2] = m1[0] * m2[2] + m1[2] * m2[3];
998 out[3] = m1[1] * m2[2] + m1[3] * m2[3];
1003 template <
typename T>
1004 inline void TimesHelper(
const Matrix<T, 3, 3>& m1,
const Matrix<T, 3, 3>& m2,
1005 Matrix<T, 3, 3>* out_m) {
1006 Matrix<T, 3, 3>& out = *out_m;
1008 Vector<T, 3> row(m1[0], m1[3], m1[6]);
1014 Vector<T, 3> row(m1[1], m1[4], m1[7]);
1020 Vector<T, 3> row(m1[2], m1[5], m1[8]);
1030 inline void TimesHelper(
const Matrix<T, 4, 4>& m1,
const Matrix<T, 4, 4>& m2,
1031 Matrix<T, 4, 4>* out_m) {
1032 Matrix<T, 4, 4>& out = *out_m;
1034 Vector<T, 4> row(m1[0], m1[4], m1[8], m1[12]);
1041 Vector<T, 4> row(m1[1], m1[5], m1[9], m1[13]);
1048 Vector<T, 4> row(m1[2], m1[6], m1[10], m1[14]);
1055 Vector<T, 4> row(m1[3], m1[7], m1[11], m1[15]);
1074 template <
class T,
int rows,
int columns>
1075 inline Matrix<T, rows, columns> IdentityHelper() {
1076 Matrix<T, rows, columns> return_matrix(0.f);
1077 int min_d = rows < columns ? rows : columns;
1078 for (
int i = 0; i < min_d; ++i) return_matrix(i, i) = 1;
1079 return return_matrix;
1085 inline Matrix<T, 2, 2> IdentityHelper() {
1086 return Matrix<T, 2, 2>(1, 0, 0, 1);
1092 inline Matrix<T, 3, 3> IdentityHelper() {
1093 return Matrix<T, 3, 3>(1, 0, 0, 0, 1, 0, 0, 0, 1);
1099 inline Matrix<T, 4, 4> IdentityHelper() {
1100 return Matrix<T, 4, 4>(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1109 template <
class T,
int rows,
int columns>
1110 static inline Matrix<T, rows, columns> OuterProductHelper(
1111 const Vector<T, rows>& v1,
const Vector<T, columns>& v2) {
1112 Matrix<T, rows, columns> result(0);
1114 for (
int column = 0; column < columns; column++) {
1115 for (
int row = 0; row < rows; row++) {
1116 result[row + offset] = v1[row] * v2[column];
1126 static inline Matrix<T, 2, 2> OuterProductHelper(
const Vector<T, 2>& v1,
1127 const Vector<T, 2>& v2) {
1128 return Matrix<T, 2, 2>(v1[0] * v2[0], v1[1] * v2[0], v1[0] * v2[1],
1135 static inline Matrix<T, 3, 3> OuterProductHelper(
const Vector<T, 3>& v1,
1136 const Vector<T, 3>& v2) {
1137 return Matrix<T, 3, 3>(v1[0] * v2[0], v1[1] * v2[0], v1[2] * v2[0],
1138 v1[0] * v2[1], v1[1] * v2[1], v1[2] * v2[1],
1139 v1[0] * v2[2], v1[1] * v2[2], v1[2] * v2[2]);
1145 static inline Matrix<T, 4, 4> OuterProductHelper(
const Vector<T, 4>& v1,
1146 const Vector<T, 4>& v2) {
1147 return Matrix<T, 4, 4>(
1148 v1[0] * v2[0], v1[1] * v2[0], v1[2] * v2[0], v1[3] * v2[0], v1[0] * v2[1],
1149 v1[1] * v2[1], v1[2] * v2[1], v1[3] * v2[1], v1[0] * v2[2], v1[1] * v2[2],
1150 v1[2] * v2[2], v1[3] * v2[2], v1[0] * v2[3], v1[1] * v2[3], v1[2] * v2[3],
1162 static T GetDeterminantThreshold() {
1172 class Constants<float> {
1191 class Constants<double> {
1217 template <
bool check_invertible,
class T,
int rows,
int columns>
1218 inline bool InverseHelper(
const Matrix<T, rows, columns>& m,
1219 Matrix<T, rows, columns>*
const inverse) {
1222 *inverse = T::Identity();
1228 template <
bool check_invertible,
class T>
1229 inline bool InverseHelper(
const Matrix<T, 2, 2>& m,
1230 Matrix<T, 2, 2>*
const inverse) {
1231 T determinant = m[0] * m[3] - m[1] * m[2];
1232 if (check_invertible &&
1233 fabs(determinant) < Constants<T>::GetDeterminantThreshold()) {
1236 T inverseDeterminant = 1 / determinant;
1237 (*inverse)[0] = inverseDeterminant * m[3];
1238 (*inverse)[1] = -inverseDeterminant * m[1];
1239 (*inverse)[2] = -inverseDeterminant * m[2];
1240 (*inverse)[3] = inverseDeterminant * m[0];
1246 template <
bool check_invertible,
class T>
1247 inline bool InverseHelper(
const Matrix<T, 3, 3>& m,
1248 Matrix<T, 3, 3>*
const inverse) {
1250 T sub11 = m[4] * m[8] - m[5] * m[7], sub12 = -m[1] * m[8] + m[2] * m[7],
1251 sub13 = m[1] * m[5] - m[2] * m[4];
1252 T determinant = m[0] * sub11 + m[3] * sub12 + m[6] * sub13;
1253 if (check_invertible &&
1254 fabs(determinant) < Constants<T>::GetDeterminantThreshold()) {
1258 *inverse = Matrix<T, 3, 3>(
1259 sub11, sub12, sub13, m[6] * m[5] - m[3] * m[8], m[0] * m[8] - m[6] * m[2],
1260 m[3] * m[2] - m[0] * m[5], m[3] * m[7] - m[6] * m[4],
1261 m[6] * m[1] - m[0] * m[7], m[0] * m[4] - m[3] * m[1]);
1262 *(inverse) *= 1 / determinant;
1269 inline int FindLargestPivotElem(
const Matrix<T, 4, 4>& m) {
1270 Vector<T, 4> fabs_column(fabs(m[0]), fabs(m[1]), fabs(m[2]), fabs(m[3]));
1271 if (fabs_column[0] > fabs_column[1]) {
1272 if (fabs_column[0] > fabs_column[2]) {
1273 if (fabs_column[0] > fabs_column[3]) {
1278 }
else if (fabs_column[2] > fabs_column[3]) {
1283 }
else if (fabs_column[1] > fabs_column[2]) {
1284 if (fabs_column[1] > fabs_column[3]) {
1289 }
else if (fabs_column[2] > fabs_column[3]) {
1298 template <
bool check_invertible,
class T>
1299 bool InverseHelper(
const Matrix<T, 4, 4>& m, Matrix<T, 4, 4>*
const inverse) {
1301 int pivot_elem = FindLargestPivotElem(m);
1304 Vector<T, 3> row, column;
1305 Matrix<T, 3> matrix;
1306 if (pivot_elem == 0) {
1307 row = Vector<T, 3>(m[4], m[8], m[12]);
1308 column = Vector<T, 3>(m[1], m[2], m[3]);
1310 Matrix<T, 3>(m[5], m[6], m[7], m[9], m[10], m[11], m[13], m[14], m[15]);
1311 }
else if (pivot_elem == 1) {
1312 row = Vector<T, 3>(m[5], m[9], m[13]);
1313 column = Vector<T, 3>(m[0], m[2], m[3]);
1315 Matrix<T, 3>(m[4], m[6], m[7], m[8], m[10], m[11], m[12], m[14], m[15]);
1316 }
else if (pivot_elem == 2) {
1317 row = Vector<T, 3>(m[6], m[10], m[14]);
1318 column = Vector<T, 3>(m[0], m[1], m[3]);
1320 Matrix<T, 3>(m[4], m[5], m[7], m[8], m[9], m[11], m[12], m[13], m[15]);
1322 row = Vector<T, 3>(m[7], m[11], m[15]);
1323 column = Vector<T, 3>(m[0], m[1], m[2]);
1325 Matrix<T, 3>(m[4], m[5], m[6], m[8], m[9], m[10], m[12], m[13], m[14]);
1327 T pivot_value = m[pivot_elem];
1328 if (check_invertible &&
1329 fabs(pivot_value) < Constants<T>::GetDeterminantThreshold()) {
1333 T inv = -1 / pivot_value;
1336 Matrix<T, 3> mat_inverse;
1337 if (!InverseHelper<check_invertible>(matrix, &mat_inverse) &&
1341 Vector<T, 3> col_inverse = mat_inverse * (column * inv);
1342 Vector<T, 3> row_inverse = row * mat_inverse;
1344 if (pivot_elem == 0) {
1345 *inverse = Matrix<T, 4, 4>(
1346 pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2],
1347 row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
1348 row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
1349 row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8]);
1350 }
else if (pivot_elem == 1) {
1351 *inverse = Matrix<T, 4, 4>(
1352 row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
1353 pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2],
1354 row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
1355 row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8]);
1356 }
else if (pivot_elem == 2) {
1357 *inverse = Matrix<T, 4, 4>(
1358 row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
1359 row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
1360 pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2],
1361 row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8]);
1363 *inverse = Matrix<T, 4, 4>(
1364 row_inverse[0], mat_inverse[0], mat_inverse[1], mat_inverse[2],
1365 row_inverse[1], mat_inverse[3], mat_inverse[4], mat_inverse[5],
1366 row_inverse[2], mat_inverse[6], mat_inverse[7], mat_inverse[8],
1367 pivot_inverse, col_inverse[0], col_inverse[1], col_inverse[2]);
1376 inline Matrix<T, 4, 4> PerspectiveHelper(T fovy, T aspect, T znear, T zfar,
1378 const T y = 1 / std::tan(fovy * static_cast<T>(.5));
1379 const T x = y / aspect;
1380 const T zdist = (znear - zfar);
1381 const T zfar_per_zdist = zfar / zdist;
1382 return Matrix<T, 4, 4>(x, 0, 0, 0, 0, y, 0, 0, 0, 0,
1383 zfar_per_zdist * handedness, -1 * handedness, 0, 0,
1384 2.0f * znear * zfar_per_zdist, 0);
1391 static inline Matrix<T, 4, 4> OrthoHelper(T left, T right, T bottom, T top,
1392 T znear, T zfar, T handedness) {
1393 return Matrix<T, 4, 4>(
static_cast<T
>(2) / (right - left), 0, 0, 0, 0,
1394 static_cast<T
>(2) / (top - bottom), 0, 0, 0, 0,
1395 -handedness *
static_cast<T
>(2) / (zfar - znear), 0,
1396 -(right + left) / (right - left),
1397 -(top + bottom) / (top - bottom),
1398 -(zfar + znear) / (zfar - znear),
static_cast<T
>(1));
1407 static void LookAtHelperCalculateAxes(
const Vector<T, 3>& at,
1408 const Vector<T, 3>& eye,
1409 const Vector<T, 3>& up, T handedness,
1410 Vector<T, 3>*
const axes) {
1412 axes[2] = (at - eye).Normalized();
1421 const T neg = -handedness;
1430 static inline Matrix<T, 4, 4> LookAtHelper(
const Vector<T, 3>& at,
1431 const Vector<T, 3>& eye,
1432 const Vector<T, 3>& up,
1434 Vector<T, 3> axes[4];
1435 LookAtHelperCalculateAxes(at, eye, up, handedness, axes);
1436 const Vector<T, 4> column0(axes[0][0], axes[1][0], axes[2][0], 0);
1437 const Vector<T, 4> column1(axes[0][1], axes[1][1], axes[2][1], 0);
1438 const Vector<T, 4> column2(axes[0][2], axes[1][2], axes[2][2], 0);
1439 const Vector<T, 4> column3(axes[3], 1);
1440 return Matrix<T, 4, 4>(column0, column1, column2, column3);
1447 static inline bool UnProjectHelper(
const Vector<T, 3>& window_coord,
1448 const Matrix<T, 4, 4>& model_view,
1449 const Matrix<T, 4, 4>& projection,
1450 const float window_width,
1451 const float window_height,
1452 Vector<T, 3>& result) {
1453 if (window_coord.z < static_cast<T>(0) ||
1454 window_coord.z > static_cast<T>(1)) {
1460 Matrix<T, 4, 4> matrix = (projection * model_view).Inverse();
1461 Vector<T, 4> standardized = Vector<T, 4>(
1462 static_cast<T
>(2) * (window_coord.x - window_width) / window_width +
1464 static_cast<T>(2) * (window_coord.y - window_height) / window_height +
1466 static_cast<T
>(2) * window_coord.z - static_cast<T>(1),
1469 Vector<T, 4> multiply = matrix * standardized;
1470 if (multiply.w == static_cast<T>(0)) {
1473 result = multiply.xyz() / multiply.w;
1479 template <
typename T,
int rows,
int columns,
typename CompatibleT>
1480 static inline Matrix<T, rows, columns> FromTypeHelper(
const CompatibleT& compatible) {
1482 #if __cplusplus >= 201103L
1484 union ConversionUnion {
1485 ConversionUnion() {}
1486 CompatibleT compatible;
1487 VectorPacked<T, rows> packed[columns];
1489 static_assert(
sizeof(u.compatible) ==
sizeof(u.packed),
"Conversion size mismatch.");
1493 u.compatible = compatible;
1496 return Matrix<T, rows, columns>(u.packed);
1506 Matrix<T, rows, columns> m;
1507 assert(
sizeof(m) ==
sizeof(compatible));
1508 memcpy(&m, &compatible,
sizeof(m));
1510 #endif // __cplusplus >= 201103L
1515 template <
typename T,
int rows,
int columns,
typename CompatibleT>
1516 static inline CompatibleT ToTypeHelper(
const Matrix<T, rows, columns>& m) {
1518 #if __cplusplus >= 201103L
1519 union ConversionUnion {
1520 ConversionUnion() {}
1521 CompatibleT compatible;
1522 VectorPacked<T, rows> packed[columns];
1524 static_assert(
sizeof(u.compatible) ==
sizeof(u.packed),
"Conversion size mismatch.");
1526 return u.compatible;
1528 CompatibleT compatible;
1529 assert(
sizeof(m) ==
sizeof(compatible));
1530 memcpy(&compatible, &m,
sizeof(compatible));
1532 #endif // __cplusplus >= 201103L
1547 #pragma warning(pop)
1552 #include "mathfu/matrix_4x4.h"
1554 #endif // MATHFU_MATRIX_H_
Matrix(const T &s00, const T &s10, const T &s20, const T &s01, const T &s11, const T &s21, const T &s02, const T &s12, const T &s22)
Create a Matrix from nine floats.
Definition: matrix.h:193
Definition: vector_3.h:24
T & operator()(const int row, const int column)
Access an element of the Matrix.
Definition: matrix.h:305
Matrix< T, rows, columns > Inverse() const
Calculate the inverse of this Matrix.
Definition: matrix.h:511
static Matrix< T, 3 > RotationX(T angle)
Create a 3x3 rotation Matrix from an angle (in radians) around the X axis.
Definition: matrix.h:748
Vector< T, 3 > TranslationVector3D() const
Get the 3-dimensional translation of a 3-dimensional affine transform.
Definition: matrix.h:563
static Matrix< T, 4, 4 > LookAt(const Vector< T, 3 > &at, const Vector< T, 3 > &eye, const Vector< T, 3 > &up, T handedness=-1)
Create a 3-dimensional camera Matrix.
Definition: matrix.h:807
Matrix()
Construct a Matrix of uninitialized values.
Definition: matrix.h:150
static Matrix< T, 3 > RotationZ(T angle)
Create a 3x3 rotation Matrix from an angle (in radians) around the Z axis.
Definition: matrix.h:766
static Matrix< T, 4 > FromAffineTransform(const Matrix< T, 4, 3 > &affine)
Constructs a Matrix<float, 4> from an AffineTransform.
Definition: matrix.h:696
static const int kElements
Total number of elements in the matrix.
Definition: matrix.h:853
Matrix< T, rows, columns > & operator*=(const T &s)
Multiply each element of this Matrix with a scalar (in-place).
Definition: matrix.h:483
Definition: vector_2.h:24
T & operator()(const int i)
Access an element of the Matrix.
Definition: matrix.h:321
Utility macros and functions.
Matrix< T, rows, columns > & operator*=(const Matrix< T, rows, columns > &m)
Multiply this Matrix with another Matrix (in-place).
Definition: matrix.h:499
Matrix(const T &s00, const T &s10, const T &s20, const T &s30, const T &s01, const T &s11, const T &s21, const T &s31, const T &s02, const T &s12, const T &s22, const T &s32, const T &s03, const T &s13, const T &s23, const T &s33)
Create a Matrix from sixteen floats.
Definition: matrix.h:248
static Matrix< T, 4, 4 > Ortho(T left, T right, T bottom, T top, T znear, T zfar, T handedness=1)
Create a 4x4 orthographic Matrix.
Definition: matrix.h:793
static float GetDeterminantThreshold()
Minimum absolute value of the determinant of an invertible float Matrix.
Definition: matrix.h:1186
bool InverseWithDeterminantCheck(Matrix< T, rows, columns > *const inverse) const
Calculate the inverse of this Matrix.
Definition: matrix.h:532
#define MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
Macro which defines the new and delete for MathFu classes.
Definition: utilities.h:600
static double GetDeterminantThreshold()
Minimum absolute value of the determinant of an invertible double Matrix.
Definition: matrix.h:1205
friend Vector< T, columns > operator*(const Vector< T, rows > &v, const Matrix< T, rows, columns > &m)
Multiply a Vector by a Matrix.
Definition: matrix.h:841
T & operator[](const int i)
Access an element of the Matrix.
Definition: matrix.h:337
static Matrix< T, 4 > FromRotationMatrix(const Matrix< T, 3 > &m)
Create a 4x4 Matrix from a 3x3 rotation Matrix.
Definition: matrix.h:675
static Matrix< T, rows > FromScaleVector(const Vector< T, rows-1 > &v)
Create a square Matrix with the diagonal component set to v.
Definition: matrix.h:659
static Vector< T, 3 > UnProject(const Vector< T, 3 > &window_coord, const Matrix< T, 4, 4 > &model_view, const Matrix< T, 4, 4 > &projection, const float window_width, const float window_height)
Get the 3D position in object space from a window coordinate.
Definition: matrix.h:825
Matrix< T, rows, columns > operator+(const Matrix< T, rows, columns > &m) const
Add a Matrix to this Matrix.
Definition: matrix.h:388
Matrix stores a set of "rows" by "columns" elements of type T and provides functions that operate on ...
Definition: matrix.h:147
#define MATHFU_STATIC_ASSERT(x)
Compile time assert for pre-C++11 compilers.
Definition: utilities.h:244
Matrix< T, rows, columns > & operator+=(const Matrix< T, rows, columns > &m)
Add a Matrix to this Matrix (in-place).
Definition: matrix.h:449
static Matrix< T, rows, columns > HadamardProduct(const Matrix< T, rows, columns > &m1, const Matrix< T, rows, columns > &m2)
Calculate the hadamard / component-wise product of two matrices.
Definition: matrix.h:619
static Matrix< T, rows, columns > OuterProduct(const Vector< T, rows > &v1, const Vector< T, columns > &v2)
Calculate the outer product of two Vectors.
Definition: matrix.h:609
Matrix< T, rows, columns > operator*(const T &s) const
Multiply each element of this Matrix with a scalar.
Definition: matrix.h:422
const T & operator()(const int row, const int column) const
Access an element of the matrix.
Definition: matrix.h:296
Matrix(const VectorPacked< T, rows > *const vectors)
Create a Matrix from an array of "columns", "rows" element packed vectors.
Definition: matrix.h:287
Matrix(const T &s00, const T &s10, const T &s20, const T &s30, const T &s01, const T &s11, const T &s21, const T &s31, const T &s02, const T &s12, const T &s22, const T &s32)
Creates a Matrix from twelve floats.
Definition: matrix.h:219
Matrix(const Vector< T, 4 > &column0, const Vector< T, 4 > &column1, const Vector< T, 4 > &column2, const Vector< T, 4 > &column3)
Create 4x4 Matrix from 4, 4 element vectors.
Definition: matrix.h:267
Matrix< T, rows, columns > operator*(const T &s, const Matrix< T, columns, rows > &m)
Multiply each element of a Matrix by a scalar.
Definition: matrix.h:876
static Matrix< T, 3 > RotationZ(const Vector< T, 2 > &v)
Create a 3x3 rotation Matrix from a 2D normalized directional Vector around the Z axis...
Definition: matrix.h:739
Vector< T, d > operator*(const Vector< T, d > &lhs, const Vector< T, d > &rhs)
Multiply a vector by another Vector.
Definition: vector.h:589
Vector< T, 2 > TranslationVector2D() const
Get the 2-dimensional translation of a 2-dimensional affine transform.
Definition: matrix.h:553
static Matrix< T, rows, columns > FromType(const CompatibleT &compatible)
Load from any byte-wise compatible external matrix.
Definition: matrix.h:585
const T & operator()(const int i) const
Access an element of the Matrix.
Definition: matrix.h:314
Definition: vector_4.h:25
static Matrix< T, 3 > RotationY(const Vector< T, 2 > &v)
Create a 3x3 rotation Matrix from a 2D normalized directional Vector around the Y axis...
Definition: matrix.h:730
Matrix< float, 4, 3 > AffineTransform
A typedef representing a 4x3 float affine transformation. Since the last row ('w' row) of an affine t...
Definition: matrix.h:1541
Matrix(const T &s00, const T &s10, const T &s01, const T &s11)
Construct a Matrix from four floats.
Definition: matrix.h:174
static T DotProduct(const Vector< T, d > &v1, const Vector< T, d > &v2)
Calculate the dot product of two vectors.
Definition: vector.h:426
static const int kColumns
Number of columns in the matrix.
Definition: matrix.h:851
Vector< T, 3 > operator*(const Matrix< T, 4, 4 > &m, const Vector< T, 3 > &v)
Multiply a 4x4 Matrix by a 3-dimensional Vector.
Definition: matrix.h:953
static Matrix< T, 4, 4 > Perspective(T fovy, T aspect, T znear, T zfar, T handedness=1)
Create a 4x4 perspective Matrix.
Definition: matrix.h:778
static CompatibleT ToType(const Matrix< T, rows, columns > &m)
Load into any byte-wise compatible external matrix.
Definition: matrix.h:602
static Matrix< T, 3 > RotationX(const Vector< T, 2 > &v)
Create a 3x3 rotation Matrix from a 2D normalized directional Vector around the X axis...
Definition: matrix.h:721
const T & operator[](const int i) const
Access an element of the Matrix.
Definition: matrix.h:328
static Matrix< T, 3 > ToRotationMatrix(const Matrix< T, 4 > &m)
Extracts the 3x3 rotation Matrix from a 4x4 Matrix.
Definition: matrix.h:687
Matrix(const T *const a)
Create a Matrix from the first row * column elements of an array.
Definition: matrix.h:279
Matrix< T, rows, columns > & operator-=(const Matrix< T, rows, columns > &m)
Subtract a Matrix from this Matrix (in-place).
Definition: matrix.h:458
Packed N-dimensional vector.
Definition: vector.h:121
Matrix< T, rows, columns > & operator-=(const T &s)
Subtract a scalar from each element of this Matrix (in-place).
Definition: matrix.h:475
Vector class and functions.
static Matrix< T, rows, columns > Identity()
Calculate the identity Matrix.
Definition: matrix.h:627
void Pack(VectorPacked< T, rows > *const vector) const
Pack the matrix to an array of "rows" element vectors, one vector per matrix column.
Definition: matrix.h:357
Matrix< T, rows, columns > & operator/=(const T &s)
Divide each element of this Matrix by a scalar (in-place).
Definition: matrix.h:491
Matrix< T, rows, columns > operator-() const
Negate this Matrix.
Definition: matrix.h:380
static Matrix< T, 4 > FromTranslationVector(const Vector< T, 3 > &v)
Create a 4x4 translation Matrix from a 3-dimensional Vector.
Definition: matrix.h:647
Matrix(const Matrix< T, rows, columns > &m)
Construct a Matrix from another Matrix copying each element. /.
Definition: matrix.h:155
Matrix< T, rows, columns > operator/(const T &s) const
Divide each element of this Matrix with a scalar.
Definition: matrix.h:430
static Matrix< T, 3 > FromTranslationVector(const Vector< T, 2 > &v)
Create a 3x3 translation Matrix from a 2-dimensional Vector.
Definition: matrix.h:637
Matrix< T, rows, columns > operator*(const Matrix< T, rows, columns > &m) const
Multiply this Matrix with another Matrix.
Definition: matrix.h:438
static Matrix< T, 4, 3 > ToAffineTransform(const Matrix< T, 4 > &m)
Converts a Matrix<float, 4> into an AffineTransform.
Definition: matrix.h:711
Vector< T, rows > operator*(const Matrix< T, rows, columns > &m, const Vector< T, columns > &v)
Multiply a Matrix by a Vector.
Definition: matrix.h:893
Matrix(const T &s)
Construct a Matrix from a single float.
Definition: matrix.h:162
static Vector< T, 3 > CrossProduct(const Vector< T, 3 > &v1, const Vector< T, 3 > &v2)
Calculate the cross product of two vectors.
Definition: vector.h:446
Matrix< T, rows, columns > operator+(const T &s) const
Add a scalar to each element of this Matrix.
Definition: matrix.h:406
Matrix< T, rows, columns > operator-(const Matrix< T, rows, columns > &m) const
Subtract a Matrix from this Matrix.
Definition: matrix.h:397
Matrix< T, columns, rows > Transpose() const
Calculate the transpose of this Matrix.
Definition: matrix.h:540
Matrix< T, rows, columns > operator-(const T &s) const
Subtract a scalar from each element of this Matrix.
Definition: matrix.h:414
static Matrix< T, 3 > RotationY(T angle)
Create a 3x3 rotation Matrix from an angle (in radians) around the Y axis.
Definition: matrix.h:757
Matrix< T, rows, columns > & operator+=(const T &s)
Add a scalar to each element of this Matrix (in-place).
Definition: matrix.h:467
static const int kRows
Number of rows in the matrix.
Definition: matrix.h:849