mat4.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2015 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
32 #pragma once
33
34 #include "../System/cl_platform.h"
35 #include "mat2.h"
36 #include "mat3.h"
37 #include "vec3.h"
38 #include "angle.h"
39
40 namespace clan
41 {
44
45 enum Handedness
46 {
47 handed_left,
48 handed_right
49 };
50
51 enum ClipZRange
52 {
53 clip_negative_positive_w, // OpenGL, -wclip <= zclip <= wclip
54 clip_zero_positive_w // Direct3D, 0 <= zclip <= wclip
55 };
56
57 template<typename Type>
58 class Mat2;
59
60 template<typename Type>
61 class Mat3;
62
63 template<typename Type>
64 class Mat4;
65
66 template<typename Type>
67 class Vec3;
68
69 template<typename Type>
70 class Quaternionx;
71
72 class Angle;
73
77 template<typename Type>
78 class Mat4
79 {
82
83 public:
85 Mat4()
86 {
87 for (auto & elem : matrix)
88 elem = 0;
89 }
90
92 Mat4(const Mat4<Type> &copy)
93 {
94 for (int i=0; i<16; i++)
95 matrix[i] = copy.matrix[i];
96 }
97
99 explicit Mat4(const Mat2<Type> &copy);
100
102 explicit Mat4(const Mat3<Type> &copy);
103
105 explicit Mat4(const float *init_matrix)
106 {
107 for (int i=0; i<16; i++)
108 matrix[i] = (Type) init_matrix[i];
109 }
110
112 explicit Mat4(const double *init_matrix)
113 {
114 for (int i=0; i<16; i++)
115 matrix[i] = (Type) init_matrix[i];
116 }
117
119 explicit Mat4(const int64_t *init_matrix)
120 {
121 for (int i=0; i<16; i++)
122 matrix[i] = (Type) init_matrix[i];
123 }
124
126 explicit Mat4(const int32_t *init_matrix)
127 {
128 for (int i=0; i<16; i++)
129 matrix[i] = (Type) init_matrix[i];
130 }
131
133 explicit Mat4(const int16_t *init_matrix)
134 {
135 for (int i=0; i<16; i++)
136 matrix[i] = (Type) init_matrix[i];
137 }
138
140 explicit Mat4(const int8_t *init_matrix)
141 {
142 for (int i=0; i<16; i++)
143 matrix[i] = (Type) init_matrix[i];
144 }
145
149 static Mat4<Type> null();
150
153 static Mat4<Type> identity();
154
159 static Mat4<Type> frustum(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
160
165 static Mat4<Type> perspective(
166 Type field_of_view_y_degrees,
167 Type aspect,
168 Type z_near,
169 Type z_far,
170 Handedness handedness,
171 ClipZRange clip_z);
172
177 static Mat4<Type> ortho(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
178
183 static Mat4<Type> ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z);
184
194 static Mat4<Type> rotate(const Angle &angle, Type x, Type y, Type z, bool normalize = true);
195
203 static Mat4<Type> rotate(const Angle &angle, Vec3<Type> rotation, bool normalize = true)
204 {
205 return rotate(angle, rotation.x, rotation.y, rotation.z, normalize);
206 }
207
213 static Mat4<Type> rotate(const Angle &angle_x, const Angle &angle_y, const Angle &angle_z, EulerOrder order);
214
221 static Mat4<Type> scale(Type x, Type y, Type z);
222
227 static Mat4<Type> scale(const Vec3<Type> &xyz)
228 {
229 return scale(xyz.x, xyz.y, xyz.z);
230 }
231
239 static Mat4<Type> translate(Type x, Type y, Type z);
240
246 static Mat4<Type> translate(const Vec3<Type> &xyz)
247 {
248 return translate(xyz.x, xyz.y, xyz.z);
249 }
250
264 static Mat4<Type> look_at(
265 Type eye_x, Type eye_y, Type eye_z,
266 Type center_x, Type center_y, Type center_z,
267 Type up_x, Type up_y, Type up_z);
268
276 static Mat4<Type> look_at(
277 Vec3<Type> eye,
278 Vec3<Type> center,
279 Vec3<Type> up)
280 {
281 return look_at(eye.x, eye.y, eye.z, center.x, center.y, center.z, up.x, up.y, up.z);
282 }
283
292 static Mat4<Type> multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
293
301 static Mat4<Type> add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
302
310 static Mat4<Type> subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
311
316 static Mat4<Type> adjoint(const Mat4<Type> &matrix);
317
323 static Mat4<Type> inverse(const Mat4<Type> &matrix);
324
329 static Mat4<Type> transpose(const Mat4<Type> &matrix);
330
336 static bool is_equal(const Mat4<Type> &first, const Mat4<Type> &second, Type epsilon)
337 {
338 for (int i=0; i<16; i++)
339 {
340 Type diff = second.matrix[i] - first.matrix[i];
341 if (diff < -epsilon || diff > epsilon) return false;
342 }
343 return true;
344 }
345
349
350 public:
352 Type matrix[16];
353
355 Vec3<Type> get_translate() const { return Vec3<Type>(matrix[12], matrix[13], matrix[14]); }
356
360 Vec3<Type> get_euler(EulerOrder order) const;
361
365 Vec3<Type> get_transformed_point(const Vec3<Type> &vector) const;
366
370
371 public:
381 Mat4<Type> &scale_self(Type x, Type y, Type z);
382
390 Mat4<Type> &scale_self(const Vec3<Type> &scale) { return scale_self(scale.x, scale.y, scale.z); }
391
402 Mat4<Type> &translate_self(Type x, Type y, Type z);
403
412 Mat4<Type> &translate_self(const Vec3<Type> &translation) { return translate_self(translation.x, translation.y, translation.z); }
413
424 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;}
425
434 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; }
435
439 double det() const;
440
444 Mat4<Type> &adjoint();
445
450 Mat4<Type> &inverse();
451
455 Mat4<Type> &transpose();
456
458 void decompose(Vec3<Type> &out_position, Quaternionx<Type> &out_orientation, Vec3<Type> &out_scale) const;
459
464 bool is_equal(const Mat4<Type> &other, Type epsilon) const { return Mat4<Type>::is_equal(*this, other, epsilon); }
465
469
470 public:
472 operator Type const*() const { return matrix; }
473
475 operator Type *() { return matrix; }
476
478 Type &operator[](int i) { return matrix[i]; }
479
481 const Type &operator[](int i) const { return matrix[i]; }
482
484 Type &operator[](unsigned int i) { return matrix[i]; }
485
487 const Type &operator[](unsigned int i) const { return matrix[i]; }
488
490 Mat4<Type> &operator =(const Mat4<Type> &copy) {memcpy(matrix, copy.matrix, sizeof(matrix)); return *this; }
491
493 Mat4<Type> &operator =(const Mat3<Type> &copy);
494
496 Mat4<Type> &operator =(const Mat2<Type> &copy);
497
499 Mat4<Type> operator *(const Mat4<Type> &mult) const;
500
502 Mat4<Type> operator +(const Mat4<Type> &add_matrix) const;
503
505 Mat4<Type> operator -(const Mat4<Type> &sub_matrix) const;
506
508 bool operator==(const Mat4<Type> &other) const
509 {
510 for (int i=0; i<16; i++)
511 if (matrix[i] != other.matrix[i]) return false;
512 return true;
513 }
514
516 bool operator!=(const Mat4<Type> &other) { return !((*this) == other); }
517
521
522 private:
524 };
525
526 template<typename Type>
527 inline Mat4<Type> Mat4<Type>::null() { Mat4<Type> m; memset(m.matrix, 0, sizeof(m.matrix)); return m; }
528
529 template<typename Type>
530 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; }
531
532 template<typename Type>
533 inline Mat4<Type> Mat4<Type>::multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 * matrix_2; }
534
535 template<typename Type>
536 inline Mat4<Type> Mat4<Type>::add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 + matrix_2; }
537
538 template<typename Type>
539 inline Mat4<Type> Mat4<Type>::subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 - matrix_2; }
540
541 template<typename Type>
542 inline Mat4<Type> Mat4<Type>::adjoint(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.adjoint(); return dest; }
543
544 template<typename Type>
545 inline Mat4<Type> Mat4<Type>::inverse(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.inverse(); return dest; }
546
547 template<typename Type>
548 inline Mat4<Type> Mat4<Type>::transpose(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.transpose(); return dest; }
549
550 typedef Mat4<int> Mat4i;
551 typedef Mat4<float> Mat4f;
552 typedef Mat4<double> Mat4d;
553
554 }
555
clan::Mat4::scale_self
Mat4< Type > & scale_self(const Vec3< Type > &scale)
Scale this matrix.
Definition: mat4.h:390
clan::Mat4::Mat4
Mat4(const int32_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 32 bit integers)
Definition: mat4.h:126
clan
Definition: clanapp.h:35
clan::Mat4::set_translate
Mat4< Type > & set_translate(Type x, Type y, Type z)
Set this matrix translation values.
Definition: mat4.h:424
clan::Mat4::ortho
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.
clan::Mat4::det
double det() const
Calculate the matrix determinant of this matrix.
clan::Vec3::x
Type x
Definition: vec3.h:80
clan::Mat4::Mat4
Mat4(const double *init_matrix)
Constructs a 4x4 matrix (copied from a array of doubles)
Definition: mat4.h:112
clan::Mat4::set_translate
Mat4< Type > & set_translate(const Vec3< Type > &translation)
Set this matrix translation values.
Definition: mat4.h:434
clan::Mat4::translate_self
Mat4< Type > & translate_self(Type x, Type y, Type z)
Translate this matrix.
clan::Angle
Angle class.
Definition: angle.h:62
clan::Mat4::operator-
Mat4< Type > operator-(const Mat4< Type > &sub_matrix) const
Subtraction operator.
clan::Vec3::y
Type y
Definition: vec3.h:81
clan::Mat4::subtract
static Mat4< Type > subtract(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Subtract 2 matrices.
Definition: mat4.h:539
clan::Mat4::Mat4
Mat4(const Mat4< Type > &copy)
Constructs a 4x4 matrix (copied)
Definition: mat4.h:92
clan::Mat4::Mat4
Mat4(const int8_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 8 bit integers)
Definition: mat4.h:140
clan::Key::x
clan::Mat4::look_at
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.
clan::Mat4::get_translate
Vec3< Type > get_translate() const
Returns the translation coordinates for this matrix (in column-major format)
Definition: mat4.h:355
clan::Mat4::operator=
Mat4< Type > & operator=(const Mat4< Type > &copy)
Copy assignment operator.
Definition: mat4.h:490
clan::Mat4::operator+
Mat4< Type > operator+(const Mat4< Type > &add_matrix) const
Addition operator.
clan::Mat4::get_transformed_point
Vec3< Type > get_transformed_point(const Vec3< Type > &vector) const
Get a transformed point from the matrix (in column-major format)
clan::clip_negative_positive_w
Definition: mat4.h:53
clan::Key::up
clan::ClipZRange
ClipZRange
Definition: mat4.h:51
clan::Mat4::translate
static Mat4< Type > translate(const Vec3< Type > &xyz)
Create a translation matrix.
Definition: mat4.h:246
clan::Mat4::Mat4
Mat4(const int16_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 16 bit integers)
Definition: mat4.h:133
clan::Mat4::identity
static Mat4< Type > identity()
Create the identity matrix.
Definition: mat4.h:530
clan::Mat4::null
static Mat4< Type > null()
Create a zero matrix.
Definition: mat4.h:527
clan::Mat4::translate_self
Mat4< Type > & translate_self(const Vec3< Type > &translation)
Translate this matrix.
Definition: mat4.h:412
clan::Mat4::Mat4
Mat4(const int64_t *init_matrix)
Constructs a 4x4 matrix (copied from a array of 64 bit integers)
Definition: mat4.h:119
clan::Handedness
Handedness
Definition: mat4.h:45
clan::Mat4::look_at
static Mat4< Type > look_at(Vec3< Type > eye, Vec3< Type > center, Vec3< Type > up)
Create the "look at" matrix.
Definition: mat4.h:276
clan::Mat4::adjoint
static Mat4< Type > adjoint(const Mat4< Type > &matrix)
Calculate the adjoint (or known as Adjugate or Conjugate Transpose) of a matrix.
Definition: mat4.h:542
clan::Mat4::operator!=
bool operator!=(const Mat4< Type > &other)
Not-equal operator.
Definition: mat4.h:516
clan::Mat4::rotate
static Mat4< Type > rotate(const Angle &angle, Vec3< Type > rotation, bool normalize=true)
Create a rotation matrix.
Definition: mat4.h:203
clan::Key::m
clan::Quaternionx
Quaternion.
Definition: mat4.h:70
clan::Key::y
clan::Mat4::Mat4
Mat4()
Constructs a 4x4 matrix (zero'ed)
Definition: mat4.h:85
clan::Mat4::multiply
static Mat4< Type > multiply(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Multiply 2 matrices.
Definition: mat4.h:533
clan::Mat2
2D matrix
Definition: mat2.h:45
clan::Mat4::operator*
Mat4< Type > operator*(const Mat4< Type > &mult) const
Multiplication operator.
clan::StyleValueType::angle
value is a color
clan::Mat4::operator[]
Type & operator[](int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:478
clan::Mat4::Mat4
Mat4(const float *init_matrix)
Constructs a 4x4 matrix (copied from a array of floats)
Definition: mat4.h:105
clan::Mat4::transpose
Mat4< Type > & transpose()
Calculate the transpose of this matrix.
clan::Mat3
3D matrix
Definition: mat2.h:48
clan::clip_zero_positive_w
Definition: mat4.h:54
clan::Mat4::decompose
void decompose(Vec3< Type > &out_position, Quaternionx< Type > &out_orientation, Vec3< Type > &out_scale) const
Decompose matrix into position, orientation/rotation and scale.
clan::Mat4::is_equal
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:336
clan::StyleTokenType::null
clan::Vec3
3D vector
Definition: line_ray.h:48
clan::Mat4::scale
static Mat4< Type > scale(Type x, Type y, Type z)
Create a scale matrix.
clan::Mat4::translate
static Mat4< Type > translate(Type x, Type y, Type z)
Create a translation matrix.
clan::Mat4::rotate
static Mat4< Type > rotate(const Angle &angle, Type x, Type y, Type z, bool normalize=true)
Create a rotation matrix.
clan::Mat4::operator[]
Type & operator[](unsigned int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:484
clan::Key::i
clan::handed_right
Definition: mat4.h:48
clan::Key::left
clan::Mat4::operator==
bool operator==(const Mat4< Type > &other) const
Equality operator.
Definition: mat4.h:508
clan::EulerOrder
EulerOrder
Euler angle rotation order.
Definition: angle.h:50
clan::Key::right
clan::Mat4d
Mat4< double > Mat4d
Definition: mat4.h:552
clan::TextAlignment::center
clan::Mat4::ortho_2d
static Mat4< Type > ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z)
Create a ortho_2d matrix.
clan::Mat4::transpose
static Mat4< Type > transpose(const Mat4< Type > &matrix)
Calculate the transpose of a matrix.
Definition: mat4.h:548
clan::Mat4::inverse
static Mat4< Type > inverse(const Mat4< Type > &matrix)
Calculate the matrix inverse of a matrix.
Definition: mat4.h:545
clan::Mat4f
Mat4< float > Mat4f
Definition: mat4.h:551
clan::Mat4::is_equal
bool is_equal(const Mat4< Type > &other, Type epsilon) const
Returns true if equal within the bounds of an epsilon.
Definition: mat4.h:464
clan::Mat4
4D matrix
Definition: mat2.h:51
clan::Mat4::operator[]
const Type & operator[](unsigned int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:487
clan::Mat4::matrix
Type matrix[16]
The matrix (in column-major format)
Definition: mat4.h:352
clan::Mat4::get_euler
Vec3< Type > get_euler(EulerOrder order) const
Extract the euler angles (in radians) from a matrix (in column-major format)
clan::Mat4i
Mat4< int > Mat4i
Definition: mat4.h:550
clan::Mat4::adjoint
Mat4< Type > & adjoint()
Calculate the adjoint (or known as adjugate) of this matrix.
clan::handed_left
Definition: mat4.h:47
clan::Mat4::scale_self
Mat4< Type > & scale_self(Type x, Type y, Type z)
Scale this matrix.
clan::Mat4::frustum
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.
clan::Mat4::operator[]
const Type & operator[](int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:481
clan::Mat4::scale
static Mat4< Type > scale(const Vec3< Type > &xyz)
Create a scale matrix.
Definition: mat4.h:227
clan::Vec3::z
Type z
Definition: vec3.h:82
clan::Mat4::inverse
Mat4< Type > & inverse()
Calculate the matrix inverse of this matrix.
clan::Mat4::add
static Mat4< Type > add(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Add 2 matrices.
Definition: mat4.h:536
clan::Mat4::perspective
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.
clan::Key::z