Mat4 Mat4::Inverse()

in agdk/agde/Teapot/GameEngine/VecMath.cpp [110:179]


    Mat4 Mat4::Inverse() {
        Mat4 ret;
        float det_1;
        float pos = 0;
        float neg = 0;
        float temp;

        temp = f_[0] * f_[5] * f_[10];
        if (temp >= 0)
            pos += temp;
        else
            neg += temp;
        temp = f_[4] * f_[9] * f_[2];
        if (temp >= 0)
            pos += temp;
        else
            neg += temp;
        temp = f_[8] * f_[1] * f_[6];
        if (temp >= 0)
            pos += temp;
        else
            neg += temp;
        temp = -f_[8] * f_[5] * f_[2];
        if (temp >= 0)
            pos += temp;
        else
            neg += temp;
        temp = -f_[4] * f_[1] * f_[10];
        if (temp >= 0)
            pos += temp;
        else
            neg += temp;
        temp = -f_[0] * f_[9] * f_[6];
        if (temp >= 0)
            pos += temp;
        else
            neg += temp;
        det_1 = pos + neg;

        if (det_1 == 0.0) {
            // Error
        } else {
            det_1 = 1.0f / det_1;
            ret.f_[0] = (f_[5] * f_[10] - f_[9] * f_[6]) * det_1;
            ret.f_[1] = -(f_[1] * f_[10] - f_[9] * f_[2]) * det_1;
            ret.f_[2] = (f_[1] * f_[6] - f_[5] * f_[2]) * det_1;
            ret.f_[4] = -(f_[4] * f_[10] - f_[8] * f_[6]) * det_1;
            ret.f_[5] = (f_[0] * f_[10] - f_[8] * f_[2]) * det_1;
            ret.f_[6] = -(f_[0] * f_[6] - f_[4] * f_[2]) * det_1;
            ret.f_[8] = (f_[4] * f_[9] - f_[8] * f_[5]) * det_1;
            ret.f_[9] = -(f_[0] * f_[9] - f_[8] * f_[1]) * det_1;
            ret.f_[10] = (f_[0] * f_[5] - f_[4] * f_[1]) * det_1;

            /* Calculate -C * inverse(A) */
            ret.f_[12] =
                    -(f_[12] * ret.f_[0] + f_[13] * ret.f_[4] + f_[14] * ret.f_[8]);
            ret.f_[13] =
                    -(f_[12] * ret.f_[1] + f_[13] * ret.f_[5] + f_[14] * ret.f_[9]);
            ret.f_[14] =
                    -(f_[12] * ret.f_[2] + f_[13] * ret.f_[6] + f_[14] * ret.f_[10]);

            ret.f_[3] = 0.0f;
            ret.f_[7] = 0.0f;
            ret.f_[11] = 0.0f;
            ret.f_[15] = 1.0f;
        }

        *this = ret;
        return *this;
    }