3#include "egg/math/Quat.hh"
14 a.fill(std::numeric_limits<f32>::signaling_NaN());
20 constexpr Matrix34f(f32 _e00, f32 _e01, f32 _e02, f32 _e03, f32 _e10, f32 _e11, f32 _e12,
21 f32 _e13, f32 _e20, f32 _e21, f32 _e22, f32 _e23)
22 : a{{_e00, _e01, _e02, _e03, _e10, _e11, _e12, _e13, _e20, _e21, _e22, _e23}} {}
26 constexpr bool operator==(
const Matrix34f &rhs)
const {
27 return mtx == rhs.mtx;
31 [[nodiscard]]
constexpr f32 &
operator[](
size_t row,
size_t col) {
36 [[nodiscard]]
constexpr f32
operator[](
size_t row,
size_t col)
const {
43 f32 yy = 2.0f * q.v.y * q.v.y;
44 f32 zz = 2.0f * q.v.z * q.v.z;
45 f32 xx = 2.0f * q.v.x * q.v.x;
46 f32 xy = 2.0f * q.v.x * q.v.y;
47 f32 xz = 2.0f * q.v.x * q.v.z;
48 f32 yz = 2.0f * q.v.y * q.v.z;
49 f32 wz = 2.0f * q.w * q.v.z;
50 f32 wx = 2.0f * q.w * q.v.x;
51 f32 wy = 2.0f * q.w * q.v.y;
53 mtx[0][0] = 1.0f - yy - zz;
58 mtx[1][1] = 1.0f - xx - zz;
63 mtx[2][2] = 1.0f - xx - yy;
73 f32 yy = 2.0f * q.v.y * q.v.y;
74 f32 zz = 2.0f * q.v.z * q.v.z;
75 f32 xx = 2.0f * q.v.x * q.v.x;
76 f32 xy = 2.0f * q.v.x * q.v.y;
77 f32 xz = 2.0f * q.v.x * q.v.z;
78 f32 yz = 2.0f * q.v.y * q.v.z;
79 f32 wz = 2.0f * q.w * q.v.z;
80 f32 wx = 2.0f * q.w * q.v.x;
81 f32 wy = 2.0f * q.w * q.v.y;
83 mtx[0][0] = 1.0f - yy - zz;
88 mtx[1][1] = 1.0f - xx - zz;
93 mtx[2][2] = 1.0f - xx - yy;
106 const f32 c0_c2 = c.x * c.z;
107 const f32 s0_s1 = s.x * s.y;
108 const f32 c0_s2 = c.x * s.z;
110 mtx[0][0] = (c.y * c.z);
111 mtx[1][0] = (c.y * s.z);
114 mtx[0][1] = (s0_s1 * c.z) - c0_s2;
115 mtx[1][1] = (s0_s1 * s.z) + c0_c2;
116 mtx[2][1] = (s.x * c.y);
118 mtx[0][2] = (c0_c2 * s.y) + (s.x * s.z);
119 mtx[1][2] = (c0_s2 * s.y) - (s.x * c.z);
120 mtx[2][2] = (c.x * c.y);
133 const f32 c0_c2 = c.x * c.z;
134 const f32 s0_s1 = s.x * s.y;
135 const f32 c0_s2 = c.x * s.z;
137 mtx[0][0] = (c.y * c.z);
138 mtx[1][0] = (c.y * s.z);
141 mtx[0][1] = (s0_s1 * c.z) - c0_s2;
142 mtx[1][1] = (s0_s1 * s.z) + c0_c2;
143 mtx[2][1] = (s.x * c.y);
145 mtx[0][2] = (c0_c2 * s.y) + (s.x * s.z);
146 mtx[1][2] = (c0_s2 * s.y) - (s.x * c.z);
147 mtx[2][2] = (c.x * c.y);
155 constexpr void makeS(
const Vector3f &s) {
163 constexpr void makeT(
const Vector3f &t) {
203 forward.normalise2();
206 up = forward.cross(right);
208 setBase(3, EGG::Vector3f::zero);
224 mtx[rowIdx][0] *= row.x;
225 mtx[rowIdx][1] *= row.y;
226 mtx[rowIdx][2] *= row.z;
231 mtx[0][col] =
base.x;
232 mtx[1][col] =
base.y;
233 mtx[2][col] =
base.z;
241 mat[0, 0] =
fma(rhs[2, 0], mtx[0][2],
fma(rhs[1, 0], mtx[0][1], rhs[0, 0] * mtx[0][0]));
242 mat[0, 1] =
fma(rhs[2, 1], mtx[0][2],
fma(rhs[1, 1], mtx[0][1], rhs[0, 1] * mtx[0][0]));
243 mat[1, 0] =
fma(rhs[2, 0], mtx[1][2],
fma(rhs[1, 0], mtx[1][1], rhs[0, 0] * mtx[1][0]));
244 mat[1, 1] =
fma(rhs[2, 1], mtx[1][2],
fma(rhs[1, 1], mtx[1][1], rhs[0, 1] * mtx[1][0]));
245 mat[0, 2] =
fma(rhs[2, 2], mtx[0][2],
fma(rhs[1, 2], mtx[0][1], rhs[0, 2] * mtx[0][0]));
246 mat[0, 3] =
fma(1.0f, mtx[0][3],
247 fma(rhs[2, 3], mtx[0][2],
fma(rhs[1, 3], mtx[0][1], rhs[0, 3] * mtx[0][0])));
248 mat[1, 2] =
fma(rhs[2, 2], mtx[1][2],
fma(rhs[1, 2], mtx[1][1], rhs[0, 2] * mtx[1][0]));
249 mat[1, 3] =
fma(1.0f, mtx[1][3],
250 fma(rhs[2, 3], mtx[1][2],
fma(rhs[1, 3], mtx[1][1], rhs[0, 3] * mtx[1][0])));
251 mat[2, 0] =
fma(rhs[2, 0], mtx[2][2],
fma(rhs[1, 0], mtx[2][1], rhs[0, 0] * mtx[2][0]));
252 mat[2, 1] =
fma(rhs[2, 1], mtx[2][2],
fma(rhs[1, 1], mtx[2][1], rhs[0, 1] * mtx[2][0]));
253 mat[2, 2] =
fma(rhs[2, 2], mtx[2][2],
fma(rhs[1, 2], mtx[2][1], rhs[0, 2] * mtx[2][0]));
254 mat[2, 3] =
fma(1.0f, mtx[2][3],
255 fma(rhs[2, 3], mtx[2][2],
fma(rhs[1, 3], mtx[2][1], rhs[0, 3] * mtx[2][0])));
264 ret.x = mtx[0][0] * vec.x + mtx[0][3] + mtx[0][1] * vec.y + mtx[0][2] * vec.z;
265 ret.y = mtx[1][0] * vec.x + mtx[1][3] + mtx[1][1] * vec.y + mtx[1][2] * vec.z;
266 ret.z = mtx[2][0] * vec.x + mtx[2][3] + mtx[2][1] * vec.y + mtx[2][2] * vec.z;
276 ret.x =
fma(mtx[0][2], vec.z, mtx[0][0] * vec.x) +
fma(mtx[0][3], 1.0f, mtx[0][1] * vec.y);
277 ret.y =
fma(mtx[1][2], vec.z, mtx[1][0] * vec.x) +
fma(mtx[1][3], 1.0f, mtx[1][1] * vec.y);
278 ret.z =
fma(mtx[2][2], vec.z, mtx[2][0] * vec.x) +
fma(mtx[2][3], 1.0f, mtx[2][1] * vec.y);
288 ret.x = mtx[0][2] * vec.z + (mtx[0][0] * vec.x + mtx[0][1] * vec.y);
289 ret.y = mtx[1][2] * vec.z + (mtx[1][0] * vec.x + mtx[1][1] * vec.y);
290 ret.z = mtx[2][2] * vec.z + (mtx[2][0] * vec.x + mtx[2][1] * vec.y);
296 [[nodiscard]]
constexpr Vector3f calcRPY()
const {
297 constexpr f32 GIMBAL_LOCK_THRESHOLD = 0.999999f;
300 f32 absZ = EGG::Mathf::abs(xAxisBasis.z);
302 if (absZ > GIMBAL_LOCK_THRESHOLD) {
303 f32 y = xAxisBasis.z / absZ * -HALF_PI;
304 f32 z = EGG::Mathf::atan2(-mtx[0][1], -xAxisBasis.z * mtx[0][2]);
308 f32 x = EGG::Mathf::atan2(mtx[2][1], mtx[2][2]);
309 f32 y = EGG::Mathf::asin(-xAxisBasis.z);
310 f32 z = EGG::Mathf::atan2(xAxisBasis.y, xAxisBasis.x);
320 ret.x =
fma(mtx[0][2], vec.z, mtx[0][0] * vec.x + mtx[0][1] * vec.y);
321 ret.y =
fma(mtx[1][2], vec.z, mtx[1][0] * vec.x + mtx[1][1] * vec.y);
322 ret.z =
fma(mtx[2][2], vec.z, mtx[2][0] * vec.x + mtx[2][1] * vec.y);
332 f32 determinant = ((((mtx[2][1] * (mtx[0][2] * mtx[1][0])) +
333 ((mtx[2][2] * (mtx[0][0] * mtx[1][1])) +
334 (mtx[2][0] * (mtx[0][1] * mtx[1][2])))) -
335 (mtx[0][2] * (mtx[2][0] * mtx[1][1]))) -
336 (mtx[2][2] * (mtx[1][0] * mtx[0][1]))) -
337 (mtx[1][2] * (mtx[0][0] * mtx[2][1]));
339 if (determinant == 0.0f) {
344 f32 invDet = 1.0f / determinant;
346 out[0, 2] = (mtx[0][1] * mtx[1][2] - mtx[1][1] * mtx[0][2]) * invDet;
347 out[1, 2] = -(mtx[0][0] * mtx[1][2] - mtx[0][2] * mtx[1][0]) * invDet;
348 out[2, 1] = -(mtx[0][0] * mtx[2][1] - mtx[2][0] * mtx[0][1]) * invDet;
349 out[2, 2] = (mtx[0][0] * mtx[1][1] - mtx[1][0] * mtx[0][1]) * invDet;
350 out[2, 0] = (mtx[1][0] * mtx[2][1] - mtx[2][0] * mtx[1][1]) * invDet;
351 out[0, 0] = (mtx[1][1] * mtx[2][2] - mtx[2][1] * mtx[1][2]) * invDet;
352 out[0, 1] = -(mtx[0][1] * mtx[2][2] - mtx[2][1] * mtx[0][2]) * invDet;
353 out[1, 0] = -(mtx[1][0] * mtx[2][2] - mtx[2][0] * mtx[1][2]) * invDet;
354 out[1, 1] = (mtx[0][0] * mtx[2][2] - mtx[2][0] * mtx[0][2]) * invDet;
361 f32 fVar14 =
fms(mtx[0][1], mtx[1][2], mtx[1][1] * mtx[0][2]);
362 f32 fVar15 =
fms(mtx[1][1], mtx[2][2], mtx[2][1] * mtx[1][2]);
363 f32 fVar13 =
fms(mtx[2][1], mtx[0][2], mtx[0][1] * mtx[2][2]);
364 f32 determinant =
fma(mtx[2][0], fVar14,
fma(mtx[1][0], fVar13, mtx[0][0] * fVar15));
366 if (determinant == 0.0f) {
372 out[0, 0] = fVar15 * invDet;
373 out[0, 1] = fVar13 * invDet;
374 out[1, 0] =
fms(mtx[1][2], mtx[2][0], mtx[2][2] * mtx[1][0]) * invDet;
375 out[1, 1] =
fms(mtx[2][2], mtx[0][0], mtx[0][2] * mtx[2][0]) * invDet;
376 out[2, 0] =
fms(mtx[1][0], mtx[2][1], mtx[1][1] * mtx[2][0]) * invDet;
377 out[2, 1] =
fms(mtx[0][1], mtx[2][0], mtx[0][0] * mtx[2][1]) * invDet;
378 out[2, 2] =
fms(mtx[0][0], mtx[1][1], mtx[0][1] * mtx[1][0]) * invDet;
379 out[0, 2] = fVar14 * invDet;
380 out[0, 3] = -
fma(out[0, 2], mtx[2][3],
fma(out[0, 1], mtx[1][3], out[0, 0] * mtx[0][3]));
381 out[1, 2] =
fms(mtx[0][2], mtx[1][0], mtx[1][2] * mtx[0][0]) * invDet;
382 out[1, 3] = -
fma(out[1, 2], mtx[2][3],
fma(out[1, 1], mtx[1][3], out[1, 0] * mtx[0][3]));
383 out[2, 3] = -
fma(out[2, 2], mtx[2][3],
fma(out[2, 1], mtx[1][3], out[2, 0] * mtx[0][3]));
392 ret[0, 1] = mtx[1][0];
393 ret[0, 2] = mtx[2][0];
394 ret[1, 0] = mtx[0][1];
395 ret[1, 2] = mtx[2][1];
396 ret[2, 0] = mtx[0][2];
397 ret[2, 1] = mtx[1][2];
402 [[nodiscard]]
constexpr Vector3f translation()
const {
403 return Vector3f(mtx[0][3], mtx[1][3], mtx[2][3]);
409 return Vector3f(mtx[0][col], mtx[1][col], mtx[2][col]);
417 std::array<std::array<f32, 4>, 3> mtx;
418 std::array<f32, 12> a;
423inline constexpr Matrix34f Matrix34f::ident(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
426inline constexpr Matrix34f Matrix34f::zero(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
constexpr Vector3f ps_multVector33(const Vector3f &vec) const
Paired-singles impl. of multVector33.
constexpr void makeZero()
Zeroes every element of the matrix.
constexpr void makeR(const Vector3f &r)
Sets 3x3 rotation matrix from a vector of Euler angles.
constexpr void makeQT(const Quatf &q, const Vector3f &t)
Sets matrix from rotation and position.
constexpr void setAxisRotation(f32 angle, const EGG::Vector3f &axis)
Rotates the matrix about an axis.
constexpr void makeQ(const Quatf &q)
Sets rotation matrix from quaternion.
constexpr void makeOrthonormalBasis(const Vector3f &forward, const Vector3f &up)
Sets a 3x3 orthonormal basis for a local coordinate system.
constexpr Matrix34f transpose() const
Transposes the 3x3 portion of the matrix.
constexpr Vector3f ps_multVector(const Vector3f &vec) const
Paired-singles impl. of multVector.
constexpr Vector3f multVector(const Vector3f &vec) const
Multiplies a vector by a matrix.
constexpr f32 & operator[](size_t row, size_t col)
Accesses the matrix element at the specified row and column.
constexpr Vector3f base(size_t col) const
Get a particular column from a matrix.
constexpr bool ps_inverse(Matrix34f &out) const
constexpr f32 operator[](size_t row, size_t col) const
Accesses the matrix element at the specified row and column.
constexpr void mulRow33(size_t rowIdx, const Vector3f &row)
Multiplies one row of a 3x3 matrix by a vector.
constexpr void setBase(size_t col, const Vector3f &base)
Sets one column of a matrix.
constexpr void inverseTo33(Matrix34f &out) const
Inverts the 3x3 portion of the 3x4 matrix.
constexpr Vector3f multVector33(const Vector3f &vec) const
Multiplies a 3x3 matrix by a vector.
constexpr Matrix34f multiplyTo(const Matrix34f &rhs) const
Multiplies two matrices.
constexpr void makeRT(const Vector3f &r, const Vector3f &t)
Sets rotation-translation matrix.
static constexpr f32 cos(f32 x)
static constexpr f32 fms(f32 x, f32 y, f32 z)
Fused multiply-subtract operation.
static constexpr f32 finv(f32 x)
Fused Newton-Raphson operation.
static constexpr f32 sin(f32 x)
static constexpr f32 fma(f32 x, f32 y, f32 z)
Fused multiply-add operation.
A quaternion, used to represent 3D rotation.
constexpr void setAxisRotation(f32 angle, const EGG::Vector3f &axis)
Set the quat given angle and axis.
constexpr f32 normalise()
Normalizes the vector and returns the original length.