mat4.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2020 The ClanLib 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 ClanLib 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 "../System/cl_platform.h"
34 #include "mat2.h"
35 #include "mat3.h"
36 #include "vec3.h"
37 #include "angle.h"
38 
39 namespace clan
40 {
43 
44  enum class Handedness
45  {
46  left,
47  right
48  };
49 
50  enum class ClipZRange
51  {
52  negative_positive_w, // OpenGL, -wclip <= zclip <= wclip
53  zero_positive_w // Direct3D, 0 <= zclip <= wclip
54  };
55 
56  template<typename Type>
57  class Mat2;
58 
59  template<typename Type>
60  class Mat3;
61 
62  template<typename Type>
63  class Mat4;
64 
65  template<typename Type>
66  class Vec3;
67 
68  template<typename Type>
69  class Quaternionx;
70 
71  class Angle;
72 
76  template<typename Type>
77  class Mat4
78  {
79  public:
81  Mat4()
82  {
83  for (int i = 0; i < 16; i++)
84  matrix[i] = 0;
85  }
86 
88  Mat4(const Mat4<Type> &copy) = default;
89 
91  explicit Mat4(const Mat2<Type> &copy);
92 
94  explicit Mat4(const Mat3<Type> &copy);
95 
97  explicit Mat4(const float *init_matrix)
98  {
99  for (int i = 0; i < 16; i++)
100  matrix[i] = (Type)init_matrix[i];
101  }
102 
104  explicit Mat4(const double *init_matrix)
105  {
106  for (int i = 0; i < 16; i++)
107  matrix[i] = (Type)init_matrix[i];
108  }
109 
111  explicit Mat4(const int64_t *init_matrix)
112  {
113  for (int i = 0; i < 16; i++)
114  matrix[i] = (Type)init_matrix[i];
115  }
116 
118  explicit Mat4(const int32_t *init_matrix)
119  {
120  for (int i = 0; i < 16; i++)
121  matrix[i] = (Type)init_matrix[i];
122  }
123 
125  explicit Mat4(const int16_t *init_matrix)
126  {
127  for (int i = 0; i < 16; i++)
128  matrix[i] = (Type)init_matrix[i];
129  }
130 
132  explicit Mat4(const int8_t *init_matrix)
133  {
134  for (int i = 0; i < 16; i++)
135  matrix[i] = (Type)init_matrix[i];
136  }
137 
141  static Mat4<Type> null();
142 
145  static Mat4<Type> identity();
146 
151  static Mat4<Type> frustum(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
152 
157  static Mat4<Type> perspective(
158  Type field_of_view_y_degrees,
159  Type aspect,
160  Type z_near,
161  Type z_far,
162  Handedness handedness,
163  ClipZRange clip_z);
164 
169  static Mat4<Type> ortho(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
170 
175  static Mat4<Type> ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z);
176 
186  static Mat4<Type> rotate(const Angle &angle, Type x, Type y, Type z, bool normalize = true);
187 
195  static Mat4<Type> rotate(const Angle &angle, Vec3<Type> rotation, bool normalize = true)
196  {
197  return rotate(angle, rotation.x, rotation.y, rotation.z, normalize);
198  }
199 
205  static Mat4<Type> rotate(const Angle &angle_x, const Angle &angle_y, const Angle &angle_z, EulerOrder order);
206 
213  static Mat4<Type> scale(Type x, Type y, Type z);
214 
219  static Mat4<Type> scale(const Vec3<Type> &xyz)
220  {
221  return scale(xyz.x, xyz.y, xyz.z);
222  }
223 
231  static Mat4<Type> translate(Type x, Type y, Type z);
232 
238  static Mat4<Type> translate(const Vec3<Type> &xyz)
239  {
240  return translate(xyz.x, xyz.y, xyz.z);
241  }
242 
256  static Mat4<Type> look_at(
257  Type eye_x, Type eye_y, Type eye_z,
258  Type center_x, Type center_y, Type center_z,
259  Type up_x, Type up_y, Type up_z);
260 
269  Vec3<Type> eye,
271  Vec3<Type> up)
272  {
273  return look_at(eye.x, eye.y, eye.z, center.x, center.y, center.z, up.x, up.y, up.z);
274  }
275 
284  static Mat4<Type> multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
285 
293  static Mat4<Type> add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
294 
302  static Mat4<Type> subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
303 
308  static Mat4<Type> adjoint(const Mat4<Type> &matrix);
309 
315  static Mat4<Type> inverse(const Mat4<Type> &matrix);
316 
321  static Mat4<Type> transpose(const Mat4<Type> &matrix);
322 
328  static bool is_equal(const Mat4<Type> &first, const Mat4<Type> &second, Type epsilon)
329  {
330  for (int i = 0; i < 16; i++)
331  {
332  Type diff = second.matrix[i] - first.matrix[i];
333  if (diff < -epsilon || diff > epsilon) return false;
334  }
335  return true;
336  }
337 
339  Type matrix[16];
340 
342  Vec3<Type> get_translate() const { return Vec3<Type>(matrix[12], matrix[13], matrix[14]); }
343 
347  Vec3<Type> get_euler(EulerOrder order) const;
348 
352  Vec3<Type> get_transformed_point(const Vec3<Type> &vector) const;
353 
363  Mat4<Type> &scale_self(Type x, Type y, Type z);
364 
373 
384  Mat4<Type> &translate_self(Type x, Type y, Type z);
385 
394  Mat4<Type> &translate_self(const Vec3<Type> &translation) { return translate_self(translation.x, translation.y, translation.z); }
395 
406  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; }
407 
416  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; }
417 
421  double det() const;
422 
426  Mat4<Type> &adjoint();
427 
432  Mat4<Type> &inverse();
433 
438 
440  void decompose(Vec3<Type> &out_position, Quaternionx<Type> &out_orientation, Vec3<Type> &out_scale) const;
441 
446  bool is_equal(const Mat4<Type> &other, Type epsilon) const { return Mat4<Type>::is_equal(*this, other, epsilon); }
447 
449  operator Type const*() const { return matrix; }
450 
452  operator Type *() { return matrix; }
453 
455  Type &operator[](int i) { return matrix[i]; }
456 
458  const Type &operator[](int i) const { return matrix[i]; }
459 
461  Type &operator[](unsigned int i) { return matrix[i]; }
462 
464  const Type &operator[](unsigned int i) const { return matrix[i]; }
465 
467  Mat4<Type> &operator =(const Mat4<Type> &copy) = default;
468 
470  Mat4<Type> &operator =(const Mat3<Type> &copy);
471 
473  Mat4<Type> &operator =(const Mat2<Type> &copy);
474 
476  Mat4<Type> operator *(const Mat4<Type> &mult) const;
477 
479  Mat4<Type> operator +(const Mat4<Type> &add_matrix) const;
480 
482  Mat4<Type> operator -(const Mat4<Type> &sub_matrix) const;
483 
485  bool operator==(const Mat4<Type> &other) const
486  {
487  for (int i = 0; i < 16; i++)
488  if (matrix[i] != other.matrix[i]) return false;
489  return true;
490  }
491 
493  bool operator!=(const Mat4<Type> &other) { return !((*this) == other); }
494  };
495 
496  template<typename Type>
497  inline Mat4<Type> Mat4<Type>::null() { Mat4<Type> m; memset(m.matrix, 0, sizeof(m.matrix)); return m; }
498 
499  template<typename Type>
500  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; }
501 
502  template<typename Type>
503  inline Mat4<Type> Mat4<Type>::multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 * matrix_2; }
504 
505  template<typename Type>
506  inline Mat4<Type> Mat4<Type>::add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 + matrix_2; }
507 
508  template<typename Type>
509  inline Mat4<Type> Mat4<Type>::subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 - matrix_2; }
510 
511  template<typename Type>
512  inline Mat4<Type> Mat4<Type>::adjoint(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.adjoint(); return dest; }
513 
514  template<typename Type>
515  inline Mat4<Type> Mat4<Type>::inverse(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.inverse(); return dest; }
516 
517  template<typename Type>
518  inline Mat4<Type> Mat4<Type>::transpose(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.transpose(); return dest; }
519 
520  typedef Mat4<int> Mat4i;
523 
525 }
Vec3< Type > get_euler(EulerOrder order) const
Extract the euler angles (in radians) from a matrix (in column-major format)
Definition: clanapp.h:35
Mat4< Type > & adjoint()
Calculate the adjoint (or known as adjugate) of this matrix.
Mat4(const int8_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 8 bit integers)
Definition: mat4.h:132
Angle class.
Definition: angle.h:59
Mat4< Type > & set_translate(const Vec3< Type > &translation)
Set this matrix translation values.
Definition: mat4.h:416
Mat4< Type > & scale_self(Type x, Type y, Type z)
Scale this matrix.
static Mat4< Type > subtract(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Subtract 2 matrices.
Definition: mat4.h:509
static Mat4< Type > ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z)
Create a ortho_2d matrix.
Mat4< Type > operator+(const Mat4< Type > &add_matrix) const
Addition operator.
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.
Type x
Definition: vec3.h:79
Mat4(const double *init_matrix)
Constructs a 4x4 matrix (copied from a array of doubles)
Definition: mat4.h:104
double det() const
Calculate the matrix determinant of this matrix.
static Mat4< Type > scale(const Vec3< Type > &xyz)
Create a scale matrix.
Definition: mat4.h:219
Type y
Definition: vec3.h:80
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.
Mat4< Type > & translate_self(Type x, Type y, Type z)
Translate this matrix.
Mat4< Type > & translate_self(const Vec3< Type > &translation)
Translate this matrix.
Definition: mat4.h:394
ClipZRange
Definition: mat4.h:50
void decompose(Vec3< Type > &out_position, Quaternionx< Type > &out_orientation, Vec3< Type > &out_scale) const
Decompose matrix into position, orientation/rotation and scale.
bool operator!=(const Mat4< Type > &other)
Not-equal operator.
Definition: mat4.h:493
Vec3< Type > get_translate() const
Returns the translation coordinates for this matrix (in column-major format)
Definition: mat4.h:342
static Mat4< Type > identity()
Create the identity matrix.
Definition: mat4.h:500
static Mat4< Type > null()
Create a zero matrix.
Definition: mat4.h:497
Handedness
Definition: mat4.h:44
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.
Vec3< Type > get_transformed_point(const Vec3< Type > &vector) const
Get a transformed point from the matrix (in column-major format)
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.
Mat4()
Constructs a 4x4 matrix (zero&#39;ed)
Definition: mat4.h:81
static Mat4< Type > adjoint(const Mat4< Type > &matrix)
Calculate the adjoint (or known as Adjugate or Conjugate Transpose) of a matrix.
Definition: mat4.h:512
Mat4< Type > operator-(const Mat4< Type > &sub_matrix) const
Subtraction operator.
Quaternion.
Definition: mat4.h:69
static Mat4< Type > multiply(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Multiply 2 matrices.
Definition: mat4.h:503
2D matrix
Definition: mat2.h:44
Mat4(const int16_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 16 bit integers)
Definition: mat4.h:125
Mat4(const float *init_matrix)
Constructs a 4x4 matrix (copied from a array of floats)
Definition: mat4.h:97
static Mat4< Type > scale(Type x, Type y, Type z)
Create a scale matrix.
Mat4< Type > & operator=(const Mat4< Type > &copy)=default
Copy assignment operator.
Mat4< Type > & transpose()
Calculate the transpose of this matrix.
3D matrix
Definition: mat2.h:47
bool operator==(const Mat4< Type > &other) const
Equality operator.
Definition: mat4.h:485
const Type & operator[](int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:458
Type & operator[](unsigned int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:461
static Mat4< Type > translate(const Vec3< Type > &xyz)
Create a translation matrix.
Definition: mat4.h:238
3D vector
Definition: line_ray.h:46
Mat4< Type > & scale_self(const Vec3< Type > &scale)
Scale this matrix.
Definition: mat4.h:372
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:328
static Mat4< Type > look_at(Vec3< Type > eye, Vec3< Type > center, Vec3< Type > up)
Create the "look at" matrix.
Definition: mat4.h:268
static Mat4< Type > rotate(const Angle &angle, Type x, Type y, Type z, bool normalize=true)
Create a rotation matrix.
EulerOrder
Euler angle rotation order.
Definition: angle.h:48
Mat4< double > Mat4d
Definition: mat4.h:522
const Type & operator[](unsigned int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:464
Type matrix[16]
The matrix (in column-major format)
Definition: mat4.h:339
bool is_equal(const Mat4< Type > &other, Type epsilon) const
Returns true if equal within the bounds of an epsilon.
Definition: mat4.h:446
Mat4< Type > operator*(const Mat4< Type > &mult) const
Multiplication operator.
Mat4(const int64_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 64 bit integers)
Definition: mat4.h:111
Mat4< Type > & set_translate(Type x, Type y, Type z)
Set this matrix translation values.
Definition: mat4.h:406
static Mat4< Type > rotate(const Angle &angle, Vec3< Type > rotation, bool normalize=true)
Create a rotation matrix.
Definition: mat4.h:195
static Mat4< Type > translate(Type x, Type y, Type z)
Create a translation matrix.
static Mat4< Type > transpose(const Mat4< Type > &matrix)
Calculate the transpose of a matrix.
Definition: mat4.h:518
static Mat4< Type > inverse(const Mat4< Type > &matrix)
Calculate the matrix inverse of a matrix.
Definition: mat4.h:515
Type z
Definition: vec3.h:81
Mat4< float > Mat4f
Definition: mat4.h:521
4D matrix
Definition: mat2.h:50
Mat4(const int32_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 32 bit integers)
Definition: mat4.h:118
Mat4< int > Mat4i
Definition: mat4.h:520
Mat4< Type > & inverse()
Calculate the matrix inverse of this matrix.
static Mat4< Type > add(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Add 2 matrices.
Definition: mat4.h:506
Type & operator[](int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:455