// David Eberly, Geometric Tools, Redmond WA 98052 // Copyright (c) 1998-2020 // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt // Version: 4.0.2019.08.13 #pragma once #include #include namespace WwiseGTE { // Template alias for convenience. template using Matrix3x3 = Matrix<3, 3, Real>; // Geometric operations. template Matrix3x3 Inverse(Matrix3x3 const& M, bool* reportInvertibility = nullptr) { Matrix3x3 inverse; bool invertible; Real c00 = M(1, 1) * M(2, 2) - M(1, 2) * M(2, 1); Real c10 = M(1, 2) * M(2, 0) - M(1, 0) * M(2, 2); Real c20 = M(1, 0) * M(2, 1) - M(1, 1) * M(2, 0); Real det = M(0, 0) * c00 + M(0, 1) * c10 + M(0, 2) * c20; if (det != (Real)0) { Real invDet = (Real)1 / det; inverse = Matrix3x3 { c00 * invDet, (M(0, 2) * M(2, 1) - M(0, 1) * M(2, 2)) * invDet, (M(0, 1) * M(1, 2) - M(0, 2) * M(1, 1)) * invDet, c10 * invDet, (M(0, 0) * M(2, 2) - M(0, 2) * M(2, 0)) * invDet, (M(0, 2) * M(1, 0) - M(0, 0) * M(1, 2)) * invDet, c20 * invDet, (M(0, 1) * M(2, 0) - M(0, 0) * M(2, 1)) * invDet, (M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0)) * invDet }; invertible = true; } else { inverse.MakeZero(); invertible = false; } if (reportInvertibility) { *reportInvertibility = invertible; } return inverse; } template Matrix3x3 Adjoint(Matrix3x3 const& M) { return Matrix3x3 { M(1, 1)* M(2, 2) - M(1, 2) * M(2, 1), M(0, 2)* M(2, 1) - M(0, 1) * M(2, 2), M(0, 1)* M(1, 2) - M(0, 2) * M(1, 1), M(1, 2)* M(2, 0) - M(1, 0) * M(2, 2), M(0, 0)* M(2, 2) - M(0, 2) * M(2, 0), M(0, 2)* M(1, 0) - M(0, 0) * M(1, 2), M(1, 0)* M(2, 1) - M(1, 1) * M(2, 0), M(0, 1)* M(2, 0) - M(0, 0) * M(2, 1), M(0, 0)* M(1, 1) - M(0, 1) * M(1, 0) }; } template Real Determinant(Matrix3x3 const& M) { Real c00 = M(1, 1) * M(2, 2) - M(1, 2) * M(2, 1); Real c10 = M(1, 2) * M(2, 0) - M(1, 0) * M(2, 2); Real c20 = M(1, 0) * M(2, 1) - M(1, 1) * M(2, 0); Real det = M(0, 0) * c00 + M(0, 1) * c10 + M(0, 2) * c20; return det; } template Real Trace(Matrix3x3 const& M) { Real trace = M(0, 0) + M(1, 1) + M(2, 2); return trace; } // Multiply M and V according to the user-selected convention. If it is // GTE_USE_MAT_VEC, the function returns M*V. If it is GTE_USE_VEC_MAT, // the function returns V*M. This function is provided to hide the // preprocessor symbols in the GTEngine sample applications. template Vector3 DoTransform(Matrix3x3 const& M, Vector3 const& V) { #if defined(GTE_USE_MAT_VEC) return M * V; #else return V * M; #endif } template Matrix3x3 DoTransform(Matrix3x3 const& A, Matrix3x3 const& B) { #if defined(GTE_USE_MAT_VEC) return A * B; #else return B * A; #endif } // For GTE_USE_MAT_VEC, the columns of an invertible matrix form a basis // for the range of the matrix. For GTE_USE_VEC_MAT, the rows of an // invertible matrix form a basis for the range of the matrix. These // functions allow you to access the basis vectors. The caller is // responsible for ensuring that the matrix is invertible (although the // inverse is not calculated by these functions). template void SetBasis(Matrix3x3& M, int i, Vector3 const& V) { #if defined(GTE_USE_MAT_VEC) return M.SetCol(i, V); #else return M.SetRow(i, V); #endif } template Vector3 GetBasis(Matrix3x3 const& M, int i) { #if defined(GTE_USE_MAT_VEC) return M.GetCol(i); #else return M.GetRow(i); #endif } }