123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- #pragma once
- #include <Mathematics/Matrix.h>
- #include <Mathematics/Vector4.h>
- namespace WwiseGTE
- {
-
- template <typename Real>
- using Matrix4x4 = Matrix<4, 4, Real>;
-
- template <typename Real>
- Matrix4x4<Real> Inverse(Matrix4x4<Real> const& M, bool* reportInvertibility = nullptr)
- {
- Matrix4x4<Real> inverse;
- bool invertible;
- Real a0 = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0);
- Real a1 = M(0, 0) * M(1, 2) - M(0, 2) * M(1, 0);
- Real a2 = M(0, 0) * M(1, 3) - M(0, 3) * M(1, 0);
- Real a3 = M(0, 1) * M(1, 2) - M(0, 2) * M(1, 1);
- Real a4 = M(0, 1) * M(1, 3) - M(0, 3) * M(1, 1);
- Real a5 = M(0, 2) * M(1, 3) - M(0, 3) * M(1, 2);
- Real b0 = M(2, 0) * M(3, 1) - M(2, 1) * M(3, 0);
- Real b1 = M(2, 0) * M(3, 2) - M(2, 2) * M(3, 0);
- Real b2 = M(2, 0) * M(3, 3) - M(2, 3) * M(3, 0);
- Real b3 = M(2, 1) * M(3, 2) - M(2, 2) * M(3, 1);
- Real b4 = M(2, 1) * M(3, 3) - M(2, 3) * M(3, 1);
- Real b5 = M(2, 2) * M(3, 3) - M(2, 3) * M(3, 2);
- Real det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
- if (det != (Real)0)
- {
- Real invDet = (Real)1 / det;
- inverse = Matrix4x4<Real>
- {
- (+M(1, 1) * b5 - M(1, 2) * b4 + M(1, 3) * b3) * invDet,
- (-M(0, 1) * b5 + M(0, 2) * b4 - M(0, 3) * b3) * invDet,
- (+M(3, 1) * a5 - M(3, 2) * a4 + M(3, 3) * a3) * invDet,
- (-M(2, 1) * a5 + M(2, 2) * a4 - M(2, 3) * a3) * invDet,
- (-M(1, 0) * b5 + M(1, 2) * b2 - M(1, 3) * b1) * invDet,
- (+M(0, 0) * b5 - M(0, 2) * b2 + M(0, 3) * b1) * invDet,
- (-M(3, 0) * a5 + M(3, 2) * a2 - M(3, 3) * a1) * invDet,
- (+M(2, 0) * a5 - M(2, 2) * a2 + M(2, 3) * a1) * invDet,
- (+M(1, 0) * b4 - M(1, 1) * b2 + M(1, 3) * b0) * invDet,
- (-M(0, 0) * b4 + M(0, 1) * b2 - M(0, 3) * b0) * invDet,
- (+M(3, 0) * a4 - M(3, 1) * a2 + M(3, 3) * a0) * invDet,
- (-M(2, 0) * a4 + M(2, 1) * a2 - M(2, 3) * a0) * invDet,
- (-M(1, 0) * b3 + M(1, 1) * b1 - M(1, 2) * b0) * invDet,
- (+M(0, 0) * b3 - M(0, 1) * b1 + M(0, 2) * b0) * invDet,
- (-M(3, 0) * a3 + M(3, 1) * a1 - M(3, 2) * a0) * invDet,
- (+M(2, 0) * a3 - M(2, 1) * a1 + M(2, 2) * a0) * invDet
- };
- invertible = true;
- }
- else
- {
- inverse.MakeZero();
- invertible = false;
- }
- if (reportInvertibility)
- {
- *reportInvertibility = invertible;
- }
- return inverse;
- }
- template <typename Real>
- Matrix4x4<Real> Adjoint(Matrix4x4<Real> const& M)
- {
- Real a0 = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0);
- Real a1 = M(0, 0) * M(1, 2) - M(0, 2) * M(1, 0);
- Real a2 = M(0, 0) * M(1, 3) - M(0, 3) * M(1, 0);
- Real a3 = M(0, 1) * M(1, 2) - M(0, 2) * M(1, 1);
- Real a4 = M(0, 1) * M(1, 3) - M(0, 3) * M(1, 1);
- Real a5 = M(0, 2) * M(1, 3) - M(0, 3) * M(1, 2);
- Real b0 = M(2, 0) * M(3, 1) - M(2, 1) * M(3, 0);
- Real b1 = M(2, 0) * M(3, 2) - M(2, 2) * M(3, 0);
- Real b2 = M(2, 0) * M(3, 3) - M(2, 3) * M(3, 0);
- Real b3 = M(2, 1) * M(3, 2) - M(2, 2) * M(3, 1);
- Real b4 = M(2, 1) * M(3, 3) - M(2, 3) * M(3, 1);
- Real b5 = M(2, 2) * M(3, 3) - M(2, 3) * M(3, 2);
- return Matrix4x4<Real>
- {
- +M(1, 1) * b5 - M(1, 2) * b4 + M(1, 3) * b3,
- -M(0, 1) * b5 + M(0, 2) * b4 - M(0, 3) * b3,
- +M(3, 1) * a5 - M(3, 2) * a4 + M(3, 3) * a3,
- -M(2, 1) * a5 + M(2, 2) * a4 - M(2, 3) * a3,
- -M(1, 0) * b5 + M(1, 2) * b2 - M(1, 3) * b1,
- +M(0, 0) * b5 - M(0, 2) * b2 + M(0, 3) * b1,
- -M(3, 0) * a5 + M(3, 2) * a2 - M(3, 3) * a1,
- +M(2, 0) * a5 - M(2, 2) * a2 + M(2, 3) * a1,
- +M(1, 0) * b4 - M(1, 1) * b2 + M(1, 3) * b0,
- -M(0, 0) * b4 + M(0, 1) * b2 - M(0, 3) * b0,
- +M(3, 0) * a4 - M(3, 1) * a2 + M(3, 3) * a0,
- -M(2, 0) * a4 + M(2, 1) * a2 - M(2, 3) * a0,
- -M(1, 0) * b3 + M(1, 1) * b1 - M(1, 2) * b0,
- +M(0, 0) * b3 - M(0, 1) * b1 + M(0, 2) * b0,
- -M(3, 0) * a3 + M(3, 1) * a1 - M(3, 2) * a0,
- +M(2, 0) * a3 - M(2, 1) * a1 + M(2, 2) * a0
- };
- }
- template <typename Real>
- Real Determinant(Matrix4x4<Real> const& M)
- {
- Real a0 = M(0, 0) * M(1, 1) - M(0, 1) * M(1, 0);
- Real a1 = M(0, 0) * M(1, 2) - M(0, 2) * M(1, 0);
- Real a2 = M(0, 0) * M(1, 3) - M(0, 3) * M(1, 0);
- Real a3 = M(0, 1) * M(1, 2) - M(0, 2) * M(1, 1);
- Real a4 = M(0, 1) * M(1, 3) - M(0, 3) * M(1, 1);
- Real a5 = M(0, 2) * M(1, 3) - M(0, 3) * M(1, 2);
- Real b0 = M(2, 0) * M(3, 1) - M(2, 1) * M(3, 0);
- Real b1 = M(2, 0) * M(3, 2) - M(2, 2) * M(3, 0);
- Real b2 = M(2, 0) * M(3, 3) - M(2, 3) * M(3, 0);
- Real b3 = M(2, 1) * M(3, 2) - M(2, 2) * M(3, 1);
- Real b4 = M(2, 1) * M(3, 3) - M(2, 3) * M(3, 1);
- Real b5 = M(2, 2) * M(3, 3) - M(2, 3) * M(3, 2);
- Real det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
- return det;
- }
- template <typename Real>
- Real Trace(Matrix4x4<Real> const& M)
- {
- Real trace = M(0, 0) + M(1, 1) + M(2, 2) + M(3, 3);
- return trace;
- }
-
-
-
-
- template <typename Real>
- Vector4<Real> DoTransform(Matrix4x4<Real> const& M, Vector4<Real> const& V)
- {
- #if defined(GTE_USE_MAT_VEC)
- return M * V;
- #else
- return V * M;
- #endif
- }
- template <typename Real>
- Matrix4x4<Real> DoTransform(Matrix4x4<Real> const& A, Matrix4x4<Real> const& B)
- {
- #if defined(GTE_USE_MAT_VEC)
- return A * B;
- #else
- return B * A;
- #endif
- }
-
-
-
-
-
-
- template <typename Real>
- void SetBasis(Matrix4x4<Real>& M, int i, Vector4<Real> const& V)
- {
- #if defined(GTE_USE_MAT_VEC)
- return M.SetCol(i, V);
- #else
- return M.SetRow(i, V);
- #endif
- }
- template <typename Real>
- Vector4<Real> GetBasis(Matrix4x4<Real> const& M, int i)
- {
- #if defined(GTE_USE_MAT_VEC)
- return M.GetCol(i);
- #else
- return M.GetRow(i);
- #endif
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- template <typename Real>
- Matrix4x4<Real> MakeObliqueProjection(Vector4<Real> const& origin,
- Vector4<Real> const& normal, Vector4<Real> const& direction)
- {
- Matrix4x4<Real> M;
- Real const zero = (Real)0;
- Real dotND = Dot(normal, direction);
- Real dotNO = Dot(origin, normal);
- #if defined(GTE_USE_MAT_VEC)
- M(0, 0) = direction[0] * normal[0] - dotND;
- M(0, 1) = direction[0] * normal[1];
- M(0, 2) = direction[0] * normal[2];
- M(0, 3) = -dotNO * direction[0];
- M(1, 0) = direction[1] * normal[0];
- M(1, 1) = direction[1] * normal[1] - dotND;
- M(1, 2) = direction[1] * normal[2];
- M(1, 3) = -dotNO * direction[1];
- M(2, 0) = direction[2] * normal[0];
- M(2, 1) = direction[2] * normal[1];
- M(2, 2) = direction[2] * normal[2] - dotND;
- M(2, 3) = -dotNO * direction[2];
- M(3, 0) = zero;
- M(3, 1) = zero;
- M(3, 2) = zero;
- M(3, 3) = -dotND;
- #else
- M(0, 0) = direction[0] * normal[0] - dotND;
- M(1, 0) = direction[0] * normal[1];
- M(2, 0) = direction[0] * normal[2];
- M(3, 0) = -dotNO * direction[0];
- M(0, 1) = direction[1] * normal[0];
- M(1, 1) = direction[1] * normal[1] - dotND;
- M(2, 1) = direction[1] * normal[2];
- M(3, 1) = -dotNO * direction[1];
- M(0, 2) = direction[2] * normal[0];
- M(1, 2) = direction[2] * normal[1];
- M(2, 2) = direction[2] * normal[2] - dotND;
- M(3, 2) = -dotNO * direction[2];
- M(0, 2) = zero;
- M(1, 3) = zero;
- M(2, 3) = zero;
- M(3, 3) = -dotND;
- #endif
- return M;
- }
-
-
-
-
-
-
-
-
-
- template <typename Real>
- Matrix4x4<Real> MakePerspectiveProjection(Vector4<Real> const& origin,
- Vector4<Real> const& normal, Vector4<Real> const& eye)
- {
- Matrix4x4<Real> M;
- Real dotND = Dot(normal, eye - origin);
- #if defined(GTE_USE_MAT_VEC)
- M(0, 0) = dotND - eye[0] * normal[0];
- M(0, 1) = -eye[0] * normal[1];
- M(0, 2) = -eye[0] * normal[2];
- M(0, 3) = -(M(0, 0) * eye[0] + M(0, 1) * eye[1] + M(0, 2) * eye[2]);
- M(1, 0) = -eye[1] * normal[0];
- M(1, 1) = dotND - eye[1] * normal[1];
- M(1, 2) = -eye[1] * normal[2];
- M(1, 3) = -(M(1, 0) * eye[0] + M(1, 1) * eye[1] + M(1, 2) * eye[2]);
- M(2, 0) = -eye[2] * normal[0];
- M(2, 1) = -eye[2] * normal[1];
- M(2, 2) = dotND - eye[2] * normal[2];
- M(2, 3) = -(M(2, 0) * eye[0] + M(2, 1) * eye[1] + M(2, 2) * eye[2]);
- M(3, 0) = -normal[0];
- M(3, 1) = -normal[1];
- M(3, 2) = -normal[2];
- M(3, 3) = Dot(eye, normal);
- #else
- M(0, 0) = dotND - eye[0] * normal[0];
- M(1, 0) = -eye[0] * normal[1];
- M(2, 0) = -eye[0] * normal[2];
- M(3, 0) = -(M(0, 0) * eye[0] + M(0, 1) * eye[1] + M(0, 2) * eye[2]);
- M(0, 1) = -eye[1] * normal[0];
- M(1, 1) = dotND - eye[1] * normal[1];
- M(2, 1) = -eye[1] * normal[2];
- M(3, 1) = -(M(1, 0) * eye[0] + M(1, 1) * eye[1] + M(1, 2) * eye[2]);
- M(0, 2) = -eye[2] * normal[0];
- M(1, 2) = -eye[2] * normal[1];
- M(2, 2) = dotND - eye[2] * normal[2];
- M(3, 2) = -(M(2, 0) * eye[0] + M(2, 1) * eye[1] + M(2, 2) * eye[2]);
- M(0, 3) = -normal[0];
- M(1, 3) = -normal[1];
- M(2, 3) = -normal[2];
- M(3, 3) = Dot(eye, normal);
- #endif
- return M;
- }
-
-
-
-
-
-
-
- template <typename Real>
- Matrix4x4<Real> MakeReflection(Vector4<Real> const& origin,
- Vector4<Real> const& normal)
- {
- Matrix4x4<Real> M;
- Real const zero = (Real)0, one = (Real)1, two = (Real)2;
- Real twoDotNO = two * Dot(origin, normal);
- #if defined(GTE_USE_MAT_VEC)
- M(0, 0) = one - two * normal[0] * normal[0];
- M(0, 1) = -two * normal[0] * normal[1];
- M(0, 2) = -two * normal[0] * normal[2];
- M(0, 3) = twoDotNO * normal[0];
- M(1, 0) = M(0, 1);
- M(1, 1) = one - two * normal[1] * normal[1];
- M(1, 2) = -two * normal[1] * normal[2];
- M(1, 3) = twoDotNO * normal[1];
- M(2, 0) = M(0, 2);
- M(2, 1) = M(1, 2);
- M(2, 2) = one - two * normal[2] * normal[2];
- M(2, 3) = twoDotNO * normal[2];
- M(3, 0) = zero;
- M(3, 1) = zero;
- M(3, 2) = zero;
- M(3, 3) = one;
- #else
- M(0, 0) = one - two * normal[0] * normal[0];
- M(1, 0) = -two * normal[0] * normal[1];
- M(2, 0) = -two * normal[0] * normal[2];
- M(3, 0) = twoDotNO * normal[0];
- M(0, 1) = M(1, 0);
- M(1, 1) = one - two * normal[1] * normal[1];
- M(2, 1) = -two * normal[1] * normal[2];
- M(3, 1) = twoDotNO * normal[1];
- M(0, 2) = M(2, 0);
- M(1, 2) = M(2, 1);
- M(2, 2) = one - two * normal[2] * normal[2];
- M(3, 2) = twoDotNO * normal[2];
- M(0, 3) = zero;
- M(1, 3) = zero;
- M(2, 3) = zero;
- M(3, 3) = one;
- #endif
- return M;
- }
- }
|