~hikiko/nux/arb-srgba-shader

« back to all changes in this revision

Viewing changes to NuxCore/Math/Matrix4.h

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-01 19:25:37 UTC
  • Revision ID: neil.patel@canonical.com-20100901192537-mfz7rm6q262pewg6
Import and build NuxCore

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef MATRIX4_H
 
2
#define MATRIX4_H
 
3
 
 
4
 
 
5
#include "Vector3.h"
 
6
#include "Vector4.h"
 
7
 
 
8
NAMESPACE_BEGIN
 
9
 
 
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
 
13
//  
 
14
//    |a00,  a01,  a02,  a03|       |v0|
 
15
//    |a10,  a11,  a12,  a13|   *   |v1|
 
16
//    |a20,  a21,  a22,  a23|       |v2|
 
17
//    |a30,  a31,  a32,  a33|       |v3|
 
18
//
 
19
// Note: OpenGL is column major. Before passing it a Matrix4x4 through glLoadMatrix, transpose it.
 
20
 
 
21
template<typename T>
 
22
class Matrix4x4
 
23
{
 
24
public:
 
25
    Matrix4x4<T>();
 
26
    ~Matrix4x4<T>();
 
27
    Matrix4x4<T>(const Matrix4x4&);
 
28
    Matrix4x4<T>(
 
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);
 
33
 
 
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;
 
42
 
 
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;
 
47
 
 
48
    Vector4      operator * (const Vector4&) const;     
 
49
        Matrix4x4<T> operator - ();
 
50
 
 
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;
 
54
 
 
55
    // Get a pointer to the current matrix.
 
56
    operator T *();
 
57
    operator const T *() const;
 
58
 
 
59
    // Utility for 3D 
 
60
    void Translate(T x, T y, T z);
 
61
    void Translate(const Vector3 &);
 
62
 
 
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);
 
67
 
 
68
    // Matrix Math
 
69
    T Trace() const;
 
70
    T Determinant() const ;
 
71
    void Inverse();
 
72
    Matrix4x4<T> GetInverse() const;
 
73
    void Transpose();
 
74
 
 
75
    //Matrix3x3<T> GetUpper3x3() const;
 
76
    //Matrix2x2<T> GetUpper2x2() const;
 
77
 
 
78
    ///////////////////////////////////////////////
 
79
    void Scale(T s);
 
80
    void Diagonal(T x, T y, T z, T w = T(1));
 
81
    void Rotate(T angle, Vector3 axis);
 
82
    
 
83
    // OpenGL
 
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);
 
89
 
 
90
    void Zero();
 
91
    void Identity();
 
92
 
 
93
    static Matrix4x4<T> IDENTITY();
 
94
    static Matrix4x4<T> ZERO();
 
95
        T m[4][4];
 
96
};
 
97
 
 
98
 
 
99
/***************************************************************************************\
 
100
Function:       Matrix4x4<T>::Matrix4x4<T>
 
101
 
 
102
Description:    Constructor. Initialize the matrix to identity.
 
103
 
 
104
Parameters:     None.
 
105
 
 
106
Return Value:   None.
 
107
 
 
108
Comments:       None.
 
109
\***************************************************************************************/
 
110
template<typename T>
 
111
Matrix4x4<T>::Matrix4x4()
 
112
{
 
113
    Identity();
 
114
}
 
115
 
 
116
/***************************************************************************************\
 
117
Function:       Matrix4x4<T>::~Matrix4x4
 
118
 
 
119
Description:    Destructor.
 
120
 
 
121
Parameters:     None.
 
122
 
 
123
Return Value:   None.
 
124
 
 
125
Comments:       None.
 
126
\***************************************************************************************/
 
127
template<typename T>
 
128
Matrix4x4<T>::~Matrix4x4()
 
129
{
 
130
 
 
131
}
 
132
 
 
133
/***************************************************************************************\
 
134
Function:       Matrix4x4<T>::Matrix4x4
 
135
 
 
136
Description:    None. 
 
137
 
 
138
Parameters:     - M
 
139
 
 
140
Return Value:   None.
 
141
 
 
142
Comments:       None.
 
143
\***************************************************************************************/
 
144
template<typename T>
 
145
Matrix4x4<T>::Matrix4x4(const Matrix4x4& M) 
 
146
{
 
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];
 
151
}
 
152
 
 
153
/***************************************************************************************\
 
154
Function:       Matrix4x4<T>::Matrix4x4
 
155
 
 
156
Description:    None. 
 
157
 
 
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
 
162
 
 
163
Return Value:   None.
 
164
 
 
165
Comments:       None.
 
166
\***************************************************************************************/
 
167
template<typename T>
 
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)
 
173
{
 
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;
 
178
}
 
179
 
 
180
/***************************************************************************************\
 
181
Function:       Matrix4x4<T>::Matrix4x4
 
182
 
 
183
Description:    Assignment operator.
 
184
 
 
185
Parameters:     - M
 
186
 
 
187
Return Value:   Matrix4x4<T>.
 
188
 
 
189
Comments:       None.
 
190
\***************************************************************************************/
 
191
template<typename T>
 
192
Matrix4x4<T>& Matrix4x4<T>::operator = (const Matrix4x4<T>& M) 
 
193
{
 
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];
 
198
 
 
199
    return (*this);
 
200
}
 
201
 
 
202
template <typename T>
 
203
t_bool Matrix4x4<T>::operator == (const Matrix4x4<T>& M) 
 
204
{
 
205
    for(int i = 0; i < 4; i++)
 
206
        for(int j = 0; j < 4; j++)
 
207
        {
 
208
            if(m[i][j] != M.m[i][j])
 
209
                return false;
 
210
        }
 
211
        return true;
 
212
}
 
213
 
 
214
 
 
215
/***************************************************************************************\
 
216
Function:       Matrix4x4<T>::operator *
 
217
 
 
218
Description:    Multiply by matrix iM.
 
219
 
 
220
Parameters:     - iM
 
221
 
 
222
Return Value:   Matrix4x4<T>.
 
223
 
 
224
Comments:       None.
 
225
\***************************************************************************************/
 
226
template<typename T>
 
227
Matrix4x4<T> Matrix4x4<T>::operator * (const Matrix4x4<T>& iM) const 
 
228
{
 
229
    Matrix4x4<T> oM;
 
230
 
 
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];
 
236
 
 
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];
 
242
 
 
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];
 
248
 
 
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];
 
254
 
 
255
    return oM;
 
256
}
 
257
 
 
258
/***************************************************************************************\
 
259
Function:       Matrix4x4<T>::operator +
 
260
 
 
261
Description:    Add matrix iM.
 
262
 
 
263
Parameters:     - iM
 
264
 
 
265
Return Value:   Matrix4x4<T>.
 
266
 
 
267
Comments:       None.
 
268
\***************************************************************************************/
 
269
template<typename T>
 
270
Matrix4x4<T> Matrix4x4<T>::operator + (const Matrix4x4<T>& iM) const 
 
271
{
 
272
    Matrix4x4<T> oM;
 
273
 
 
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]; 
 
278
 
 
279
    return oM;
 
280
}
 
281
 
 
282
/***************************************************************************************\
 
283
Function:       Matrix4x4<T>::operator -
 
284
 
 
285
Description:    Substract matrix iM.
 
286
 
 
287
Parameters:     - iM
 
288
 
 
289
Return Value:   Matrix4x4<T>.
 
290
 
 
291
Comments:       None.
 
292
\***************************************************************************************/
 
293
template<typename T>
 
294
Matrix4x4<T> Matrix4x4<T>::operator - (const Matrix4x4<T>& iM) const 
 
295
{
 
296
    Matrix4x4<T> oM;
 
297
 
 
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]; 
 
302
 
 
303
    return oM;
 
304
}
 
305
 
 
306
 
 
307
 
 
308
 
 
309
 
 
310
/***************************************************************************************\
 
311
Function:       Matrix4x4<T>::operator *=
 
312
 
 
313
Description:    Multiply by matrix iM.
 
314
 
 
315
Parameters:     - iM
 
316
 
 
317
Return Value:   Matrix4x4<T>.
 
318
 
 
319
Comments:       None.
 
320
\***************************************************************************************/
 
321
template<typename T>
 
322
Matrix4x4<T>& Matrix4x4<T>::operator *= (const Matrix4x4<T>& iM) const 
 
323
{
 
324
    Matrix4x4<T> oM;
 
325
 
 
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];
 
330
 
 
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];
 
335
 
 
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];
 
340
 
 
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];
 
345
 
 
346
    *this = oM;
 
347
    return *this;
 
348
}
 
349
 
 
350
/***************************************************************************************\
 
351
Function:       Matrix4x4<T>::operator +=
 
352
 
 
353
Description:    Add matrix iM.
 
354
 
 
355
Parameters:     - iM
 
356
 
 
357
Return Value:   Matrix4x4<T>.
 
358
 
 
359
Comments:       None.
 
360
\***************************************************************************************/
 
361
template<typename T>
 
362
Matrix4x4<T>& Matrix4x4<T>::operator += (const Matrix4x4<T>& iM) const 
 
363
{
 
364
    Matrix4x4<T> oM;
 
365
 
 
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]; 
 
370
 
 
371
    *this = oM;
 
372
    return *this;
 
373
}
 
374
 
 
375
/***************************************************************************************\
 
376
Function:       Matrix4x4<T>::operator -=
 
377
 
 
378
Description:    Substract matrix iM.
 
379
 
 
380
Parameters:     - iM
 
381
 
 
382
Return Value:   Matrix4x4<T>.
 
383
 
 
384
Comments:       None.
 
385
\***************************************************************************************/
 
386
template<typename T>
 
387
Matrix4x4<T>& Matrix4x4<T>::operator -= (const Matrix4x4<T>& iM) const 
 
388
{
 
389
    Matrix4x4<T> oM;
 
390
 
 
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]; 
 
395
 
 
396
    *this = oM;
 
397
    return *this;
 
398
}
 
399
 
 
400
 
 
401
/***************************************************************************************\
 
402
Function:       Matrix4x4<T>::operator *
 
403
 
 
404
Description:    Multiply all elements by f.
 
405
 
 
406
Parameters:     - f
 
407
 
 
408
Return Value:   Matrix4x4<T>.
 
409
 
 
410
Comments:       None.
 
411
\***************************************************************************************/
 
412
template<typename T>
 
413
Matrix4x4<T> Matrix4x4<T>::operator * (const T& f) const 
 
414
{
 
415
    Matrix4x4<T> oM;
 
416
 
 
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; 
 
421
 
 
422
    return oM;
 
423
}
 
424
 
 
425
/***************************************************************************************\
 
426
Function:       Matrix4x4<T>::operator /
 
427
 
 
428
Description:    Divide all elements by f.
 
429
 
 
430
Parameters:     - f
 
431
 
 
432
Return Value:   Matrix4x4<T>.
 
433
 
 
434
Comments:       None.
 
435
\***************************************************************************************/
 
436
template<typename T>
 
437
Matrix4x4<T> Matrix4x4<T>::operator / (const T& f) const 
 
438
{
 
439
    Matrix4x4<T> oM;
 
440
 
 
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; 
 
445
 
 
446
    return oM;
 
447
}
 
448
 
 
449
 
 
450
 
 
451
 
 
452
/***************************************************************************************\
 
453
Function:       Matrix4x4<T>::operator *=
 
454
 
 
455
Description:    Multiply all elements by f.
 
456
 
 
457
Parameters:     - f
 
458
 
 
459
Return Value:   Matrix4x4<T>.
 
460
 
 
461
Comments:       None.
 
462
\***************************************************************************************/
 
463
template<typename T>
 
464
Matrix4x4<T> Matrix4x4<T>::operator *= (const T& f) const 
 
465
{
 
466
    Matrix4x4<T> oM;
 
467
 
 
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; 
 
472
 
 
473
    *this = oM;
 
474
    return *this;
 
475
}
 
476
 
 
477
/***************************************************************************************\
 
478
Function:       Matrix4x4<T>::operator /=
 
479
 
 
480
Description:    Divide all elements by f.
 
481
 
 
482
Parameters:     - f
 
483
 
 
484
Return Value:   Matrix4x4<T>.
 
485
 
 
486
Comments:       None.
 
487
\***************************************************************************************/
 
488
template<typename T>
 
489
Matrix4x4<T> Matrix4x4<T>::operator /= (const T& f) const 
 
490
{
 
491
    Matrix4x4<T> oM;
 
492
 
 
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; 
 
497
 
 
498
    *this = oM;
 
499
    return *this;
 
500
}
 
501
 
 
502
/***************************************************************************************\
 
503
Function:       Matrix4x4<T>::operator *
 
504
 
 
505
Description:    Multiply a matrix by a vector.
 
506
 
 
507
Parameters:     - V
 
508
 
 
509
Return Value:   Vector4.
 
510
 
 
511
Comments:       None.
 
512
\***************************************************************************************/
 
513
template<typename T>
 
514
Vector4 Matrix4x4<T>::operator * (const Vector4& V) const 
 
515
{
 
516
    Vector4 oV;
 
517
 
 
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];
 
522
 
 
523
    return oV;
 
524
}
 
525
 
 
526
/***************************************************************************************\
 
527
Function:       Matrix4x4<T>::operator - ()
 
528
 
 
529
Description:    Negate all elements of the matrix.
 
530
 
 
531
Parameters:     None.
 
532
 
 
533
Return Value:   Matrix4x4<T>.
 
534
 
 
535
Comments:       None.
 
536
\***************************************************************************************/
 
537
template<typename T>
 
538
Matrix4x4<T> Matrix4x4<T>::operator - ()
 
539
{
 
540
    Matrix4x4<T> oM;
 
541
 
 
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];
 
546
 
 
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];
 
551
 
 
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];
 
556
 
 
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];
 
561
 
 
562
    return oM;
 
563
}
 
564
 
 
565
template <typename T>
 
566
T& Matrix4x4<T>::operator ()(unsigned int i, unsigned int j)
 
567
{
 
568
    return m[i][j];
 
569
}
 
570
 
 
571
template <typename T>
 
572
T Matrix4x4<T>::operator ()(unsigned int i, unsigned int j) const
 
573
{
 
574
    return m[i][j];
 
575
}
 
576
 
 
577
template <typename T>
 
578
Matrix4x4<T>::operator T *()
 
579
{
 
580
    return reinterpret_cast<T*>(&m);
 
581
}
 
582
 
 
583
template <typename T>
 
584
Matrix4x4<T>::operator const T *() const
 
585
{
 
586
    return reinterpret_cast<const T*>(&m);
 
587
}
 
588
 
 
589
 
 
590
/***************************************************************************************\
 
591
Function:       Matrix4x4<T>::zero
 
592
 
 
593
Description:    Set the matrix to zero.
 
594
 
 
595
Parameters:     None.
 
596
 
 
597
Return Value:   None.
 
598
 
 
599
Comments:       None.
 
600
\***************************************************************************************/
 
601
template <typename T>
 
602
void Matrix4x4<T>::Zero()
 
603
{
 
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;
 
608
 
 
609
    //memset(m, 0, sizeof(m));
 
610
}
 
611
 
 
612
/***************************************************************************************\
 
613
Function:       Matrix4x4<T>::identity
 
614
 
 
615
Description:    Set the matrix to identity.
 
616
 
 
617
Parameters:     None.
 
618
 
 
619
Return Value:   None.
 
620
 
 
621
Comments:       None.
 
622
\***************************************************************************************/
 
623
template <typename T>
 
624
void Matrix4x4<T>::Identity()
 
625
{
 
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;
 
630
}
 
631
 
 
632
/***************************************************************************************\
 
633
Function:       Matrix4x4<T>::translate
 
634
 
 
635
Description:    Add a translation to the current matrix.
 
636
 
 
637
Parameters:     - x
 
638
- y
 
639
- z
 
640
 
 
641
Return Value:   None.
 
642
 
 
643
Comments:       None.
 
644
\***************************************************************************************/
 
645
template <typename T>
 
646
void Matrix4x4<T>::Translate(T x, T y, T z)
 
647
{
 
648
    Identity();
 
649
    m[0][3] = x;
 
650
    m[1][3] = y;
 
651
    m[2][3] = z;
 
652
}
 
653
 
 
654
/***************************************************************************************\
 
655
Function:       Matrix4x4<T>::Transpose
 
656
 
 
657
Description:    Transpose the current matrix.
 
658
 
 
659
Parameters:     None
 
660
 
 
661
Return Value:   None.
 
662
 
 
663
Comments:       None.
 
664
\***************************************************************************************/
 
665
template <typename T>
 
666
void Matrix4x4<T>::Transpose()
 
667
{
 
668
    for(int i = 0; i < 4; i++)
 
669
    {
 
670
        for(int j = 0; j < i; j++)
 
671
        {
 
672
            T t = m[i][j];
 
673
            m[i][j] = m[j][i];
 
674
            m[j][i] = t;
 
675
        }
 
676
    }
 
677
}
 
678
 
 
679
 
 
680
/***************************************************************************************\
 
681
Function:       Matrix4x4<T>::Rotate_x
 
682
 
 
683
Description:    Add rotation matrix around axe X.
 
684
 
 
685
Parameters:     - angle
 
686
 
 
687
Return Value:   None.
 
688
 
 
689
Comments:       None.
 
690
\***************************************************************************************/
 
691
template <typename T>
 
692
void Matrix4x4<T>::Rotate_x(T angle)
 
693
{
 
694
    Identity();
 
695
 
 
696
    m[0][0] = 1.0f;
 
697
    m[1][0] = 0.0f;
 
698
    m[2][0] = 0.0f;
 
699
    m[3][0] = 0.0f;
 
700
 
 
701
    m[0][1] = 0.0f;
 
702
    m[1][1] = (T) cos(angle);
 
703
    m[2][1] = (T) sin(angle);
 
704
    m[3][1] = 0.0f;
 
705
 
 
706
    m[0][2] = 0.0f;
 
707
    m[1][2] = (T) -sin(angle);
 
708
    m[2][2] = (T) cos(angle);
 
709
    m[3][2] = 0.0f;
 
710
 
 
711
    m[0][3] = 0.0f;
 
712
    m[1][3] = 0.0f;
 
713
    m[2][3] = 0.0f;
 
714
    m[3][3] = 1.0f;
 
715
}
 
716
 
 
717
/***************************************************************************************\
 
718
Function:       Matrix4x4<T>::Rotate_y
 
719
 
 
720
Description:    Add rotation matrix around axe Y.
 
721
 
 
722
Parameters:     - angle
 
723
 
 
724
Return Value:   None.
 
725
 
 
726
Comments:       None.
 
727
\***************************************************************************************/
 
728
template <typename T>
 
729
void Matrix4x4<T>::Rotate_y(T angle)
 
730
{
 
731
    Identity();
 
732
 
 
733
    m[0][0] = (T) cos(angle);
 
734
    m[1][0] = 0.0f;
 
735
    m[2][0] = (T) -sin(angle);
 
736
    m[3][0] = 0.0f;
 
737
 
 
738
    m[0][1] = 0.0f;
 
739
    m[1][1] = 1.0f;
 
740
    m[2][1] = 0.0f;
 
741
    m[3][1] = 0.0f;
 
742
 
 
743
    m[0][2] = (T) sin(angle);
 
744
    m[1][2] = 0.0f;
 
745
    m[2][2] = (T) cos(angle);
 
746
    m[3][2] = 0.0f;
 
747
 
 
748
    m[0][3] = 0.0f;
 
749
    m[1][3] = 0.0f;
 
750
    m[2][3] = 0.0f;
 
751
    m[3][3] = 1.0f;
 
752
}
 
753
 
 
754
/***************************************************************************************\
 
755
Function:       Matrix4x4<T>::Rotate_z
 
756
 
 
757
Description:    Add rotation matrix around axe Z.
 
758
 
 
759
Parameters:     - angle
 
760
 
 
761
Return Value:   None.
 
762
 
 
763
Comments:       None.
 
764
\***************************************************************************************/
 
765
template <typename T>
 
766
void Matrix4x4<T>::Rotate_z(T angle)
 
767
{
 
768
    Identity();
 
769
 
 
770
    m[0][0] = (T) cos(angle);
 
771
    m[1][0] = (T) sin(angle);
 
772
    m[2][0] = 0.0f;
 
773
    m[3][0] = 0.0f;
 
774
 
 
775
    m[0][1] = (T) -sin(angle);
 
776
    m[1][1] = (T) cos(angle);
 
777
    m[2][1] = 0.0f;
 
778
    m[3][1] = 0.0f;
 
779
 
 
780
    m[0][2] = 0.0f;
 
781
    m[1][2] = 0.0f;
 
782
    m[2][2] = 1.0f;
 
783
    m[3][2] = 0.0f;
 
784
 
 
785
    m[0][3] = 0.0f;
 
786
    m[1][3] = 0.0f;
 
787
    m[2][3] = 0.0f;
 
788
    m[3][3] = 1.0f;
 
789
}
 
790
 
 
791
/***************************************************************************************\
 
792
Function:       Matrix4x4<T>::Scale
 
793
 
 
794
Description:    Add a scale matrix.
 
795
 
 
796
Parameters:     - sx, sy, sz
 
797
 
 
798
Return Value:   None.
 
799
 
 
800
Comments:       None.
 
801
\***************************************************************************************/
 
802
template <typename T>
 
803
void Matrix4x4<T>::Scale(T sx, T sy, T sz)
 
804
{
 
805
    Identity();
 
806
 
 
807
    m[0][0] = sx;
 
808
    m[1][0] = 0.0f;
 
809
    m[2][0] = 0.0f;
 
810
    m[3][0] = 0.0f;
 
811
 
 
812
    m[0][1] = 0.0f;
 
813
    m[1][1] = sy;
 
814
    m[2][1] = 0.0f;
 
815
    m[3][1] = 0.0f;
 
816
 
 
817
    m[0][2] = 0.0f;
 
818
    m[1][2] = 0.0f;
 
819
    m[2][2] = sz;
 
820
    m[3][2] = 0.0f;
 
821
 
 
822
    m[0][3] = 0.0f;
 
823
    m[1][3] = 0.0f;
 
824
    m[2][3] = 0.0f;
 
825
    m[3][3] = 1.0f;
 
826
}
 
827
 
 
828
template <typename T>
 
829
T Matrix4x4<T>::Trace() const
 
830
{
 
831
    return m[0][0] + m[1][1] + m[2][2] + m[3][3];
 
832
}
 
833
 
 
834
template <typename T>
 
835
T Matrix4x4<T>::Determinant() const
 
836
{
 
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]; 
 
841
 
 
842
    T det =
 
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;
 
849
 
 
850
    return det;
 
851
}
 
852
 
 
853
template <typename T>
 
854
void Matrix4x4<T>::Inverse()
 
855
{
 
856
    T det = Determinant();
 
857
    if(det == T(0))
 
858
    {
 
859
        // Determinant is null. Matrix cannot be inverted.
 
860
#ifdef _DEBUG
 
861
        INL_HARDWARE_BREAK;
 
862
#endif
 
863
        return;
 
864
    }
 
865
 
 
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]; 
 
870
 
 
871
    Matrix4x4<T> Temp;
 
872
 
 
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;
 
889
 
 
890
    *this = (T(1) / det) * Temp; 
 
891
}
 
892
 
 
893
template <typename T>
 
894
Matrix4x4<T> Matrix4x4<T>::GetInverse() const
 
895
{
 
896
    Matrix4x4<T> Temp = *this;
 
897
    Temp.Inverse();
 
898
    return Temp;
 
899
}
 
900
 
 
901
// template <typename T>
 
902
// Matrix3x3<T> Matrix4x4<T>::GetUpper3x3() const
 
903
// {
 
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];
 
908
// 
 
909
//     Temp.m[1][0] = m[1][0];
 
910
//     Temp.m[1][1] = m[1][1];
 
911
//     Temp.m[1][2] = m[1][2];
 
912
// 
 
913
//     Temp.m[2][0] = m[2][0];
 
914
//     Temp.m[2][1] = m[2][1];
 
915
//     Temp.m[2][2] = m[2][2];
 
916
// 
 
917
//     return Temp;
 
918
// }
 
919
// 
 
920
// template <typename T>
 
921
// Matrix2x2<T> Matrix4x4<T>::GetUpper2x2() const
 
922
// {
 
923
//     Matrix2x2<T> Temp;
 
924
//     Temp.m[0][0] = m[0][0];
 
925
//     Temp.m[0][1] = m[0][1];
 
926
// 
 
927
//     Temp.m[1][0] = m[1][0];
 
928
//     Temp.m[1][1] = m[1][1];
 
929
// 
 
930
//     return Temp;
 
931
// }
 
932
 
 
933
// s 0 0 0 
 
934
// 0 s 0 0
 
935
// 0 0 s 0
 
936
// 0 0 0 1
 
937
 
 
938
template <typename T>
 
939
void Matrix4x4<T>::Scale(T s)
 
940
{
 
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;
 
945
}
 
946
 
 
947
// x 0 0 0 
 
948
// 0 y 0 0
 
949
// 0 0 z 0
 
950
// 0 0 0 w
 
951
 
 
952
template <typename T>
 
953
void Matrix4x4<T>::Diagonal(T x, T y, T z, T w)
 
954
{
 
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;
 
959
}
 
960
 
 
961
 
 
962
template <typename T>
 
963
void Matrix4x4<T>::Rotate(T angle, Vector3 axis)
 
964
{
 
965
    //See Quaternion::from_angle_axis() and Quaternion::get_matrix()
 
966
 
 
967
 
 
968
    // note: adapted from david eberly's code without permission
 
969
    //TODO: make sure it is correct
 
970
    /*if (axis.LengthSquared() < EpsilonMicro)
 
971
    {
 
972
    Identity();
 
973
    }
 
974
    else
 
975
    {
 
976
    axis.Normalize();
 
977
 
 
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;
 
990
 
 
991
    m[0][0] = fX2*fOneMinusCos+fCos;
 
992
    m[0][1] = fXYM-fZSin;
 
993
    m[0][2] = fXZM+fYSin;
 
994
    m[0][3] = 0;
 
995
 
 
996
    m[1][0] = fXYM+fZSin;
 
997
    m[1][1] = fY2*fOneMinusCos+fCos;
 
998
    m[1][2] = fYZM-fXSin;
 
999
    m[1][3] = 0;
 
1000
 
 
1001
    m[2][0] = fXZM-fYSin;
 
1002
    m[2][1] = fYZM+fXSin;
 
1003
    m[2][2] = fZ2*fOneMinusCos+fCos;
 
1004
    m[2][3] = 0;
 
1005
 
 
1006
    m[3][0] = 0;
 
1007
    m[3][1] = 0;
 
1008
    m[3][2] = 0;
 
1009
    m[3][3] = 1;
 
1010
    }
 
1011
    */
 
1012
}
 
1013
 
 
1014
template <typename T>
 
1015
void Matrix4x4<T>::LookAt(const Vector3 &eye, const Vector3 &at, const Vector3 &up)
 
1016
{
 
1017
    // left handed
 
1018
 
 
1019
    Vector3 z_axis = at - eye;
 
1020
    Vector3 x_axis = z_axis.CrossProduct(up);
 
1021
    Vector3 y_axis = x_axis.CrossProduct(z_axis);
 
1022
 
 
1023
    x_axis.Normalize();
 
1024
    y_axis.Normalize();
 
1025
    z_axis.Normalize();
 
1026
 
 
1027
    Matrix4x4<T> Rot;
 
1028
    Rot.m[0][0] = x_axis.x;
 
1029
    Rot.m[0][1] = x_axis.y;
 
1030
    Rot.m[0][2] = x_axis.z;
 
1031
    Rot.m[0][3] = 0;
 
1032
 
 
1033
    Rot.m[1][0] = y_axis.x;
 
1034
    Rot.m[1][1] = y_axis.y;
 
1035
    Rot.m[1][2] = y_axis.z;
 
1036
    Rot.m[1][3] = 0;
 
1037
 
 
1038
    Rot.m[2][0] = -z_axis.x;
 
1039
    Rot.m[2][1] = -z_axis.y;
 
1040
    Rot.m[2][2] = -z_axis.z;
 
1041
    Rot.m[2][3] = 0;
 
1042
 
 
1043
    Rot.m[3][0] = 0.0f;
 
1044
    Rot.m[3][1] = 0.0f;
 
1045
    Rot.m[3][2] = 0.0f;
 
1046
    Rot.m[3][3] = 1.0f;
 
1047
 
 
1048
    Matrix4x4<T> Trans;
 
1049
    Trans.Translate(-eye.x, -eye.y, -eye.z);
 
1050
 
 
1051
    *this = Rot * Trans;
 
1052
}
 
1053
 
 
1054
/// set to an orthographic projection matrix.
 
1055
 
 
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)
 
1059
// 0        0           0           1
 
1060
template <typename T>
 
1061
void Matrix4x4<T>::Orthographic(T l, T r, T b, T t, T n, T f)
 
1062
{
 
1063
    T sx = 1 / (r - l);
 
1064
    T sy = 1 / (t - b);
 
1065
    T sz = 1 / (f - n);
 
1066
 
 
1067
    m[0][0] = 2.0f * sx;
 
1068
    m[0][1] = 0.0f;
 
1069
    m[0][2] = 0.0f;
 
1070
    m[0][3] = -(r+l) * sx;
 
1071
 
 
1072
    m[1][0] = 0.0f;
 
1073
    m[1][1] = 2.0f * sy;
 
1074
    m[1][2] = 0.0f;
 
1075
    m[1][3] = -(t+b) * sy;
 
1076
 
 
1077
    m[2][0] = 0.0f;
 
1078
    m[2][1] = 0.0f;
 
1079
    m[2][2] = -2.0f * sz;
 
1080
    m[2][3] = -(f+n) * sz;
 
1081
 
 
1082
    m[3][0] = 0.0f;
 
1083
    m[3][1] = 0.0f;
 
1084
    m[3][2] = 0.0f;
 
1085
    m[3][3] = 1.0f;
 
1086
}
 
1087
 
 
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)
 
1092
// 0            0           -1              0
 
1093
template <typename T>
 
1094
void Matrix4x4<T>::Perspective(T l, T r, T t, T b, T n, T f)
 
1095
{
 
1096
    m[0][0]     = 2.0f * n / (r-l);
 
1097
    m[0][1] = 0.0f;
 
1098
    m[0][2] = (r+l) / (r-l);
 
1099
    m[0][3] = 0.0f;
 
1100
 
 
1101
    m[1][0] = 0.0f;
 
1102
    m[1][1] = 2.0f * n / (t-b);
 
1103
    m[1][2] = (t+b) / (t-b);
 
1104
    m[1][3] = 0.0f;
 
1105
 
 
1106
    m[2][0] = 0.0f;
 
1107
    m[2][1] = 0.0f;
 
1108
    m[2][2] = -(f+n) / (f-n);
 
1109
    m[2][3] = -2.0f * f * n / (f-n);
 
1110
 
 
1111
    m[3][0] = 0.0f;
 
1112
    m[3][1] = 0.0f;
 
1113
    m[3][2] = -1.0f;
 
1114
    m[3][3] = 0.0f;
 
1115
}
 
1116
 
 
1117
// (r-l)/2*n    0           0               (r+l)/(2*n)
 
1118
// 0            (t-b)/(2*n) 0               (t+b)/(2*n)
 
1119
// 0            0           0               -1
 
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)
 
1123
{
 
1124
    m[0][0]     = (r-l)/(2.0f*n);
 
1125
    m[0][1] = 0;
 
1126
    m[0][2] = 0;
 
1127
    m[0][3] = (r+l)/(2.0f*n);
 
1128
 
 
1129
    m[1][0] = 0;
 
1130
    m[1][1] = (t-b)/(2.0f*n);
 
1131
    m[1][2] = (t+b)/(2.0f*n);
 
1132
    m[1][3] = 0;
 
1133
 
 
1134
    m[2][0] = 0;
 
1135
    m[2][1] = 0;
 
1136
    m[2][2] = 0;
 
1137
    m[2][3] = -1;
 
1138
 
 
1139
    m[3][0] = 0;
 
1140
    m[3][1] = 0;
 
1141
    m[3][2] = -(f-n)/(2.0f*f*n);
 
1142
    m[3][3] = (f+n)/(2.0f*f*n);
 
1143
}
 
1144
 
 
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)
 
1148
{
 
1149
    const T t = tan(FoV*0.5f) * NearPlane;
 
1150
    const T b = -t;
 
1151
 
 
1152
    const T l = AspectRatio * b;
 
1153
    const T r = AspectRatio * t;
 
1154
 
 
1155
    Perspective(l, r, t, b, NearPlane, FarPlane);
 
1156
}
 
1157
 
 
1158
template <typename T>
 
1159
Matrix4x4<T> Matrix4x4<T>::IDENTITY()
 
1160
{
 
1161
    Matrix4x4<T> matrix;
 
1162
    matrix.Identity();
 
1163
    return matrix;
 
1164
}
 
1165
 
 
1166
template <typename T>
 
1167
Matrix4x4<T> Matrix4x4<T>::ZERO()
 
1168
{
 
1169
    Matrix4x4<T> matrix;
 
1170
    matrix.Zero();
 
1171
    return matrix;
 
1172
}
 
1173
/***************************************************************************************\
 
1174
Function:       operator *
 
1175
 
 
1176
Description:    Multiply matrix rhs by constant lhs.
 
1177
                Allow "f * matrix" operation.
 
1178
 
 
1179
Parameters:     None.
 
1180
 
 
1181
Return Value:   Matrix4.
 
1182
 
 
1183
Comments:       None.
 
1184
\***************************************************************************************/
 
1185
template<typename T>
 
1186
Matrix4x4<T> operator * (const T& lhs, const Matrix4x4<T>& rhs)
 
1187
{
 
1188
    Matrix4x4<T> oM;
 
1189
 
 
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;
 
1194
 
 
1195
    return oM;
 
1196
}
 
1197
 
 
1198
typedef Matrix4x4<float> Matrix4;
 
1199
 
 
1200
NAMESPACE_END
 
1201
 
 
1202
 
 
1203
#endif // MATRIX4_H
 
1204