DMat44.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2022 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/Math/MathTypes.h>
  6. JPH_NAMESPACE_BEGIN
  7. /// Holds a 4x4 matrix of floats with the last column consisting of doubles
  8. class [[nodiscard]] alignas(JPH_DVECTOR_ALIGNMENT) DMat44
  9. {
  10. public:
  11. JPH_OVERRIDE_NEW_DELETE
  12. // Underlying column type
  13. using Type = Vec4::Type;
  14. using DType = DVec3::Type;
  15. using DTypeArg = DVec3::TypeArg;
  16. // Argument type
  17. using ArgType = DMat44Arg;
  18. /// Constructor
  19. DMat44() = default; ///< Intentionally not initialized for performance reasons
  20. JPH_INLINE DMat44(Vec4Arg inC1, Vec4Arg inC2, Vec4Arg inC3, DVec3Arg inC4);
  21. DMat44(const DMat44 &inM2) = default;
  22. DMat44 & operator = (const DMat44 &inM2) = default;
  23. JPH_INLINE explicit DMat44(Mat44Arg inM);
  24. JPH_INLINE DMat44(Mat44Arg inRot, DVec3Arg inT);
  25. JPH_INLINE DMat44(Type inC1, Type inC2, Type inC3, DTypeArg inC4);
  26. /// Zero matrix
  27. static JPH_INLINE DMat44 sZero();
  28. /// Identity matrix
  29. static JPH_INLINE DMat44 sIdentity();
  30. /// Rotate from quaternion
  31. static JPH_INLINE DMat44 sRotation(QuatArg inQuat) { return DMat44(Mat44::sRotation(inQuat), DVec3::sZero()); }
  32. /// Get matrix that translates
  33. static JPH_INLINE DMat44 sTranslation(DVec3Arg inV) { return DMat44(Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(0, 0, 1, 0), inV); }
  34. /// Get matrix that rotates and translates
  35. static JPH_INLINE DMat44 sRotationTranslation(QuatArg inR, DVec3Arg inT) { return DMat44(Mat44::sRotation(inR), inT); }
  36. /// Get inverse matrix of sRotationTranslation
  37. static JPH_INLINE DMat44 sInverseRotationTranslation(QuatArg inR, DVec3Arg inT);
  38. /// Get matrix that scales (produces a matrix with (inV, 1) on its diagonal)
  39. static JPH_INLINE DMat44 sScale(Vec3Arg inV) { return DMat44(Mat44::sScale(inV), DVec3::sZero()); }
  40. /// Convert to Mat44 rounding to nearest
  41. JPH_INLINE Mat44 ToMat44() const { return Mat44(mCol[0], mCol[1], mCol[2], Vec3(mCol3)); }
  42. /// Comparsion
  43. JPH_INLINE bool operator == (DMat44Arg inM2) const;
  44. JPH_INLINE bool operator != (DMat44Arg inM2) const { return !(*this == inM2); }
  45. /// Test if two matrices are close
  46. JPH_INLINE bool IsClose(DMat44Arg inM2, float inMaxDistSq = 1.0e-12f) const;
  47. /// Multiply matrix by matrix
  48. JPH_INLINE DMat44 operator * (Mat44Arg inM) const;
  49. /// Multiply matrix by matrix
  50. JPH_INLINE DMat44 operator * (DMat44Arg inM) const;
  51. /// Multiply vector by matrix
  52. JPH_INLINE DVec3 operator * (Vec3Arg inV) const;
  53. /// Multiply vector by matrix
  54. JPH_INLINE DVec3 operator * (DVec3Arg inV) const;
  55. /// Multiply vector by only 3x3 part of the matrix
  56. JPH_INLINE Vec3 Multiply3x3(Vec3Arg inV) const { return GetRotation().Multiply3x3(inV); }
  57. /// Multiply vector by only 3x3 part of the matrix
  58. JPH_INLINE DVec3 Multiply3x3(DVec3Arg inV) const;
  59. /// Multiply vector by only 3x3 part of the transpose of the matrix (\f$result = this^T \: inV\f$)
  60. JPH_INLINE Vec3 Multiply3x3Transposed(Vec3Arg inV) const { return GetRotation().Multiply3x3Transposed(inV); }
  61. /// Scale a matrix: result = this * Mat44::sScale(inScale)
  62. JPH_INLINE DMat44 PreScaled(Vec3Arg inScale) const;
  63. /// Scale a matrix: result = Mat44::sScale(inScale) * this
  64. JPH_INLINE DMat44 PostScaled(Vec3Arg inScale) const;
  65. /// Pre multiply by translation matrix: result = this * Mat44::sTranslation(inTranslation)
  66. JPH_INLINE DMat44 PreTranslated(Vec3Arg inTranslation) const;
  67. /// Pre multiply by translation matrix: result = this * Mat44::sTranslation(inTranslation)
  68. JPH_INLINE DMat44 PreTranslated(DVec3Arg inTranslation) const;
  69. /// Post multiply by translation matrix: result = Mat44::sTranslation(inTranslation) * this (i.e. add inTranslation to the 4-th column)
  70. JPH_INLINE DMat44 PostTranslated(Vec3Arg inTranslation) const;
  71. /// Post multiply by translation matrix: result = Mat44::sTranslation(inTranslation) * this (i.e. add inTranslation to the 4-th column)
  72. JPH_INLINE DMat44 PostTranslated(DVec3Arg inTranslation) const;
  73. /// Access to the columns
  74. JPH_INLINE Vec3 GetAxisX() const { return Vec3(mCol[0]); }
  75. JPH_INLINE void SetAxisX(Vec3Arg inV) { mCol[0] = Vec4(inV, 0.0f); }
  76. JPH_INLINE Vec3 GetAxisY() const { return Vec3(mCol[1]); }
  77. JPH_INLINE void SetAxisY(Vec3Arg inV) { mCol[1] = Vec4(inV, 0.0f); }
  78. JPH_INLINE Vec3 GetAxisZ() const { return Vec3(mCol[2]); }
  79. JPH_INLINE void SetAxisZ(Vec3Arg inV) { mCol[2] = Vec4(inV, 0.0f); }
  80. JPH_INLINE DVec3 GetTranslation() const { return mCol3; }
  81. JPH_INLINE void SetTranslation(DVec3Arg inV) { mCol3 = inV; }
  82. JPH_INLINE Vec3 GetColumn3(uint inCol) const { JPH_ASSERT(inCol < 3); return Vec3(mCol[inCol]); }
  83. JPH_INLINE void SetColumn3(uint inCol, Vec3Arg inV) { JPH_ASSERT(inCol < 3); mCol[inCol] = Vec4(inV, 0.0f); }
  84. JPH_INLINE Vec4 GetColumn4(uint inCol) const { JPH_ASSERT(inCol < 3); return mCol[inCol]; }
  85. JPH_INLINE void SetColumn4(uint inCol, Vec4Arg inV) { JPH_ASSERT(inCol < 3); mCol[inCol] = inV; }
  86. /// Transpose 3x3 subpart of matrix
  87. JPH_INLINE Mat44 Transposed3x3() const { return GetRotation().Transposed3x3(); }
  88. /// Inverse 4x4 matrix
  89. JPH_INLINE DMat44 Inversed() const;
  90. /// Inverse 4x4 matrix when it only contains rotation and translation
  91. JPH_INLINE DMat44 InversedRotationTranslation() const;
  92. /// Get rotation part only (note: retains the first 3 values from the bottom row)
  93. JPH_INLINE Mat44 GetRotation() const { return Mat44(mCol[0], mCol[1], mCol[2], Vec4(0, 0, 0, 1)); }
  94. /// Updates the rotation part of this matrix (the first 3 columns)
  95. JPH_INLINE void SetRotation(Mat44Arg inRotation);
  96. /// Convert to quaternion
  97. JPH_INLINE Quat GetQuaternion() const { return GetRotation().GetQuaternion(); }
  98. /// Get matrix that transforms a direction with the same transform as this matrix (length is not preserved)
  99. JPH_INLINE Mat44 GetDirectionPreservingMatrix() const { return GetRotation().Inversed3x3().Transposed3x3(); }
  100. /// Works identical to Mat44::Decompose
  101. JPH_INLINE DMat44 Decompose(Vec3 &outScale) const { return DMat44(GetRotation().Decompose(outScale), mCol3); }
  102. /// To String
  103. friend ostream & operator << (ostream &inStream, DMat44Arg inM)
  104. {
  105. inStream << inM.mCol[0] << ", " << inM.mCol[1] << ", " << inM.mCol[2] << ", " << inM.mCol3;
  106. return inStream;
  107. }
  108. private:
  109. Vec4 mCol[3]; ///< Rotation columns
  110. DVec3 mCol3; ///< Translation column, 4th element is assumed to be 1
  111. };
  112. static_assert(is_trivial<DMat44>(), "Is supposed to be a trivial type!");
  113. JPH_NAMESPACE_END
  114. #include "DMat44.inl"