5 #ifndef __IRR_MATRIX_H_INCLUDED__
6 #define __IRR_MATRIX_H_INCLUDED__
24 #if defined( USE_MATRIX_TEST_DEBUG )
28 MatrixTest () : ID(0), Calls(0) {}
33 static MatrixTest MTest;
71 #if defined ( USE_MATRIX_TEST )
72 definitelyIdentityMatrix=
false;
74 return M[ row * 4 + col ];
83 #if defined ( USE_MATRIX_TEST )
84 definitelyIdentityMatrix=
false;
102 #if defined ( USE_MATRIX_TEST )
103 definitelyIdentityMatrix=
false;
404 #if defined ( USE_MATRIX_TEST )
405 mutable u32 definitelyIdentityMatrix;
408 #if defined ( USE_MATRIX_TEST_DEBUG )
418 #if defined ( USE_MATRIX_TEST )
419 : definitelyIdentityMatrix(BIT_UNTESTED)
421 #if defined ( USE_MATRIX_TEST_DEBUG )
422 ,id ( MTest.ID++), calls ( 0 )
425 switch ( constructor )
427 case EM4CONST_NOTHING:
430 case EM4CONST_IDENTITY:
431 case EM4CONST_INVERSE:
441 #if defined ( USE_MATRIX_TEST )
442 : definitelyIdentityMatrix(BIT_UNTESTED)
444 #if defined ( USE_MATRIX_TEST_DEBUG )
445 ,id ( MTest.ID++), calls ( 0 )
448 switch ( constructor )
450 case EM4CONST_IDENTITY:
453 case EM4CONST_NOTHING:
458 case EM4CONST_TRANSPOSED:
461 case EM4CONST_INVERSE:
463 memset(M, 0, 16*
sizeof(T));
465 case EM4CONST_INVERSE_TRANSPOSED:
467 memset(M, 0, 16*
sizeof(T));
469 *
this=getTransposed();
480 temp[0] = M[0]+other[0];
481 temp[1] = M[1]+other[1];
482 temp[2] = M[2]+other[2];
483 temp[3] = M[3]+other[3];
484 temp[4] = M[4]+other[4];
485 temp[5] = M[5]+other[5];
486 temp[6] = M[6]+other[6];
487 temp[7] = M[7]+other[7];
488 temp[8] = M[8]+other[8];
489 temp[9] = M[9]+other[9];
490 temp[10] = M[10]+other[10];
491 temp[11] = M[11]+other[11];
492 temp[12] = M[12]+other[12];
493 temp[13] = M[13]+other[13];
494 temp[14] = M[14]+other[14];
495 temp[15] = M[15]+other[15];
530 temp[0] = M[0]-other[0];
531 temp[1] = M[1]-other[1];
532 temp[2] = M[2]-other[2];
533 temp[3] = M[3]-other[3];
534 temp[4] = M[4]-other[4];
535 temp[5] = M[5]-other[5];
536 temp[6] = M[6]-other[6];
537 temp[7] = M[7]-other[7];
538 temp[8] = M[8]-other[8];
539 temp[9] = M[9]-other[9];
540 temp[10] = M[10]-other[10];
541 temp[11] = M[11]-other[11];
542 temp[12] = M[12]-other[12];
543 temp[13] = M[13]-other[13];
544 temp[14] = M[14]-other[14];
545 temp[15] = M[15]-other[15];
580 temp[0] = M[0]*scalar;
581 temp[1] = M[1]*scalar;
582 temp[2] = M[2]*scalar;
583 temp[3] = M[3]*scalar;
584 temp[4] = M[4]*scalar;
585 temp[5] = M[5]*scalar;
586 temp[6] = M[6]*scalar;
587 temp[7] = M[7]*scalar;
588 temp[8] = M[8]*scalar;
589 temp[9] = M[9]*scalar;
590 temp[10] = M[10]*scalar;
591 temp[11] = M[11]*scalar;
592 temp[12] = M[12]*scalar;
593 temp[13] = M[13]*scalar;
594 temp[14] = M[14]*scalar;
595 temp[15] = M[15]*scalar;
628 #if defined ( USE_MATRIX_TEST )
632 if ( this->isIdentity() )
634 return (*
this = other);
639 return setbyproduct_nocheck( temp, other );
645 return setbyproduct_nocheck( temp, other );
655 const T *m1 = other_a.M;
656 const T *m2 = other_b.M;
658 M[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
659 M[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
660 M[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
661 M[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];
663 M[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
664 M[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
665 M[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
666 M[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];
668 M[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
669 M[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
670 M[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
671 M[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];
673 M[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
674 M[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
675 M[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
676 M[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
677 #if defined ( USE_MATRIX_TEST )
678 definitelyIdentityMatrix=
false;
690 #if defined ( USE_MATRIX_TEST )
692 return (*
this = other_b);
695 return (*
this = other_a);
697 return setbyproduct_nocheck(other_a,other_b);
699 return setbyproduct_nocheck(other_a,other_b);
707 #if defined ( USE_MATRIX_TEST )
709 if ( this->isIdentity() )
719 m3[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3];
720 m3[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3];
721 m3[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3];
722 m3[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3];
724 m3[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7];
725 m3[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7];
726 m3[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7];
727 m3[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7];
729 m3[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11];
730 m3[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11];
731 m3[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11];
732 m3[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11];
734 m3[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15];
735 m3[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15];
736 m3[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15];
737 m3[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15];
753 M[12] = translation.
X;
754 M[13] = translation.
Y;
755 M[14] = translation.
Z;
756 #if defined ( USE_MATRIX_TEST )
757 definitelyIdentityMatrix=
false;
765 M[12] = -translation.
X;
766 M[13] = -translation.
Y;
767 M[14] = -translation.
Z;
768 #if defined ( USE_MATRIX_TEST )
769 definitelyIdentityMatrix=
false;
780 #if defined ( USE_MATRIX_TEST )
781 definitelyIdentityMatrix=
false;
807 return vector3d<T>(sqrtf(M[0] * M[0] + M[1] * M[1] + M[2] * M[2]),
808 sqrtf(M[4] * M[4] + M[5] * M[5] + M[6] * M[6]),
809 sqrtf(M[8] * M[8] + M[9] * M[9] + M[10] * M[10]));
827 const f64 cr = cos( rotation.
X );
828 const f64 sr = sin( rotation.
X );
829 const f64 cp = cos( rotation.
Y );
830 const f64 sp = sin( rotation.
Y );
831 const f64 cy = cos( rotation.
Z );
832 const f64 sy = sin( rotation.
Z );
838 const f64 srsp = sr*sp;
839 const f64 crsp = cr*sp;
841 M[4] = (T)( srsp*cy-cr*sy );
842 M[5] = (T)( srsp*sy+cr*cy );
845 M[8] = (T)( crsp*cy+sr*sy );
846 M[9] = (T)( crsp*sy-sr*cy );
847 M[10] = (T)( cr*cp );
848 #if defined ( USE_MATRIX_TEST )
849 definitelyIdentityMatrix=
false;
865 if (scale.
Y<0 && scale.
Z<0)
870 else if (scale.
X<0 && scale.
Z<0)
875 else if (scale.
X<0 && scale.
Y<0)
883 const f64 C = cos(Y);
886 f64 rotx, roty, X, Z;
891 rotx = mat[10] * invC * invScale.
Z;
892 roty = mat[6] * invC * invScale.
Y;
894 rotx = mat[0] * invC * invScale.
X;
895 roty = mat[1] * invC * invScale.
X;
901 rotx = mat[5] * invScale.
Y;
902 roty = -mat[4] * invScale.
Y;
907 if (X < 0.0) X += 360.0;
908 if (Y < 0.0) Y += 360.0;
909 if (Z < 0.0) Z += 360.0;
919 f64 cr = cos( rotation.
X );
920 f64 sr = sin( rotation.
X );
921 f64 cp = cos( rotation.
Y );
922 f64 sp = sin( rotation.
Y );
923 f64 cy = cos( rotation.
Z );
924 f64 sy = sin( rotation.
Z );
933 M[1] = (T)( srsp*cy-cr*sy );
934 M[5] = (T)( srsp*sy+cr*cy );
937 M[2] = (T)( crsp*cy+sr*sy );
938 M[6] = (T)( crsp*sy-sr*cy );
939 M[10] = (T)( cr*cp );
940 #if defined ( USE_MATRIX_TEST )
941 definitelyIdentityMatrix=
false;
950 const f64 c = cos(angle);
951 const f64 s = sin(angle);
952 const f64 t = 1.0 - c;
954 const f64 tx = t * axis.
X;
955 const f64 ty = t * axis.
Y;
956 const f64 tz = t * axis.
Z;
958 const f64 sx = s * axis.
X;
959 const f64 sy = s * axis.
Y;
960 const f64 sz = s * axis.
Z;
962 M[0] = (T)(tx * axis.
X + c);
963 M[1] = (T)(tx * axis.
Y + sz);
964 M[2] = (T)(tx * axis.
Z - sy);
966 M[4] = (T)(ty * axis.
X - sz);
967 M[5] = (T)(ty * axis.
Y + c);
968 M[6] = (T)(ty * axis.
Z + sx);
970 M[8] = (T)(tz * axis.
X + sy);
971 M[9] = (T)(tz * axis.
Y - sx);
972 M[10] = (T)(tz * axis.
Z + c);
974 #if defined ( USE_MATRIX_TEST )
975 definitelyIdentityMatrix=
false;
986 memset(M, 0, 16*
sizeof(T));
987 M[0] = M[5] = M[10] = M[15] = (T)1;
988 #if defined ( USE_MATRIX_TEST )
989 definitelyIdentityMatrix=
true;
1002 #if defined ( USE_MATRIX_TEST )
1003 if (definitelyIdentityMatrix)
1029 #if defined ( USE_MATRIX_TEST )
1030 definitelyIdentityMatrix=
true;
1040 T dp=M[0] * M[4 ] + M[1] * M[5 ] + M[2 ] * M[6 ] + M[3 ] * M[7 ];
1043 dp = M[0] * M[8 ] + M[1] * M[9 ] + M[2 ] * M[10] + M[3 ] * M[11];
1046 dp = M[0] * M[12] + M[1] * M[13] + M[2 ] * M[14] + M[3 ] * M[15];
1049 dp = M[4] * M[8 ] + M[5] * M[9 ] + M[6 ] * M[10] + M[7 ] * M[11];
1052 dp = M[4] * M[12] + M[5] * M[13] + M[6 ] * M[14] + M[7 ] * M[15];
1055 dp = M[8] * M[12] + M[9] * M[13] + M[10] * M[14] + M[11] * M[15];
1069 #if defined ( USE_MATRIX_TEST )
1070 if (definitelyIdentityMatrix)
1074 if(
IR(M[1])!=0)
return false;
1075 if(
IR(M[2])!=0)
return false;
1076 if(
IR(M[3])!=0)
return false;
1078 if(
IR(M[4])!=0)
return false;
1080 if(
IR(M[6])!=0)
return false;
1081 if(
IR(M[7])!=0)
return false;
1083 if(
IR(M[8])!=0)
return false;
1084 if(
IR(M[9])!=0)
return false;
1086 if(
IR(M[11])!=0)
return false;
1088 if(
IR(M[12])!=0)
return false;
1089 if(
IR(M[13])!=0)
return false;
1090 if(
IR(M[13])!=0)
return false;
1093 #if defined ( USE_MATRIX_TEST )
1094 definitelyIdentityMatrix=
true;
1104 vect.
X = tmp.
X*M[0] + tmp.
Y*M[4] + tmp.
Z*M[8];
1105 vect.
Y = tmp.
X*M[1] + tmp.
Y*M[5] + tmp.
Z*M[9];
1106 vect.
Z = tmp.
X*M[2] + tmp.
Y*M[6] + tmp.
Z*M[10];
1113 out.
X = in.
X*M[0] + in.
Y*M[4] + in.
Z*M[8];
1114 out.
Y = in.
X*M[1] + in.
Y*M[5] + in.
Z*M[9];
1115 out.
Z = in.
X*M[2] + in.
Y*M[6] + in.
Z*M[10];
1122 out[0] = in.
X*M[0] + in.
Y*M[4] + in.
Z*M[8];
1123 out[1] = in.
X*M[1] + in.
Y*M[5] + in.
Z*M[9];
1124 out[2] = in.
X*M[2] + in.
Y*M[6] + in.
Z*M[10];
1131 vect.
X = tmp.
X*M[0] + tmp.
Y*M[1] + tmp.
Z*M[2];
1132 vect.
Y = tmp.
X*M[4] + tmp.
Y*M[5] + tmp.
Z*M[6];
1133 vect.
Z = tmp.
X*M[8] + tmp.
Y*M[9] + tmp.
Z*M[10];
1141 vector[0] = vect.
X*M[0] + vect.
Y*M[4] + vect.
Z*M[8] + M[12];
1142 vector[1] = vect.
X*M[1] + vect.
Y*M[5] + vect.
Z*M[9] + M[13];
1143 vector[2] = vect.
X*M[2] + vect.
Y*M[6] + vect.
Z*M[10] + M[14];
1153 out.
X = in.
X*M[0] + in.
Y*M[4] + in.
Z*M[8] + M[12];
1154 out.
Y = in.
X*M[1] + in.
Y*M[5] + in.
Z*M[9] + M[13];
1155 out.
Z = in.
X*M[2] + in.
Y*M[6] + in.
Z*M[10] + M[14];
1162 out[0] = in.
X*M[0] + in.
Y*M[4] + in.
Z*M[8] + M[12];
1163 out[1] = in.
X*M[1] + in.
Y*M[5] + in.
Z*M[9] + M[13];
1164 out[2] = in.
X*M[2] + in.
Y*M[6] + in.
Z*M[10] + M[14];
1165 out[3] = in.
X*M[3] + in.
Y*M[7] + in.
Z*M[11] + M[15];
1171 out[0] = in[0]*M[0] + in[1]*M[4] + in[2]*M[8] + M[12];
1172 out[1] = in[0]*M[1] + in[1]*M[5] + in[2]*M[9] + M[13];
1173 out[2] = in[0]*M[2] + in[1]*M[6] + in[2]*M[10] + M[14];
1186 CMatrix4<T> transposedInverse(*
this, EM4CONST_INVERSE_TRANSPOSED);
1188 transposedInverse.transformVect(normal);
1198 transformPlane( out );
1205 #if defined ( USE_MATRIX_TEST )
1219 #if defined ( USE_MATRIX_TEST )
1230 Bmin[0] = Bmax[0] = M[12];
1231 Bmin[1] = Bmax[1] = M[13];
1232 Bmin[2] = Bmax[2] = M[14];
1236 for (
u32 i = 0; i < 3; ++i)
1238 for (
u32 j = 0; j < 3; ++j)
1240 const f32 a = m(j,i) * Amin[j];
1241 const f32 b = m(j,i) * Amax[j];
1283 matrix[0] = M[0]*mat[0] + M[4]*mat[1] + M[8]*mat[2] + M[12]*mat[3];
1284 matrix[1] = M[1]*mat[0] + M[5]*mat[1] + M[9]*mat[2] + M[13]*mat[3];
1285 matrix[2] = M[2]*mat[0] + M[6]*mat[1] + M[10]*mat[2] + M[14]*mat[3];
1286 matrix[3] = M[3]*mat[0] + M[7]*mat[1] + M[11]*mat[2] + M[15]*mat[3];
1292 vect.
X = vect.
X-M[12];
1293 vect.
Y = vect.
Y-M[13];
1294 vect.
Z = vect.
Z-M[14];
1300 vect.
X = vect.
X+M[12];
1301 vect.
Y = vect.
Y+M[13];
1302 vect.
Z = vect.
Z+M[14];
1313 #if defined ( USE_MATRIX_TEST )
1314 if ( this->isIdentity() )
1322 f32 d = (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) -
1323 (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
1324 (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)) +
1325 (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) -
1326 (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) +
1327 (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0));
1334 out(0, 0) = d * (m(1, 1) * (m(2, 2) * m(3, 3) - m(2, 3) * m(3, 2)) +
1335 m(1, 2) * (m(2, 3) * m(3, 1) - m(2, 1) * m(3, 3)) +
1336 m(1, 3) * (m(2, 1) * m(3, 2) - m(2, 2) * m(3, 1)));
1337 out(0, 1) = d * (m(2, 1) * (m(0, 2) * m(3, 3) - m(0, 3) * m(3, 2)) +
1338 m(2, 2) * (m(0, 3) * m(3, 1) - m(0, 1) * m(3, 3)) +
1339 m(2, 3) * (m(0, 1) * m(3, 2) - m(0, 2) * m(3, 1)));
1340 out(0, 2) = d * (m(3, 1) * (m(0, 2) * m(1, 3) - m(0, 3) * m(1, 2)) +
1341 m(3, 2) * (m(0, 3) * m(1, 1) - m(0, 1) * m(1, 3)) +
1342 m(3, 3) * (m(0, 1) * m(1, 2) - m(0, 2) * m(1, 1)));
1343 out(0, 3) = d * (m(0, 1) * (m(1, 3) * m(2, 2) - m(1, 2) * m(2, 3)) +
1344 m(0, 2) * (m(1, 1) * m(2, 3) - m(1, 3) * m(2, 1)) +
1345 m(0, 3) * (m(1, 2) * m(2, 1) - m(1, 1) * m(2, 2)));
1346 out(1, 0) = d * (m(1, 2) * (m(2, 0) * m(3, 3) - m(2, 3) * m(3, 0)) +
1347 m(1, 3) * (m(2, 2) * m(3, 0) - m(2, 0) * m(3, 2)) +
1348 m(1, 0) * (m(2, 3) * m(3, 2) - m(2, 2) * m(3, 3)));
1349 out(1, 1) = d * (m(2, 2) * (m(0, 0) * m(3, 3) - m(0, 3) * m(3, 0)) +
1350 m(2, 3) * (m(0, 2) * m(3, 0) - m(0, 0) * m(3, 2)) +
1351 m(2, 0) * (m(0, 3) * m(3, 2) - m(0, 2) * m(3, 3)));
1352 out(1, 2) = d * (m(3, 2) * (m(0, 0) * m(1, 3) - m(0, 3) * m(1, 0)) +
1353 m(3, 3) * (m(0, 2) * m(1, 0) - m(0, 0) * m(1, 2)) +
1354 m(3, 0) * (m(0, 3) * m(1, 2) - m(0, 2) * m(1, 3)));
1355 out(1, 3) = d * (m(0, 2) * (m(1, 3) * m(2, 0) - m(1, 0) * m(2, 3)) +
1356 m(0, 3) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) +
1357 m(0, 0) * (m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2)));
1358 out(2, 0) = d * (m(1, 3) * (m(2, 0) * m(3, 1) - m(2, 1) * m(3, 0)) +
1359 m(1, 0) * (m(2, 1) * m(3, 3) - m(2, 3) * m(3, 1)) +
1360 m(1, 1) * (m(2, 3) * m(3, 0) - m(2, 0) * m(3, 3)));
1361 out(2, 1) = d * (m(2, 3) * (m(0, 0) * m(3, 1) - m(0, 1) * m(3, 0)) +
1362 m(2, 0) * (m(0, 1) * m(3, 3) - m(0, 3) * m(3, 1)) +
1363 m(2, 1) * (m(0, 3) * m(3, 0) - m(0, 0) * m(3, 3)));
1364 out(2, 2) = d * (m(3, 3) * (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0)) +
1365 m(3, 0) * (m(0, 1) * m(1, 3) - m(0, 3) * m(1, 1)) +
1366 m(3, 1) * (m(0, 3) * m(1, 0) - m(0, 0) * m(1, 3)));
1367 out(2, 3) = d * (m(0, 3) * (m(1, 1) * m(2, 0) - m(1, 0) * m(2, 1)) +
1368 m(0, 0) * (m(1, 3) * m(2, 1) - m(1, 1) * m(2, 3)) +
1369 m(0, 1) * (m(1, 0) * m(2, 3) - m(1, 3) * m(2, 0)));
1370 out(3, 0) = d * (m(1, 0) * (m(2, 2) * m(3, 1) - m(2, 1) * m(3, 2)) +
1371 m(1, 1) * (m(2, 0) * m(3, 2) - m(2, 2) * m(3, 0)) +
1372 m(1, 2) * (m(2, 1) * m(3, 0) - m(2, 0) * m(3, 1)));
1373 out(3, 1) = d * (m(2, 0) * (m(0, 2) * m(3, 1) - m(0, 1) * m(3, 2)) +
1374 m(2, 1) * (m(0, 0) * m(3, 2) - m(0, 2) * m(3, 0)) +
1375 m(2, 2) * (m(0, 1) * m(3, 0) - m(0, 0) * m(3, 1)));
1376 out(3, 2) = d * (m(3, 0) * (m(0, 2) * m(1, 1) - m(0, 1) * m(1, 2)) +
1377 m(3, 1) * (m(0, 0) * m(1, 2) - m(0, 2) * m(1, 0)) +
1378 m(3, 2) * (m(0, 1) * m(1, 0) - m(0, 0) * m(1, 1)));
1379 out(3, 3) = d * (m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) +
1380 m(0, 1) * (m(1, 2) * m(2, 0) - m(1, 0) * m(2, 2)) +
1381 m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0)));
1383 #if defined ( USE_MATRIX_TEST )
1384 out.definitelyIdentityMatrix = definitelyIdentityMatrix;
1410 out.M[12] = (T)-(M[12]*M[0] + M[13]*M[1] + M[14]*M[2]);
1411 out.M[13] = (T)-(M[12]*M[4] + M[13]*M[5] + M[14]*M[6]);
1412 out.M[14] = (T)-(M[12]*M[8] + M[13]*M[9] + M[14]*M[10]);
1415 #if defined ( USE_MATRIX_TEST )
1416 out.definitelyIdentityMatrix = definitelyIdentityMatrix;
1426 #if defined ( USE_MATRIX_TEST )
1427 if (definitelyIdentityMatrix)
1432 if (getInverse(temp))
1447 memcpy(M, other.M, 16*
sizeof(T));
1448 #if defined ( USE_MATRIX_TEST )
1449 definitelyIdentityMatrix=other.definitelyIdentityMatrix;
1458 for (
s32 i = 0; i < 16; ++i)
1461 #if defined ( USE_MATRIX_TEST )
1462 definitelyIdentityMatrix=
false;
1471 #if defined ( USE_MATRIX_TEST )
1472 if (definitelyIdentityMatrix && other.definitelyIdentityMatrix)
1475 for (
s32 i = 0; i < 16; ++i)
1476 if (M[i] != other.M[i])
1486 return !(*
this == other);
1493 f32 fieldOfViewRadians,
f32 aspectRatio,
f32 zNear,
f32 zFar)
1497 const T w =
static_cast<T
>(h / aspectRatio);
1512 M[10] = (T)(zFar/(zNear-zFar));
1518 M[14] = (T)(zNear*zFar/(zNear-zFar));
1522 #if defined ( USE_MATRIX_TEST )
1523 definitelyIdentityMatrix=
false;
1532 f32 fieldOfViewRadians,
f32 aspectRatio,
f32 zNear,
f32 zFar)
1536 const T w =
static_cast<T
>(h / aspectRatio);
1551 M[10] = (T)(zFar/(zFar-zNear));
1556 M[14] = (T)(-zNear*zFar/(zFar-zNear));
1559 #if defined ( USE_MATRIX_TEST )
1560 definitelyIdentityMatrix=
false;
1569 f32 fieldOfViewRadians,
f32 aspectRatio,
f32 zNear,
f32 epsilon)
1573 const T w =
static_cast<T
>(h / aspectRatio);
1587 M[10] = (T)(1.f-epsilon);
1592 M[14] = (T)(zNear*(epsilon-1.f));
1595 #if defined ( USE_MATRIX_TEST )
1596 definitelyIdentityMatrix=
false;
1605 f32 widthOfViewVolume,
f32 heightOfViewVolume,
f32 zNear,
f32 zFar)
1610 M[0] = (T)(2/widthOfViewVolume);
1616 M[5] = (T)(2/heightOfViewVolume);
1622 M[10] = (T)(1/(zFar-zNear));
1627 M[14] = (T)(zNear/(zNear-zFar));
1630 #if defined ( USE_MATRIX_TEST )
1631 definitelyIdentityMatrix=
false;
1640 f32 widthOfViewVolume,
f32 heightOfViewVolume,
f32 zNear,
f32 zFar)
1645 M[0] = (T)(2/widthOfViewVolume);
1651 M[5] = (T)(2/heightOfViewVolume);
1657 M[10] = (T)(1/(zNear-zFar));
1662 M[14] = (T)(zNear/(zNear-zFar));
1665 #if defined ( USE_MATRIX_TEST )
1666 definitelyIdentityMatrix=
false;
1675 f32 widthOfViewVolume,
f32 heightOfViewVolume,
f32 zNear,
f32 zFar)
1680 M[0] = (T)(2*zNear/widthOfViewVolume);
1686 M[5] = (T)(2*zNear/heightOfViewVolume);
1692 M[10] = (T)(zFar/(zNear-zFar));
1697 M[14] = (T)(zNear*zFar/(zNear-zFar));
1700 #if defined ( USE_MATRIX_TEST )
1701 definitelyIdentityMatrix=
false;
1710 f32 widthOfViewVolume,
f32 heightOfViewVolume,
f32 zNear,
f32 zFar)
1715 M[0] = (T)(2*zNear/widthOfViewVolume);
1721 M[5] = (T)(2*zNear/heightOfViewVolume);
1727 M[10] = (T)(zFar/(zFar-zNear));
1732 M[14] = (T)(zNear*zFar/(zNear-zFar));
1734 #if defined ( USE_MATRIX_TEST )
1735 definitelyIdentityMatrix=
false;
1748 M[ 0] = (T)(-plane.
Normal.
X * light.
X + d);
1749 M[ 1] = (T)(-plane.
Normal.
X * light.
Y);
1750 M[ 2] = (T)(-plane.
Normal.
X * light.
Z);
1751 M[ 3] = (T)(-plane.
Normal.
X * point);
1753 M[ 4] = (T)(-plane.
Normal.
Y * light.
X);
1754 M[ 5] = (T)(-plane.
Normal.
Y * light.
Y + d);
1755 M[ 6] = (T)(-plane.
Normal.
Y * light.
Z);
1756 M[ 7] = (T)(-plane.
Normal.
Y * point);
1758 M[ 8] = (T)(-plane.
Normal.
Z * light.
X);
1759 M[ 9] = (T)(-plane.
Normal.
Z * light.
Y);
1760 M[10] = (T)(-plane.
Normal.
Z * light.
Z + d);
1761 M[11] = (T)(-plane.
Normal.
Z * point);
1763 M[12] = (T)(-plane.
D * light.
X);
1764 M[13] = (T)(-plane.
D * light.
Y);
1765 M[14] = (T)(-plane.
D * light.
Z);
1766 M[15] = (T)(-plane.
D * point + d);
1767 #if defined ( USE_MATRIX_TEST )
1768 definitelyIdentityMatrix=
false;
1807 #if defined ( USE_MATRIX_TEST )
1808 definitelyIdentityMatrix=
false;
1848 #if defined ( USE_MATRIX_TEST )
1849 definitelyIdentityMatrix=
false;
1861 for (
u32 i=0; i < 16; i += 4)
1863 mat.M[i+0] = (T)(M[i+0] + ( b.M[i+0] - M[i+0] ) * time);
1864 mat.M[i+1] = (T)(M[i+1] + ( b.M[i+1] - M[i+1] ) * time);
1865 mat.M[i+2] = (T)(M[i+2] + ( b.M[i+2] - M[i+2] ) * time);
1866 mat.M[i+3] = (T)(M[i+3] + ( b.M[i+3] - M[i+3] ) * time);
1877 getTransposed ( t );
1905 #if defined ( USE_MATRIX_TEST )
1906 o.definitelyIdentityMatrix=definitelyIdentityMatrix;
1915 const f32 scaleX = (viewport.
getWidth() - 0.75f ) * 0.5f;
1916 const f32 scaleY = -(viewport.
getHeight() - 0.75f ) * 0.5f;
1954 M[0] = vt.
X * v.X + ca;
1955 M[5] = vt.
Y * v.Y + ca;
1956 M[10] = vt.
Z * v.Z + ca;
2015 M[0] =
static_cast<T
>(vt.
X * up.
X + ca);
2016 M[5] =
static_cast<T
>(vt.
Y * up.
Y + ca);
2017 M[10] =
static_cast<T
>(vt.
Z * up.
Z + ca);
2023 M[1] =
static_cast<T
>(vt.
X - vs.
Z);
2024 M[2] =
static_cast<T
>(vt.
Z + vs.
Y);
2027 M[4] =
static_cast<T
>(vt.
X + vs.
Z);
2028 M[6] =
static_cast<T
>(vt.
Y - vs.
X);
2031 M[8] =
static_cast<T
>(vt.
Z - vs.
Y);
2032 M[9] =
static_cast<T
>(vt.
Y + vs.
X);
2035 setRotationCenter(center, translation);
2043 M[12] = -M[0]*center.
X - M[4]*center.
Y - M[8]*center.
Z + (center.
X - translation.
X );
2044 M[13] = -M[1]*center.
X - M[5]*center.
Y - M[9]*center.
Z + (center.
Y - translation.
Y );
2045 M[14] = -M[2]*center.
X - M[6]*center.
Y - M[10]*center.
Z + (center.
Z - translation.
Z );
2047 #if defined ( USE_MATRIX_TEST )
2048 definitelyIdentityMatrix=
false;
2070 const f32 c = cosf(rotateRad);
2071 const f32 s = sinf(rotateRad);
2073 M[0] = (T)(c * scale.
X);
2074 M[1] = (T)(s * scale.
Y);
2078 M[4] = (T)(-s * scale.
X);
2079 M[5] = (T)(c * scale.
Y);
2083 M[8] = (T)(c * scale.
X * rotatecenter.
X + -s * rotatecenter.
Y + translate.
X);
2084 M[9] = (T)(s * scale.
Y * rotatecenter.
X + c * rotatecenter.
Y + translate.
Y);
2092 #if defined ( USE_MATRIX_TEST )
2093 definitelyIdentityMatrix=
false;
2103 const f32 c = cosf(rotateRad);
2104 const f32 s = sinf(rotateRad);
2111 M[8] = (T)(0.5f * ( s - c) + 0.5f);
2112 M[9] = (T)(-0.5f * ( s + c) + 0.5f);
2114 #if defined ( USE_MATRIX_TEST )
2115 definitelyIdentityMatrix = definitelyIdentityMatrix && (rotateRad==0.0f);
2127 #if defined ( USE_MATRIX_TEST )
2128 definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f);
2140 #if defined ( USE_MATRIX_TEST )
2141 definitelyIdentityMatrix = definitelyIdentityMatrix && (x==0.0f) && (y==0.0f) ;
2151 #if defined ( USE_MATRIX_TEST )
2152 definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f);
2163 M[8] = (T)(0.5f - 0.5f * sx);
2164 M[9] = (T)(0.5f - 0.5f * sy);
2166 #if defined ( USE_MATRIX_TEST )
2167 definitelyIdentityMatrix = definitelyIdentityMatrix && (sx==1.0f) && (sy==1.0f);
2177 memcpy(M,data, 16*
sizeof(T));
2179 #if defined ( USE_MATRIX_TEST )
2180 definitelyIdentityMatrix=
false;
2190 #if defined ( USE_MATRIX_TEST )
2191 definitelyIdentityMatrix = isDefinitelyIdentityMatrix;
2200 #if defined ( USE_MATRIX_TEST )
2201 return definitelyIdentityMatrix;
2212 #if defined ( USE_MATRIX_TEST )
2213 if (definitelyIdentityMatrix && other.definitelyIdentityMatrix)
2216 for (
s32 i = 0; i < 16; ++i)
void rotateVect(vector3df &vect) const
Rotate a vector by the rotation part of this matrix.
bool getInversePrimitive(CMatrix4< T > &out) const
Inverts a primitive matrix which only contains a translation and a rotation.
const f64 RADTODEG64
64bit constant for converting from radians to degrees
CMatrix4< T > & buildCameraLookAtMatrixLH(const vector3df &position, const vector3df &target, const vector3df &upVector)
Builds a left-handed look-at matrix.
vector3d< T > MaxEdge
The far edge.
T Y
Y coordinate of the vector.
bool iszero(const f64 a, const f64 tolerance=ROUNDING_ERROR_f64)
returns if a equals zero, taking rounding errors into account
CMatrix4< T > & buildProjectionMatrixOrthoRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
Builds a right-handed orthogonal projection matrix.
const T * pointer() const
Returns pointer to internal array.
IRRLICHT_API const matrix4 IdentityMatrix
global const identity matrix
void setDefinitelyIdentityMatrix(bool isDefinitelyIdentityMatrix)
Sets if the matrix is definitely identity matrix.
CMatrix4< T > & buildProjectionMatrixPerspectiveFovRH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
Builds a right-handed perspective projection matrix based on a field of view.
core::vector3d< T > getScale() const
Get Scale.
CMatrix4< T > & setTextureTranslateTransposed(f32 x, f32 y)
Set texture transformation translation, using a transposed representation.
const T & operator[](u32 index) const
Simple operator for linearly accessing every element of the matrix.
void transformBox(core::aabbox3d< f32 > &box) const
Transforms a axis aligned bounding box.
float f32
32 bit floating point variable.
void transformVect(vector3df &vect) const
Transforms the vector by this matrix.
CMatrix4< T > & setTextureTranslate(f32 x, f32 y)
Set texture transformation translation.
CMatrix4< T > & setScale(const T scale)
Set Scale.
vector3d< T > Normal
Normal vector of the plane.
position2d< T > UpperLeftCorner
Upper left corner.
CMatrix4< T > & operator+=(const CMatrix4< T > &other)
Add another matrix.
void transformVec3(T *out, const T *in) const
An alternate transform vector method, reading from and writing to an array of 3 floats.
T Y
Y coordinate of vector.
void setRotationCenter(const core::vector3df ¢er, const core::vector3df &translate)
Builds a combined matrix which translates to a center before rotation and translates from origin afte...
#define IRRLICHT_API
Set FPU settings.
T X
X coordinate of the vector.
CMatrix4< T > & setRotationAxisRadians(const T &angle, const vector3d< T > &axis)
Make a rotation matrix from angle and axis, assuming left handed rotation.
void transformBoxEx(core::aabbox3d< f32 > &box) const
Transforms a axis aligned bounding box.
CMatrix4< T > & setInverseRotationRadians(const vector3d< T > &rotation)
Make an inverted rotation matrix from Euler angles.
3d vector template class with lots of operators and methods.
bool isOrthogonal() const
Returns true if the matrix is orthogonal.
bool equals(const core::CMatrix4< T > &other, const T tolerance=(T) ROUNDING_ERROR_f64) const
Compare two matrices using the equal method.
vector3d< T > getTranslation() const
Gets the current translation.
CMatrix4< T > & buildProjectionMatrixPerspectiveRH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
Builds a right-handed perspective projection matrix.
CMatrix4< T > & setTextureRotationCenter(f32 radAngle)
Set texture transformation rotation.
CMatrix4< T > & buildNDCToDCMatrix(const core::rect< s32 > &area, f32 zScale)
Builds a matrix which transforms a normalized Device Coordinate to Device Coordinates.
double f64
64 bit floating point variable.
bool isIdentity() const
Returns true if the matrix is the identity matrix.
vector3d< T > crossProduct(const vector3d< T > &p) const
Calculates the cross product with another vector.
position2d< T > LowerRightCorner
Lower right corner.
CMatrix4< T > & buildTextureTransform(f32 rotateRad, const core::vector2df &rotatecenter, const core::vector2df &translate, const core::vector2df &scale)
Set to a texture transformation matrix with the given parameters.
CMatrix4< T > & setbyproduct_nocheck(const CMatrix4< T > &other_a, const CMatrix4< T > &other_b)
Set this matrix to the product of two matrices.
CMatrix4< T > & operator*=(const CMatrix4< T > &other)
Multiply by another matrix.
CMatrix4< T > & setInverseRotationDegrees(const vector3d< T > &rotation)
Make an inverted rotation matrix from Euler angles.
vector3d< T > getMemberPoint() const
Gets a member point of the plane.
CMatrix4< T > & setScale(const vector3d< T > &scale)
Set Scale.
void multiplyWith1x4Matrix(T *matrix) const
Multiplies this matrix by a 1x4 matrix.
CMatrix4< T > & setbyproduct(const CMatrix4< T > &other_a, const CMatrix4< T > &other_b)
set this matrix to the product of two matrices
const f64 ROUNDING_ERROR_f64
signed int s32
32 bit signed variable.
CMatrix4< T > & buildCameraLookAtMatrixRH(const vector3df &position, const vector3df &target, const vector3df &upVector)
Builds a right-handed look-at matrix.
bool getDefinitelyIdentityMatrix() const
Gets if the matrix is definitely identity matrix.
bool operator==(const CMatrix4< T > &other) const
Returns true if other matrix is equal to this matrix.
T getWidth() const
Get width of rectangle.
REALINLINE f32 reciprocal(const f32 f)
void setPlane(const vector3d< T > &point, const vector3d< T > &nvector)
CMatrix4< T > & setTextureScale(f32 sx, f32 sy)
Set texture transformation scale.
CMatrix4< T > & buildRotateFromTo(const core::vector3df &from, const core::vector3df &to)
Builds a matrix that rotates from one vector to another.
CMatrix4< T > & setRotationDegrees(const vector3d< T > &rotation)
Make a rotation matrix from Euler angles. The 4th row and column are unmodified.
unsigned int u32
32 bit unsigned variable.
void inverseTranslateVect(vector3df &vect) const
Translate a vector by the inverse of the translation part of this matrix.
CMatrix4< T > operator+(const CMatrix4< T > &other) const
Add another matrix.
CMatrix4< T > & buildShadowMatrix(const core::vector3df &light, core::plane3df plane, f32 point=1.0f)
Builds a matrix that flattens geometry into a plane.
CMatrix4(eConstructor constructor=EM4CONST_IDENTITY)
Default constructor.
bool getInverse(CMatrix4< T > &out) const
Gets the inversed matrix of this one.
#define _IRR_DEBUG_BREAK_IF(_CONDITION_)
define a break macro for debugging.
CMatrix4< T > & operator=(const CMatrix4< T > &other)
Sets this matrix equal to the other matrix.
CMatrix4< T > & setInverseTranslation(const vector3d< T > &translation)
Set the inverse translation of the current matrix. Will erase any previous values.
const f32 DEGTORAD
32bit Constant for converting from degrees to radians
CMatrix4< T > & buildProjectionMatrixPerspectiveLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
Builds a left-handed perspective projection matrix.
vector3d< T > & normalize()
Normalizes the vector.
CMatrix4< T > operator-(const CMatrix4< T > &other) const
Subtract another matrix.
T getHeight() const
Get height of rectangle.
vector3d< T > MinEdge
The near edge.
4x4 matrix. Mostly used as transformation matrix for 3d calculations.
CMatrix4< T > getTransposed() const
Gets transposed matrix.
CMatrix4< T > & setTranslation(const vector3d< T > &translation)
Set the translation of the current matrix. Will erase any previous values.
bool makeInverse()
Calculates inverse of matrix. Slow.
CMatrix4< T > & setTextureScaleCenter(f32 sx, f32 sy)
Set texture transformation scale, and recenter at (0.5,0.5)
CMatrix4< T > operator*(const CMatrix4< T > &other) const
Multiply by another matrix.
CMatrix4< T > & buildProjectionMatrixPerspectiveFovInfinityLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 epsilon=0)
Builds a left-handed perspective projection matrix based on a field of view, with far plane at infini...
void buildAxisAlignedBillboard(const core::vector3df &camPos, const core::vector3df ¢er, const core::vector3df &translation, const core::vector3df &axis, const core::vector3df &from)
Builds a matrix which rotates a source vector to a look vector over an arbitrary axis.
T & operator[](u32 index)
Simple operator for linearly accessing every element of the matrix.
T Z
Z coordinate of the vector.
core::vector3d< T > getRotationDegrees() const
Returns the rotation, as set by setRotation().
CMatrix4< T > & buildProjectionMatrixPerspectiveFovLH(f32 fieldOfViewRadians, f32 aspectRatio, f32 zNear, f32 zFar)
Builds a left-handed perspective projection matrix based on a field of view.
CMatrix4< T > & buildProjectionMatrixOrthoLH(f32 widthOfViewVolume, f32 heightOfViewVolume, f32 zNear, f32 zFar)
Builds a left-handed orthogonal projection matrix.
CMatrix4< f32 > matrix4
Typedef for f32 matrix.
bool isIdentity_integer_base() const
Returns true if the matrix is the identity matrix.
const T & operator()(const s32 row, const s32 col) const
Simple operator for directly accessing every element of the matrix.
T dotProduct(const vector3d< T > &other) const
Get the dot product with another vector.
eConstructor
Constructor Flags.
void inverseRotateVect(vector3df &vect) const
Rotate a vector by the inverse of the rotation part of this matrix.
CMatrix4< T > operator*(const T scalar, const CMatrix4< T > &mat)
void repair()
Repairs the box.
CMatrix4< T > & setRotationRadians(const vector3d< T > &rotation)
Make a rotation matrix from Euler angles. The 4th row and column are unmodified.
void transformPlane(core::plane3d< f32 > &plane) const
Transforms a plane by this matrix.
CMatrix4< T > & setM(const T *data)
Sets all matrix data members at once.
bool operator!=(const CMatrix4< T > &other) const
Returns true if other matrix is not equal to this matrix.
bool equals(const f64 a, const f64 b, const f64 tolerance=ROUNDING_ERROR_f64)
returns if a equals b, taking possible rounding errors into account
void translateVect(vector3df &vect) const
Translate a vector by the translation part of this matrix.
CMatrix4< T > & makeIdentity()
Set matrix to identity.
CMatrix4< T > interpolate(const core::CMatrix4< T > &b, f32 time) const
Creates a new matrix as interpolated matrix from two other ones.
T & operator()(const s32 row, const s32 col)
Simple operator for directly accessing every element of the matrix.
const T clamp(const T &value, const T &low, const T &high)
clamps a value between low and high
CMatrix4< T > & operator-=(const CMatrix4< T > &other)
Subtract another matrix.
T X
X coordinate of vector.