inline mat3 inverse(mat3 const& m) { scalar_t const d = 1 / m.determinant(); if (d != 0) { scalar_t const id = 1 / d; return mat3( vec3( id * (m.y.y * m.z.z - m.y.z * m.z.y), -id * (m.x.y * m.z.z - m.x.z * m.z.y), id * (m.x.y * m.y.z - m.x.z * m.y.y)), vec3( -id * (m.y.x * m.z.z - m.y.z * m.z.x), id * (m.x.x * m.z.z - m.x.z * m.z.x), -id * (m.x.x * m.y.z - m.x.z * m.y.x)), vec3( id * (m.y.x * m.z.y - m.y.y * m.z.x), -id * (m.x.x * m.z.y - m.x.y * m.z.x), id * (m.x.x * m.y.y - m.x.y * m.y.x))); } else { return mat3::identity(); } }
vec3 et::removeMatrixScale(mat3& mat) { vec3 c0 = mat.column(0); vec3 c1 = mat.column(1); vec3 c2 = mat.column(2); float lengths[3] = { c0.length(), c1.length(), c2.length() }; ET_ASSERT(lengths[0] > 0.0f); ET_ASSERT(lengths[1] > 0.0f); ET_ASSERT(lengths[2] > 0.0f); if (mat.determinant() < 0.0f) { float minValues[3] = { etMin(c0.x, etMin(c0.y, c0.z)), etMin(c1.x, etMin(c1.y, c1.z)), etMin(c2.x, etMin(c2.y, c2.z)) }; auto offset = std::min_element(minValues, minValues + 3) - minValues; lengths[offset] = -lengths[offset]; } for (size_t i = 0; i < 3; ++i) { mat[0][i] /= lengths[i]; mat[1][i] /= lengths[i]; mat[2][i] /= lengths[i]; } return vec3(lengths[0], lengths[1], lengths[2]); }