10
// Our matrices are Row major just like C/C++:
11
// m[2][3] represent the element at row 2 and column 3.
12
// When multiplying a vector by a matrix, the vector is a column at the right of the matrix
14
// |a00, a01, a02, a03| |v0|
15
// |a10, a11, a12, a13| * |v1|
16
// |a20, a21, a22, a23| |v2|
17
// |a30, a31, a32, a33| |v3|
19
// Note: OpenGL is column major. Before passing it a Matrix4x4 through glLoadMatrix, transpose it.
27
Matrix4x4<T>(const Matrix4x4&);
29
T a00, T a01, T a02, T a03,
30
T a10, T a11, T a12, T a13,
31
T a20, T a21, T a22, T a23,
32
T a30, T a31, T a32, T a33);
34
Matrix4x4<T>& operator = (const Matrix4x4<T>&);
35
t_bool operator == (const Matrix4x4<T>&);
36
Matrix4x4<T> operator * (const Matrix4x4<T>&) const;
37
Matrix4x4<T> operator + (const Matrix4x4<T>&) const;
38
Matrix4x4<T> operator - (const Matrix4x4<T>&) const;
39
Matrix4x4<T>& operator *= (const Matrix4x4<T>&) const;
40
Matrix4x4<T>& operator += (const Matrix4x4<T>&) const;
41
Matrix4x4<T>& operator -= (const Matrix4x4<T>&) const;
43
Matrix4x4<T> operator * (const T&) const;
44
Matrix4x4<T> operator / (const T&) const;
45
Matrix4x4<T> operator *= (const T&) const;
46
Matrix4x4<T> operator /= (const T&) const;
48
Vector4 operator * (const Vector4&) const;
49
Matrix4x4<T> operator - ();
51
// Get the (i, j) element of the current matrix.
52
T& operator()(unsigned int i, unsigned int j);
53
T operator ()(unsigned int i, unsigned int j) const;
55
// Get a pointer to the current matrix.
57
operator const T *() const;
60
void Translate(T x, T y, T z);
61
void Translate(const Vector3 &);
63
void Rotate_x(T angle);
64
void Rotate_y(T angle);
65
void Rotate_z(T angle);
66
void Scale(T sx, T sy, T sz);
70
T Determinant() const ;
72
Matrix4x4<T> GetInverse() const;
75
//Matrix3x3<T> GetUpper3x3() const;
76
//Matrix2x2<T> GetUpper2x2() const;
78
///////////////////////////////////////////////
80
void Diagonal(T x, T y, T z, T w = T(1));
81
void Rotate(T angle, Vector3 axis);
84
void LookAt(const Vector3 &eye, const Vector3 &at, const Vector3 &up);
85
void Orthographic(T l, T r, T b, T t, T n, T f);
86
void Perspective(T l, T r, T t, T b, T n, T f);
87
void PerspectiveInverse(T l, T r, T t, T b, T n, T f);
88
void Perspective(T FoV, T AspectRatio, T NearPlane, T FarPlane);
93
static Matrix4x4<T> IDENTITY();
94
static Matrix4x4<T> ZERO();
99
/***************************************************************************************\
100
Function: Matrix4x4<T>::Matrix4x4<T>
102
Description: Constructor. Initialize the matrix to identity.
109
\***************************************************************************************/
111
Matrix4x4<T>::Matrix4x4()
116
/***************************************************************************************\
117
Function: Matrix4x4<T>::~Matrix4x4
119
Description: Destructor.
126
\***************************************************************************************/
128
Matrix4x4<T>::~Matrix4x4()
133
/***************************************************************************************\
134
Function: Matrix4x4<T>::Matrix4x4
143
\***************************************************************************************/
145
Matrix4x4<T>::Matrix4x4(const Matrix4x4& M)
147
m[0][0] = M.m[0][0]; m[0][1] = M.m[0][1]; m[0][2] = M.m[0][2]; m[0][3] = M.m[0][3];
148
m[1][0] = M.m[1][0]; m[1][1] = M.m[1][1]; m[1][2] = M.m[1][2]; m[1][3] = M.m[1][3];
149
m[2][0] = M.m[2][0]; m[2][1] = M.m[2][1]; m[2][2] = M.m[2][2]; m[2][3] = M.m[2][3];
150
m[3][0] = M.m[3][0]; m[3][1] = M.m[3][1]; m[3][2] = M.m[3][2]; m[3][3] = M.m[3][3];
153
/***************************************************************************************\
154
Function: Matrix4x4<T>::Matrix4x4
158
Parameters: T a00, T a01, T a02, T a03,
159
T a10, T a11, T a12, T a13,
160
T a20, T a21, T a22, T a23,
161
T a30, T a31, T a32, T a33
166
\***************************************************************************************/
168
Matrix4x4<T>::Matrix4x4(
169
T a00, T a01, T a02, T a03,
170
T a10, T a11, T a12, T a13,
171
T a20, T a21, T a22, T a23,
172
T a30, T a31, T a32, T a33)
174
m[0][0] = a00; m[0][1] = a01; m[0][2] = a02; m[0][3] = a03;
175
m[1][0] = a10; m[1][1] = a11; m[1][2] = a12; m[1][3] = a13;
176
m[2][0] = a20; m[2][1] = a21; m[2][2] = a22; m[2][3] = a23;
177
m[3][0] = a30; m[3][1] = a31; m[3][2] = a32; m[3][3] = a33;
180
/***************************************************************************************\
181
Function: Matrix4x4<T>::Matrix4x4
183
Description: Assignment operator.
187
Return Value: Matrix4x4<T>.
190
\***************************************************************************************/
192
Matrix4x4<T>& Matrix4x4<T>::operator = (const Matrix4x4<T>& M)
194
m[0][0] = M.m[0][0]; m[0][1] = M.m[0][1]; m[0][2] = M.m[0][2]; m[0][3] = M.m[0][3];
195
m[1][0] = M.m[1][0]; m[1][1] = M.m[1][1]; m[1][2] = M.m[1][2]; m[1][3] = M.m[1][3];
196
m[2][0] = M.m[2][0]; m[2][1] = M.m[2][1]; m[2][2] = M.m[2][2]; m[2][3] = M.m[2][3];
197
m[3][0] = M.m[3][0]; m[3][1] = M.m[3][1]; m[3][2] = M.m[3][2]; m[3][3] = M.m[3][3];
202
template <typename T>
203
t_bool Matrix4x4<T>::operator == (const Matrix4x4<T>& M)
205
for(int i = 0; i < 4; i++)
206
for(int j = 0; j < 4; j++)
208
if(m[i][j] != M.m[i][j])
215
/***************************************************************************************\
216
Function: Matrix4x4<T>::operator *
218
Description: Multiply by matrix iM.
222
Return Value: Matrix4x4<T>.
225
\***************************************************************************************/
227
Matrix4x4<T> Matrix4x4<T>::operator * (const Matrix4x4<T>& iM) const
231
// Output matrix first row
232
oM.m[0][0] = m[0][0] * iM.m[0][0] + m[0][1] * iM.m[1][0] + m[0][2] * iM.m[2][0] + m[0][3] * iM.m[3][0];
233
oM.m[0][1] = m[0][0] * iM.m[0][1] + m[0][1] * iM.m[1][1] + m[0][2] * iM.m[2][1] + m[0][3] * iM.m[3][1];
234
oM.m[0][2] = m[0][0] * iM.m[0][2] + m[0][1] * iM.m[1][2] + m[0][2] * iM.m[2][2] + m[0][3] * iM.m[3][2];
235
oM.m[0][3] = m[0][0] * iM.m[0][3] + m[0][1] * iM.m[1][3] + m[0][2] * iM.m[2][3] + m[0][3] * iM.m[3][3];
237
// Output matrix second row
238
oM.m[1][0] = m[1][0] * iM.m[0][0] + m[1][1] * iM.m[1][0] + m[1][2] * iM.m[2][0] + m[1][3] * iM.m[3][0];
239
oM.m[1][1] = m[1][0] * iM.m[0][1] + m[1][1] * iM.m[1][1] + m[1][2] * iM.m[2][1] + m[1][3] * iM.m[3][1];
240
oM.m[1][2] = m[1][0] * iM.m[0][2] + m[1][1] * iM.m[1][2] + m[1][2] * iM.m[2][2] + m[1][3] * iM.m[3][2];
241
oM.m[1][3] = m[1][0] * iM.m[0][3] + m[1][1] * iM.m[1][3] + m[1][2] * iM.m[2][3] + m[1][3] * iM.m[3][3];
243
// Output matrix third row
244
oM.m[2][0] = m[2][0] * iM.m[0][0] + m[2][1] * iM.m[1][0] + m[2][2] * iM.m[2][0] + m[2][3] * iM.m[3][0];
245
oM.m[2][1] = m[2][0] * iM.m[0][1] + m[2][1] * iM.m[1][1] + m[2][2] * iM.m[2][1] + m[2][3] * iM.m[3][1];
246
oM.m[2][2] = m[2][0] * iM.m[0][2] + m[2][1] * iM.m[1][2] + m[2][2] * iM.m[2][2] + m[2][3] * iM.m[3][2];
247
oM.m[2][3] = m[2][0] * iM.m[0][3] + m[2][1] * iM.m[1][3] + m[2][2] * iM.m[2][3] + m[2][3] * iM.m[3][3];
249
// Output matrix fourth row
250
oM.m[3][0] = m[3][0] * iM.m[0][0] + m[3][1] * iM.m[1][0] + m[3][2] * iM.m[2][0] + m[3][3] * iM.m[3][0];
251
oM.m[3][1] = m[3][0] * iM.m[0][1] + m[3][1] * iM.m[1][1] + m[3][2] * iM.m[2][1] + m[3][3] * iM.m[3][1];
252
oM.m[3][2] = m[3][0] * iM.m[0][2] + m[3][1] * iM.m[1][2] + m[3][2] * iM.m[2][2] + m[3][3] * iM.m[3][2];
253
oM.m[3][3] = m[3][0] * iM.m[0][3] + m[3][1] * iM.m[1][3] + m[3][2] * iM.m[2][3] + m[3][3] * iM.m[3][3];
258
/***************************************************************************************\
259
Function: Matrix4x4<T>::operator +
261
Description: Add matrix iM.
265
Return Value: Matrix4x4<T>.
268
\***************************************************************************************/
270
Matrix4x4<T> Matrix4x4<T>::operator + (const Matrix4x4<T>& iM) const
274
oM.m[0][0] = m[0][0]+iM.m[0][0]; oM.m[0][1] = m[0][1]+iM.m[0][1]; oM.m[0][2] = m[0][2]+iM.m[0][2]; oM.m[0][3] = m[0][3]+iM.m[0][3];
275
oM.m[1][0] = m[1][0]+iM.m[1][0]; oM.m[1][1] = m[1][1]+iM.m[1][1]; oM.m[1][2] = m[1][2]+iM.m[1][2]; oM.m[1][3] = m[1][3]+iM.m[1][3];
276
oM.m[2][0] = m[2][0]+iM.m[2][0]; oM.m[2][1] = m[2][1]+iM.m[2][1]; oM.m[2][2] = m[2][2]+iM.m[2][2]; oM.m[2][3] = m[2][3]+iM.m[2][3];
277
oM.m[3][0] = m[3][0]+iM.m[3][0]; oM.m[3][1] = m[3][1]+iM.m[3][1]; oM.m[3][2] = m[3][2]+iM.m[3][2]; oM.m[3][3] = m[3][3]+iM.m[3][3];
282
/***************************************************************************************\
283
Function: Matrix4x4<T>::operator -
285
Description: Substract matrix iM.
289
Return Value: Matrix4x4<T>.
292
\***************************************************************************************/
294
Matrix4x4<T> Matrix4x4<T>::operator - (const Matrix4x4<T>& iM) const
298
oM.m[0][0] = m[0][0]-iM.m[0][0]; oM.m[0][1] = m[0][1]-iM.m[0][1]; oM.m[0][2] = m[0][2]-iM.m[0][2]; oM.m[0][3] = m[0][3]-iM.m[0][3];
299
oM.m[1][0] = m[1][0]-iM.m[1][0]; oM.m[1][1] = m[1][1]-iM.m[1][1]; oM.m[1][2] = m[1][2]-iM.m[1][2]; oM.m[1][3] = m[1][3]-iM.m[1][3];
300
oM.m[2][0] = m[2][0]-iM.m[2][0]; oM.m[2][1] = m[2][1]-iM.m[2][1]; oM.m[2][2] = m[2][2]-iM.m[2][2]; oM.m[2][3] = m[2][3]-iM.m[2][3];
301
oM.m[3][0] = m[3][0]-iM.m[3][0]; oM.m[3][1] = m[3][1]-iM.m[3][1]; oM.m[3][2] = m[3][2]-iM.m[3][2]; oM.m[3][3] = m[3][3]-iM.m[3][3];
310
/***************************************************************************************\
311
Function: Matrix4x4<T>::operator *=
313
Description: Multiply by matrix iM.
317
Return Value: Matrix4x4<T>.
320
\***************************************************************************************/
322
Matrix4x4<T>& Matrix4x4<T>::operator *= (const Matrix4x4<T>& iM) const
326
oM.m[0][0] = m[0][0] * iM.m[0][0] + m[0][1] * iM.m[1][0] + m[0][2] * iM.m[2][0] + m[0][3] * iM.m[3][0];
327
oM.m[1][0] = m[1][0] * iM.m[0][0] + m[1][1] * iM.m[1][0] + m[1][2] * iM.m[2][0] + m[1][3] * iM.m[3][0];
328
oM.m[2][0] = m[2][0] * iM.m[0][0] + m[2][1] * iM.m[1][0] + m[2][2] * iM.m[2][0] + m[2][3] * iM.m[3][0];
329
oM.m[3][0] = m[3][0] * iM.m[0][0] + m[3][1] * iM.m[1][0] + m[3][2] * iM.m[2][0] + m[3][3] * iM.m[3][0];
331
oM.m[0][1] = m[0][0] * iM.m[0][1] + m[0][1] * iM.m[1][1] + m[0][2] * iM.m[2][1] + m[0][3] * iM.m[3][1];
332
oM.m[1][1] = m[1][0] * iM.m[0][1] + m[1][1] * iM.m[1][1] + m[1][2] * iM.m[2][1] + m[1][3] * iM.m[3][1];
333
oM.m[2][1] = m[2][0] * iM.m[0][1] + m[2][1] * iM.m[1][1] + m[2][2] * iM.m[2][1] + m[2][3] * iM.m[3][1];
334
oM.m[3][1] = m[3][0] * iM.m[0][1] + m[3][1] * iM.m[1][1] + m[3][2] * iM.m[2][1] + m[3][3] * iM.m[3][1];
336
oM.m[0][2] = m[0][0] * iM.m[0][2] + m[0][1] * iM.m[1][2] + m[0][2] * iM.m[2][2] + m[0][3] * iM.m[3][2];
337
oM.m[1][2] = m[1][0] * iM.m[0][2] + m[1][1] * iM.m[1][2] + m[1][2] * iM.m[2][2] + m[1][3] * iM.m[3][2];
338
oM.m[2][2] = m[2][0] * iM.m[0][2] + m[2][1] * iM.m[1][2] + m[2][2] * iM.m[2][2] + m[2][3] * iM.m[3][2];
339
oM.m[3][2] = m[3][0] * iM.m[0][2] + m[3][1] * iM.m[1][2] + m[3][2] * iM.m[2][2] + m[3][3] * iM.m[3][2];
341
oM.m[0][3] = m[0][0] * iM.m[0][3] + m[0][1] * iM.m[1][3] + m[0][2] * iM.m[2][3] + m[0][3] * iM.m[3][3];
342
oM.m[1][3] = m[1][0] * iM.m[0][3] + m[1][1] * iM.m[1][3] + m[1][2] * iM.m[2][3] + m[1][3] * iM.m[3][3];
343
oM.m[2][3] = m[2][0] * iM.m[0][3] + m[2][1] * iM.m[1][3] + m[2][2] * iM.m[2][3] + m[2][3] * iM.m[3][3];
344
oM.m[3][3] = m[3][0] * iM.m[0][3] + m[3][1] * iM.m[1][3] + m[3][2] * iM.m[2][3] + m[3][3] * iM.m[3][3];
350
/***************************************************************************************\
351
Function: Matrix4x4<T>::operator +=
353
Description: Add matrix iM.
357
Return Value: Matrix4x4<T>.
360
\***************************************************************************************/
362
Matrix4x4<T>& Matrix4x4<T>::operator += (const Matrix4x4<T>& iM) const
366
oM.m[0][0] = m[0][0]+iM.m[0][0]; oM.m[0][1] = m[0][1]+iM.m[0][1]; oM.m[0][2] = m[0][2]+iM.m[0][2]; oM.m[0][3] = m[0][3]+iM.m[0][3];
367
oM.m[1][0] = m[1][0]+iM.m[1][0]; oM.m[1][1] = m[1][1]+iM.m[1][1]; oM.m[1][2] = m[1][2]+iM.m[1][2]; oM.m[1][3] = m[1][3]+iM.m[1][3];
368
oM.m[2][0] = m[2][0]+iM.m[2][0]; oM.m[2][1] = m[2][1]+iM.m[2][1]; oM.m[2][2] = m[2][2]+iM.m[2][2]; oM.m[2][3] = m[2][3]+iM.m[2][3];
369
oM.m[3][0] = m[3][0]+iM.m[3][0]; oM.m[3][1] = m[3][1]+iM.m[3][1]; oM.m[3][2] = m[3][2]+iM.m[3][2]; oM.m[3][3] = m[3][3]+iM.m[3][3];
375
/***************************************************************************************\
376
Function: Matrix4x4<T>::operator -=
378
Description: Substract matrix iM.
382
Return Value: Matrix4x4<T>.
385
\***************************************************************************************/
387
Matrix4x4<T>& Matrix4x4<T>::operator -= (const Matrix4x4<T>& iM) const
391
oM.m[0][0] = m[0][0]-iM.m[0][0]; oM.m[0][1] = m[0][1]-iM.m[0][1]; oM.m[0][2] = m[0][2]-iM.m[0][2]; oM.m[0][3] = m[0][3]-iM.m[0][3];
392
oM.m[1][0] = m[1][0]-iM.m[1][0]; oM.m[1][1] = m[1][1]-iM.m[1][1]; oM.m[1][2] = m[1][2]-iM.m[1][2]; oM.m[1][3] = m[1][3]-iM.m[1][3];
393
oM.m[2][0] = m[2][0]-iM.m[2][0]; oM.m[2][1] = m[2][1]-iM.m[2][1]; oM.m[2][2] = m[2][2]-iM.m[2][2]; oM.m[2][3] = m[2][3]-iM.m[2][3];
394
oM.m[3][0] = m[3][0]-iM.m[3][0]; oM.m[3][1] = m[3][1]-iM.m[3][1]; oM.m[3][2] = m[3][2]-iM.m[3][2]; oM.m[3][3] = m[3][3]-iM.m[3][3];
401
/***************************************************************************************\
402
Function: Matrix4x4<T>::operator *
404
Description: Multiply all elements by f.
408
Return Value: Matrix4x4<T>.
411
\***************************************************************************************/
413
Matrix4x4<T> Matrix4x4<T>::operator * (const T& f) const
417
oM.m[0][0] = m[0][0]*f; oM.m[0][1] = m[0][1]*f; oM.m[0][2] = m[0][2]*f; oM.m[0][3] = m[0][3]*f;
418
oM.m[1][0] = m[1][0]*f; oM.m[1][1] = m[1][1]*f; oM.m[1][2] = m[1][2]*f; oM.m[1][3] = m[1][3]*f;
419
oM.m[2][0] = m[2][0]*f; oM.m[2][1] = m[2][1]*f; oM.m[2][2] = m[2][2]*f; oM.m[2][3] = m[2][3]*f;
420
oM.m[3][0] = m[3][0]*f; oM.m[3][1] = m[3][1]*f; oM.m[3][2] = m[3][2]*f; oM.m[3][3] = m[3][3]*f;
425
/***************************************************************************************\
426
Function: Matrix4x4<T>::operator /
428
Description: Divide all elements by f.
432
Return Value: Matrix4x4<T>.
435
\***************************************************************************************/
437
Matrix4x4<T> Matrix4x4<T>::operator / (const T& f) const
441
oM.m[0][0] = m[0][0]/f; oM.m[0][1] = m[0][1]/f; oM.m[0][2] = m[0][2]/f; oM.m[0][3] = m[0][3]/f;
442
oM.m[1][0] = m[1][0]/f; oM.m[1][1] = m[1][1]/f; oM.m[1][2] = m[1][2]/f; oM.m[1][3] = m[1][3]/f;
443
oM.m[2][0] = m[2][0]/f; oM.m[2][1] = m[2][1]/f; oM.m[2][2] = m[2][2]/f; oM.m[2][3] = m[2][3]/f;
444
oM.m[3][0] = m[3][0]/f; oM.m[3][1] = m[3][1]/f; oM.m[3][2] = m[3][2]/f; oM.m[3][3] = m[3][3]/f;
452
/***************************************************************************************\
453
Function: Matrix4x4<T>::operator *=
455
Description: Multiply all elements by f.
459
Return Value: Matrix4x4<T>.
462
\***************************************************************************************/
464
Matrix4x4<T> Matrix4x4<T>::operator *= (const T& f) const
468
oM.m[0][0] = m[0][0]*f; oM.m[0][1] = m[0][1]*f; oM.m[0][2] = m[0][2]*f; oM.m[0][3] = m[0][3]*f;
469
oM.m[1][0] = m[1][0]*f; oM.m[1][1] = m[1][1]*f; oM.m[1][2] = m[1][2]*f; oM.m[1][3] = m[1][3]*f;
470
oM.m[2][0] = m[2][0]*f; oM.m[2][1] = m[2][1]*f; oM.m[2][2] = m[2][2]*f; oM.m[2][3] = m[2][3]*f;
471
oM.m[3][0] = m[3][0]*f; oM.m[3][1] = m[3][1]*f; oM.m[3][2] = m[3][2]*f; oM.m[3][3] = m[3][3]*f;
477
/***************************************************************************************\
478
Function: Matrix4x4<T>::operator /=
480
Description: Divide all elements by f.
484
Return Value: Matrix4x4<T>.
487
\***************************************************************************************/
489
Matrix4x4<T> Matrix4x4<T>::operator /= (const T& f) const
493
oM.m[0][0] = m[0][0]/f; oM.m[0][1] = m[0][1]/f; oM.m[0][2] = m[0][2]/f; oM.m[0][3] = m[0][3]/f;
494
oM.m[1][0] = m[1][0]/f; oM.m[1][1] = m[1][1]/f; oM.m[1][2] = m[1][2]/f; oM.m[1][3] = m[1][3]/f;
495
oM.m[2][0] = m[2][0]/f; oM.m[2][1] = m[2][1]/f; oM.m[2][2] = m[2][2]/f; oM.m[2][3] = m[2][3]/f;
496
oM.m[3][0] = m[3][0]/f; oM.m[3][1] = m[3][1]/f; oM.m[3][2] = m[3][2]/f; oM.m[3][3] = m[3][3]/f;
502
/***************************************************************************************\
503
Function: Matrix4x4<T>::operator *
505
Description: Multiply a matrix by a vector.
509
Return Value: Vector4.
512
\***************************************************************************************/
514
Vector4 Matrix4x4<T>::operator * (const Vector4& V) const
518
oV.x = V.x*m[0][0] + V.y*m[0][1] + V.z*m[0][2] + V.w*m[0][3];
519
oV.y = V.x*m[1][0] + V.y*m[1][1] + V.z*m[1][2] + V.w*m[1][3];
520
oV.z = V.x*m[2][0] + V.y*m[2][1] + V.z*m[2][2] + V.w*m[2][3];
521
oV.w = V.x*m[3][0] + V.y*m[3][1] + V.z*m[3][2] + V.w*m[3][3];
526
/***************************************************************************************\
527
Function: Matrix4x4<T>::operator - ()
529
Description: Negate all elements of the matrix.
533
Return Value: Matrix4x4<T>.
536
\***************************************************************************************/
538
Matrix4x4<T> Matrix4x4<T>::operator - ()
542
oM.m[0][0] = -m[0][0];
543
oM.m[0][1] = -m[0][1];
544
oM.m[0][2] = -m[0][2];
545
oM.m[0][3] = -m[0][3];
547
oM.m[1][0] = -m[1][0];
548
oM.m[1][1] = -m[1][1];
549
oM.m[1][2] = -m[1][2];
550
oM.m[1][3] = -m[1][3];
552
oM.m[2][0] = -m[2][0];
553
oM.m[2][1] = -m[2][1];
554
oM.m[2][2] = -m[2][2];
555
oM.m[2][3] = -m[2][3];
557
oM.m[3][0] = -m[3][0];
558
oM.m[3][1] = -m[3][1];
559
oM.m[3][2] = -m[3][2];
560
oM.m[3][3] = -m[3][3];
565
template <typename T>
566
T& Matrix4x4<T>::operator ()(unsigned int i, unsigned int j)
571
template <typename T>
572
T Matrix4x4<T>::operator ()(unsigned int i, unsigned int j) const
577
template <typename T>
578
Matrix4x4<T>::operator T *()
580
return reinterpret_cast<T*>(&m);
583
template <typename T>
584
Matrix4x4<T>::operator const T *() const
586
return reinterpret_cast<const T*>(&m);
590
/***************************************************************************************\
591
Function: Matrix4x4<T>::zero
593
Description: Set the matrix to zero.
600
\***************************************************************************************/
601
template <typename T>
602
void Matrix4x4<T>::Zero()
604
m[0][0] = 0.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = 0.0;
605
m[1][0] = 0.0; m[1][1] = 0.0; m[1][2] = 0.0; m[1][3] = 0.0;
606
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 0.0; m[2][3] = 0.0;
607
m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 0.0;
609
//memset(m, 0, sizeof(m));
612
/***************************************************************************************\
613
Function: Matrix4x4<T>::identity
615
Description: Set the matrix to identity.
622
\***************************************************************************************/
623
template <typename T>
624
void Matrix4x4<T>::Identity()
626
m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = 0.0;
627
m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0; m[1][3] = 0.0;
628
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0; m[2][3] = 0.0;
629
m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1.0;
632
/***************************************************************************************\
633
Function: Matrix4x4<T>::translate
635
Description: Add a translation to the current matrix.
644
\***************************************************************************************/
645
template <typename T>
646
void Matrix4x4<T>::Translate(T x, T y, T z)
654
/***************************************************************************************\
655
Function: Matrix4x4<T>::Transpose
657
Description: Transpose the current matrix.
664
\***************************************************************************************/
665
template <typename T>
666
void Matrix4x4<T>::Transpose()
668
for(int i = 0; i < 4; i++)
670
for(int j = 0; j < i; j++)
680
/***************************************************************************************\
681
Function: Matrix4x4<T>::Rotate_x
683
Description: Add rotation matrix around axe X.
690
\***************************************************************************************/
691
template <typename T>
692
void Matrix4x4<T>::Rotate_x(T angle)
702
m[1][1] = (T) cos(angle);
703
m[2][1] = (T) sin(angle);
707
m[1][2] = (T) -sin(angle);
708
m[2][2] = (T) cos(angle);
717
/***************************************************************************************\
718
Function: Matrix4x4<T>::Rotate_y
720
Description: Add rotation matrix around axe Y.
727
\***************************************************************************************/
728
template <typename T>
729
void Matrix4x4<T>::Rotate_y(T angle)
733
m[0][0] = (T) cos(angle);
735
m[2][0] = (T) -sin(angle);
743
m[0][2] = (T) sin(angle);
745
m[2][2] = (T) cos(angle);
754
/***************************************************************************************\
755
Function: Matrix4x4<T>::Rotate_z
757
Description: Add rotation matrix around axe Z.
764
\***************************************************************************************/
765
template <typename T>
766
void Matrix4x4<T>::Rotate_z(T angle)
770
m[0][0] = (T) cos(angle);
771
m[1][0] = (T) sin(angle);
775
m[0][1] = (T) -sin(angle);
776
m[1][1] = (T) cos(angle);
791
/***************************************************************************************\
792
Function: Matrix4x4<T>::Scale
794
Description: Add a scale matrix.
796
Parameters: - sx, sy, sz
801
\***************************************************************************************/
802
template <typename T>
803
void Matrix4x4<T>::Scale(T sx, T sy, T sz)
828
template <typename T>
829
T Matrix4x4<T>::Trace() const
831
return m[0][0] + m[1][1] + m[2][2] + m[3][3];
834
template <typename T>
835
T Matrix4x4<T>::Determinant() const
837
const T& m00 = m[0][0]; const T& m01 = m[0][1]; const T& m02 = m[0][2]; const T& m03 = m[0][3];
838
const T& m10 = m[1][0]; const T& m11 = m[1][1]; const T& m12 = m[1][2]; const T& m13 = m[1][3];
839
const T& m20 = m[2][0]; const T& m21 = m[2][1]; const T& m22 = m[2][2]; const T& m23 = m[2][3];
840
const T& m30 = m[3][0]; const T& m31 = m[3][1]; const T& m32 = m[3][2]; const T& m33 = m[3][3];
843
m03 * m12 * m21 * m30 - m02 * m13 * m21 * m30-m03 * m11 * m22 * m30 + m01 * m13 * m22 * m30 +
844
m02 * m11 * m23 * m30 - m01 * m12 * m23 * m30-m03 * m12 * m20 * m31 + m02 * m13 * m20 * m31 +
845
m03 * m10 * m22 * m31 - m00 * m13 * m22 * m31-m02 * m10 * m23 * m31 + m00 * m12 * m23 * m31 +
846
m03 * m11 * m20 * m32 - m01 * m13 * m20 * m32-m03 * m10 * m21 * m32 + m00 * m13 * m21 * m32 +
847
m01 * m10 * m23 * m32 - m00 * m11 * m23 * m32-m02 * m11 * m20 * m33 + m01 * m12 * m20 * m33 +
848
m02 * m10 * m21 * m33 - m00 * m12 * m21 * m33-m01 * m10 * m22 * m33 + m00 * m11 * m22 * m33;
853
template <typename T>
854
void Matrix4x4<T>::Inverse()
856
T det = Determinant();
859
// Determinant is null. Matrix cannot be inverted.
866
const T& m00 = m[0][0]; const T& m01 = m[0][1]; const T& m02 = m[0][2]; const T& m03 = m[0][3];
867
const T& m10 = m[1][0]; const T& m11 = m[1][1]; const T& m12 = m[1][2]; const T& m13 = m[1][3];
868
const T& m20 = m[2][0]; const T& m21 = m[2][1]; const T& m22 = m[2][2]; const T& m23 = m[2][3];
869
const T& m30 = m[3][0]; const T& m31 = m[3][1]; const T& m32 = m[3][2]; const T& m33 = m[3][3];
873
Temp.m[0][0] = m12*m23*m31 - m13*m22*m31 + m13*m21*m32 - m11*m23*m32 - m12*m21*m33 + m11*m22*m33;
874
Temp.m[0][1] = m03*m22*m31 - m02*m23*m31 - m03*m21*m32 + m01*m23*m32 + m02*m21*m33 - m01*m22*m33;
875
Temp.m[0][2] = m02*m13*m31 - m03*m12*m31 + m03*m11*m32 - m01*m13*m32 - m02*m11*m33 + m01*m12*m33;
876
Temp.m[0][3] = m03*m12*m21 - m02*m13*m21 - m03*m11*m22 + m01*m13*m22 + m02*m11*m23 - m01*m12*m23;
877
Temp.m[1][0] = m13*m22*m30 - m12*m23*m30 - m13*m20*m32 + m10*m23*m32 + m12*m20*m33 - m10*m22*m33;
878
Temp.m[1][1] = m02*m23*m30 - m03*m22*m30 + m03*m20*m32 - m00*m23*m32 - m02*m20*m33 + m00*m22*m33;
879
Temp.m[1][2] = m03*m12*m30 - m02*m13*m30 - m03*m10*m32 + m00*m13*m32 + m02*m10*m33 - m00*m12*m33;
880
Temp.m[1][3] = m02*m13*m20 - m03*m12*m20 + m03*m10*m22 - m00*m13*m22 - m02*m10*m23 + m00*m12*m23;
881
Temp.m[2][0] = m11*m23*m30 - m13*m21*m30 + m13*m20*m31 - m10*m23*m31 - m11*m20*m33 + m10*m21*m33;
882
Temp.m[2][1] = m03*m21*m30 - m01*m23*m30 - m03*m20*m31 + m00*m23*m31 + m01*m20*m33 - m00*m21*m33;
883
Temp.m[2][2] = m01*m13*m30 - m03*m11*m30 + m03*m10*m31 - m00*m13*m31 - m01*m10*m33 + m00*m11*m33;
884
Temp.m[2][3] = m03*m11*m20 - m01*m13*m20 - m03*m10*m21 + m00*m13*m21 + m01*m10*m23 - m00*m11*m23;
885
Temp.m[3][0] = m12*m21*m30 - m11*m22*m30 - m12*m20*m31 + m10*m22*m31 + m11*m20*m32 - m10*m21*m32;
886
Temp.m[3][1] = m01*m22*m30 - m02*m21*m30 + m02*m20*m31 - m00*m22*m31 - m01*m20*m32 + m00*m21*m32;
887
Temp.m[3][2] = m02*m11*m30 - m01*m12*m30 - m02*m10*m31 + m00*m12*m31 + m01*m10*m32 - m00*m11*m32;
888
Temp.m[3][3] = m01*m12*m20 - m02*m11*m20 + m02*m10*m21 - m00*m12*m21 - m01*m10*m22 + m00*m11*m22;
890
*this = (T(1) / det) * Temp;
893
template <typename T>
894
Matrix4x4<T> Matrix4x4<T>::GetInverse() const
896
Matrix4x4<T> Temp = *this;
901
// template <typename T>
902
// Matrix3x3<T> Matrix4x4<T>::GetUpper3x3() const
904
// Matrix3x3<T> Temp;
905
// Temp.m[0][0] = m[0][0];
906
// Temp.m[0][1] = m[0][1];
907
// Temp.m[0][2] = m[0][2];
909
// Temp.m[1][0] = m[1][0];
910
// Temp.m[1][1] = m[1][1];
911
// Temp.m[1][2] = m[1][2];
913
// Temp.m[2][0] = m[2][0];
914
// Temp.m[2][1] = m[2][1];
915
// Temp.m[2][2] = m[2][2];
920
// template <typename T>
921
// Matrix2x2<T> Matrix4x4<T>::GetUpper2x2() const
923
// Matrix2x2<T> Temp;
924
// Temp.m[0][0] = m[0][0];
925
// Temp.m[0][1] = m[0][1];
927
// Temp.m[1][0] = m[1][0];
928
// Temp.m[1][1] = m[1][1];
938
template <typename T>
939
void Matrix4x4<T>::Scale(T s)
941
m[0][0] = s; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = 0.0;
942
m[1][0] = 0.0; m[1][1] = s; m[1][2] = 0.0; m[1][3] = 0.0;
943
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = s; m[2][3] = 0.0;
944
m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = 1;
952
template <typename T>
953
void Matrix4x4<T>::Diagonal(T x, T y, T z, T w)
955
m[0][0] = x; m[0][1] = 0.0; m[0][2] = 0.0; m[0][3] = 0.0;
956
m[1][0] = 0.0; m[1][1] = y; m[1][2] = 0.0; m[1][3] = 0.0;
957
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = z; m[2][3] = 0.0;
958
m[3][0] = 0.0; m[3][1] = 0.0; m[3][2] = 0.0; m[3][3] = w;
962
template <typename T>
963
void Matrix4x4<T>::Rotate(T angle, Vector3 axis)
965
//See Quaternion::from_angle_axis() and Quaternion::get_matrix()
968
// note: adapted from david eberly's code without permission
969
//TODO: make sure it is correct
970
/*if (axis.LengthSquared() < EpsilonMicro)
978
T fCos = (T) cos(angle);
979
T fSin = (T) sin(angle);
980
T fOneMinusCos = 1.0f-fCos;
981
T fX2 = axis.x*axis.x;
982
T fY2 = axis.y*axis.y;
983
T fZ2 = axis.z*axis.z;
984
T fXYM = axis.x*axis.y*fOneMinusCos;
985
T fXZM = axis.x*axis.z*fOneMinusCos;
986
T fYZM = axis.y*axis.z*fOneMinusCos;
987
T fXSin = axis.x*fSin;
988
T fYSin = axis.y*fSin;
989
T fZSin = axis.z*fSin;
991
m[0][0] = fX2*fOneMinusCos+fCos;
992
m[0][1] = fXYM-fZSin;
993
m[0][2] = fXZM+fYSin;
996
m[1][0] = fXYM+fZSin;
997
m[1][1] = fY2*fOneMinusCos+fCos;
998
m[1][2] = fYZM-fXSin;
1001
m[2][0] = fXZM-fYSin;
1002
m[2][1] = fYZM+fXSin;
1003
m[2][2] = fZ2*fOneMinusCos+fCos;
1014
template <typename T>
1015
void Matrix4x4<T>::LookAt(const Vector3 &eye, const Vector3 &at, const Vector3 &up)
1019
Vector3 z_axis = at - eye;
1020
Vector3 x_axis = z_axis.CrossProduct(up);
1021
Vector3 y_axis = x_axis.CrossProduct(z_axis);
1028
Rot.m[0][0] = x_axis.x;
1029
Rot.m[0][1] = x_axis.y;
1030
Rot.m[0][2] = x_axis.z;
1033
Rot.m[1][0] = y_axis.x;
1034
Rot.m[1][1] = y_axis.y;
1035
Rot.m[1][2] = y_axis.z;
1038
Rot.m[2][0] = -z_axis.x;
1039
Rot.m[2][1] = -z_axis.y;
1040
Rot.m[2][2] = -z_axis.z;
1049
Trans.Translate(-eye.x, -eye.y, -eye.z);
1051
*this = Rot * Trans;
1054
/// set to an orthographic projection matrix.
1056
// 2/(r-l) 0 0 -(r+l)/(r-l)
1057
// 0 2/(t-b) 0 -(t+b)/(t-b)
1058
// 0 0 -2/(f-n) -(f+n)/(f-n)
1060
template <typename T>
1061
void Matrix4x4<T>::Orthographic(T l, T r, T b, T t, T n, T f)
1067
m[0][0] = 2.0f * sx;
1070
m[0][3] = -(r+l) * sx;
1073
m[1][1] = 2.0f * sy;
1075
m[1][3] = -(t+b) * sy;
1079
m[2][2] = -2.0f * sz;
1080
m[2][3] = -(f+n) * sz;
1088
/// set to a perspective projection matrix.
1089
// 2*n/(r-l) 0 (r+l)/(r-l) 0
1090
// 0 2*n/(t-b) (t+b)/(t-b) 0
1091
// 0 0 -(f+n)/(f-n) -2*f*n/(f-n)
1093
template <typename T>
1094
void Matrix4x4<T>::Perspective(T l, T r, T t, T b, T n, T f)
1096
m[0][0] = 2.0f * n / (r-l);
1098
m[0][2] = (r+l) / (r-l);
1102
m[1][1] = 2.0f * n / (t-b);
1103
m[1][2] = (t+b) / (t-b);
1108
m[2][2] = -(f+n) / (f-n);
1109
m[2][3] = -2.0f * f * n / (f-n);
1117
// (r-l)/2*n 0 0 (r+l)/(2*n)
1118
// 0 (t-b)/(2*n) 0 (t+b)/(2*n)
1120
// 0 0 -(f-n)/(2*f*n) (f+n)/(2*f*n)
1121
template <typename T>
1122
void Matrix4x4<T>::PerspectiveInverse(T l, T r, T t, T b, T n, T f)
1124
m[0][0] = (r-l)/(2.0f*n);
1127
m[0][3] = (r+l)/(2.0f*n);
1130
m[1][1] = (t-b)/(2.0f*n);
1131
m[1][2] = (t+b)/(2.0f*n);
1141
m[3][2] = -(f-n)/(2.0f*f*n);
1142
m[3][3] = (f+n)/(2.0f*f*n);
1145
/// set to a perspective projection matrix specified in terms of field of view and aspect ratio.
1146
template <typename T>
1147
void Matrix4x4<T>::Perspective(T FoV, T AspectRatio, T NearPlane, T FarPlane)
1149
const T t = tan(FoV*0.5f) * NearPlane;
1152
const T l = AspectRatio * b;
1153
const T r = AspectRatio * t;
1155
Perspective(l, r, t, b, NearPlane, FarPlane);
1158
template <typename T>
1159
Matrix4x4<T> Matrix4x4<T>::IDENTITY()
1161
Matrix4x4<T> matrix;
1166
template <typename T>
1167
Matrix4x4<T> Matrix4x4<T>::ZERO()
1169
Matrix4x4<T> matrix;
1173
/***************************************************************************************\
1174
Function: operator *
1176
Description: Multiply matrix rhs by constant lhs.
1177
Allow "f * matrix" operation.
1181
Return Value: Matrix4.
1184
\***************************************************************************************/
1185
template<typename T>
1186
Matrix4x4<T> operator * (const T& lhs, const Matrix4x4<T>& rhs)
1190
oM.m[0][0] = rhs.m[0][0]*lhs; oM.m[0][1] = rhs.m[0][1]*lhs; oM.m[0][2] = rhs.m[0][2]*lhs; oM.m[0][3] = rhs.m[0][3]*lhs;
1191
oM.m[1][0] = rhs.m[1][0]*lhs; oM.m[1][1] = rhs.m[1][1]*lhs; oM.m[1][2] = rhs.m[1][2]*lhs; oM.m[1][3] = rhs.m[1][3]*lhs;
1192
oM.m[2][0] = rhs.m[2][0]*lhs; oM.m[2][1] = rhs.m[2][1]*lhs; oM.m[2][2] = rhs.m[2][2]*lhs; oM.m[2][3] = rhs.m[2][3]*lhs;
1193
oM.m[3][0] = rhs.m[3][0]*lhs; oM.m[3][1] = rhs.m[3][1]*lhs; oM.m[3][2] = rhs.m[3][2]*lhs; oM.m[3][3] = rhs.m[3][3]*lhs;
1198
typedef Matrix4x4<float> Matrix4;