mat4.h
1 /*
2 ** UICore
3 ** Copyright (c) 1997-2015 The UICore Team
4 **
5 ** This software is provided 'as-is', without any express or implied
6 ** warranty. In no event will the authors be held liable for any damages
7 ** arising from the use of this software.
8 **
9 ** Permission is granted to anyone to use this software for any purpose,
10 ** including commercial applications, and to alter it and redistribute it
11 ** freely, subject to the following restrictions:
12 **
13 ** 1. The origin of this software must not be misrepresented; you must not
14 ** claim that you wrote the original software. If you use this software
15 ** in a product, an acknowledgment in the product documentation would be
16 ** appreciated but is not required.
17 ** 2. Altered source versions must be plainly marked as such, and must not be
18 ** misrepresented as being the original software.
19 ** 3. This notice may not be removed or altered from any source distribution.
20 **
21 ** Note: Some of the libraries UICore may link to may have additional
22 ** requirements or restrictions.
23 **
24 ** File Author(s):
25 **
26 ** Magnus Norddahl
27 ** Mark Page
28 ** Harry Storbacka
29 */
30 
31 #pragma once
32 
33 #include <cstdint>
34 #include "mat2.h"
35 #include "mat3.h"
36 #include "vec3.h"
37 #include "angle.h"
38 
39 namespace uicore
40 {
42  {
45  };
46 
48  {
49  clip_negative_positive_w, // OpenGL, -wclip <= zclip <= wclip
50  clip_zero_positive_w // Direct3D, 0 <= zclip <= wclip
51  };
52 
53  template<typename Type>
54  class Mat2;
55 
56  template<typename Type>
57  class Mat3;
58 
59  template<typename Type>
60  class Mat4;
61 
62  template<typename Type>
63  class Vec3;
64 
65  template<typename Type>
66  class Quaternionx;
67 
71  template<typename Type>
72  class Mat4
73  {
74  public:
76  Mat4()
77  {
78  for (auto & elem : matrix)
79  elem = 0;
80  }
81 
83  Mat4(const Mat4<Type> &copy)
84  {
85  for (int i = 0; i < 16; i++)
86  matrix[i] = copy.matrix[i];
87  }
88 
90  explicit Mat4(const Mat2<Type> &copy);
91 
93  explicit Mat4(const Mat3<Type> &copy);
94 
96  explicit Mat4(const float *init_matrix)
97  {
98  for (int i = 0; i < 16; i++)
99  matrix[i] = (Type)init_matrix[i];
100  }
101 
103  explicit Mat4(const double *init_matrix)
104  {
105  for (int i = 0; i < 16; i++)
106  matrix[i] = (Type)init_matrix[i];
107  }
108 
110  explicit Mat4(const int64_t *init_matrix)
111  {
112  for (int i = 0; i < 16; i++)
113  matrix[i] = (Type)init_matrix[i];
114  }
115 
117  explicit Mat4(const int32_t *init_matrix)
118  {
119  for (int i = 0; i < 16; i++)
120  matrix[i] = (Type)init_matrix[i];
121  }
122 
124  explicit Mat4(const int16_t *init_matrix)
125  {
126  for (int i = 0; i < 16; i++)
127  matrix[i] = (Type)init_matrix[i];
128  }
129 
131  explicit Mat4(const int8_t *init_matrix)
132  {
133  for (int i = 0; i < 16; i++)
134  matrix[i] = (Type)init_matrix[i];
135  }
136 
140  static Mat4<Type> null();
141 
144  static Mat4<Type> identity();
145 
150  static Mat4<Type> frustum(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
151 
156  static Mat4<Type> perspective(
157  Type field_of_view_y_degrees,
158  Type aspect,
159  Type z_near,
160  Type z_far,
161  Handedness handedness,
162  ClipZRange clip_z);
163 
168  static Mat4<Type> ortho(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
169 
174  static Mat4<Type> ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z);
175 
185  static Mat4<Type> rotate(Type angle, Type x, Type y, Type z, bool normalize = true);
186 
194  static Mat4<Type> rotate(Type angle, Vec3<Type> rotation, bool normalize = true)
195  {
196  return rotate(angle, rotation.x, rotation.y, rotation.z, normalize);
197  }
198 
204  static Mat4<Type> rotate(Type angle_x, Type angle_y, Type angle_z, EulerOrder order);
205 
212  static Mat4<Type> scale(Type x, Type y, Type z);
213 
219  {
220  return scale(xyz.x, xyz.y, xyz.z);
221  }
222 
230  static Mat4<Type> translate(Type x, Type y, Type z);
231 
238  {
239  return translate(xyz.x, xyz.y, xyz.z);
240  }
241 
255  static Mat4<Type> look_at(
256  Type eye_x, Type eye_y, Type eye_z,
257  Type center_x, Type center_y, Type center_z,
258  Type up_x, Type up_y, Type up_z);
259 
268  Vec3<Type> eye,
270  Vec3<Type> up)
271  {
272  return look_at(eye.x, eye.y, eye.z, center.x, center.y, center.z, up.x, up.y, up.z);
273  }
274 
283  static Mat4<Type> multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
284 
292  static Mat4<Type> add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
293 
301  static Mat4<Type> subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
302 
307  static Mat4<Type> adjoint(const Mat4<Type> &matrix);
308 
314  static Mat4<Type> inverse(const Mat4<Type> &matrix);
315 
320  static Mat4<Type> transpose(const Mat4<Type> &matrix);
321 
327  static bool is_equal(const Mat4<Type> &first, const Mat4<Type> &second, Type epsilon)
328  {
329  for (int i = 0; i < 16; i++)
330  {
331  Type diff = second.matrix[i] - first.matrix[i];
332  if (diff < -epsilon || diff > epsilon) return false;
333  }
334  return true;
335  }
336 
338  Type matrix[16];
339 
341  Vec3<Type> get_translate() const { return Vec3<Type>(matrix[12], matrix[13], matrix[14]); }
342 
346  Vec3<Type> get_euler(EulerOrder order) const;
347 
351  Vec3<Type> get_transformed_point(const Vec3<Type> &vector) const;
352 
362  Mat4<Type> &scale_self(Type x, Type y, Type z);
363 
371  Mat4<Type> &scale_self(const Vec3<Type> &scale) { return scale_self(scale.x, scale.y, scale.z); }
372 
383  Mat4<Type> &translate_self(Type x, Type y, Type z);
384 
393  Mat4<Type> &translate_self(const Vec3<Type> &translation) { return translate_self(translation.x, translation.y, translation.z); }
394 
405  Mat4<Type> &set_translate(Type x, Type y, Type z) { matrix[3 * 4 + 0] = x; matrix[3 * 4 + 1] = y; matrix[3 * 4 + 2] = z; return *this; }
406 
415  Mat4<Type> &set_translate(const Vec3<Type> &translation) { matrix[3 * 4 + 0] = translation.x; matrix[3 * 4 + 1] = translation.y; matrix[3 * 4 + 2] = translation.z; return *this; }
416 
420  double det() const;
421 
425  Mat4<Type> &adjoint();
426 
431  Mat4<Type> &inverse();
432 
437 
439  void decompose(Vec3<Type> &out_position, Quaternionx<Type> &out_orientation, Vec3<Type> &out_scale) const;
440 
445  bool is_equal(const Mat4<Type> &other, Type epsilon) const { return Mat4<Type>::is_equal(*this, other, epsilon); }
446 
448  operator Type const*() const { return matrix; }
449 
451  operator Type *() { return matrix; }
452 
454  Type &operator[](int i) { return matrix[i]; }
455 
457  const Type &operator[](int i) const { return matrix[i]; }
458 
460  Type &operator[](unsigned int i) { return matrix[i]; }
461 
463  const Type &operator[](unsigned int i) const { return matrix[i]; }
464 
466  Mat4<Type> &operator =(const Mat4<Type> &copy) { memcpy(matrix, copy.matrix, sizeof(matrix)); return *this; }
467 
469  Mat4<Type> &operator =(const Mat3<Type> &copy);
470 
472  Mat4<Type> &operator =(const Mat2<Type> &copy);
473 
475  Mat4<Type> operator *(const Mat4<Type> &mult) const;
476 
478  Mat4<Type> operator +(const Mat4<Type> &add_matrix) const;
479 
481  Mat4<Type> operator -(const Mat4<Type> &sub_matrix) const;
482 
484  bool operator==(const Mat4<Type> &other) const
485  {
486  for (int i = 0; i < 16; i++)
487  if (matrix[i] != other.matrix[i]) return false;
488  return true;
489  }
490 
492  bool operator!=(const Mat4<Type> &other) { return !((*this) == other); }
493  };
494 
495  template<typename Type>
496  inline Mat4<Type> Mat4<Type>::null() { Mat4<Type> m; memset(m.matrix, 0, sizeof(m.matrix)); return m; }
497 
498  template<typename Type>
499  inline Mat4<Type> Mat4<Type>::identity() { Mat4<Type> m = null(); m.matrix[0] = 1; m.matrix[5] = 1; m.matrix[10] = 1; m.matrix[15] = 1; return m; }
500 
501  template<typename Type>
502  inline Mat4<Type> Mat4<Type>::multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 * matrix_2; }
503 
504  template<typename Type>
505  inline Mat4<Type> Mat4<Type>::add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 + matrix_2; }
506 
507  template<typename Type>
508  inline Mat4<Type> Mat4<Type>::subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 - matrix_2; }
509 
510  template<typename Type>
511  inline Mat4<Type> Mat4<Type>::adjoint(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.adjoint(); return dest; }
512 
513  template<typename Type>
514  inline Mat4<Type> Mat4<Type>::inverse(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.inverse(); return dest; }
515 
516  template<typename Type>
517  inline Mat4<Type> Mat4<Type>::transpose(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.transpose(); return dest; }
518 
519  typedef Mat4<int> Mat4i;
522 }
static Mat4< Type > rotate(Type angle, Vec3< Type > rotation, bool normalize=true)
Create a rotation matrix.
Definition: mat4.h:194
Mat4< Type > & translate_self(Type x, Type y, Type z)
Translate this matrix.
void decompose(Vec3< Type > &out_position, Quaternionx< Type > &out_orientation, Vec3< Type > &out_scale) const
Decompose matrix into position, orientation/rotation and scale.
Mat4< Type > operator+(const Mat4< Type > &add_matrix) const
Addition operator.
static Mat4< Type > ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z)
Create a ortho_2d matrix.
Mat4(const float *init_matrix)
Constructs a 4x4 matrix (copied from a array of floats)
Definition: mat4.h:96
2D matrix
Definition: mat2.h:41
Handedness
Definition: mat4.h:41
Type x
Definition: vec3.h:74
Mat4< Type > & translate_self(const Vec3< Type > &translation)
Translate this matrix.
Definition: mat4.h:393
Mat4< Type > & scale_self(const Vec3< Type > &scale)
Scale this matrix.
Definition: mat4.h:371
3D matrix
Definition: mat2.h:44
Mat4< float > Mat4f
Definition: mat4.h:520
Mat4(const double *init_matrix)
Constructs a 4x4 matrix (copied from a array of doubles)
Definition: mat4.h:103
3D vector
Definition: line_ray.h:43
static Mat4< Type > look_at(Type eye_x, Type eye_y, Type eye_z, Type center_x, Type center_y, Type center_z, Type up_x, Type up_y, Type up_z)
Create the "look at" matrix.
Mat4< Type > & adjoint()
Calculate the adjoint (or known as adjugate) of this matrix.
static Mat4< Type > subtract(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Subtract 2 matrices.
Definition: mat4.h:508
bool operator!=(const Mat4< Type > &other)
Not-equal operator.
Definition: mat4.h:492
Definition: mat4.h:50
Mat4< Type > operator*(const Mat4< Type > &mult) const
Multiplication operator.
Mat4(const int32_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 32 bit integers)
Definition: mat4.h:117
ClipZRange
Definition: mat4.h:47
Mat4(const int64_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 64 bit integers)
Definition: mat4.h:110
Vec3< Type > get_euler(EulerOrder order) const
Extract the euler angles (in radians) from a matrix (in column-major format)
static Mat4< Type > inverse(const Mat4< Type > &matrix)
Calculate the matrix inverse of a matrix.
Definition: mat4.h:514
static Mat4< Type > adjoint(const Mat4< Type > &matrix)
Calculate the adjoint (or known as Adjugate or Conjugate Transpose) of a matrix.
Definition: mat4.h:511
Type z
Definition: vec3.h:76
Type matrix[16]
The matrix (in column-major format)
Definition: mat4.h:338
Mat4< Type > & transpose()
Calculate the transpose of this matrix.
static Mat4< Type > transpose(const Mat4< Type > &matrix)
Calculate the transpose of a matrix.
Definition: mat4.h:517
Mat4< Type > & operator=(const Mat4< Type > &copy)
Copy assignment operator.
Definition: mat4.h:466
static Mat4< Type > scale(const Vec3< Type > &xyz)
Create a scale matrix.
Definition: mat4.h:218
Mat4()
Constructs a 4x4 matrix (zero'ed)
Definition: mat4.h:76
Mat4< Type > & set_translate(const Vec3< Type > &translation)
Set this matrix translation values.
Definition: mat4.h:415
Definition: mat4.h:43
Quaternion.
Definition: mat4.h:66
static Mat4< Type > frustum(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z)
Create a frustum matrix.
EulerOrder
Euler angle rotation order.
Definition: angle.h:40
static Mat4< Type > scale(Type x, Type y, Type z)
Create a scale matrix.
Vec3< Type > get_translate() const
Returns the translation coordinates for this matrix (in column-major format)
Definition: mat4.h:341
static Mat4< Type > rotate(Type angle, Type x, Type y, Type z, bool normalize=true)
Create a rotation matrix.
Mat4< Type > operator-(const Mat4< Type > &sub_matrix) const
Subtraction operator.
static Mat4< Type > multiply(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Multiply 2 matrices.
Definition: mat4.h:502
static Mat4< Type > look_at(Vec3< Type > eye, Vec3< Type > center, Vec3< Type > up)
Create the "look at" matrix.
Definition: mat4.h:267
Mat4< Type > & set_translate(Type x, Type y, Type z)
Set this matrix translation values.
Definition: mat4.h:405
static Mat4< Type > translate(Type x, Type y, Type z)
Create a translation matrix.
Definition: mat4.h:44
Vec3< Type > get_transformed_point(const Vec3< Type > &vector) const
Get a transformed point from the matrix (in column-major format)
Mat4(const int16_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 16 bit integers)
Definition: mat4.h:124
static Mat4< Type > ortho(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z)
Create a ortho matrix.
bool operator==(const Mat4< Type > &other) const
Equality operator.
Definition: mat4.h:484
static bool is_equal(const Mat4< Type > &first, const Mat4< Type > &second, Type epsilon)
Returns true if equal within the bounds of an epsilon.
Definition: mat4.h:327
const Type & operator[](unsigned int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:463
static Mat4< Type > translate(const Vec3< Type > &xyz)
Create a translation matrix.
Definition: mat4.h:237
Mat4< Type > & scale_self(Type x, Type y, Type z)
Scale this matrix.
const Type & operator[](int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:457
Type y
Definition: vec3.h:75
Mat4< int > Mat4i
Definition: mat4.h:519
Mat4(const Mat4< Type > &copy)
Constructs a 4x4 matrix (copied)
Definition: mat4.h:83
static Mat4< Type > identity()
Create the identity matrix.
Definition: mat4.h:499
static Mat4< Type > add(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Add 2 matrices.
Definition: mat4.h:505
static Mat4< Type > null()
Create a zero matrix.
Definition: mat4.h:496
Mat4(const int8_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 8 bit integers)
Definition: mat4.h:131
Mat4< Type > & inverse()
Calculate the matrix inverse of this matrix.
Type & operator[](unsigned int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:460
double det() const
Calculate the matrix determinant of this matrix.
static Mat4< Type > perspective(Type field_of_view_y_degrees, Type aspect, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z)
Create a perspective matrix.
bool is_equal(const Mat4< Type > &other, Type epsilon) const
Returns true if equal within the bounds of an epsilon.
Definition: mat4.h:445
Definition: Application/application.h:35
Mat4< double > Mat4d
Definition: mat4.h:521
4D matrix
Definition: mat2.h:47
Type & operator[](int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:454