Path: blob/master/thirdparty/jolt_physics/Jolt/Math/Mat44.h
9913 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Math/MathTypes.h>78JPH_NAMESPACE_BEGIN910/// Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.11class [[nodiscard]] alignas(JPH_VECTOR_ALIGNMENT) Mat4412{13public:14JPH_OVERRIDE_NEW_DELETE1516// Underlying column type17using Type = Vec4::Type;1819// Argument type20using ArgType = Mat44Arg;2122/// Constructor23Mat44() = default; ///< Intentionally not initialized for performance reasons24JPH_INLINE Mat44(Vec4Arg inC1, Vec4Arg inC2, Vec4Arg inC3, Vec4Arg inC4);25JPH_INLINE Mat44(Vec4Arg inC1, Vec4Arg inC2, Vec4Arg inC3, Vec3Arg inC4);26Mat44(const Mat44 &inM2) = default;27Mat44 & operator = (const Mat44 &inM2) = default;28JPH_INLINE Mat44(Type inC1, Type inC2, Type inC3, Type inC4);2930/// Zero matrix31static JPH_INLINE Mat44 sZero();3233/// Identity matrix34static JPH_INLINE Mat44 sIdentity();3536/// Matrix filled with NaN's37static JPH_INLINE Mat44 sNaN();3839/// Load 16 floats from memory40static JPH_INLINE Mat44 sLoadFloat4x4(const Float4 *inV);4142/// Load 16 floats from memory, 16 bytes aligned43static JPH_INLINE Mat44 sLoadFloat4x4Aligned(const Float4 *inV);4445/// Rotate around X, Y or Z axis (angle in radians)46static JPH_INLINE Mat44 sRotationX(float inX);47static JPH_INLINE Mat44 sRotationY(float inY);48static JPH_INLINE Mat44 sRotationZ(float inZ);4950/// Rotate around arbitrary axis51static JPH_INLINE Mat44 sRotation(Vec3Arg inAxis, float inAngle);5253/// Rotate from quaternion54static JPH_INLINE Mat44 sRotation(QuatArg inQuat);5556/// Get matrix that translates57static JPH_INLINE Mat44 sTranslation(Vec3Arg inV);5859/// Get matrix that rotates and translates60static JPH_INLINE Mat44 sRotationTranslation(QuatArg inR, Vec3Arg inT);6162/// Get inverse matrix of sRotationTranslation63static JPH_INLINE Mat44 sInverseRotationTranslation(QuatArg inR, Vec3Arg inT);6465/// Get matrix that scales uniformly66static JPH_INLINE Mat44 sScale(float inScale);6768/// Get matrix that scales (produces a matrix with (inV, 1) on its diagonal)69static JPH_INLINE Mat44 sScale(Vec3Arg inV);7071/// Get outer product of inV and inV2 (equivalent to \f$inV1 \otimes inV2\f$)72static JPH_INLINE Mat44 sOuterProduct(Vec3Arg inV1, Vec3Arg inV2);7374/// Get matrix that represents a cross product \f$A \times B = \text{sCrossProduct}(A) \: B\f$75static JPH_INLINE Mat44 sCrossProduct(Vec3Arg inV);7677/// Returns matrix ML so that \f$ML(q) \: p = q \: p\f$ (where p and q are quaternions)78static JPH_INLINE Mat44 sQuatLeftMultiply(QuatArg inQ);7980/// Returns matrix MR so that \f$MR(q) \: p = p \: q\f$ (where p and q are quaternions)81static JPH_INLINE Mat44 sQuatRightMultiply(QuatArg inQ);8283/// Returns a look at matrix that transforms from world space to view space84/// @param inPos Position of the camera85/// @param inTarget Target of the camera86/// @param inUp Up vector87static JPH_INLINE Mat44 sLookAt(Vec3Arg inPos, Vec3Arg inTarget, Vec3Arg inUp);8889/// Returns a right-handed perspective projection matrix90static JPH_INLINE Mat44 sPerspective(float inFovY, float inAspect, float inNear, float inFar);9192/// Get float component by element index93JPH_INLINE float operator () (uint inRow, uint inColumn) const { JPH_ASSERT(inRow < 4); JPH_ASSERT(inColumn < 4); return mCol[inColumn].mF32[inRow]; }94JPH_INLINE float & operator () (uint inRow, uint inColumn) { JPH_ASSERT(inRow < 4); JPH_ASSERT(inColumn < 4); return mCol[inColumn].mF32[inRow]; }9596/// Comparison97JPH_INLINE bool operator == (Mat44Arg inM2) const;98JPH_INLINE bool operator != (Mat44Arg inM2) const { return !(*this == inM2); }99100/// Test if two matrices are close101JPH_INLINE bool IsClose(Mat44Arg inM2, float inMaxDistSq = 1.0e-12f) const;102103/// Multiply matrix by matrix104JPH_INLINE Mat44 operator * (Mat44Arg inM) const;105106/// Multiply vector by matrix107JPH_INLINE Vec3 operator * (Vec3Arg inV) const;108JPH_INLINE Vec4 operator * (Vec4Arg inV) const;109110/// Multiply vector by only 3x3 part of the matrix111JPH_INLINE Vec3 Multiply3x3(Vec3Arg inV) const;112113/// Multiply vector by only 3x3 part of the transpose of the matrix (\f$result = this^T \: inV\f$)114JPH_INLINE Vec3 Multiply3x3Transposed(Vec3Arg inV) const;115116/// Multiply 3x3 matrix by 3x3 matrix117JPH_INLINE Mat44 Multiply3x3(Mat44Arg inM) const;118119/// Multiply transpose of 3x3 matrix by 3x3 matrix (\f$result = this^T \: inM\f$)120JPH_INLINE Mat44 Multiply3x3LeftTransposed(Mat44Arg inM) const;121122/// Multiply 3x3 matrix by the transpose of a 3x3 matrix (\f$result = this \: inM^T\f$)123JPH_INLINE Mat44 Multiply3x3RightTransposed(Mat44Arg inM) const;124125/// Multiply matrix with float126JPH_INLINE Mat44 operator * (float inV) const;127friend JPH_INLINE Mat44 operator * (float inV, Mat44Arg inM) { return inM * inV; }128129/// Multiply matrix with float130JPH_INLINE Mat44 & operator *= (float inV);131132/// Per element addition of matrix133JPH_INLINE Mat44 operator + (Mat44Arg inM) const;134135/// Negate136JPH_INLINE Mat44 operator - () const;137138/// Per element subtraction of matrix139JPH_INLINE Mat44 operator - (Mat44Arg inM) const;140141/// Per element addition of matrix142JPH_INLINE Mat44 & operator += (Mat44Arg inM);143144/// Access to the columns145JPH_INLINE Vec3 GetAxisX() const { return Vec3(mCol[0]); }146JPH_INLINE void SetAxisX(Vec3Arg inV) { mCol[0] = Vec4(inV, 0.0f); }147JPH_INLINE Vec3 GetAxisY() const { return Vec3(mCol[1]); }148JPH_INLINE void SetAxisY(Vec3Arg inV) { mCol[1] = Vec4(inV, 0.0f); }149JPH_INLINE Vec3 GetAxisZ() const { return Vec3(mCol[2]); }150JPH_INLINE void SetAxisZ(Vec3Arg inV) { mCol[2] = Vec4(inV, 0.0f); }151JPH_INLINE Vec3 GetTranslation() const { return Vec3(mCol[3]); }152JPH_INLINE void SetTranslation(Vec3Arg inV) { mCol[3] = Vec4(inV, 1.0f); }153JPH_INLINE Vec3 GetDiagonal3() const { return Vec3(mCol[0][0], mCol[1][1], mCol[2][2]); }154JPH_INLINE void SetDiagonal3(Vec3Arg inV) { mCol[0][0] = inV.GetX(); mCol[1][1] = inV.GetY(); mCol[2][2] = inV.GetZ(); }155JPH_INLINE Vec4 GetDiagonal4() const { return Vec4(mCol[0][0], mCol[1][1], mCol[2][2], mCol[3][3]); }156JPH_INLINE void SetDiagonal4(Vec4Arg inV) { mCol[0][0] = inV.GetX(); mCol[1][1] = inV.GetY(); mCol[2][2] = inV.GetZ(); mCol[3][3] = inV.GetW(); }157JPH_INLINE Vec3 GetColumn3(uint inCol) const { JPH_ASSERT(inCol < 4); return Vec3(mCol[inCol]); }158JPH_INLINE void SetColumn3(uint inCol, Vec3Arg inV) { JPH_ASSERT(inCol < 4); mCol[inCol] = Vec4(inV, inCol == 3? 1.0f : 0.0f); }159JPH_INLINE Vec4 GetColumn4(uint inCol) const { JPH_ASSERT(inCol < 4); return mCol[inCol]; }160JPH_INLINE void SetColumn4(uint inCol, Vec4Arg inV) { JPH_ASSERT(inCol < 4); mCol[inCol] = inV; }161162/// Store matrix to memory163JPH_INLINE void StoreFloat4x4(Float4 *outV) const;164165/// Transpose matrix166JPH_INLINE Mat44 Transposed() const;167168/// Transpose 3x3 subpart of matrix169JPH_INLINE Mat44 Transposed3x3() const;170171/// Inverse 4x4 matrix172JPH_INLINE Mat44 Inversed() const;173174/// Inverse 4x4 matrix when it only contains rotation and translation175JPH_INLINE Mat44 InversedRotationTranslation() const;176177/// Get the determinant of a 3x3 matrix178JPH_INLINE float GetDeterminant3x3() const;179180/// Get the adjoint of a 3x3 matrix181JPH_INLINE Mat44 Adjointed3x3() const;182183/// Inverse 3x3 matrix184JPH_INLINE Mat44 Inversed3x3() const;185186/// *this = inM.Inversed3x3(), returns false if the matrix is singular in which case *this is unchanged187JPH_INLINE bool SetInversed3x3(Mat44Arg inM);188189/// Get rotation part only (note: retains the first 3 values from the bottom row)190JPH_INLINE Mat44 GetRotation() const;191192/// Get rotation part only (note: also clears the bottom row)193JPH_INLINE Mat44 GetRotationSafe() const;194195/// Updates the rotation part of this matrix (the first 3 columns)196JPH_INLINE void SetRotation(Mat44Arg inRotation);197198/// Convert to quaternion199JPH_INLINE Quat GetQuaternion() const;200201/// Get matrix that transforms a direction with the same transform as this matrix (length is not preserved)202JPH_INLINE Mat44 GetDirectionPreservingMatrix() const { return GetRotation().Inversed3x3().Transposed3x3(); }203204/// Pre multiply by translation matrix: result = this * Mat44::sTranslation(inTranslation)205JPH_INLINE Mat44 PreTranslated(Vec3Arg inTranslation) const;206207/// Post multiply by translation matrix: result = Mat44::sTranslation(inTranslation) * this (i.e. add inTranslation to the 4-th column)208JPH_INLINE Mat44 PostTranslated(Vec3Arg inTranslation) const;209210/// Scale a matrix: result = this * Mat44::sScale(inScale)211JPH_INLINE Mat44 PreScaled(Vec3Arg inScale) const;212213/// Scale a matrix: result = Mat44::sScale(inScale) * this214JPH_INLINE Mat44 PostScaled(Vec3Arg inScale) const;215216/// Decompose a matrix into a rotation & translation part and into a scale part so that:217/// this = return_value * Mat44::sScale(outScale).218/// This equation only holds when the matrix is orthogonal, if it is not the returned matrix219/// will be made orthogonal using the modified Gram-Schmidt algorithm (see: https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process)220JPH_INLINE Mat44 Decompose(Vec3 &outScale) const;221222#ifndef JPH_DOUBLE_PRECISION223/// In single precision mode just return the matrix itself224JPH_INLINE Mat44 ToMat44() const { return *this; }225#endif // !JPH_DOUBLE_PRECISION226227/// To String228friend ostream & operator << (ostream &inStream, Mat44Arg inM)229{230inStream << inM.mCol[0] << ", " << inM.mCol[1] << ", " << inM.mCol[2] << ", " << inM.mCol[3];231return inStream;232}233234private:235Vec4 mCol[4]; ///< Column236};237238static_assert(std::is_trivial<Mat44>(), "Is supposed to be a trivial type!");239240JPH_NAMESPACE_END241242#include "Mat44.inl"243244245