mat4.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2016 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 
45  {
48  };
49 
51  {
52  clip_negative_positive_w, // OpenGL, -wclip <= zclip <= wclip
53  clip_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 (auto & elem : matrix)
84  elem = 0;
85  }
86 
88  Mat4(const Mat4<Type> &copy)
89  {
90  for (int i = 0; i < 16; i++)
91  matrix[i] = copy.matrix[i];
92  }
93 
95  explicit Mat4(const Mat2<Type> &copy);
96 
98  explicit Mat4(const Mat3<Type> &copy);
99 
101  explicit Mat4(const float *init_matrix)
102  {
103  for (int i = 0; i < 16; i++)
104  matrix[i] = (Type)init_matrix[i];
105  }
106 
108  explicit Mat4(const double *init_matrix)
109  {
110  for (int i = 0; i < 16; i++)
111  matrix[i] = (Type)init_matrix[i];
112  }
113 
115  explicit Mat4(const int64_t *init_matrix)
116  {
117  for (int i = 0; i < 16; i++)
118  matrix[i] = (Type)init_matrix[i];
119  }
120 
122  explicit Mat4(const int32_t *init_matrix)
123  {
124  for (int i = 0; i < 16; i++)
125  matrix[i] = (Type)init_matrix[i];
126  }
127 
129  explicit Mat4(const int16_t *init_matrix)
130  {
131  for (int i = 0; i < 16; i++)
132  matrix[i] = (Type)init_matrix[i];
133  }
134 
136  explicit Mat4(const int8_t *init_matrix)
137  {
138  for (int i = 0; i < 16; i++)
139  matrix[i] = (Type)init_matrix[i];
140  }
141 
145  static Mat4<Type> null();
146 
149  static Mat4<Type> identity();
150 
155  static Mat4<Type> frustum(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
156 
161  static Mat4<Type> perspective(
162  Type field_of_view_y_degrees,
163  Type aspect,
164  Type z_near,
165  Type z_far,
166  Handedness handedness,
167  ClipZRange clip_z);
168 
173  static Mat4<Type> ortho(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
174 
179  static Mat4<Type> ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z);
180 
190  static Mat4<Type> rotate(const Angle &angle, Type x, Type y, Type z, bool normalize = true);
191 
199  static Mat4<Type> rotate(const Angle &angle, Vec3<Type> rotation, bool normalize = true)
200  {
201  return rotate(angle, rotation.x, rotation.y, rotation.z, normalize);
202  }
203 
209  static Mat4<Type> rotate(const Angle &angle_x, const Angle &angle_y, const Angle &angle_z, EulerOrder order);
210 
217  static Mat4<Type> scale(Type x, Type y, Type z);
218 
223  static Mat4<Type> scale(const Vec3<Type> &xyz)
224  {
225  return scale(xyz.x, xyz.y, xyz.z);
226  }
227 
235  static Mat4<Type> translate(Type x, Type y, Type z);
236 
242  static Mat4<Type> translate(const Vec3<Type> &xyz)
243  {
244  return translate(xyz.x, xyz.y, xyz.z);
245  }
246 
260  static Mat4<Type> look_at(
261  Type eye_x, Type eye_y, Type eye_z,
262  Type center_x, Type center_y, Type center_z,
263  Type up_x, Type up_y, Type up_z);
264 
273  Vec3<Type> eye,
275  Vec3<Type> up)
276  {
277  return look_at(eye.x, eye.y, eye.z, center.x, center.y, center.z, up.x, up.y, up.z);
278  }
279 
288  static Mat4<Type> multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
289 
297  static Mat4<Type> add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
298 
306  static Mat4<Type> subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
307 
312  static Mat4<Type> adjoint(const Mat4<Type> &matrix);
313 
319  static Mat4<Type> inverse(const Mat4<Type> &matrix);
320 
325  static Mat4<Type> transpose(const Mat4<Type> &matrix);
326 
332  static bool is_equal(const Mat4<Type> &first, const Mat4<Type> &second, Type epsilon)
333  {
334  for (int i = 0; i < 16; i++)
335  {
336  Type diff = second.matrix[i] - first.matrix[i];
337  if (diff < -epsilon || diff > epsilon) return false;
338  }
339  return true;
340  }
341 
343  Type matrix[16];
344 
346  Vec3<Type> get_translate() const { return Vec3<Type>(matrix[12], matrix[13], matrix[14]); }
347 
351  Vec3<Type> get_euler(EulerOrder order) const;
352 
356  Vec3<Type> get_transformed_point(const Vec3<Type> &vector) const;
357 
367  Mat4<Type> &scale_self(Type x, Type y, Type z);
368 
376  Mat4<Type> &scale_self(const Vec3<Type> &scale) { return scale_self(scale.x, scale.y, scale.z); }
377 
388  Mat4<Type> &translate_self(Type x, Type y, Type z);
389 
398  Mat4<Type> &translate_self(const Vec3<Type> &translation) { return translate_self(translation.x, translation.y, translation.z); }
399 
410  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; }
411 
420  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; }
421 
425  double det() const;
426 
430  Mat4<Type> &adjoint();
431 
436  Mat4<Type> &inverse();
437 
442 
444  void decompose(Vec3<Type> &out_position, Quaternionx<Type> &out_orientation, Vec3<Type> &out_scale) const;
445 
450  bool is_equal(const Mat4<Type> &other, Type epsilon) const { return Mat4<Type>::is_equal(*this, other, epsilon); }
451 
453  operator Type const*() const { return matrix; }
454 
456  operator Type *() { return matrix; }
457 
459  Type &operator[](int i) { return matrix[i]; }
460 
462  const Type &operator[](int i) const { return matrix[i]; }
463 
465  Type &operator[](unsigned int i) { return matrix[i]; }
466 
468  const Type &operator[](unsigned int i) const { return matrix[i]; }
469 
471  Mat4<Type> &operator =(const Mat4<Type> &copy) { memcpy(matrix, copy.matrix, sizeof(matrix)); return *this; }
472 
474  Mat4<Type> &operator =(const Mat3<Type> &copy);
475 
477  Mat4<Type> &operator =(const Mat2<Type> &copy);
478 
480  Mat4<Type> operator *(const Mat4<Type> &mult) const;
481 
483  Mat4<Type> operator +(const Mat4<Type> &add_matrix) const;
484 
486  Mat4<Type> operator -(const Mat4<Type> &sub_matrix) const;
487 
489  bool operator==(const Mat4<Type> &other) const
490  {
491  for (int i = 0; i < 16; i++)
492  if (matrix[i] != other.matrix[i]) return false;
493  return true;
494  }
495 
497  bool operator!=(const Mat4<Type> &other) { return !((*this) == other); }
498  };
499 
500  template<typename Type>
501  inline Mat4<Type> Mat4<Type>::null() { Mat4<Type> m; memset(m.matrix, 0, sizeof(m.matrix)); return m; }
502 
503  template<typename Type>
504  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; }
505 
506  template<typename Type>
507  inline Mat4<Type> Mat4<Type>::multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 * matrix_2; }
508 
509  template<typename Type>
510  inline Mat4<Type> Mat4<Type>::add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 + matrix_2; }
511 
512  template<typename Type>
513  inline Mat4<Type> Mat4<Type>::subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 - matrix_2; }
514 
515  template<typename Type>
516  inline Mat4<Type> Mat4<Type>::adjoint(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.adjoint(); return dest; }
517 
518  template<typename Type>
519  inline Mat4<Type> Mat4<Type>::inverse(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.inverse(); return dest; }
520 
521  template<typename Type>
522  inline Mat4<Type> Mat4<Type>::transpose(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.transpose(); return dest; }
523 
524  typedef Mat4<int> Mat4i;
527 
529 }
Mat4< Type > & translate_self(const Vec3< Type > &translation)
Translate this matrix.
Definition: mat4.h:398
Mat4< Type > & scale_self(Type x, Type y, Type z)
Scale this matrix.
Mat4< Type > & translate_self(Type x, Type y, Type z)
Translate this matrix.
Mat4(const int8_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 8 bit integers)
Definition: mat4.h:136
Definition: clanapp.h:35
Vec3< Type > get_euler(EulerOrder order) const
Extract the euler angles (in radians) from a matrix (in column-major format)
Mat4< Type > & set_translate(Type x, Type y, Type z)
Set this matrix translation values.
Definition: mat4.h:410
bool is_equal(const Mat4< Type > &other, Type epsilon) const
Returns true if equal within the bounds of an epsilon.
Definition: mat4.h:450
Angle class.
Definition: angle.h:59
Quaternion.
Definition: mat4.h:69
static Mat4< Type > subtract(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Subtract 2 matrices.
Definition: mat4.h:513
Mat4< Type > & scale_self(const Vec3< Type > &scale)
Scale this matrix.
Definition: mat4.h:376
double det() const
Calculate the matrix determinant of this matrix.
Mat4< Type > operator*(const Mat4< Type > &mult) const
Multiplication operator.
Mat4(const double *init_matrix)
Constructs a 4x4 matrix (copied from a array of doubles)
Definition: mat4.h:108
Vec3< Type > get_transformed_point(const Vec3< Type > &vector) const
Get a transformed point from the matrix (in column-major format)
static Mat4< Type > rotate(const Angle &angle, Type x, Type y, Type z, bool normalize=true)
Create a rotation matrix.
3D matrix
Definition: mat2.h:47
Definition: mat4.h:52
static Mat4< Type > translate(const Vec3< Type > &xyz)
Create a translation matrix.
Definition: mat4.h:242
Mat4(const int64_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 64 bit integers)
Definition: mat4.h:115
void decompose(Vec3< Type > &out_position, Quaternionx< Type > &out_orientation, Vec3< Type > &out_scale) const
Decompose matrix into position, orientation/rotation and scale.
ClipZRange
Definition: mat4.h:50
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.
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:346
Type y
Definition: vec3.h:80
static Mat4< Type > identity()
Create the identity matrix.
Definition: mat4.h:504
Mat4< Type > operator+(const Mat4< Type > &add_matrix) const
Addition operator.
static Mat4< Type > rotate(const Angle &angle, Vec3< Type > rotation, bool normalize=true)
Create a rotation matrix.
Definition: mat4.h:199
static Mat4< Type > null()
Create a zero matrix.
Definition: mat4.h:501
const Type & operator[](unsigned int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:468
Handedness
Definition: mat4.h:44
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(const int16_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 16 bit integers)
Definition: mat4.h:129
Mat4(const float *init_matrix)
Constructs a 4x4 matrix (copied from a array of floats)
Definition: mat4.h:101
static Mat4< Type > adjoint(const Mat4< Type > &matrix)
Calculate the adjoint (or known as Adjugate or Conjugate Transpose) of a matrix.
Definition: mat4.h:516
4D matrix
Definition: mat2.h:50
2D matrix
Definition: mat2.h:44
Mat4< Type > & inverse()
Calculate the matrix inverse of this matrix.
static Mat4< Type > multiply(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Multiply 2 matrices.
Definition: mat4.h:507
Type z
Definition: vec3.h:81
bool operator!=(const Mat4< Type > &other)
Not-equal operator.
Definition: mat4.h:497
Type & operator[](unsigned int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:465
Mat4()
Constructs a 4x4 matrix (zero'ed)
Definition: mat4.h:81
Mat4< Type > operator-(const Mat4< Type > &sub_matrix) const
Subtraction operator.
static Mat4< Type > ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z)
Create a ortho_2d matrix.
static Mat4< Type > look_at(Vec3< Type > eye, Vec3< Type > center, Vec3< Type > up)
Create the "look at" matrix.
Definition: mat4.h:272
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.
static Mat4< Type > scale(const Vec3< Type > &xyz)
Create a scale matrix.
Definition: mat4.h:223
Definition: mat4.h:53
bool operator==(const Mat4< Type > &other) const
Equality operator.
Definition: mat4.h:489
Mat4< Type > & operator=(const Mat4< Type > &copy)
Copy assignment operator.
Definition: mat4.h:471
Mat4< Type > & set_translate(const Vec3< Type > &translation)
Set this matrix translation values.
Definition: mat4.h:420
const Type & operator[](int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:462
Type matrix[16]
The matrix (in column-major format)
Definition: mat4.h:343
Definition: mat4.h:47
Type x
Definition: vec3.h:79
Type & operator[](int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:459
EulerOrder
Euler angle rotation order.
Definition: angle.h:48
Mat4< double > Mat4d
Definition: mat4.h:526
Mat4(const Mat4< Type > &copy)
Constructs a 4x4 matrix (copied)
Definition: mat4.h:88
static Mat4< Type > transpose(const Mat4< Type > &matrix)
Calculate the transpose of a matrix.
Definition: mat4.h:522
Mat4< Type > & transpose()
Calculate the transpose of this matrix.
static Mat4< Type > inverse(const Mat4< Type > &matrix)
Calculate the matrix inverse of a matrix.
Definition: mat4.h:519
Mat4< float > Mat4f
Definition: mat4.h:525
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:332
Mat4< Type > & adjoint()
Calculate the adjoint (or known as adjugate) of this matrix.
Mat4< int > Mat4i
Definition: mat4.h:524
Definition: mat4.h:46
3D vector
Definition: line_ray.h:46
static Mat4< Type > translate(Type x, Type y, Type z)
Create a translation matrix.
Mat4(const int32_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 32 bit integers)
Definition: mat4.h:122
static Mat4< Type > add(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Add 2 matrices.
Definition: mat4.h:510
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.