// 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 Matrix2x2 = Matrix<2, 2, Real>; // Create a rotation matrix from an angle (in radians). The matrix is // [GTE_USE_MAT_VEC] // R(t) = {{c,-s},{s,c}} // [GTE_USE_VEC_MAT] // R(t) = {{c,s},{-s,c}} // where c = cos(t), s = sin(t), and the inner-brace pairs are rows of the // matrix. template void MakeRotation(Real angle, Matrix2x2& rotation) { Real cs = std::cos(angle); Real sn = std::sin(angle); #if defined(GTE_USE_MAT_VEC) rotation(0, 0) = cs; rotation(0, 1) = -sn; rotation(1, 0) = sn; rotation(1, 1) = cs; #else rotation(0, 0) = cs; rotation(0, 1) = sn; rotation(1, 0) = -sn; rotation(1, 1) = cs; #endif } // Get the angle (radians) from a rotation matrix. The caller is // responsible for ensuring the matrix is a rotation. template Real GetRotationAngle(Matrix2x2 const& rotation) { #if defined(GTE_USE_MAT_VEC) return std::atan2(rotation(1, 0), rotation(0, 0)); #else return std::atan2(rotation(0, 1), rotation(0, 0)); #endif } // Geometric operations. template Matrix2x2 Inverse(Matrix2x2 const& M, bool* reportInvertibility = nullptr) { Matrix2x2 inverse; bool invertible; Real det = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0); if (det != (Real)0) { Real invDet = ((Real)1) / det; inverse = Matrix2x2 { M(1, 1) * invDet, -M(0, 1) * invDet, -M(1, 0) * invDet, M(0, 0) * invDet }; invertible = true; } else { inverse.MakeZero(); invertible = false; } if (reportInvertibility) { *reportInvertibility = invertible; } return inverse; } template Matrix2x2 Adjoint(Matrix2x2 const& M) { return Matrix2x2 { M(1, 1), -M(0, 1), -M(1, 0), M(0, 0) }; } template Real Determinant(Matrix2x2 const& M) { Real det = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0); return det; } template Real Trace(Matrix2x2 const& M) { Real trace = M(0, 0) + M(1, 1); 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 Vector2 DoTransform(Matrix2x2 const& M, Vector2 const& V) { #if defined(GTE_USE_MAT_VEC) return M * V; #else return V * M; #endif } template Matrix2x2 DoTransform(Matrix2x2 const& A, Matrix2x2 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(Matrix2x2& M, int i, Vector2 const& V) { #if defined(GTE_USE_MAT_VEC) return M.SetCol(i, V); #else return M.SetRow(i, V); #endif } template Vector2 GetBasis(Matrix2x2 const& M, int i) { #if defined(GTE_USE_MAT_VEC) return M.GetCol(i); #else return M.GetRow(i); #endif } }