Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Math/Mat44.h
9913 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include <Jolt/Math/MathTypes.h>
8
9
JPH_NAMESPACE_BEGIN
10
11
/// Holds a 4x4 matrix of floats, but supports also operations on the 3x3 upper left part of the matrix.
12
class [[nodiscard]] alignas(JPH_VECTOR_ALIGNMENT) Mat44
13
{
14
public:
15
JPH_OVERRIDE_NEW_DELETE
16
17
// Underlying column type
18
using Type = Vec4::Type;
19
20
// Argument type
21
using ArgType = Mat44Arg;
22
23
/// Constructor
24
Mat44() = default; ///< Intentionally not initialized for performance reasons
25
JPH_INLINE Mat44(Vec4Arg inC1, Vec4Arg inC2, Vec4Arg inC3, Vec4Arg inC4);
26
JPH_INLINE Mat44(Vec4Arg inC1, Vec4Arg inC2, Vec4Arg inC3, Vec3Arg inC4);
27
Mat44(const Mat44 &inM2) = default;
28
Mat44 & operator = (const Mat44 &inM2) = default;
29
JPH_INLINE Mat44(Type inC1, Type inC2, Type inC3, Type inC4);
30
31
/// Zero matrix
32
static JPH_INLINE Mat44 sZero();
33
34
/// Identity matrix
35
static JPH_INLINE Mat44 sIdentity();
36
37
/// Matrix filled with NaN's
38
static JPH_INLINE Mat44 sNaN();
39
40
/// Load 16 floats from memory
41
static JPH_INLINE Mat44 sLoadFloat4x4(const Float4 *inV);
42
43
/// Load 16 floats from memory, 16 bytes aligned
44
static JPH_INLINE Mat44 sLoadFloat4x4Aligned(const Float4 *inV);
45
46
/// Rotate around X, Y or Z axis (angle in radians)
47
static JPH_INLINE Mat44 sRotationX(float inX);
48
static JPH_INLINE Mat44 sRotationY(float inY);
49
static JPH_INLINE Mat44 sRotationZ(float inZ);
50
51
/// Rotate around arbitrary axis
52
static JPH_INLINE Mat44 sRotation(Vec3Arg inAxis, float inAngle);
53
54
/// Rotate from quaternion
55
static JPH_INLINE Mat44 sRotation(QuatArg inQuat);
56
57
/// Get matrix that translates
58
static JPH_INLINE Mat44 sTranslation(Vec3Arg inV);
59
60
/// Get matrix that rotates and translates
61
static JPH_INLINE Mat44 sRotationTranslation(QuatArg inR, Vec3Arg inT);
62
63
/// Get inverse matrix of sRotationTranslation
64
static JPH_INLINE Mat44 sInverseRotationTranslation(QuatArg inR, Vec3Arg inT);
65
66
/// Get matrix that scales uniformly
67
static JPH_INLINE Mat44 sScale(float inScale);
68
69
/// Get matrix that scales (produces a matrix with (inV, 1) on its diagonal)
70
static JPH_INLINE Mat44 sScale(Vec3Arg inV);
71
72
/// Get outer product of inV and inV2 (equivalent to \f$inV1 \otimes inV2\f$)
73
static JPH_INLINE Mat44 sOuterProduct(Vec3Arg inV1, Vec3Arg inV2);
74
75
/// Get matrix that represents a cross product \f$A \times B = \text{sCrossProduct}(A) \: B\f$
76
static JPH_INLINE Mat44 sCrossProduct(Vec3Arg inV);
77
78
/// Returns matrix ML so that \f$ML(q) \: p = q \: p\f$ (where p and q are quaternions)
79
static JPH_INLINE Mat44 sQuatLeftMultiply(QuatArg inQ);
80
81
/// Returns matrix MR so that \f$MR(q) \: p = p \: q\f$ (where p and q are quaternions)
82
static JPH_INLINE Mat44 sQuatRightMultiply(QuatArg inQ);
83
84
/// Returns a look at matrix that transforms from world space to view space
85
/// @param inPos Position of the camera
86
/// @param inTarget Target of the camera
87
/// @param inUp Up vector
88
static JPH_INLINE Mat44 sLookAt(Vec3Arg inPos, Vec3Arg inTarget, Vec3Arg inUp);
89
90
/// Returns a right-handed perspective projection matrix
91
static JPH_INLINE Mat44 sPerspective(float inFovY, float inAspect, float inNear, float inFar);
92
93
/// Get float component by element index
94
JPH_INLINE float operator () (uint inRow, uint inColumn) const { JPH_ASSERT(inRow < 4); JPH_ASSERT(inColumn < 4); return mCol[inColumn].mF32[inRow]; }
95
JPH_INLINE float & operator () (uint inRow, uint inColumn) { JPH_ASSERT(inRow < 4); JPH_ASSERT(inColumn < 4); return mCol[inColumn].mF32[inRow]; }
96
97
/// Comparison
98
JPH_INLINE bool operator == (Mat44Arg inM2) const;
99
JPH_INLINE bool operator != (Mat44Arg inM2) const { return !(*this == inM2); }
100
101
/// Test if two matrices are close
102
JPH_INLINE bool IsClose(Mat44Arg inM2, float inMaxDistSq = 1.0e-12f) const;
103
104
/// Multiply matrix by matrix
105
JPH_INLINE Mat44 operator * (Mat44Arg inM) const;
106
107
/// Multiply vector by matrix
108
JPH_INLINE Vec3 operator * (Vec3Arg inV) const;
109
JPH_INLINE Vec4 operator * (Vec4Arg inV) const;
110
111
/// Multiply vector by only 3x3 part of the matrix
112
JPH_INLINE Vec3 Multiply3x3(Vec3Arg inV) const;
113
114
/// Multiply vector by only 3x3 part of the transpose of the matrix (\f$result = this^T \: inV\f$)
115
JPH_INLINE Vec3 Multiply3x3Transposed(Vec3Arg inV) const;
116
117
/// Multiply 3x3 matrix by 3x3 matrix
118
JPH_INLINE Mat44 Multiply3x3(Mat44Arg inM) const;
119
120
/// Multiply transpose of 3x3 matrix by 3x3 matrix (\f$result = this^T \: inM\f$)
121
JPH_INLINE Mat44 Multiply3x3LeftTransposed(Mat44Arg inM) const;
122
123
/// Multiply 3x3 matrix by the transpose of a 3x3 matrix (\f$result = this \: inM^T\f$)
124
JPH_INLINE Mat44 Multiply3x3RightTransposed(Mat44Arg inM) const;
125
126
/// Multiply matrix with float
127
JPH_INLINE Mat44 operator * (float inV) const;
128
friend JPH_INLINE Mat44 operator * (float inV, Mat44Arg inM) { return inM * inV; }
129
130
/// Multiply matrix with float
131
JPH_INLINE Mat44 & operator *= (float inV);
132
133
/// Per element addition of matrix
134
JPH_INLINE Mat44 operator + (Mat44Arg inM) const;
135
136
/// Negate
137
JPH_INLINE Mat44 operator - () const;
138
139
/// Per element subtraction of matrix
140
JPH_INLINE Mat44 operator - (Mat44Arg inM) const;
141
142
/// Per element addition of matrix
143
JPH_INLINE Mat44 & operator += (Mat44Arg inM);
144
145
/// Access to the columns
146
JPH_INLINE Vec3 GetAxisX() const { return Vec3(mCol[0]); }
147
JPH_INLINE void SetAxisX(Vec3Arg inV) { mCol[0] = Vec4(inV, 0.0f); }
148
JPH_INLINE Vec3 GetAxisY() const { return Vec3(mCol[1]); }
149
JPH_INLINE void SetAxisY(Vec3Arg inV) { mCol[1] = Vec4(inV, 0.0f); }
150
JPH_INLINE Vec3 GetAxisZ() const { return Vec3(mCol[2]); }
151
JPH_INLINE void SetAxisZ(Vec3Arg inV) { mCol[2] = Vec4(inV, 0.0f); }
152
JPH_INLINE Vec3 GetTranslation() const { return Vec3(mCol[3]); }
153
JPH_INLINE void SetTranslation(Vec3Arg inV) { mCol[3] = Vec4(inV, 1.0f); }
154
JPH_INLINE Vec3 GetDiagonal3() const { return Vec3(mCol[0][0], mCol[1][1], mCol[2][2]); }
155
JPH_INLINE void SetDiagonal3(Vec3Arg inV) { mCol[0][0] = inV.GetX(); mCol[1][1] = inV.GetY(); mCol[2][2] = inV.GetZ(); }
156
JPH_INLINE Vec4 GetDiagonal4() const { return Vec4(mCol[0][0], mCol[1][1], mCol[2][2], mCol[3][3]); }
157
JPH_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(); }
158
JPH_INLINE Vec3 GetColumn3(uint inCol) const { JPH_ASSERT(inCol < 4); return Vec3(mCol[inCol]); }
159
JPH_INLINE void SetColumn3(uint inCol, Vec3Arg inV) { JPH_ASSERT(inCol < 4); mCol[inCol] = Vec4(inV, inCol == 3? 1.0f : 0.0f); }
160
JPH_INLINE Vec4 GetColumn4(uint inCol) const { JPH_ASSERT(inCol < 4); return mCol[inCol]; }
161
JPH_INLINE void SetColumn4(uint inCol, Vec4Arg inV) { JPH_ASSERT(inCol < 4); mCol[inCol] = inV; }
162
163
/// Store matrix to memory
164
JPH_INLINE void StoreFloat4x4(Float4 *outV) const;
165
166
/// Transpose matrix
167
JPH_INLINE Mat44 Transposed() const;
168
169
/// Transpose 3x3 subpart of matrix
170
JPH_INLINE Mat44 Transposed3x3() const;
171
172
/// Inverse 4x4 matrix
173
JPH_INLINE Mat44 Inversed() const;
174
175
/// Inverse 4x4 matrix when it only contains rotation and translation
176
JPH_INLINE Mat44 InversedRotationTranslation() const;
177
178
/// Get the determinant of a 3x3 matrix
179
JPH_INLINE float GetDeterminant3x3() const;
180
181
/// Get the adjoint of a 3x3 matrix
182
JPH_INLINE Mat44 Adjointed3x3() const;
183
184
/// Inverse 3x3 matrix
185
JPH_INLINE Mat44 Inversed3x3() const;
186
187
/// *this = inM.Inversed3x3(), returns false if the matrix is singular in which case *this is unchanged
188
JPH_INLINE bool SetInversed3x3(Mat44Arg inM);
189
190
/// Get rotation part only (note: retains the first 3 values from the bottom row)
191
JPH_INLINE Mat44 GetRotation() const;
192
193
/// Get rotation part only (note: also clears the bottom row)
194
JPH_INLINE Mat44 GetRotationSafe() const;
195
196
/// Updates the rotation part of this matrix (the first 3 columns)
197
JPH_INLINE void SetRotation(Mat44Arg inRotation);
198
199
/// Convert to quaternion
200
JPH_INLINE Quat GetQuaternion() const;
201
202
/// Get matrix that transforms a direction with the same transform as this matrix (length is not preserved)
203
JPH_INLINE Mat44 GetDirectionPreservingMatrix() const { return GetRotation().Inversed3x3().Transposed3x3(); }
204
205
/// Pre multiply by translation matrix: result = this * Mat44::sTranslation(inTranslation)
206
JPH_INLINE Mat44 PreTranslated(Vec3Arg inTranslation) const;
207
208
/// Post multiply by translation matrix: result = Mat44::sTranslation(inTranslation) * this (i.e. add inTranslation to the 4-th column)
209
JPH_INLINE Mat44 PostTranslated(Vec3Arg inTranslation) const;
210
211
/// Scale a matrix: result = this * Mat44::sScale(inScale)
212
JPH_INLINE Mat44 PreScaled(Vec3Arg inScale) const;
213
214
/// Scale a matrix: result = Mat44::sScale(inScale) * this
215
JPH_INLINE Mat44 PostScaled(Vec3Arg inScale) const;
216
217
/// Decompose a matrix into a rotation & translation part and into a scale part so that:
218
/// this = return_value * Mat44::sScale(outScale).
219
/// This equation only holds when the matrix is orthogonal, if it is not the returned matrix
220
/// will be made orthogonal using the modified Gram-Schmidt algorithm (see: https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process)
221
JPH_INLINE Mat44 Decompose(Vec3 &outScale) const;
222
223
#ifndef JPH_DOUBLE_PRECISION
224
/// In single precision mode just return the matrix itself
225
JPH_INLINE Mat44 ToMat44() const { return *this; }
226
#endif // !JPH_DOUBLE_PRECISION
227
228
/// To String
229
friend ostream & operator << (ostream &inStream, Mat44Arg inM)
230
{
231
inStream << inM.mCol[0] << ", " << inM.mCol[1] << ", " << inM.mCol[2] << ", " << inM.mCol[3];
232
return inStream;
233
}
234
235
private:
236
Vec4 mCol[4]; ///< Column
237
};
238
239
static_assert(std::is_trivial<Mat44>(), "Is supposed to be a trivial type!");
240
241
JPH_NAMESPACE_END
242
243
#include "Mat44.inl"
244
245