16 for (
int i = 0; i < 4; i++) {
23 for (
int i = 0; i < 3; i++) {
24 for (
int j = 0; j < 3; j++) {
44 rotation.
e[0][0] = 1.0 - 2.0 * (y * y + z * z);
45 rotation.
e[0][1] = 2.0 * (
x * y - z * w);
46 rotation.
e[0][2] = 2.0 * (
x * z + y * w);
47 rotation.
e[1][0] = 2.0 * (
x * y + z * w);
48 rotation.
e[1][1] = 1.0 - 2.0 * (
x *
x + z * z);
49 rotation.
e[1][2] = 2.0 * (y * z -
x * w);
50 rotation.
e[2][0] = 2.0 * (
x * z - y * w);
51 rotation.
e[2][1] = 2.0 * (y * z +
x * w);
52 rotation.
e[2][2] = 1.0 - 2.0 * (
x *
x + y * y);
54 *
this = *
this * rotation;
63 *
this = *
this * shear;
69 *
this = *
this * shear;
75 *
this = *
this * shear;
81 for (
int i = 0; i < 3; i++) {
82 for (
int j = 0; j < 3; j++) {
90 m[0] + o.
m[0],
m[1] + o.
m[1],
m[2] + o.
m[2],
m[3] + o.
m[3],
91 m[4] + o.
m[4],
m[5] + o.
m[5],
m[6] + o.
m[6],
m[7] + o.
m[7],
92 m[8] + o.
m[8],
m[9] + o.
m[9],
m[10] + o.
m[10],
m[11] + o.
m[11],
93 m[12] + o.
m[12],
m[13] + o.
m[13],
m[14] + o.
m[14],
m[15] + o.
m[15]
99 m[5] *
m[10] *
m[15] -
m[5] *
m[11] *
m[14] -
m[9] *
m[6] *
m[15] +
100 m[9] *
m[7] *
m[14] +
m[13] *
m[6] *
m[11] -
m[13] *
m[7] *
m[10],
102 -
m[1] *
m[10] *
m[15] +
m[1] *
m[11] *
m[14] +
m[9] *
m[2] *
m[15] -
103 m[9] *
m[3] *
m[14] -
m[13] *
m[2] *
m[11] +
m[13] *
m[3] *
m[10],
105 m[1] *
m[6] *
m[15] -
m[1] *
m[7] *
m[14] -
m[5] *
m[2] *
m[15] +
106 m[5] *
m[3] *
m[14] +
m[13] *
m[2] *
m[7] -
m[13] *
m[3] *
m[6],
108 -
m[1] *
m[6] *
m[11] +
m[1] *
m[7] *
m[10] +
m[5] *
m[2] *
m[11] -
109 m[5] *
m[3] *
m[10] -
m[9] *
m[2] *
m[7] +
m[9] *
m[3] *
m[6],
111 -
m[4] *
m[10] *
m[15] +
m[4] *
m[11] *
m[14] +
m[8] *
m[6] *
m[15] -
112 m[8] *
m[7] *
m[14] -
m[12] *
m[6] *
m[11] +
m[12] *
m[7] *
m[10],
114 m[0] *
m[10] *
m[15] -
m[0] *
m[11] *
m[14] -
m[8] *
m[2] *
m[15] +
115 m[8] *
m[3] *
m[14] +
m[12] *
m[2] *
m[11] -
m[12] *
m[3] *
m[10],
117 -
m[0] *
m[6] *
m[15] +
m[0] *
m[7] *
m[14] +
m[4] *
m[2] *
m[15] -
118 m[4] *
m[3] *
m[14] -
m[12] *
m[2] *
m[7] +
m[12] *
m[3] *
m[6],
120 m[0] *
m[6] *
m[11] -
m[0] *
m[7] *
m[10] -
m[4] *
m[2] *
m[11] +
121 m[4] *
m[3] *
m[10] +
m[8] *
m[2] *
m[7] -
m[8] *
m[3] *
m[6],
123 m[4] *
m[9] *
m[15] -
m[4] *
m[11] *
m[13] -
m[8] *
m[5] *
m[15] +
124 m[8] *
m[7] *
m[13] +
m[12] *
m[5] *
m[11] -
m[12] *
m[7] *
m[9],
126 -
m[0] *
m[9] *
m[15] +
m[0] *
m[11] *
m[13] +
m[8] *
m[1] *
m[15] -
127 m[8] *
m[3] *
m[13] -
m[12] *
m[1] *
m[11] +
m[12] *
m[3] *
m[9],
129 m[0] *
m[5] *
m[15] -
m[0] *
m[7] *
m[13] -
m[4] *
m[1] *
m[15] +
130 m[4] *
m[3] *
m[13] +
m[12] *
m[1] *
m[7] -
m[12] *
m[3] *
m[5],
132 -
m[0] *
m[5] *
m[11] +
m[0] *
m[7] *
m[9] +
m[4] *
m[1] *
m[11] -
133 m[4] *
m[3] *
m[9] -
m[8] *
m[1] *
m[7] +
m[8] *
m[3] *
m[5],
135 -
m[4] *
m[9] *
m[14] +
m[4] *
m[10] *
m[13] +
m[8] *
m[5] *
m[14] -
136 m[8] *
m[6] *
m[13] -
m[12] *
m[5] *
m[10] +
m[12] *
m[6] *
m[9],
138 m[0] *
m[9] *
m[14] -
m[0] *
m[10] *
m[13] -
m[8] *
m[1] *
m[14] +
139 m[8] *
m[2] *
m[13] +
m[12] *
m[1] *
m[10] -
m[12] *
m[2] *
m[9],
141 -
m[0] *
m[5] *
m[14] +
m[0] *
m[6] *
m[13] +
m[4] *
m[1] *
m[14] -
142 m[4] *
m[2] *
m[13] -
m[12] *
m[1] *
m[6] +
m[12] *
m[2] *
m[5],
144 m[0] *
m[5] *
m[10] -
m[0] *
m[6] *
m[9] -
m[4] *
m[1] *
m[10] +
145 m[4] *
m[2] *
m[9] +
m[8] *
m[1] *
m[6] -
m[8] *
m[2] *
m[5]};
148 m[0] * tmp.m[0] +
m[1] * tmp.m[4] +
m[2] * tmp.m[8] +
m[3] * tmp.m[12];
156 return {tmp.m[0] * det, tmp.m[1] * det, tmp.m[2] * det, tmp.m[3] * det,
157 tmp.m[4] * det, tmp.m[5] * det, tmp.m[6] * det, tmp.m[7] * det,
158 tmp.m[8] * det, tmp.m[9] * det, tmp.m[10] * det, tmp.m[11] * det,
159 tmp.m[12] * det, tmp.m[13] * det, tmp.m[14] * det, tmp.m[15] * det};
180 auto b00 = a00 * a11 - a01 * a10;
181 auto b01 = a00 * a12 - a02 * a10;
182 auto b02 = a00 * a13 - a03 * a10;
183 auto b03 = a01 * a12 - a02 * a11;
184 auto b04 = a01 * a13 - a03 * a11;
185 auto b05 = a02 * a13 - a03 * a12;
186 auto b06 = a20 * a31 - a21 * a30;
187 auto b07 = a20 * a32 - a22 * a30;
188 auto b08 = a20 * a33 - a23 * a30;
189 auto b09 = a21 * a32 - a22 * a31;
190 auto b10 = a21 * a33 - a23 * a31;
191 auto b11 = a22 * a33 - a23 * a32;
193 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
206 if (
self.
e[3][3] == 0) {
210 for (
int i = 0; i < 4; i++) {
211 for (
int j = 0; j < 4; j++) {
212 self.
e[i][j] /=
self.e[3][3];
220 Matrix perpectiveMatrix =
self;
221 for (
int i = 0; i < 3; i++) {
222 perpectiveMatrix.
e[i][3] = 0;
225 perpectiveMatrix.
e[3][3] = 1;
238 if (
self.
e[0][3] != 0.0 ||
self.
e[1][3] != 0.0 ||
self.
e[2][3] != 0.0) {
242 const Vector4 rightHandSide(
self.
e[0][3],
257 self.
e[0][3] =
self.e[1][3] =
self.e[2][3] = 0;
266 result.
translation = {
self.
e[3][0],
self.e[3][1],
self.e[3][2]};
267 self.e[3][0] =
self.e[3][1] =
self.e[3][2] = 0.0;
275 for (
int i = 0; i < 3; i++) {
276 row[i].
x =
self.e[i][0];
277 row[i].
y =
self.e[i][1];
278 row[i].
z =
self.e[i][2];
322 if (row[0].Dot(row[1].Cross(row[2])) < 0) {
327 for (
int i = 0; i < 3; i++) {
340 0.5 * sqrt(fmax(1.0 + row[0].
x - row[1].y - row[2].z, 0.0));
342 0.5 * sqrt(fmax(1.0 - row[0].
x + row[1].y - row[2].z, 0.0));
344 0.5 * sqrt(fmax(1.0 - row[0].
x - row[1].y + row[2].z, 0.0));
346 0.5 * sqrt(fmax(1.0 + row[0].
x + row[1].y + row[2].z, 0.0));
348 if (row[2].y > row[1].z) {
351 if (row[0].z > row[2].
x) {
354 if (row[1].
x > row[0].y) {
369 Vector4 defaultPerspective(0.0, 0.0, 0.0, 1.0);
374 Shear noShear(0.0, 0.0, 0.0);
375 if (
shear != noShear) {
379 Vector3 defaultScale(1.0, 1.0, 1.0);
380 if (
scale != defaultScale) {
384 Vector3 defaultTranslation(0.0, 0.0, 0.0);
uint64_t GetComponentsMask() const
A 4x4 matrix using column-major storage.
bool IsInvertible() const
Matrix operator+(const Vector3 &t) const
std::optional< MatrixDecomposition > Decompose() const
Scalar GetDeterminant() const
constexpr Matrix Transpose() const
Vector3 Normalize() const
static constexpr Vector3 Combine(const Vector3 &a, Scalar aScale, const Vector3 &b, Scalar bScale)
constexpr Scalar Dot(const Vector3 &other) const