Oxygine  1
2g game engine
Matrix.h
1 #pragma once
2 #include "oxygine-include.h"
3 
4 #include "Vector3.h"
5 #include "Vector4.h"
6 #include <math.h>
7 #include <stdlib.h>
8 #include <algorithm>
9 
10 namespace oxygine
11 {
12  template <class T>
13  class MatrixT
14  {
15  typedef VectorT3<T> vector3;
16  typedef VectorT4<T> vector4;
17  typedef MatrixT<T> matrix;
18 
19  public:
20 
21  MatrixT();
22  MatrixT(const T*);
23  MatrixT(
24  T _11, T _12, T _13, T _14,
25  T _21, T _22, T _23, T _24,
26  T _31, T _32, T _33, T _34,
27  T _41, T _42, T _43, T _44);
28 
29  operator T* ()const;
30  operator const T* () const;
31 
32  MatrixT operator * (const MatrixT& m) const;
33  vector4& operator[](int row);
34 
35  void identity();
36  void inverse();
37  void transpose();
38  void translate(const vector3&);
39  void scale(const vector3&);
40  void buildSRT(const vector3& scale, T angle, const vector3& t);
41 
42  MatrixT inversed() const;
43  MatrixT transposed() const;
44 
45  vector3 transformVec3(const vector3&)const;
46  vector4 transformVec4(const vector4&)const;
47  vector3 getTranslation()const;
48 
49  static MatrixT& lookAtLH(
50  MatrixT& out,
51  const vector3& Eye,
52  const vector3& At,
53  const vector3& Up);
54 
55  static MatrixT& lookAtRH(
56  MatrixT& out,
57  const vector3& Eye,
58  const vector3& At,
59  const vector3& Up);
60 
61  static MatrixT ident();
62  static MatrixT& inverse(MatrixT& out, const MatrixT& in);
63  static MatrixT& transpose(MatrixT& out, const MatrixT& in);
64  static MatrixT& rotationX(MatrixT& out, T angle);
65  static MatrixT& rotationY(MatrixT& out, T angle);
66  static MatrixT& rotationZ(MatrixT& out, T angle);
67  static MatrixT& translation(MatrixT& out, const vector3& v);
68  static MatrixT& scaling(MatrixT& out, const vector3& v);
69 
70  static MatrixT& perspectiveFovLH(MatrixT& out, T fovy, T aspect, T znear, T zfar);
71  static MatrixT& perspectiveFovRH(MatrixT& out, T fovy, T aspect, T znear, T zfar);
72 
73  static MatrixT& perspectiveOffCenterLH(MatrixT& out, T left, T right, T bottom, T top, T znear, T zfar);
74  static MatrixT& perspectiveOffCenterRH(MatrixT& out, T left, T right, T bottom, T top, T znear, T zfar);
75 
76  static MatrixT& orthoLH(MatrixT& out, T width, T height, T zNear, T zFar);
77 
78  static vector3& transformVec3(vector3& out, const vector3& in, const MatrixT& mat);
79  static vector4& transformVec4(vector4& out, const vector4& in, const MatrixT& mat);
80 
81 
82  union
83  {
84  struct
85  {
86  T m[4][4];
87  };
88  struct
89  {
90  T ml[16];
91  };
92  struct
93  {
94  T
95  m11, m12, m13, m14,
96  m21, m22, m23, m24,
97  m31, m32, m33, m34,
98  m41, m42, m43, m44;
99  };
100  };
101 
102  };
103 
104  template <class T>
106  {
107  }
108 
109  template <class T>
110  MatrixT<T>::MatrixT(const T* p)
111  {
112  for (int i = 0; i < 16; ++i)
113  ml[i] = p[i];
114  }
115 
116  template <class T>
117  MatrixT<T>::MatrixT(T _11, T _12, T _13, T _14,
118  T _21, T _22, T _23, T _24,
119  T _31, T _32, T _33, T _34,
120  T _41, T _42, T _43, T _44):
121  m11(_11), m12(_12), m13(_13), m14(_14),
122  m21(_21), m22(_22), m23(_23), m24(_24),
123  m31(_31), m32(_32), m33(_33), m34(_34),
124  m41(_41), m42(_42), m43(_43), m44(_44)
125  {
126  }
127 
128 
129  template <class T>
130  void MatrixT<T>::identity()
131  {
132  vector4* rows = (vector4*)ml;
133  rows[0] = VectorT4<T>(1, 0, 0, 0);
134  rows[1] = VectorT4<T>(0, 1, 0, 0);
135  rows[2] = VectorT4<T>(0, 0, 1, 0);
136  rows[3] = VectorT4<T>(0, 0, 0, 1);
137  }
138 
139  template <class T>
140  void MatrixT<T>::inverse()
141  {
142  inverse(this, *this);
143  }
144 
145 
146 
147 
148  template <class T>
149  MatrixT<T> MatrixT<T>::inversed() const
150  {
151  matrix m;
152  inverse(m, *this);
153  return m;
154  }
155 
156  template <class T>
157  MatrixT<T> MatrixT<T>::ident()
158  {
159  MatrixT m;
160  m.identity();
161  return m;
162  }
163 
164 
165  template <class T>
166  void MatrixT<T>::transpose()
167  {
168  transpose(*this, *this);
169  }
170 
171 
172  template <class T>
173  MatrixT<T> MatrixT<T>::transposed() const
174  {
175  matrix m;
176  transpose(m, *this);
177  return m;
178  }
179 
180  template <class T>
181  void MatrixT<T>::translate(const vector3& t)
182  {
183  matrix tm;
184  matrix::translation(tm, t);
185  *this = *this * tm;
186  }
187 
188  template <class T>
189  void MatrixT<T>::scale(const vector3& s)
190  {
191  matrix sm;
192  matrix::scaling(sm, s);
193  *this = *this * sm;
194  }
195 
196  template <class T>
197  void MatrixT<T>::buildSRT(const vector3& s, T angle, const vector3& t)
198  {
199  matrix sm, rm, tm;
200  matrix::scaling(&sm, s);
201  matrix::rotationY(&rm, angle);
202  matrix::translation(&tm, t);
203 
204  *this = sm * rm * tm;
205  }
206 
207 
208  template <class T>
209  VectorT3<T> MatrixT<T>::transformVec3(const vector3& v)const
210  {
211  vector3 out;
212  transformVec3(out, v, *this);
213  return out;
214  }
215 
216  template <class T>
217  VectorT4<T> MatrixT<T>::transformVec4(const vector4& v)const
218  {
219  vector4 out;
220  transformVec4(out, v, *this);
221  return out;
222  }
223 
224  template <class T>
225  VectorT3<T> MatrixT<T>::getTranslation()const
226  {
227  vector4* rows = (vector4*)ml;
228  return vector3(rows[3].x, rows[3].y, rows[3].z);
229  }
230 
231 #define rcDot4(r, c) (mrows[r].x * nrows[0][c] + mrows[r].y * nrows[1][c] + mrows[r].z * nrows[2][c] + mrows[r].w * nrows[3][c])
232 
233  template <class T>
234  MatrixT<T> MatrixT<T>::operator *(const MatrixT<T>& n) const
235  {
236  const vector4* mrows = (vector4*)ml;
237  const vector4* nrows = (vector4*)n.ml;
238  matrix mat
239  (
240  rcDot4(0, 0), rcDot4(0, 1), rcDot4(0, 2), rcDot4(0, 3),
241  rcDot4(1, 0), rcDot4(1, 1), rcDot4(1, 2), rcDot4(1, 3),
242  rcDot4(2, 0), rcDot4(2, 1), rcDot4(2, 2), rcDot4(2, 3),
243  rcDot4(3, 0), rcDot4(3, 1), rcDot4(3, 2), rcDot4(3, 3)
244  );
245  return mat;
246  }
247 
248  template <class T>
249  VectorT4<T>& MatrixT<T>::operator [](int row)
250  {
251  vector4* rows = (vector4*)ml;
252  return rows[row];
253  }
254 
255 
256  template <class T>
257  MatrixT<T>::operator T* () const
258  {
259  return ml;
260  }
261 
262  template <class T>
263  MatrixT<T>::operator const T* () const
264  {
265  return ml;
266  }
267 
268  template <class T>
269  inline MatrixT<T>& MatrixT<T>::lookAtLH(MatrixT& out,
270  const vector3& Eye,
271  const vector3& At,
272  const vector3& Up)
273  {
274  vector3 x, y, z, temp;
275  vector3::normalize(z, At - Eye);
276  vector3::normalize(x, vector3::cross(temp, Up, z));
277  vector3::normalize(y, vector3::cross(temp, z, x));
278 
279  out = matrix(
280  x.x, y.x, z.x, 0,
281  x.y, y.y, z.y, 0,
282  x.z, y.z, z.z, 0,
283  -vector3::dot(x, Eye), -vector3::dot(y, Eye), -vector3::dot(z, Eye), 1);
284 
285  return out;
286  }
287 
288  template <class T>
289  inline MatrixT<T>& MatrixT<T>::lookAtRH(MatrixT& out,
290  const vector3& Eye,
291  const vector3& At,
292  const vector3& Up)
293  {
294  vector3 x, y, z, temp;
295  vector3::normalize(z, Eye - At);
296  vector3::normalize(x, vector3::cross(temp, Up, z));
297  vector3::normalize(y, vector3::cross(temp, z, x));
298 
299  *out = matrix(
300  x.x, y.x, z.x, 0,
301  x.y, y.y, z.y, 0,
302  x.z, y.z, z.z, 0,
303  -vector3::dot(x, Eye), -vector3::dot(y, Eye), -vector3::dot(z, Eye), 1);
304 
305  return out;
306  }
307 
308  template <class T>
309  inline MatrixT<T>& MatrixT<T>::rotationX(MatrixT& out, T angle)
310  {
311  T s = scalar::sin(angle);
312  T c = scalar::cos(angle);
313 
314  out = MatrixT(
315  1, 0, 0, 0,
316  0, c, s, 0,
317  0, -s, c, 0,
318  0, 0, 0, 1);
319  return out;
320  }
321 
322  template <class T>
323  inline MatrixT<T>& MatrixT<T>::rotationY(MatrixT& out, T angle)
324  {
325  T s = scalar::sin(angle);
326  T c = scalar::cos(angle);
327  out = MatrixT(
328  c, 0, -s, 0,
329  0, 1, 0, 0,
330  s, 0, c, 0,
331  0, 0, 0, 1);
332  return out;
333  }
334 
335  template <class T>
336  inline MatrixT<T>& MatrixT<T>::rotationZ(MatrixT& out, T angle)
337  {
338  T s = scalar::sin(angle);
339  T c = scalar::cos(angle);
340  out = MatrixT(
341  c, s, 0, 0,
342  -s, c, 0, 0,
343  0, 0, 1, 0,
344  0, 0, 0, 1);
345  return out;
346  }
347 
348 
349 
350  template <class T>
351  inline MatrixT<T>& MatrixT<T>::translation(MatrixT& out, const vector3& v)
352  {
353  out = MatrixT(
354  1, 0, 0, 0,
355  0, 1, 0, 0,
356  0, 0, 1, 0,
357  v.x, v.y, v.z, 1);
358  return out;
359  }
360 
361  template <class T>
362  inline MatrixT<T>& MatrixT<T>::scaling(MatrixT& out, const vector3& v)
363  {
364  out = MatrixT(
365  v.x, 0, 0, 0,
366  0, v.y, 0, 0,
367  0, 0, v.z, 0,
368  0, 0, 0, 1);
369 
370  return out;
371  }
372 
373  template <class T>
374  inline MatrixT<T>& MatrixT<T>::perspectiveFovLH(MatrixT& out, T fovy, T aspect, T zNear, T zFar)
375  {
376  float y = T(1) / scalar::tan(T(0.5) * fovy);
377  float x = y / aspect;
378 
379  out = matrix(
380  x, 0.0f, 0.0f, 0.0f,
381  0.0f, y, 0.0f, 0.0f,
382  0.0f, 0.0f, zFar / (zFar - zNear), 1.0f,
383  0.0f, 0.0f, -zFar * zNear / (zFar - zNear), 0.0f);
384  return out;
385  }
386 
387  template <class T>
388  inline MatrixT<T>& MatrixT<T>::perspectiveFovRH(MatrixT& out, T fovy, T aspect, T zNear, T zFar)
389  {
390  float y = T(1) / scalar::tan(T(0.5) * fovy);
391  float x = y / aspect;
392 
393  out = matrix(
394  x, 0.0f, 0.0f, 0.0f,
395  0.0f, y, 0.0f, 0.0f,
396  0.0f, 0.0f, zFar / (zFar - zNear), -1.0f,
397  0.0f, 0.0f, zFar * zNear / (zFar - zNear), 0.0f);
398  return out;
399  }
400 
401  template <class T>
402  inline MatrixT<T>& MatrixT<T>::perspectiveOffCenterLH(MatrixT& out, T left, T right, T bottom, T top, T znearPlane, T zfarPlane)
403  {
404  out = matrix(
405  2 * znearPlane / (right - left), 0, 0, 0,
406  0, 2 * znearPlane / (top - bottom), 0, 0,
407  (left + right) / (left - right), (top + bottom) / (bottom - top), zfarPlane / (zfarPlane - znearPlane), 1,
408  0, 0, znearPlane * zfarPlane / (znearPlane - zfarPlane), 0);
409  return out;
410  }
411 
412  template <class T>
413  inline MatrixT<T>& MatrixT<T>::perspectiveOffCenterRH(MatrixT& out, T left, T right, T bottom, T top, T znearPlane, T zfarPlane)
414  {
415  out = matrix(
416  2 * znearPlane / (right - left), 0, 0, 0,
417  0, 2 * znearPlane / (top - bottom), 0, 0,
418  (left + right) / (right - left), (top + bottom) / (top - bottom), zfarPlane / (znearPlane - zfarPlane), -1,
419  0, 0, znearPlane * zfarPlane / (znearPlane - zfarPlane), 0);
420  return out;
421  }
422 
423  template <class T>
424  inline MatrixT<T>& MatrixT<T>::orthoLH(MatrixT& out, T w, T h, T zNear, T zFar)
425  {
426  out = matrix(
427  T(2) / w, 0, 0, 0,
428  0, T(2) / h, 0, 0,
429  0, 0, T(1) / (zFar - zNear), 0,
430  0, 0, zNear / (zNear - zFar), 1);
431  return out;
432  }
433 
434  template <class T>
435  inline MatrixT<T>& MatrixT<T>::inverse(MatrixT& out, const MatrixT& mat)
436  {
437  T a9 = mat.m31 * mat.m42 - mat.m32 * mat.m41;
438  T aa = mat.m31 * mat.m43 - mat.m33 * mat.m41;
439  T a8 = mat.m31 * mat.m44 - mat.m34 * mat.m41;
440 
441  T a2 = mat.m32 * mat.m43 - mat.m33 * mat.m42;
442  T a5 = mat.m32 * mat.m44 - mat.m34 * mat.m42;
443  T a3 = mat.m33 * mat.m44 - mat.m34 * mat.m43;
444 
445  T t1 = mat.m22 * a3 - mat.m23 * a5 + mat.m24 * a2;
446  T t2 = mat.m21 * a3 - mat.m23 * a8 + mat.m24 * aa;
447  T t3 = mat.m21 * a5 - mat.m22 * a8 + mat.m24 * a9;
448  T t4 = mat.m21 * a2 - mat.m22 * aa + mat.m23 * a9;
449 
450  T det = mat.m11 * t1 - mat.m12 * t2 + mat.m13 * t3 - mat.m14 * t4;
451 
452  if (scalar::abs(det) < T(0.0001))
453  {
454  out.identity();
455  return out;
456  }
457 
458  det = T(1) / (det);
459 
460  T a0 = mat.m21 * mat.m32 - mat.m22 * mat.m31;
461  T af = mat.m21 * mat.m42 - mat.m22 * mat.m41;
462  T ac = mat.m22 * mat.m33 - mat.m23 * mat.m32;
463  T a6 = mat.m22 * mat.m43 - mat.m23 * mat.m42;
464 
465  T ab = mat.m23 * mat.m34 - mat.m24 * mat.m33;
466  T a7 = mat.m23 * mat.m44 - mat.m24 * mat.m43;
467  T ae = mat.m21 * mat.m34 - mat.m24 * mat.m31;
468  T ad = mat.m21 * mat.m44 - mat.m24 * mat.m41;
469 
470  T b0 = mat.m22 * mat.m34 - mat.m24 * mat.m32;
471  T b1 = mat.m21 * mat.m43 - mat.m23 * mat.m41;
472  T b2 = mat.m21 * mat.m33 - mat.m23 * mat.m31;
473  T b3 = mat.m22 * mat.m44 - mat.m24 * mat.m42;
474 
475  out = MatrixT(
476  det * t1,
477  -det * (mat.m12 * a3 - mat.m13 * a5 + mat.m14 * a2),
478  det * (mat.m12 * a7 - mat.m13 * b3 + mat.m14 * a6),
479  -det * (mat.m12 * ab - mat.m13 * b0 + mat.m14 * ac),
480 
481  -det * t2,
482  det * (mat.m11 * a3 - mat.m13 * a8 + mat.m14 * aa),
483  -det * (mat.m11 * a7 - mat.m13 * ad + mat.m14 * b1),
484  det * (mat.m11 * ab - mat.m13 * ae + mat.m14 * b2),
485 
486  det * t3,
487  -det * (mat.m11 * a5 - mat.m12 * a8 + mat.m14 * a9),
488  det * (mat.m11 * b3 - mat.m12 * ad + mat.m14 * af),
489  -det * (mat.m11 * b0 - mat.m12 * ae + mat.m14 * a0),
490 
491  -det * t4,
492  det * (mat.m11 * a2 - mat.m12 * aa + mat.m13 * a9),
493  -det * (mat.m11 * a6 - mat.m12 * b1 + mat.m13 * af),
494  det * (mat.m11 * ac - mat.m12 * b2 + mat.m13 * a0));
495  return out;
496  }
497 
498  template <class T>
499  inline MatrixT<T>& MatrixT<T>::transpose(MatrixT& out, const MatrixT& mat)
500  {
501  vector4* rows = (vector4*)mat.ml;
502  out = MatrixT(
503  rows[0].x, rows[1].x, rows[2].x, rows[3].x,
504  rows[0].y, rows[1].y, rows[2].y, rows[3].y,
505  rows[0].z, rows[1].z, rows[2].z, rows[3].z,
506  rows[0].w, rows[1].w, rows[2].w, rows[3].w);
507  return out;
508  }
509 
510  template <class T>
511  inline VectorT3<T>& MatrixT<T>::transformVec3(VectorT3<T>& out, const vector3& in, const MatrixT& mat)
512  {
513  out = vector3(
514  in.x * mat.m11 + in.y * mat.m21 + in.z * mat.m31 + mat.m41,
515  in.x * mat.m12 + in.y * mat.m22 + in.z * mat.m32 + mat.m42,
516  in.x * mat.m13 + in.y * mat.m23 + in.z * mat.m33 + mat.m43);
517  return out;
518  }
519 
520  template <class T>
521  inline VectorT4<T>& MatrixT<T>::transformVec4(VectorT4<T>& out, const vector4& in, const MatrixT& mat)
522  {
523  out = vector4(
524  in.x * mat.m11 + in.y * mat.m21 + in.z * mat.m31 + in.w * mat.m41,
525  in.x * mat.m12 + in.y * mat.m22 + in.z * mat.m32 + in.w * mat.m42,
526  in.x * mat.m13 + in.y * mat.m23 + in.z * mat.m33 + in.w * mat.m43,
527  in.x * mat.m14 + in.y * mat.m24 + in.z * mat.m34 + in.w * mat.m44);
528  return out;
529  }
530 
531 
532  typedef MatrixT<float> Matrix;
533  typedef MatrixT<double> MatrixD;
534 
535 }
–oxgl-end–!
Definition: Actor.h:14
Definition: Matrix.h:13
Definition: Vector4.h:7
Definition: Vector3.h:7