mat4.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2013 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 "../api_core.h"
35 #include "../System/cl_platform.h"
36 #include "mat2.h"
37 #include "mat3.h"
38 #include "vec3.h"
39 #include "angle.h"
40 
41 namespace clan
42 {
45 
47 {
50 };
51 
53 {
54  clip_negative_positive_w, // OpenGL, -wclip <= zclip <= wclip
55  clip_zero_positive_w // Direct3D, 0 <= zclip <= wclip
56 };
57 
58 template<typename Type>
59 class Mat2;
60 
61 template<typename Type>
62 class Mat3;
63 
64 template<typename Type>
65 class Mat4;
66 
67 template<typename Type>
68 class Vec3;
69 
70 template<typename Type>
72 
73 class Angle;
74 
78 template<typename Type>
79 class Mat4
80 {
83 
84 public:
86  Mat4()
87  {
88  for (int i=0; i<16; i++)
89  matrix[i] = 0;
90  }
91 
93  Mat4(const Mat4<Type> &copy)
94  {
95  for (int i=0; i<16; i++)
96  matrix[i] = copy.matrix[i];
97  }
98 
100  explicit Mat4(const Mat2<Type> &copy);
101 
103  explicit Mat4(const Mat3<Type> &copy);
104 
106  explicit Mat4(const float *init_matrix)
107  {
108  for (int i=0; i<16; i++)
109  matrix[i] = (Type) init_matrix[i];
110  }
111 
113  explicit Mat4(const double *init_matrix)
114  {
115  for (int i=0; i<16; i++)
116  matrix[i] = (Type) init_matrix[i];
117  }
118 
120  explicit Mat4(const byte64 *init_matrix)
121  {
122  for (int i=0; i<16; i++)
123  matrix[i] = (Type) init_matrix[i];
124  }
125 
127  explicit Mat4(const byte32 *init_matrix)
128  {
129  for (int i=0; i<16; i++)
130  matrix[i] = (Type) init_matrix[i];
131  }
132 
134  explicit Mat4(const byte16 *init_matrix)
135  {
136  for (int i=0; i<16; i++)
137  matrix[i] = (Type) init_matrix[i];
138  }
139 
141  explicit Mat4(const byte8 *init_matrix)
142  {
143  for (int i=0; i<16; i++)
144  matrix[i] = (Type) init_matrix[i];
145  }
146 
150  static Mat4<Type> null();
151 
154  static Mat4<Type> identity();
155 
160  static Mat4<Type> frustum(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
161 
166  static Mat4<Type> perspective(
167  Type field_of_view_y_degrees,
168  Type aspect,
169  Type z_near,
170  Type z_far,
171  Handedness handedness,
172  ClipZRange clip_z);
173 
178  static Mat4<Type> ortho(Type left, Type right, Type bottom, Type top, Type z_near, Type z_far, Handedness handedness, ClipZRange clip_z);
179 
184  static Mat4<Type> ortho_2d(Type left, Type right, Type bottom, Type top, Handedness handedness, ClipZRange clip_z);
185 
195  static Mat4<Type> rotate(const Angle &angle, Type x, Type y, Type z, bool normalize = true);
196 
204  static Mat4<Type> rotate(const Angle &angle, Vec3<Type> rotation, bool normalize = true)
205  {
206  return rotate(angle, rotation.x, rotation.y, rotation.z, normalize);
207  }
208 
214  static Mat4<Type> rotate(const Angle &angle_x, const Angle &angle_y, const Angle &angle_z, EulerOrder order);
215 
222  static Mat4<Type> scale(Type x, Type y, Type z);
223 
229  {
230  return scale(xyz.x, xyz.y, xyz.z);
231  }
232 
240  static Mat4<Type> translate(Type x, Type y, Type z);
241 
248  {
249  return translate(xyz.x, xyz.y, xyz.z);
250  }
251 
265  static Mat4<Type> look_at(
266  Type eye_x, Type eye_y, Type eye_z,
267  Type center_x, Type center_y, Type center_z,
268  Type up_x, Type up_y, Type up_z);
269 
278  Vec3<Type> eye,
279  Vec3<Type> center,
280  Vec3<Type> up)
281  {
282  return look_at(eye.x, eye.y, eye.z, center.x, center.y, center.z, up.x, up.y, up.z);
283  }
284 
293  static Mat4<Type> multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
294 
302  static Mat4<Type> add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
303 
311  static Mat4<Type> subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2);
312 
317  static Mat4<Type> adjoint(const Mat4<Type> &matrix);
318 
324  static Mat4<Type> inverse(const Mat4<Type> &matrix);
325 
330  static Mat4<Type> transpose(const Mat4<Type> &matrix);
331 
337  static bool is_equal(const Mat4<Type> &first, const Mat4<Type> &second, Type epsilon)
338  {
339  for (int i=0; i<16; i++)
340  {
341  Type diff = second.matrix[i] - first.matrix[i];
342  if (diff < -epsilon || diff > epsilon) return false;
343  }
344  return true;
345  }
346 
350 
351 public:
353  Type matrix[16];
354 
356  Type get_origin_x() const { return matrix[12]; }
357 
359  Type get_origin_y() const { return matrix[13]; }
360 
362  Type get_origin_z() const { return matrix[14]; }
363 
367  Vec3<Type> get_euler(EulerOrder order) const;
368 
372  Vec3<Type> get_transformed_point(const Vec3<Type> &vector) const;
373 
377 
378 public:
388  Mat4<Type> &scale_self(Type x, Type y, Type z);
389 
400  Mat4<Type> &translate_self(Type x, Type y, Type z);
401 
405  double det() const;
406 
410  Mat4<Type> &adjoint();
411 
416  Mat4<Type> &inverse();
417 
422 
424  void decompose(Vec3<Type> &out_position, Quaternionx<Type> &out_orientation, Vec3<Type> &out_scale) const;
425 
430  bool is_equal(const Mat4<Type> &other, Type epsilon) const { return Mat4<Type>::is_equal(*this, other, epsilon); }
431 
435 
436 public:
438  operator Type const*() const { return matrix; }
439 
441  operator Type *() { return matrix; }
442 
444  Type &operator[](int i) { return matrix[i]; }
445 
447  const Type &operator[](int i) const { return matrix[i]; }
448 
450  Type &operator[](unsigned int i) { return matrix[i]; }
451 
453  const Type &operator[](unsigned int i) const { return matrix[i]; }
454 
456  Mat4<Type> &operator =(const Mat4<Type> &copy) {memcpy(matrix, copy.matrix, sizeof(matrix)); return *this; }
457 
459  Mat4<Type> &operator =(const Mat3<Type> &copy);
460 
462  Mat4<Type> &operator =(const Mat2<Type> &copy);
463 
465  Mat4<Type> operator *(const Mat4<Type> &mult) const;
466 
468  Mat4<Type> operator +(const Mat4<Type> &add_matrix) const;
469 
471  Mat4<Type> operator -(const Mat4<Type> &sub_matrix) const;
472 
474  bool operator==(const Mat4<Type> &other) const
475  {
476  for (int i=0; i<16; i++)
477  if (matrix[i] != other.matrix[i]) return false;
478  return true;
479  }
480 
482  bool operator!=(const Mat4<Type> &other) { return !((*this) == other); }
483 
487 
488 private:
490 };
491 
492 template<typename Type>
493 inline Mat4<Type> Mat4<Type>::null() { Mat4<Type> m; memset(m.matrix, 0, sizeof(m.matrix)); return m; }
494 
495 template<typename Type>
496 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; }
497 
498 template<typename Type>
499 inline Mat4<Type> Mat4<Type>::multiply(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 * matrix_2; }
500 
501 template<typename Type>
502 inline Mat4<Type> Mat4<Type>::add(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 + matrix_2; }
503 
504 template<typename Type>
505 inline Mat4<Type> Mat4<Type>::subtract(const Mat4<Type> &matrix_1, const Mat4<Type> &matrix_2) { return matrix_1 - matrix_2; }
506 
507 template<typename Type>
508 inline Mat4<Type> Mat4<Type>::adjoint(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.adjoint(); return dest; }
509 
510 template<typename Type>
511 inline Mat4<Type> Mat4<Type>::inverse(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.inverse(); return dest; }
512 
513 template<typename Type>
514 inline Mat4<Type> Mat4<Type>::transpose(const Mat4<Type> &matrix) { Mat4<Type> dest(matrix); dest.transpose(); return dest; }
515 
516 typedef Mat4<int> Mat4i;
519 
520 }
521 
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.
double det() const
Calculate the matrix determinant of this matrix.
Type x
Definition: vec3.h:81
Mat4(const double *init_matrix)
Constructs a 4x4 matrix (copied from a array of doubles)
Definition: mat4.h:113
Mat4< Type > & translate_self(Type x, Type y, Type z)
Translate this matrix.
Angle class.
Definition: angle.h:63
Mat4< Type > operator-(const Mat4< Type > &sub_matrix) const
Subtraction operator.
Type y
Definition: vec3.h:82
static Mat4< Type > subtract(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Subtract 2 matrices.
Definition: mat4.h:505
Mat4(const Mat4< Type > &copy)
Constructs a 4x4 matrix (copied)
Definition: mat4.h:93
char byte8
Definition: cl_platform.h:59
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< Type > & operator=(const Mat4< Type > &copy)
Copy assignment operator.
Definition: mat4.h:456
Mat4< Type > operator+(const Mat4< Type > &add_matrix) const
Addition operator.
Mat4(const byte64 *init_matrix)
Constructs a 4x4 matrix (copied from a array of 64 bit integers)
Definition: mat4.h:120
Vec3< Type > get_transformed_point(const Vec3< Type > &vector) const
Get a transformed point from the matrix (in column-major format)
Definition: mat4.h:54
ClipZRange
Definition: mat4.h:52
Type get_origin_y() const
Returns the y coordinate for the point (0,0,0) multiplied with this matrix.
Definition: mat4.h:359
Mat4(const byte16 *init_matrix)
Constructs a 4x4 matrix (copied from a array of 16 bit integers)
Definition: mat4.h:134
static Mat4< Type > identity()
Create the identity matrix.
Definition: mat4.h:496
static Mat4< Type > null()
Create a zero matrix.
Definition: mat4.h:493
static Mat4< Type > scale(Vec3< Type > xyz)
Create a scale matrix.
Definition: mat4.h:228
Handedness
Definition: mat4.h:46
Mat4(const byte32 *init_matrix)
Constructs a 4x4 matrix (copied from a array of 32 bit integers)
Definition: mat4.h:127
static Mat4< Type > look_at(Vec3< Type > eye, Vec3< Type > center, Vec3< Type > up)
Create the "look at" matrix.
Definition: mat4.h:277
static Mat4< Type > adjoint(const Mat4< Type > &matrix)
Calculate the adjoint (or known as Adjugate or Conjugate Transpose) of a matrix.
Definition: mat4.h:508
bool operator!=(const Mat4< Type > &other)
Not-equal operator.
Definition: mat4.h:482
static Mat4< Type > rotate(const Angle &angle, Vec3< Type > rotation, bool normalize=true)
Create a rotation matrix.
Definition: mat4.h:204
Quaternion.
Definition: mat4.h:71
Mat4()
Constructs a 4x4 matrix (null)
Definition: mat4.h:86
static Mat4< Type > multiply(const Mat4< Type > &matrix_1, const Mat4< Type > &matrix_2)
Multiply 2 matrices.
Definition: mat4.h:499
2D matrix
Definition: mat2.h:46
Type get_origin_z() const
Returns the z coordinate for the point (0,0,0) multiplied with this matrix.
Definition: mat4.h:362
Mat4< Type > operator*(const Mat4< Type > &mult) const
Multiplication operator.
Mat4(const byte8 *init_matrix)
Constructs a 4x4 matrix (copied from a array of 8 bit integers)
Definition: mat4.h:141
Type & operator[](int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:444
Mat4(const float *init_matrix)
Constructs a 4x4 matrix (copied from a array of floats)
Definition: mat4.h:106
Mat4< Type > & transpose()
Calculate the transpose of this matrix.
3D matrix
Definition: mat2.h:49
Definition: mat4.h:55
int byte32
Definition: cl_platform.h:63
long long byte64
Definition: cl_platform.h:65
void decompose(Vec3< Type > &out_position, Quaternionx< Type > &out_orientation, Vec3< Type > &out_scale) const
Decompose matrix into position, orientation/rotation and scale.
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:337
3D vector
Definition: line_ray.h:49
static Mat4< Type > scale(Type x, Type y, Type z)
Create a scale matrix.
Type get_origin_x() const
Returns the x coordinate for the point (0,0,0) multiplied with this matrix.
Definition: mat4.h:356
static Mat4< Type > translate(Type x, Type y, Type z)
Create a translation matrix.
static Mat4< Type > rotate(const Angle &angle, Type x, Type y, Type z, bool normalize=true)
Create a rotation matrix.
Type & operator[](unsigned int i)
Operator that returns the matrix cell at the given index.
Definition: mat4.h:450
Definition: mat4.h:49
bool operator==(const Mat4< Type > &other) const
Equality operator.
Definition: mat4.h:474
EulerOrder
Euler angle rotation order.
Definition: angle.h:51
Mat4< double > Mat4d
Definition: mat4.h:518
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 > transpose(const Mat4< Type > &matrix)
Calculate the transpose of a matrix.
Definition: mat4.h:514
static Mat4< Type > inverse(const Mat4< Type > &matrix)
Calculate the matrix inverse of a matrix.
Definition: mat4.h:511
Mat4< float > Mat4f
Definition: mat4.h:517
bool is_equal(const Mat4< Type > &other, Type epsilon) const
Returns true if equal within the bounds of an epsilon.
Definition: mat4.h:430
4D matrix
Definition: mat2.h:52
const Type & operator[](unsigned int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:453
Type matrix[16]
The matrix (in column-major format)
Definition: mat4.h:353
Vec3< Type > get_euler(EulerOrder order) const
Extract the euler angles (in radians) from a matrix (in column-major format)
Mat4< int > Mat4i
Definition: mat4.h:516
Mat4< Type > & adjoint()
Calculate the adjoint (or known as adjugate) of this matrix.
Definition: mat4.h:48
static Mat4< Type > translate(Vec3< Type > xyz)
Create a translation matrix.
Definition: mat4.h:247
Mat4< Type > & scale_self(Type x, Type y, Type z)
Scale this matrix.
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.
const Type & operator[](int i) const
Operator that returns the matrix cell at the given index.
Definition: mat4.h:447
Type z
Definition: vec3.h:83
short byte16
Definition: cl_platform.h:61
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:502
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.