public static MiMatriz4x4 operator *(MiMatriz4x4 lhs, MiMatriz4x4 rhs)
        {
            MiMatriz4x4 result = zero;

            result.r0c0 = (lhs.r0c0 * rhs.r0c0 + lhs.r0c1 * rhs.r1c0 + lhs.r0c2 * rhs.r2c0 + lhs.r0c3 * rhs.r3c0);
            result.r1c0 = (lhs.r1c0 * rhs.r0c0 + lhs.r1c1 * rhs.r1c0 + lhs.r1c2 * rhs.r2c0 + lhs.r1c3 * rhs.r3c0);
            result.r2c0 = (lhs.r2c0 * rhs.r0c0 + lhs.r2c1 * rhs.r1c0 + lhs.r2c2 * rhs.r2c0 + lhs.r2c3 * rhs.r3c0);
            result.r3c0 = (lhs.r3c0 * rhs.r0c0 + lhs.r3c1 * rhs.r1c0 + lhs.r3c2 * rhs.r2c0 + lhs.r3c3 * rhs.r3c0);

            result.r0c1 = (lhs.r0c0 * rhs.r0c1 + lhs.r0c1 * rhs.r1c1 + lhs.r0c2 * rhs.r1c2 + lhs.r0c3 * rhs.r3c1);
            result.r1c1 = (lhs.r1c0 * rhs.r0c1 + lhs.r1c1 * rhs.r1c1 + lhs.r1c2 * rhs.r2c1 + lhs.r1c3 * rhs.r3c1);
            result.r2c1 = (lhs.r2c0 * rhs.r0c1 + lhs.r2c1 * rhs.r1c1 + lhs.r2c2 * rhs.r2c1 + lhs.r2c3 * rhs.r3c1);
            result.r3c1 = (lhs.r3c0 * rhs.r0c1 + lhs.r3c1 * rhs.r1c1 + lhs.r3c2 * rhs.r2c1 + lhs.r3c3 * rhs.r3c1);

            result.r0c2 = (lhs.r0c0 * rhs.r0c2 + lhs.r0c1 * rhs.r1c2 + lhs.r0c2 * rhs.r2c2 + lhs.r0c3 * rhs.r3c2);
            result.r1c2 = (lhs.r1c0 * rhs.r0c2 + lhs.r1c1 * rhs.r1c2 + lhs.r0c2 * rhs.r2c2 + lhs.r1c3 * rhs.r3c2);
            result.r2c2 = (lhs.r2c0 * rhs.r0c2 + lhs.r2c1 * rhs.r1c2 + lhs.r0c2 * rhs.r2c2 + lhs.r2c3 * rhs.r3c2);
            result.r3c2 = (lhs.r3c0 * rhs.r0c2 + lhs.r3c1 * rhs.r1c2 + lhs.r0c2 * rhs.r2c2 + lhs.r3c3 * rhs.r3c2);

            result.r0c3 = (lhs.r0c0 * rhs.r0c3 + lhs.r0c1 * rhs.r1c3 + lhs.r0c2 * rhs.r2c3 + lhs.r0c3 * rhs.r3c3);
            result.r1c3 = (lhs.r1c0 * rhs.r0c3 + lhs.r1c1 * rhs.r1c3 + lhs.r0c2 * rhs.r2c3 + lhs.r1c3 * rhs.r3c3);
            result.r2c3 = (lhs.r2c0 * rhs.r0c3 + lhs.r2c1 * rhs.r1c3 + lhs.r0c2 * rhs.r2c3 + lhs.r2c3 * rhs.r3c3);
            result.r3c3 = (lhs.r3c0 * rhs.r0c3 + lhs.r3c1 * rhs.r1c3 + lhs.r0c2 * rhs.r2c3 + lhs.r3c3 * rhs.r3c3);

            return(result);
        }
        public static MiMatriz4x4 Rotate(Quats q)
        {
            //Manipulacion algebraica de p' = q*p*q^-1
            MiMatriz4x4 m = zero;

            m.r0c0 = 1.0f - (2.0f * q.y * q.y) - (2.0f * q.z * q.z);
            m.r0c1 = 2.0f * q.x * q.y - 2.0f * q.z * q.w;
            m.r0c2 = 2.0f * q.x * q.z + 2.0f * q.y * q.w;
            m.r0c3 = 0.0f;

            m.r1c0 = 2.0f * q.x * q.y + 2.0f * q.z * q.w;
            m.r1c1 = 1 - 2.0f * q.x * q.z - 2.0f * q.z * q.z;
            m.r1c2 = 2.0f * q.y * q.z - 2.0f * q.x * q.w;
            m.r1c3 = 0.0f;

            m.r2c0 = 2.0f * q.x * q.z - 2.0f * q.y * q.w;
            m.r2c1 = 2.0f * q.y * q.z + 2.0f * q.x * q.w;
            m.r2c2 = 1.0f - 2.0f * q.x * q.x - 2.0f * q.y * q.y;
            m.r2c3 = 0.0f;

            m.r3c0 = 0.0f;
            m.r3c1 = 0.0f;
            m.r3c2 = 0.0f;
            m.r3c3 = 1.0f;

            return(m);
        }
        public static MiMatriz4x4 TRS(Vec3 pos, Quats q, Vec3 s)
        {
            MiMatriz4x4 T   = Translate(pos);
            MiMatriz4x4 R   = Rotate(q);
            MiMatriz4x4 S   = Scale(s);
            MiMatriz4x4 TRS = T * R * S;

            return(TRS);
        }
        // Resumen:
        // Creates a scaling matrix.
        // ParĂ¡metros:
        // vector
        public static MiMatriz4x4 Scale(Vec3 vector)
        {
            MiMatriz4x4 m = new MiMatriz4x4();

            m.r0c0 = vector.x; m.r0c1 = 0.0f; m.r0c2 = 0.0f; m.r0c3 = 0.0f;
            m.r1c0 = 0.0f; m.r1c1 = vector.y; m.r1c2 = 0.0f; m.r1c3 = 0.0f;
            m.r2c0 = 0.0f; m.r2c1 = 0.0f; m.r2c2 = vector.z; m.r2c3 = 0.0f;
            m.r3c0 = 0.0f; m.r3c1 = 0.0f; m.r3c2 = 0.0f; m.r3c3 = 1.0f;
            return(m);
        }