26 #ifndef FIFE_UTIL_MATRIX_H
27 #define FIFE_UTIL_MATRIX_H
41 #include "util/base/fife_stdint.h"
42 #include "util/structures/point.h"
44 #include "fife_math.h"
55 template <
typename U>
friend class Matrix;
57 memmove(m, mat.m, 16*
sizeof(T));
66 T determinant = m0*ret[0] + m1*ret[4] + m2*ret[8] + m3*ret[12];
67 assert(determinant!=0 &&
"Singular matrix has no inverse");
76 for (
register unsigned i = 0; i < 16; ++i)
86 ret[0] = cofactorm0();
87 ret[1] = -cofactorm4();
88 ret[2] = cofactorm8();
89 ret[3] = -cofactorm12();
91 ret[4] = -cofactorm1();
92 ret[5] = cofactorm5();
93 ret[6] = -cofactorm9();
94 ret[7] = cofactorm13();
96 ret[8] = cofactorm2();
97 ret[9] = -cofactorm6();
98 ret[10] = cofactorm10();
99 ret[11] = -cofactorm14();
101 ret[12] = -cofactorm3();
102 ret[13] = cofactorm7();
103 ret[14] = -cofactorm11();
104 ret[15] = cofactorm15();
114 register T magSqr = x*x + y*y + z*z;
116 register T mag = Math<T>::Sqrt(magSqr);
121 T c = Math<T>::Cos(angle*Math<T>::pi()/180);
122 T s = Math<T>::Sin(angle*Math<T>::pi()/180);
151 *
this = temp.mult4by4(*
this);
183 *
this = temp.mult4by4(*
this);
214 vec.x * m0 + vec.y * m4 + vec.z * m8 + m12,
215 vec.x * m1 + vec.y * m5 + vec.z * m9 + m13,
216 vec.x * m2 + vec.y * m6 + vec.z * m10 + m14
223 assert(ind > -1 && ind < 16);
226 inline const T&
operator[] (int32_t ind)
const {
227 assert(ind > -1 && ind < 16);
235 m0 = temp.m0*mat.m0+temp.m4*mat.m1+temp.m8*mat.m2;
236 m4 = temp.m0*mat.m4+temp.m4*mat.m5+temp.m8*mat.m6;
237 m8 = temp.m0*mat.m8+temp.m4*mat.m9+temp.m8*mat.m10;
239 m1 = temp.m1*mat.m0+temp.m5*mat.m1+temp.m9*mat.m2;
240 m5 = temp.m1*mat.m4+temp.m5*mat.m5+temp.m9*mat.m6;
241 m9 = temp.m1*mat.m8+temp.m5*mat.m9+temp.m9*mat.m10;
243 m2 = temp.m2*mat.m0+temp.m6*mat.m1+temp.m10*mat.m2;
244 m6 = temp.m2*mat.m4+temp.m6*mat.m5+temp.m10*mat.m6;
245 m10 = temp.m2*mat.m8+temp.m6*mat.m9+temp.m10*mat.m10;
247 m3 = temp.m3*mat.m0+temp.m7*mat.m1+temp.m11*mat.m2;
248 m7 = temp.m3*mat.m4+temp.m7*mat.m5+temp.m11*mat.m6;
249 m11 = temp.m3*mat.m8+temp.m7*mat.m9+temp.m11*mat.m10;
258 m0 = mat.m0*temp.m0+mat.m4*temp.m1+mat.m8*temp.m2+mat.m12*temp.m3;
259 m4 = mat.m0*temp.m4+mat.m4*temp.m5+mat.m8*temp.m6+mat.m12*temp.m7;
260 m8 = mat.m0*temp.m8+mat.m4*temp.m9+mat.m8*temp.m10+mat.m12*temp.m11;
261 m12 = mat.m0*temp.m12+mat.m4*temp.m13+mat.m8*temp.m14+mat.m12*temp.m15;
263 m1 = mat.m1*temp.m0 + mat.m5*temp.m1 + mat.m9*temp.m2+mat.m13*temp.m3;
264 m5 = mat.m1*temp.m4 + mat.m5*temp.m5 + mat.m9*temp.m6+mat.m13*temp.m7;
265 m9 = mat.m1*temp.m8 + mat.m5*temp.m9 + mat.m9*temp.m10+mat.m13*temp.m11;
266 m13 = mat.m1*temp.m12+ mat.m5*temp.m13 + mat.m9*temp.m14+mat.m13*temp.m15;
268 m2 = mat.m2*temp.m0+mat.m6*temp.m1+mat.m10*temp.m2+mat.m14*temp.m3;
269 m6 = mat.m2*temp.m4+mat.m6*temp.m5+mat.m10*temp.m6+mat.m14*temp.m7;
270 m10 = mat.m2*temp.m8+mat.m6*temp.m9+mat.m10*temp.m10+mat.m14*temp.m11;
271 m14 = mat.m2*temp.m12+mat.m6*temp.m13+mat.m10*temp.m14+mat.m14*temp.m15;
273 m3 = mat.m3*temp.m0+mat.m7*temp.m1+mat.m11*temp.m2+mat.m15*temp.m3;
274 m7 = mat.m3*temp.m4+mat.m7*temp.m5+mat.m11*temp.m6+mat.m15*temp.m7;
275 m11 = mat.m3*temp.m8+mat.m7*temp.m9+mat.m11*temp.m10+mat.m15*temp.m11;
276 m15 = mat.m3*temp.m12+mat.m7*temp.m13+mat.m11*temp.m14+mat.m15*temp.m15;
284 m0 = temp.m0*mat.m0+temp.m4*mat.m1+temp.m8*mat.m2+temp.m12*mat.m3;
285 m4 = temp.m0*mat.m4+temp.m4*mat.m5+temp.m8*mat.m6+temp.m12*mat.m7;
286 m8 = temp.m0*mat.m8+temp.m4*mat.m9+temp.m8*mat.m10+temp.m12*mat.m11;
287 m12 = temp.m0*mat.m12+temp.m4*mat.m13+temp.m8*mat.m14+temp.m12*mat.m15;
289 m1 = temp.m1*mat.m0 + temp.m5*mat.m1 + temp.m9*mat.m2+temp.m13*mat.m3;
290 m5 = temp.m1*mat.m4 + temp.m5*mat.m5 + temp.m9*mat.m6+temp.m13*mat.m7;
291 m9 = temp.m1*mat.m8 + temp.m5*mat.m9 + temp.m9*mat.m10+temp.m13*mat.m11;
292 m13 = temp.m1*mat.m12+ temp.m5*mat.m13 + temp.m9*mat.m14+temp.m13*mat.m15;
294 m2 = temp.m2*mat.m0+temp.m6*mat.m1+temp.m10*mat.m2+temp.m14*mat.m3;
295 m6 = temp.m2*mat.m4+temp.m6*mat.m5+temp.m10*mat.m6+temp.m14*mat.m7;
296 m10 = temp.m2*mat.m8+temp.m6*mat.m9+temp.m10*mat.m10+temp.m14*mat.m11;
297 m14 = temp.m2*mat.m12+temp.m6*mat.m13+temp.m10*mat.m14+temp.m14*mat.m15;
299 m3 = temp.m3*mat.m0+temp.m7*mat.m1+temp.m11*mat.m2+temp.m15*mat.m3;
300 m7 = temp.m3*mat.m4+temp.m7*mat.m5+temp.m11*mat.m6+temp.m15*mat.m7;
301 m11 = temp.m3*mat.m8+temp.m7*mat.m9+temp.m11*mat.m10+temp.m15*mat.m11;
302 m15 = temp.m3*mat.m12+temp.m7*mat.m13+temp.m11*mat.m14+temp.m15*mat.m15;
306 Matrix& applyRotate(T angle, T x, T y, T z) {
307 static Matrix<T> temp;
308 temp.loadRotate(angle,x,y,z);
309 *
this = temp.mult4by4(*
this);
315 #define cofactor_maker(f1,mj1,mi1, f2,mj2,mi2, f3,mj3,mi3) \
316 f1*(mj1*mi1-mj2*mi3) + f2*(mj2*mi2-mj3*mi1) + f3*(mj3*mi3-mj1*mi2)
318 inline T cofactorm0()
const {
319 return cofactor_maker(m5,m10,m15, m6,m11,m13, m7,m9,m14);
321 inline T cofactorm1()
const {
322 return cofactor_maker(m6,m11,m12, m7,m8,m14, m4,m10,m15);
324 inline T cofactorm2()
const {
325 return cofactor_maker(m7,m8,m13, m4,m9,m15, m5,m11,m12);
327 inline T cofactorm3()
const {
328 return cofactor_maker(m4,m9,m14, m5,m10,m12, m6,m8,m13);
330 inline T cofactorm4()
const {
331 return cofactor_maker(m9,m14,m3, m10,m15,m1, m11,m13,m2);
333 inline T cofactorm5()
const {
334 return cofactor_maker(m10,m15,m0, m11,m12,m2, m8,m14,m3);
336 inline T cofactorm6()
const {
337 return cofactor_maker(m11,m12,m1, m8,m13,m3, m9,m15,m0);
339 inline T cofactorm7()
const {
340 return cofactor_maker(m8,m13,m2, m9,m14,m0, m10,m12,m1);
342 inline T cofactorm8()
const {
343 return cofactor_maker(m13,m2,m7, m14,m3,m5, m15,m1,m6);
345 inline T cofactorm9()
const {
346 return cofactor_maker(m14,m13,m4, m15,m0,m6, m12,m2,m7);
348 inline T cofactorm10()
const {
349 return cofactor_maker(m15,m0,m5, m12,m1,m7, m13,m3,m4);
351 inline T cofactorm11()
const {
352 return cofactor_maker(m12,m1,m6, m13,m2,m4, m14,m0,m5);
354 inline T cofactorm12()
const {
355 return cofactor_maker(m1,m6,m11, m2,m7,m9, m3,m5,m10);
357 inline T cofactorm13()
const {
358 return cofactor_maker(m2,m7,m8, m3,m4,m10, m10,m6,m11);
360 inline T cofactorm14()
const {
361 return cofactor_maker(m3,m4,m9, m0,m5,m11, m1,m7,m8);
363 inline T cofactorm15()
const {
364 return cofactor_maker(m0,m5,m10, m1,m6,m8, m2,m4,m9);
370 T m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15;
375 typedef Matrix<double> DoubleMatrix;
376 typedef Matrix<int32_t> IntMatrix;
381 std::ostream& operator<<(std::ostream& os, const Matrix<T>& m) {
383 return os <<
"\n|" << m[0] <<
"," << m[4] <<
"," << m[8] <<
"," << m[12] <<
"|\n" << \
384 "|" << m[1] <<
"," << m[5] <<
"," << m[9] <<
"," << m[13] <<
"|\n" << \
385 "|" << m[2] <<
"," << m[6] <<
"," << m[10] <<
"," << m[14] <<
"|\n" << \
386 "|" << m[3] <<
"," << m[7] <<
"," << m[11] <<
"," << m[15] <<
"|\n";