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
39namespace clan
40{
43
44 enum class Handedness
45 {
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:
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
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
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
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,
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
309
316
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
348
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
427
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
471
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
523
525}
Angle class.
Definition angle.h:60
2D matrix
Definition mat2.h:59
3D matrix
Definition mat3.h:60
4D matrix
Definition mat4.h:78
Vec3< Type > get_euler(EulerOrder order) const
Extract the euler angles (in radians) from a matrix (in column-major format)
Mat4< Type > & scale_self(Type x, Type y, Type z)
Scale this matrix.
static Mat4< Type > rotate(const Angle &angle, Type x, Type y, Type z, bool normalize=true)
Create a rotation matrix.
Mat4< Type > & inverse()
Calculate the matrix inverse of this matrix.
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:97
Mat4(const int32_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 32 bit integers)
Definition mat4.h:118
Mat4< Type > & adjoint()
Calculate the adjoint (or known as adjugate) of this matrix.
Mat4< Type > & translate_self(Type x, Type y, Type z)
Translate this matrix.
bool operator!=(const Mat4< Type > &other)
Not-equal operator.
Definition mat4.h:493
Mat4(const double *init_matrix)
Constructs a 4x4 matrix (copied from a array of doubles)
Definition mat4.h:104
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 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
const Type & operator[](unsigned int i) const
Operator that returns the matrix cell at the given index.
Definition mat4.h:464
Mat4(const Mat3< Type > &copy)
Constructs a 4x4 matrix (copied from a 3d matrix)
void decompose(Vec3< Type > &out_position, Quaternionx< Type > &out_orientation, Vec3< Type > &out_scale) const
Decompose matrix into position, orientation/rotation and scale.
Type & operator[](int i)
Operator that returns the matrix cell at the given index.
Definition mat4.h:455
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.
Type & operator[](unsigned int i)
Operator that returns the matrix cell at the given index.
Definition mat4.h:461
Mat4(const Mat2< Type > &copy)
Constructs a 4x4 matrix (copied from a 2d matrix)
Mat4< Type > operator+(const Mat4< Type > &add_matrix) const
Addition operator.
static Mat4< Type > scale(const Vec3< Type > &xyz)
Create a scale matrix.
Definition mat4.h:219
Mat4< Type > & set_translate(const Vec3< Type > &translation)
Set this matrix translation values.
Definition mat4.h:416
Mat4< Type > operator*(const Mat4< Type > &mult) const
Multiplication operator.
Mat4< Type > & operator=(const Mat4< Type > &copy)=default
Copy assignment operator.
static Mat4< Type > rotate(const Angle &angle, Vec3< Type > rotation, bool normalize=true)
Create a rotation matrix.
Definition mat4.h:195
Mat4< Type > & translate_self(const Vec3< Type > &translation)
Translate this matrix.
Definition mat4.h:394
double det() const
Calculate the matrix determinant of this matrix.
bool operator==(const Mat4< Type > &other) const
Equality operator.
Definition mat4.h:485
Mat4< Type > & transpose()
Calculate the transpose of this matrix.
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()
Constructs a 4x4 matrix (zero'ed)
Definition mat4.h:81
Mat4(const int16_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 16 bit integers)
Definition mat4.h:125
bool is_equal(const Mat4< Type > &other, Type epsilon) const
Returns true if equal within the bounds of an epsilon.
Definition mat4.h:446
static Mat4< Type > look_at(Vec3< Type > eye, Vec3< Type > center, Vec3< Type > up)
Create the "look at" matrix.
Definition mat4.h:268
Vec3< Type > get_translate() const
Returns the translation coordinates for this matrix (in column-major format)
Definition mat4.h:342
Mat4(const Mat4< Type > &copy)=default
Constructs a 4x4 matrix (copied)
static Mat4< Type > rotate(const Angle &angle_x, const Angle &angle_y, const Angle &angle_z, EulerOrder order)
Create a rotation matrix using euler angles.
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.
int matrix[16]
Definition mat4.h:339
Mat4< Type > operator-(const Mat4< Type > &sub_matrix) const
Subtraction operator.
static Mat4< Type > translate(Type x, Type y, Type z)
Create a translation matrix.
Mat4(const int64_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 64 bit integers)
Definition mat4.h:111
static Mat4< Type > translate(const Vec3< Type > &xyz)
Create a translation matrix.
Definition mat4.h:238
Mat4< Type > & set_translate(Type x, Type y, Type z)
Set this matrix translation values.
Definition mat4.h:406
static Mat4< Type > scale(Type x, Type y, Type z)
Create a scale matrix.
Mat4< Type > & scale_self(const Vec3< Type > &scale)
Scale this matrix.
Definition mat4.h:372
Mat4(const int8_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 8 bit integers)
Definition mat4.h:132
const Type & operator[](int i) const
Operator that returns the matrix cell at the given index.
Definition mat4.h:458
Quaternion.
Definition quaternion.h:44
3D vector
Definition vec3.h:75
Type z
Definition vec3.h:81
Type y
Definition vec3.h:80
Type x
Definition vec3.h:79
@ null
Definition json_value.h:49
static Mat4< Type > add(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Add 2 matrices.
Definition mat4.h:506
static Mat4< Type > null()
Create a zero matrix.
Definition mat4.h:497
Mat4< double > Mat4d
Definition mat4.h:522
Mat4< int > Mat4i
Definition mat4.h:520
static Mat4< Type > multiply(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Multiply 2 matrices.
Definition mat4.h:503
static Mat4< Type > inverse(const Mat4< Type > &matrix)
Calculate the matrix inverse of a matrix.
Definition mat4.h:515
static Mat4< Type > transpose(const Mat4< Type > &matrix)
Calculate the transpose of a matrix.
Definition mat4.h:518
ClipZRange
Definition mat4.h:51
EulerOrder
Euler angle rotation order.
Definition angle.h:49
static Mat4< Type > identity()
Create the identity matrix.
Definition mat4.h:500
static Mat4< Type > subtract(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Subtract 2 matrices.
Definition mat4.h:509
Mat4< float > Mat4f
Definition mat4.h:521
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
Handedness
Definition mat4.h:45
@ negative_positive_w
Definition mat4.h:52
@ zero_positive_w
Definition mat4.h:53
@ center
Definition origin.h:44
@ right
Definition mat4.h:47
@ left
Definition mat4.h:46
Definition clanapp.h:36
@ angle
value is a color
Definition style_value_type.h:44
@ y
Definition keys.h:105
@ up
Definition keys.h:59
@ m
Definition keys.h:93
@ i
Definition keys.h:89
@ x
Definition keys.h:104
@ z
Definition keys.h:106