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 {
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:
82 {
83 for (int i = 0; i < 16; i++)
84 matrix[i] = 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
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
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,
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
352
357
367 Mat4<Type> &scale_self(Type x, Type y, Type z);
368
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
431
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
475
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
527
529}
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:101
Mat4(const int32_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 32 bit integers)
Definition mat4.h:122
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:497
Mat4< Type > & operator=(const Mat4< Type > &copy)
Copy assignment operator.
Definition mat4.h:471
Mat4(const double *init_matrix)
Constructs a 4x4 matrix (copied from a array of doubles)
Definition mat4.h:108
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:332
const Type & operator[](unsigned int i) const
Operator that returns the matrix cell at the given index.
Definition mat4.h:468
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:459
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:465
Mat4(const Mat4< Type > &copy)
Constructs a 4x4 matrix (copied)
Definition mat4.h:88
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:223
Mat4< Type > & set_translate(const Vec3< Type > &translation)
Set this matrix translation values.
Definition mat4.h:420
Mat4< Type > operator*(const Mat4< Type > &mult) const
Multiplication operator.
static Mat4< Type > rotate(const Angle &angle, Vec3< Type > rotation, bool normalize=true)
Create a rotation matrix.
Definition mat4.h:199
Mat4< Type > & translate_self(const Vec3< Type > &translation)
Translate this matrix.
Definition mat4.h:398
double det() const
Calculate the matrix determinant of this matrix.
bool operator==(const Mat4< Type > &other) const
Equality operator.
Definition mat4.h:489
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:129
bool is_equal(const Mat4< Type > &other, Type epsilon) const
Returns true if equal within the bounds of an epsilon.
Definition mat4.h:450
static Mat4< Type > look_at(Vec3< Type > eye, Vec3< Type > center, Vec3< Type > up)
Create the "look at" matrix.
Definition mat4.h:272
Vec3< Type > get_translate() const
Returns the translation coordinates for this matrix (in column-major format)
Definition mat4.h:346
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.
Type matrix[16]
The matrix (in column-major format)
Definition mat4.h:343
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:115
static Mat4< Type > translate(const Vec3< Type > &xyz)
Create a translation matrix.
Definition mat4.h:242
Mat4< Type > & set_translate(Type x, Type y, Type z)
Set this matrix translation values.
Definition mat4.h:410
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:376
Mat4(const int8_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 8 bit integers)
Definition mat4.h:136
const Type & operator[](int i) const
Operator that returns the matrix cell at the given index.
Definition mat4.h:462
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
static Mat4< Type > add(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Add 2 matrices.
Definition mat4.h:510
static Mat4< Type > null()
Create a zero matrix.
Definition mat4.h:501
Mat4< double > Mat4d
Definition mat4.h:526
Mat4< int > Mat4i
Definition mat4.h:524
static Mat4< Type > multiply(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Multiply 2 matrices.
Definition mat4.h:507
static Mat4< Type > inverse(const Mat4< Type > &matrix)
Calculate the matrix inverse of a matrix.
Definition mat4.h:519
static Mat4< Type > transpose(const Mat4< Type > &matrix)
Calculate the transpose of a matrix.
Definition mat4.h:522
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:504
static Mat4< Type > subtract(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Subtract 2 matrices.
Definition mat4.h:513
Mat4< float > Mat4f
Definition mat4.h:525
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
Handedness
Definition mat4.h:45
Definition clanapp.h:36
@ angle
value is a color