示例#1
0
 public bool Compare(ref idMat2 a)
 {
     idVec2[] a_mat = a.mat;
     return(
         mat[0].Compare(ref a_mat[0]) &&
         mat[1].Compare(ref a_mat[1]));
 }
示例#2
0
 public bool Compare(ref idMat2 a, float epsilon)
 {
     idVec2[] a_mat = a.mat;
     return(
         mat[0].Compare(ref a_mat[0], epsilon) &&
         mat[1].Compare(ref a_mat[1], epsilon));
 }
示例#3
0
 public idMat2 opAdd(idMat2 a)
 {
     idVec2[] a_mat = a.mat;
     mat[0].x += a_mat[0].x; mat[0].y += a_mat[0].y;
     mat[1].x += a_mat[1].x; mat[1].y += a_mat[1].y;
     return(this);
 }
示例#4
0
 public idMat2 opSub(idMat2 a)
 {
     idVec2[] a_mat = a.mat;
     mat[0].x -= a_mat[0].x; mat[0].y -= a_mat[0].y;
     mat[1].x -= a_mat[1].x; mat[1].y -= a_mat[1].y;
     return(this);
 }
示例#5
0
        public idMat2 InverseFast()
        {
            idMat2 invMat = this;
            bool   r      = invMat.InverseFastSelf();

            Debug.Assert(r);
            return(invMat);
        }
示例#6
0
        public idMat2 opMul(idMat2 a)
        {
            idVec2[] a_mat = a.mat;
            float    x, y;

            x        = mat[0].x; y = mat[0].y;
            mat[0].x = x * a_mat[0].x + y * a_mat[1].x;
            mat[0].y = x * a_mat[0].y + y * a_mat[1].y;
            x        = mat[1].x; y = mat[1].y;
            mat[1].x = x * a_mat[0].x + y * a_mat[1].x;
            mat[1].y = x * a_mat[0].y + y * a_mat[1].y;
            return(this);
        }
示例#7
0
        public bool InverseFastSelf()
        {
#if false
            // 84+4+16 = 104 multiplications
            //			   1 division
            // 2x2 sub-determinants required to calculate 4x4 determinant
            float det2_01_01 = mat[0].x * mat[1].y - mat[0].y * mat[1].x;
            float det2_01_02 = mat[0].x * mat[1].z - mat[0].z * mat[1].x;
            float det2_01_03 = mat[0].x * mat[1].w - mat[0].w * mat[1].x;
            float det2_01_12 = mat[0].y * mat[1].z - mat[0].z * mat[1].y;
            float det2_01_13 = mat[0].y * mat[1].w - mat[0].w * mat[1].y;
            float det2_01_23 = mat[0].z * mat[1].w - mat[0].w * mat[1].z;
            // 3x3 sub-determinants required to calculate 4x4 determinant
            float  det3_201_012 = mat[2].x * det2_01_12 - mat[2].y * det2_01_02 + mat[2].z * det2_01_01;
            float  det3_201_013 = mat[2].x * det2_01_13 - mat[2].y * det2_01_03 + mat[2].w * det2_01_01;
            float  det3_201_023 = mat[2].x * det2_01_23 - mat[2].z * det2_01_03 + mat[2].w * det2_01_02;
            float  det3_201_123 = mat[2].y * det2_01_23 - mat[2].z * det2_01_13 + mat[2].w * det2_01_12;
            double det          = (-det3_201_123 * mat[3].x + det3_201_023 * mat[3].y - det3_201_013 * mat[3].z + det3_201_012 * mat[3].w);
            if (idMath.Fabs(det) < MATRIX_INVERSE_EPSILON)
            {
                return(false);
            }
            double invDet = 1.0f / det;
            // remaining 2x2 sub-determinants
            float det2_03_01 = mat[0].x * mat[3].y - mat[0].y * mat[3].x;
            float det2_03_02 = mat[0].x * mat[3].z - mat[0].z * mat[3].x;
            float det2_03_03 = mat[0].x * mat[3].w - mat[0].w * mat[3].x;
            float det2_03_12 = mat[0].y * mat[3].z - mat[0].z * mat[3].y;
            float det2_03_13 = mat[0].y * mat[3].w - mat[0].w * mat[3].y;
            float det2_03_23 = mat[0].z * mat[3].w - mat[0].w * mat[3].z;
            //
            float det2_13_01 = mat[1].x * mat[3].y - mat[1].y * mat[3].x;
            float det2_13_02 = mat[1].x * mat[3].z - mat[1].z * mat[3].x;
            float det2_13_03 = mat[1].x * mat[3].w - mat[1].w * mat[3].x;
            float det2_13_12 = mat[1].y * mat[3].z - mat[1].z * mat[3].y;
            float det2_13_13 = mat[1].y * mat[3].w - mat[1].w * mat[3].y;
            float det2_13_23 = mat[1].z * mat[3].w - mat[1].w * mat[3].z;
            // remaining 3x3 sub-determinants
            float det3_203_012 = mat[2].x * det2_03_12 - mat[2].y * det2_03_02 + mat[2].z * det2_03_01;
            float det3_203_013 = mat[2].x * det2_03_13 - mat[2].y * det2_03_03 + mat[2].w * det2_03_01;
            float det3_203_023 = mat[2].x * det2_03_23 - mat[2].z * det2_03_03 + mat[2].w * det2_03_02;
            float det3_203_123 = mat[2].y * det2_03_23 - mat[2].z * det2_03_13 + mat[2].w * det2_03_12;
            //
            float det3_213_012 = mat[2].x * det2_13_12 - mat[2].y * det2_13_02 + mat[2].z * det2_13_01;
            float det3_213_013 = mat[2].x * det2_13_13 - mat[2].y * det2_13_03 + mat[2].w * det2_13_01;
            float det3_213_023 = mat[2].x * det2_13_23 - mat[2].z * det2_13_03 + mat[2].w * det2_13_02;
            float det3_213_123 = mat[2].y * det2_13_23 - mat[2].z * det2_13_13 + mat[2].w * det2_13_12;
            //
            float det3_301_012 = mat[3].x * det2_01_12 - mat[3].y * det2_01_02 + mat[3].z * det2_01_01;
            float det3_301_013 = mat[3].x * det2_01_13 - mat[3].y * det2_01_03 + mat[3].w * det2_01_01;
            float det3_301_023 = mat[3].x * det2_01_23 - mat[3].z * det2_01_03 + mat[3].w * det2_01_02;
            float det3_301_123 = mat[3].y * det2_01_23 - mat[3].z * det2_01_13 + mat[3].w * det2_01_12;
            //
            mat[0].x = (float)(-det3_213_123 * invDet);
            mat[1].x = (float)(+det3_213_023 * invDet);
            mat[2].x = (float)(-det3_213_013 * invDet);
            mat[3].x = (float)(+det3_213_012 * invDet);
            //
            mat[0].y = (float)(+det3_203_123 * invDet);
            mat[1].y = (float)(-det3_203_023 * invDet);
            mat[2].y = (float)(+det3_203_013 * invDet);
            mat[3].y = (float)(-det3_203_012 * invDet);
            //
            mat[0].z = (float)(+det3_301_123 * invDet);
            mat[1].z = (float)(-det3_301_023 * invDet);
            mat[2].z = (float)(+det3_301_013 * invDet);
            mat[3].z = (float)(-det3_301_012 * invDet);
            //
            mat[0].w = (float)(-det3_201_123 * invDet);
            mat[1].w = (float)(+det3_201_023 * invDet);
            mat[2].w = (float)(-det3_201_013 * invDet);
            mat[3].w = (float)(+det3_201_012 * invDet);
            return(true);
#elif false
            // 4*18 = 72 multiplications
            //		   4 divisions
            float *mat = reinterpret_cast <float *>(this);
            float  s;
            double d, di;

            di       = mat[0];
            s        = di;
            mat[0]   = d = 1.0f / di;
            mat[1]  *= d;
            mat[2]  *= d;
            mat[3]  *= d;
            d        = -d;
            mat[4]  *= d;
            mat[8]  *= d;
            mat[12] *= d;
            d        = mat[4] * di;
            mat[5]  += mat[1] * d;
            mat[6]  += mat[2] * d;
            mat[7]  += mat[3] * d;
            d        = mat[8] * di;
            mat[9]  += mat[1] * d;
            mat[10] += mat[2] * d;
            mat[11] += mat[3] * d;
            d        = mat[12] * di;
            mat[13] += mat[1] * d;
            mat[14] += mat[2] * d;
            mat[15] += mat[3] * d;
            di       = mat[5];
            s       *= di;
            mat[5]   = d = 1.0f / di;
            mat[4]  *= d;
            mat[6]  *= d;
            mat[7]  *= d;
            d        = -d;
            mat[1]  *= d;
            mat[9]  *= d;
            mat[13] *= d;
            d        = mat[1] * di;
            mat[0]  += mat[4] * d;
            mat[2]  += mat[6] * d;
            mat[3]  += mat[7] * d;
            d        = mat[9] * di;
            mat[8]  += mat[4] * d;
            mat[10] += mat[6] * d;
            mat[11] += mat[7] * d;
            d        = mat[13] * di;
            mat[12] += mat[4] * d;
            mat[14] += mat[6] * d;
            mat[15] += mat[7] * d;
            di       = mat[10];
            s       *= di;
            mat[10]  = d = 1.0f / di;
            mat[8]  *= d;
            mat[9]  *= d;
            mat[11] *= d;
            d        = -d;
            mat[2]  *= d;
            mat[6]  *= d;
            mat[14] *= d;
            d        = mat[2] * di;
            mat[0]  += mat[8] * d;
            mat[1]  += mat[9] * d;
            mat[3]  += mat[11] * d;
            d        = mat[6] * di;
            mat[4]  += mat[8] * d;
            mat[5]  += mat[9] * d;
            mat[7]  += mat[11] * d;
            d        = mat[14] * di;
            mat[12] += mat[8] * d;
            mat[13] += mat[9] * d;
            mat[15] += mat[11] * d;
            di       = mat[15];
            s       *= di;
            mat[15]  = d = 1.0f / di;
            mat[12] *= d;
            mat[13] *= d;
            mat[14] *= d;
            d        = -d;
            mat[3]  *= d;
            mat[7]  *= d;
            mat[11] *= d;
            d        = mat[3] * di;
            mat[0]  += mat[12] * d;
            mat[1]  += mat[13] * d;
            mat[2]  += mat[14] * d;
            d        = mat[7] * di;
            mat[4]  += mat[12] * d;
            mat[5]  += mat[13] * d;
            mat[6]  += mat[14] * d;
            d        = mat[11] * di;
            mat[8]  += mat[12] * d;
            mat[9]  += mat[13] * d;
            mat[10] += mat[14] * d;

            return(s != 0.0f && !FLOAT_IS_NAN(s));
#else
            //	6*8+2*6 = 60 multiplications
            //		2*1 =  2 divisions
            float[] mat = this;
            // r0 = m0.Inverse();
            float det = mat[0 * 4 + 0] * mat[1 * 4 + 1] - mat[0 * 4 + 1] * mat[1 * 4 + 0];
            if (idMath.Fabs(det) < MATRIX_INVERSE_EPSILON)
            {
                return(false);
            }
            float  invDet = 1.0f / det;
            idMat2 r0 = new idMat2(); idVec2[] r0_mat = r0.mat;
            r0_mat[0].x = mat[1 * 4 + 1] * invDet;
            r0_mat[0].y = -mat[0 * 4 + 1] * invDet;
            r0_mat[1].x = -mat[1 * 4 + 0] * invDet;
            r0_mat[1].y = mat[0 * 4 + 0] * invDet;
            // r1 = r0 * m1;
            idMat2 r1 = new idMat2(); idVec2[] r1_mat = r1.mat;
            r1_mat[0].x = r0_mat[0].x * mat[0 * 4 + 2] + r0_mat[0].y * mat[1 * 4 + 2];
            r1_mat[0].y = r0_mat[0].x * mat[0 * 4 + 3] + r0_mat[0].y * mat[1 * 4 + 3];
            r1_mat[1].x = r0_mat[1].x * mat[0 * 4 + 2] + r0_mat[1].y * mat[1 * 4 + 2];
            r1_mat[1].y = r0_mat[1].x * mat[0 * 4 + 3] + r0_mat[1].y * mat[1 * 4 + 3];
            // r2 = m2 * r1;
            idMat2 r2 = new idMat2(); idVec2[] r2_mat = r2.mat;
            r2_mat[0].x = mat[2 * 4 + 0] * r1_mat[0].x + mat[2 * 4 + 1] * r1_mat[1].x;
            r2_mat[0].y = mat[2 * 4 + 0] * r1_mat[0].y + mat[2 * 4 + 1] * r1_mat[1].y;
            r2_mat[1].x = mat[3 * 4 + 0] * r1_mat[0].x + mat[3 * 4 + 1] * r1_mat[1].x;
            r2_mat[1].y = mat[3 * 4 + 0] * r1_mat[0].y + mat[3 * 4 + 1] * r1_mat[1].y;
            // r3 = r2 - m3;
            idMat2 r3 = new idMat2(); idVec2[] r3_mat = r3.mat;
            r3_mat[0].x = r2_mat[0].x - mat[2 * 4 + 2];
            r3_mat[0].y = r2_mat[0].y - mat[2 * 4 + 3];
            r3_mat[1].x = r2_mat[1].x - mat[3 * 4 + 2];
            r3_mat[1].y = r2_mat[1].y - mat[3 * 4 + 3];
            // r3.InverseSelf();
            det = r3_mat[0].x * r3_mat[1].y - r3_mat[0].y * r3_mat[1].x;
            if (idMath.Fabs(det) < MATRIX_INVERSE_EPSILON)
            {
                return(false);
            }
            invDet = 1.0f / det;
            float a = r3_mat[0].x;
            r3_mat[0].x = r3_mat[1].y * invDet;
            r3_mat[0].y = -r3_mat[0].y * invDet;
            r3_mat[1].x = -r3_mat[1].x * invDet;
            r3_mat[1].y = a * invDet;
            // r2 = m2 * r0;
            r2_mat[0].x = mat[2 * 4 + 0] * r0_mat[0].x + mat[2 * 4 + 1] * r0_mat[1].x;
            r2_mat[0].y = mat[2 * 4 + 0] * r0_mat[0].y + mat[2 * 4 + 1] * r0_mat[1].y;
            r2_mat[1].x = mat[3 * 4 + 0] * r0_mat[0].x + mat[3 * 4 + 1] * r0_mat[1].x;
            r2_mat[1].y = mat[3 * 4 + 0] * r0_mat[0].y + mat[3 * 4 + 1] * r0_mat[1].y;
            // m2 = r3 * r2;
            mat[2 * 4 + 0] = r3_mat[0].x * r2_mat[0].x + r3_mat[0].y * r2_mat[1].x;
            mat[2 * 4 + 1] = r3_mat[0].x * r2_mat[0].y + r3_mat[0].y * r2_mat[1].y;
            mat[3 * 4 + 0] = r3_mat[1].x * r2_mat[0].x + r3_mat[1].y * r2_mat[1].x;
            mat[3 * 4 + 1] = r3_mat[1].x * r2_mat[0].y + r3_mat[1].y * r2_mat[1].y;
            // m0 = r0 - r1 * m2;
            mat[0 * 4 + 0] = r0_mat[0].x - r1_mat[0].x * mat[2 * 4 + 0] - r1_mat[0].y * mat[3 * 4 + 0];
            mat[0 * 4 + 1] = r0_mat[0].y - r1_mat[0].x * mat[2 * 4 + 1] - r1_mat[0].y * mat[3 * 4 + 1];
            mat[1 * 4 + 0] = r0_mat[1].x - r1_mat[1].x * mat[2 * 4 + 0] - r1_mat[1].y * mat[3 * 4 + 0];
            mat[1 * 4 + 1] = r0_mat[1].y - r1_mat[1].x * mat[2 * 4 + 1] - r1_mat[1].y * mat[3 * 4 + 1];
            // m1 = r1 * r3;
            mat[0 * 4 + 2] = r1_mat[0].x * r3_mat[0].x + r1_mat[0].x * r3_mat[1].x;
            mat[0 * 4 + 3] = r1_mat[0].x * r3_mat[0].y + r1_mat[0].x * r3_mat[1].y;
            mat[1 * 4 + 2] = r1_mat[1].x * r3_mat[0].x + r1_mat[1].x * r3_mat[1].x;
            mat[1 * 4 + 3] = r1_mat[1].x * r3_mat[0].y + r1_mat[1].x * r3_mat[1].y;
            // m3 = -r3;
            mat[2 * 4 + 2] = -r3_mat[0].x;
            mat[2 * 4 + 3] = -r3_mat[0].y;
            mat[3 * 4 + 2] = -r3_mat[1].x;
            mat[3 * 4 + 3] = -r3_mat[1].y;
            return(true);
#endif
        }
 public idMat2 opMul(idMat2 a)
 {
     idVec2[] a_mat = a.mat;
     float x, y;
     x = mat[0].x; y = mat[0].y;
     mat[0].x = x * a_mat[0].x + y * a_mat[1].x;
     mat[0].y = x * a_mat[0].y + y * a_mat[1].y;
     x = mat[1].x; y = mat[1].y;
     mat[1].x = x * a_mat[0].x + y * a_mat[1].x;
     mat[1].y = x * a_mat[0].y + y * a_mat[1].y;
     return this;
 }
 public bool Compare(ref idMat2 a, float epsilon)
 {
     idVec2[] a_mat = a.mat;
     return (
         mat[0].Compare(ref a_mat[0], epsilon) &&
         mat[1].Compare(ref a_mat[1], epsilon));
 }
示例#10
0
 public bool Compare(ref idMat2 a)
 {
     idVec2[] a_mat = a.mat;
     return (
         mat[0].Compare(ref a_mat[0]) &&
         mat[1].Compare(ref a_mat[1]));
 }
示例#11
0
 public idMat2 opSub(idMat2 a)
 {
     idVec2[] a_mat = a.mat;
     mat[0].x -= a_mat[0].x; mat[0].y -= a_mat[0].y;
     mat[1].x -= a_mat[1].x; mat[1].y -= a_mat[1].y;
     return this;
 }
示例#12
0
 public idMat2 opAdd(idMat2 a)
 {
     idVec2[] a_mat = a.mat;
     mat[0].x += a_mat[0].x; mat[0].y += a_mat[0].y;
     mat[1].x += a_mat[1].x; mat[1].y += a_mat[1].y;
     return this;
 }
示例#13
0
        public bool InverseFastSelf()
        {
#if false
            // 84+4+16 = 104 multiplications
            //			   1 division
            // 2x2 sub-determinants required to calculate 4x4 determinant
            float det2_01_01 = mat[0].x * mat[1].y - mat[0].y * mat[1].x;
            float det2_01_02 = mat[0].x * mat[1].z - mat[0].z * mat[1].x;
            float det2_01_03 = mat[0].x * mat[1].w - mat[0].w * mat[1].x;
            float det2_01_12 = mat[0].y * mat[1].z - mat[0].z * mat[1].y;
            float det2_01_13 = mat[0].y * mat[1].w - mat[0].w * mat[1].y;
            float det2_01_23 = mat[0].z * mat[1].w - mat[0].w * mat[1].z;
            // 3x3 sub-determinants required to calculate 4x4 determinant
            float det3_201_012 = mat[2].x * det2_01_12 - mat[2].y * det2_01_02 + mat[2].z * det2_01_01;
            float det3_201_013 = mat[2].x * det2_01_13 - mat[2].y * det2_01_03 + mat[2].w * det2_01_01;
            float det3_201_023 = mat[2].x * det2_01_23 - mat[2].z * det2_01_03 + mat[2].w * det2_01_02;
            float det3_201_123 = mat[2].y * det2_01_23 - mat[2].z * det2_01_13 + mat[2].w * det2_01_12;
            double det = (-det3_201_123 * mat[3].x + det3_201_023 * mat[3].y - det3_201_013 * mat[3].z + det3_201_012 * mat[3].w);
            if (idMath.Fabs(det) < MATRIX_INVERSE_EPSILON)
                return false;
            double invDet = 1.0f / det;
            // remaining 2x2 sub-determinants
            float det2_03_01 = mat[0].x * mat[3].y - mat[0].y * mat[3].x;
            float det2_03_02 = mat[0].x * mat[3].z - mat[0].z * mat[3].x;
            float det2_03_03 = mat[0].x * mat[3].w - mat[0].w * mat[3].x;
            float det2_03_12 = mat[0].y * mat[3].z - mat[0].z * mat[3].y;
            float det2_03_13 = mat[0].y * mat[3].w - mat[0].w * mat[3].y;
            float det2_03_23 = mat[0].z * mat[3].w - mat[0].w * mat[3].z;
            //
            float det2_13_01 = mat[1].x * mat[3].y - mat[1].y * mat[3].x;
            float det2_13_02 = mat[1].x * mat[3].z - mat[1].z * mat[3].x;
            float det2_13_03 = mat[1].x * mat[3].w - mat[1].w * mat[3].x;
            float det2_13_12 = mat[1].y * mat[3].z - mat[1].z * mat[3].y;
            float det2_13_13 = mat[1].y * mat[3].w - mat[1].w * mat[3].y;
            float det2_13_23 = mat[1].z * mat[3].w - mat[1].w * mat[3].z;
            // remaining 3x3 sub-determinants
            float det3_203_012 = mat[2].x * det2_03_12 - mat[2].y * det2_03_02 + mat[2].z * det2_03_01;
            float det3_203_013 = mat[2].x * det2_03_13 - mat[2].y * det2_03_03 + mat[2].w * det2_03_01;
            float det3_203_023 = mat[2].x * det2_03_23 - mat[2].z * det2_03_03 + mat[2].w * det2_03_02;
            float det3_203_123 = mat[2].y * det2_03_23 - mat[2].z * det2_03_13 + mat[2].w * det2_03_12;
            //
            float det3_213_012 = mat[2].x * det2_13_12 - mat[2].y * det2_13_02 + mat[2].z * det2_13_01;
            float det3_213_013 = mat[2].x * det2_13_13 - mat[2].y * det2_13_03 + mat[2].w * det2_13_01;
            float det3_213_023 = mat[2].x * det2_13_23 - mat[2].z * det2_13_03 + mat[2].w * det2_13_02;
            float det3_213_123 = mat[2].y * det2_13_23 - mat[2].z * det2_13_13 + mat[2].w * det2_13_12;
            //
            float det3_301_012 = mat[3].x * det2_01_12 - mat[3].y * det2_01_02 + mat[3].z * det2_01_01;
            float det3_301_013 = mat[3].x * det2_01_13 - mat[3].y * det2_01_03 + mat[3].w * det2_01_01;
            float det3_301_023 = mat[3].x * det2_01_23 - mat[3].z * det2_01_03 + mat[3].w * det2_01_02;
            float det3_301_123 = mat[3].y * det2_01_23 - mat[3].z * det2_01_13 + mat[3].w * det2_01_12;
            //
            mat[0].x = (float)(-det3_213_123 * invDet);
            mat[1].x = (float)(+det3_213_023 * invDet);
            mat[2].x = (float)(-det3_213_013 * invDet);
            mat[3].x = (float)(+det3_213_012 * invDet);
            //
            mat[0].y = (float)(+det3_203_123 * invDet);
            mat[1].y = (float)(-det3_203_023 * invDet);
            mat[2].y = (float)(+det3_203_013 * invDet);
            mat[3].y = (float)(-det3_203_012 * invDet);
            //
            mat[0].z = (float)(+det3_301_123 * invDet);
            mat[1].z = (float)(-det3_301_023 * invDet);
            mat[2].z = (float)(+det3_301_013 * invDet);
            mat[3].z = (float)(-det3_301_012 * invDet);
            //
            mat[0].w = (float)(-det3_201_123 * invDet);
            mat[1].w = (float)(+det3_201_023 * invDet);
            mat[2].w = (float)(-det3_201_013 * invDet);
            mat[3].w = (float)(+det3_201_012 * invDet);
            return true;
#elif false
	// 4*18 = 72 multiplications
	//		   4 divisions
	float *mat = reinterpret_cast<float *>(this);
	float s;
	double d, di;

	di = mat[0];
	s = di;
	mat[0] = d = 1.0f / di;
	mat[1] *= d;
	mat[2] *= d;
	mat[3] *= d;
	d = -d;
	mat[4] *= d;
	mat[8] *= d;
	mat[12] *= d;
	d = mat[4] * di;
	mat[5] += mat[1] * d;
	mat[6] += mat[2] * d;
	mat[7] += mat[3] * d;
	d = mat[8] * di;
	mat[9] += mat[1] * d;
	mat[10] += mat[2] * d;
	mat[11] += mat[3] * d;
	d = mat[12] * di;
	mat[13] += mat[1] * d;
	mat[14] += mat[2] * d;
	mat[15] += mat[3] * d;
	di = mat[5];
	s *= di;
	mat[5] = d = 1.0f / di;
	mat[4] *= d;
	mat[6] *= d;
	mat[7] *= d;
	d = -d;
	mat[1] *= d;
	mat[9] *= d;
	mat[13] *= d;
	d = mat[1] * di;
	mat[0] += mat[4] * d;
	mat[2] += mat[6] * d;
	mat[3] += mat[7] * d;
	d = mat[9] * di;
	mat[8] += mat[4] * d;
	mat[10] += mat[6] * d;
	mat[11] += mat[7] * d;
	d = mat[13] * di;
	mat[12] += mat[4] * d;
	mat[14] += mat[6] * d;
	mat[15] += mat[7] * d;
	di = mat[10];
	s *= di;
	mat[10] = d = 1.0f / di;
	mat[8] *= d;
	mat[9] *= d;
	mat[11] *= d;
	d = -d;
	mat[2] *= d;
	mat[6] *= d;
	mat[14] *= d;
	d = mat[2] * di;
	mat[0] += mat[8] * d;
	mat[1] += mat[9] * d;
	mat[3] += mat[11] * d;
	d = mat[6] * di;
	mat[4] += mat[8] * d;
	mat[5] += mat[9] * d;
	mat[7] += mat[11] * d;
	d = mat[14] * di;
	mat[12] += mat[8] * d;
	mat[13] += mat[9] * d;
	mat[15] += mat[11] * d;
	di = mat[15];
	s *= di;
	mat[15] = d = 1.0f / di;
	mat[12] *= d;
	mat[13] *= d;
	mat[14] *= d;
	d = -d;
	mat[3] *= d;
	mat[7] *= d;
	mat[11] *= d;
	d = mat[3] * di;
	mat[0] += mat[12] * d;
	mat[1] += mat[13] * d;
	mat[2] += mat[14] * d;
	d = mat[7] * di;
	mat[4] += mat[12] * d;
	mat[5] += mat[13] * d;
	mat[6] += mat[14] * d;
	d = mat[11] * di;
	mat[8] += mat[12] * d;
	mat[9] += mat[13] * d;
	mat[10] += mat[14] * d;

	return ( s != 0.0f && !FLOAT_IS_NAN( s ) );
#else
            //	6*8+2*6 = 60 multiplications
            //		2*1 =  2 divisions
            float[] mat = this;
            // r0 = m0.Inverse();
            float det = mat[0 * 4 + 0] * mat[1 * 4 + 1] - mat[0 * 4 + 1] * mat[1 * 4 + 0];
            if (idMath.Fabs(det) < MATRIX_INVERSE_EPSILON)
                return false;
            float invDet = 1.0f / det;
            idMat2 r0 = new idMat2(); idVec2[] r0_mat = r0.mat;
            r0_mat[0].x = mat[1 * 4 + 1] * invDet;
            r0_mat[0].y = -mat[0 * 4 + 1] * invDet;
            r0_mat[1].x = -mat[1 * 4 + 0] * invDet;
            r0_mat[1].y = mat[0 * 4 + 0] * invDet;
            // r1 = r0 * m1;
            idMat2 r1 = new idMat2(); idVec2[] r1_mat = r1.mat;
            r1_mat[0].x = r0_mat[0].x * mat[0 * 4 + 2] + r0_mat[0].y * mat[1 * 4 + 2];
            r1_mat[0].y = r0_mat[0].x * mat[0 * 4 + 3] + r0_mat[0].y * mat[1 * 4 + 3];
            r1_mat[1].x = r0_mat[1].x * mat[0 * 4 + 2] + r0_mat[1].y * mat[1 * 4 + 2];
            r1_mat[1].y = r0_mat[1].x * mat[0 * 4 + 3] + r0_mat[1].y * mat[1 * 4 + 3];
            // r2 = m2 * r1;
            idMat2 r2 = new idMat2(); idVec2[] r2_mat = r2.mat;
            r2_mat[0].x = mat[2 * 4 + 0] * r1_mat[0].x + mat[2 * 4 + 1] * r1_mat[1].x;
            r2_mat[0].y = mat[2 * 4 + 0] * r1_mat[0].y + mat[2 * 4 + 1] * r1_mat[1].y;
            r2_mat[1].x = mat[3 * 4 + 0] * r1_mat[0].x + mat[3 * 4 + 1] * r1_mat[1].x;
            r2_mat[1].y = mat[3 * 4 + 0] * r1_mat[0].y + mat[3 * 4 + 1] * r1_mat[1].y;
            // r3 = r2 - m3;
            idMat2 r3 = new idMat2(); idVec2[] r3_mat = r3.mat;
            r3_mat[0].x = r2_mat[0].x - mat[2 * 4 + 2];
            r3_mat[0].y = r2_mat[0].y - mat[2 * 4 + 3];
            r3_mat[1].x = r2_mat[1].x - mat[3 * 4 + 2];
            r3_mat[1].y = r2_mat[1].y - mat[3 * 4 + 3];
            // r3.InverseSelf();
            det = r3_mat[0].x * r3_mat[1].y - r3_mat[0].y * r3_mat[1].x;
            if (idMath.Fabs(det) < MATRIX_INVERSE_EPSILON)
                return false;
            invDet = 1.0f / det;
            float a = r3_mat[0].x;
            r3_mat[0].x = r3_mat[1].y * invDet;
            r3_mat[0].y = -r3_mat[0].y * invDet;
            r3_mat[1].x = -r3_mat[1].x * invDet;
            r3_mat[1].y = a * invDet;
            // r2 = m2 * r0;
            r2_mat[0].x = mat[2 * 4 + 0] * r0_mat[0].x + mat[2 * 4 + 1] * r0_mat[1].x;
            r2_mat[0].y = mat[2 * 4 + 0] * r0_mat[0].y + mat[2 * 4 + 1] * r0_mat[1].y;
            r2_mat[1].x = mat[3 * 4 + 0] * r0_mat[0].x + mat[3 * 4 + 1] * r0_mat[1].x;
            r2_mat[1].y = mat[3 * 4 + 0] * r0_mat[0].y + mat[3 * 4 + 1] * r0_mat[1].y;
            // m2 = r3 * r2;
            mat[2 * 4 + 0] = r3_mat[0].x * r2_mat[0].x + r3_mat[0].y * r2_mat[1].x;
            mat[2 * 4 + 1] = r3_mat[0].x * r2_mat[0].y + r3_mat[0].y * r2_mat[1].y;
            mat[3 * 4 + 0] = r3_mat[1].x * r2_mat[0].x + r3_mat[1].y * r2_mat[1].x;
            mat[3 * 4 + 1] = r3_mat[1].x * r2_mat[0].y + r3_mat[1].y * r2_mat[1].y;
            // m0 = r0 - r1 * m2;
            mat[0 * 4 + 0] = r0_mat[0].x - r1_mat[0].x * mat[2 * 4 + 0] - r1_mat[0].y * mat[3 * 4 + 0];
            mat[0 * 4 + 1] = r0_mat[0].y - r1_mat[0].x * mat[2 * 4 + 1] - r1_mat[0].y * mat[3 * 4 + 1];
            mat[1 * 4 + 0] = r0_mat[1].x - r1_mat[1].x * mat[2 * 4 + 0] - r1_mat[1].y * mat[3 * 4 + 0];
            mat[1 * 4 + 1] = r0_mat[1].y - r1_mat[1].x * mat[2 * 4 + 1] - r1_mat[1].y * mat[3 * 4 + 1];
            // m1 = r1 * r3;
            mat[0 * 4 + 2] = r1_mat[0].x * r3_mat[0].x + r1_mat[0].x * r3_mat[1].x;
            mat[0 * 4 + 3] = r1_mat[0].x * r3_mat[0].y + r1_mat[0].x * r3_mat[1].y;
            mat[1 * 4 + 2] = r1_mat[1].x * r3_mat[0].x + r1_mat[1].x * r3_mat[1].x;
            mat[1 * 4 + 3] = r1_mat[1].x * r3_mat[0].y + r1_mat[1].x * r3_mat[1].y;
            // m3 = -r3;
            mat[2 * 4 + 2] = -r3_mat[0].x;
            mat[2 * 4 + 3] = -r3_mat[0].y;
            mat[3 * 4 + 2] = -r3_mat[1].x;
            mat[3 * 4 + 3] = -r3_mat[1].y;
            return true;
#endif
        }