5 #ifndef FLUTTER_IMPELLER_GEOMETRY_MATRIX_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_MATRIX_H_
50 Vector4(0.0f, 1.0f, 0.0f, 0.0f),
51 Vector4(0.0f, 0.0f, 1.0f, 0.0f),
52 Vector4(0.0f, 0.0f, 0.0f, 1.0f)} {}
74 return Matrix(m0, m1, m2, m3,
88 return Matrix(m0, m4, m8, m12,
97 return Matrix(1.0f, 0.0f, 0.0f, 0.0f,
98 0.0f, 1.0f, 0.0f, 0.0f,
99 0.0f, 0.0f, 1.0f, 0.0f,
100 t.
x, t.
y, t.
z, 1.0f);
106 return Matrix(s.
x, 0.0f, 0.0f, 0.0f,
107 0.0f, s.
y, 0.0f, 0.0f,
108 0.0f, 0.0f, s.
z, 0.0f,
109 0.0f, 0.0f, 0.0f, 1.0f);
116 return Matrix(s.
x, 0.0f, 0.0f, 0.0f,
117 0.0f, s.
y, 0.0f, 0.0f,
118 0.0f, 0.0f, s.
z, 0.0f,
119 t.
x , t.
y, t.
z, 1.0f);
129 return Matrix(1.0f, sy , 0.0f, 0.0f,
130 sx , 1.0f, 0.0f, 0.0f,
131 0.0f, 0.0f, 1.0f, 0.0f,
132 0.0f, 0.0f, 0.0f, 1.0f);
139 1.0f - 2.0f * q.
y * q.
y - 2.0f * q.
z * q.
z,
140 2.0f * q.
x * q.
y + 2.0f * q.
z * q.
w,
141 2.0f * q.
x * q.
z - 2.0f * q.
y * q.
w,
144 2.0f * q.
x * q.
y - 2.0f * q.
z * q.
w,
145 1.0f - 2.0f * q.
x * q.
x - 2.0f * q.
z * q.
z,
146 2.0f * q.
y * q.
z + 2.0f * q.
x * q.
w,
149 2.0f * q.
x * q.
z + 2.0f * q.
y * q.
w,
150 2.0f * q.
y * q.
z - 2.0f * q.
x * q.
w,
151 1.0f - 2.0f * q.
x * q.
x - 2.0f * q.
y * q.
y,
165 const Scalar cosine = cos_sin.
x;
166 const Scalar cosp = 1.0f - cosine;
171 cosine + cosp * v.
x * v.
x,
172 cosp * v.
x * v.
y + v.
z * sine,
173 cosp * v.
x * v.
z - v.
y * sine,
176 cosp * v.
x * v.
y - v.
z * sine,
177 cosine + cosp * v.
y * v.
y,
178 cosp * v.
y * v.
z + v.
x * sine,
181 cosp * v.
x * v.
z + v.
y * sine,
182 cosp * v.
y * v.
z - v.
x * sine,
183 cosine + cosp * v.
z * v.
z,
195 const Scalar cosine = cos_sin.
x;
200 1.0f, 0.0f, 0.0f, 0.0f,
201 0.0f, cosine, sine, 0.0f,
202 0.0f, -sine, cosine, 0.0f,
203 0.0f, 0.0f, 0.0f, 1.0f
210 const Scalar cosine = cos_sin.
x;
215 cosine, 0.0f, -sine, 0.0f,
216 0.0f, 1.0f, 0.0f, 0.0f,
217 sine, 0.0f, cosine, 0.0f,
218 0.0f, 0.0f, 0.0f, 1.0f
225 const Scalar cosine = cos_sin.
x;
230 cosine, sine, 0.0f, 0.0f,
231 -sine, cosine, 0.0f, 0.0f,
232 0.0f, 0.0f, 1.0f, 0.0f,
233 0.0f, 0.0f, 0.0f, 1.0
242 m[0],
m[1],
m[2], 0.0f,
243 m[4],
m[5],
m[6], 0.0f,
244 m[8],
m[9],
m[10], 0.0f,
245 0.0f, 0.0f, 0.0f, 1.0
258 m[12],
m[13], 0,
m[15]
266 m[4],
m[5],
m[6],
m[7],
267 m[8],
m[9],
m[10],
m[11],
268 m[0] * t.
x +
m[4] * t.
y +
m[8] * t.
z +
m[12],
269 m[1] * t.
x +
m[5] * t.
y +
m[9] * t.
z +
m[13],
270 m[2] * t.
x +
m[6] * t.
y +
m[10] * t.
z +
m[14],
271 m[3] * t.
x +
m[7] * t.
y +
m[11] * t.
z +
m[15]);
278 m[4] * s.
y,
m[5] * s.
y,
m[6] * s.
y,
m[7] * s.
y,
279 m[8] * s.
z,
m[9] * s.
z,
m[10] * s.
z,
m[11] * s.
z,
280 m[12] ,
m[13] ,
m[14] ,
m[15] );
287 m[0] * o.
m[0] +
m[4] * o.
m[1] +
m[8] * o.
m[2] +
m[12] * o.
m[3],
288 m[1] * o.
m[0] +
m[5] * o.
m[1] +
m[9] * o.
m[2] +
m[13] * o.
m[3],
289 m[2] * o.
m[0] +
m[6] * o.
m[1] +
m[10] * o.
m[2] +
m[14] * o.
m[3],
290 m[3] * o.
m[0] +
m[7] * o.
m[1] +
m[11] * o.
m[2] +
m[15] * o.
m[3],
291 m[0] * o.
m[4] +
m[4] * o.
m[5] +
m[8] * o.
m[6] +
m[12] * o.
m[7],
292 m[1] * o.
m[4] +
m[5] * o.
m[5] +
m[9] * o.
m[6] +
m[13] * o.
m[7],
293 m[2] * o.
m[4] +
m[6] * o.
m[5] +
m[10] * o.
m[6] +
m[14] * o.
m[7],
294 m[3] * o.
m[4] +
m[7] * o.
m[5] +
m[11] * o.
m[6] +
m[15] * o.
m[7],
295 m[0] * o.
m[8] +
m[4] * o.
m[9] +
m[8] * o.
m[10] +
m[12] * o.
m[11],
296 m[1] * o.
m[8] +
m[5] * o.
m[9] +
m[9] * o.
m[10] +
m[13] * o.
m[11],
297 m[2] * o.
m[8] +
m[6] * o.
m[9] +
m[10] * o.
m[10] +
m[14] * o.
m[11],
298 m[3] * o.
m[8] +
m[7] * o.
m[9] +
m[11] * o.
m[10] +
m[15] * o.
m[11],
299 m[0] * o.
m[12] +
m[4] * o.
m[13] +
m[8] * o.
m[14] +
m[12] * o.
m[15],
300 m[1] * o.
m[12] +
m[5] * o.
m[13] +
m[9] * o.
m[14] +
m[13] * o.
m[15],
301 m[2] * o.
m[12] +
m[6] * o.
m[13] +
m[10] * o.
m[14] +
m[14] * o.
m[15],
302 m[3] * o.
m[12] +
m[7] * o.
m[13] +
m[11] * o.
m[14] +
m[15] * o.
m[15]);
309 m[0],
m[4],
m[8],
m[12],
310 m[1],
m[5],
m[9],
m[13],
311 m[2],
m[6],
m[10],
m[14],
312 m[3],
m[7],
m[11],
m[15],
328 if (
e[0][1] == 0 &&
e[1][0] == 0) {
329 return std::max(std::abs(
e[0][0]), std::abs(
e[1][1]));
331 return std::sqrt(std::max(
e[0][0] *
e[0][0] +
e[0][1] *
e[0][1],
332 e[1][0] *
e[1][0] +
e[1][1] *
e[1][1]));
357 return (
m[2] == 0 &&
m[3] == 0 &&
m[6] == 0 &&
m[7] == 0 &&
m[8] == 0 &&
358 m[9] == 0 &&
m[10] == 1 &&
m[11] == 0 &&
m[14] == 0 &&
m[15] == 1);
362 return m[3] != 0 ||
m[7] != 0 ||
m[15] != 1;
366 return m[3] != 0 ||
m[7] != 0 ||
m[11] != 0 ||
m[15] != 1;
400 if (v[0] + v[1] + v[2] != 1 ||
401 v[3] + v[4] + v[5] != 1 ||
402 v[6] + v[7] + v[8] != 1) {
406 if (v[0] + v[3] + v[6] != 1 ||
407 v[1] + v[4] + v[7] != 1 ||
408 v[2] + v[5] + v[8] != 1) {
417 m[0] == 1.0f &&
m[1] == 0.0f &&
m[2] == 0.0f &&
m[3] == 0.0f &&
418 m[4] == 0.0f &&
m[5] == 1.0f &&
m[6] == 0.0f &&
m[7] == 0.0f &&
419 m[8] == 0.0f &&
m[9] == 0.0f &&
m[10] == 1.0f &&
m[11] == 0.0f &&
420 m[12] == 0.0f &&
m[13] == 0.0f &&
m[14] == 0.0f &&
m[15] == 1.0f
430 m[0] == 1.0 &&
m[1] == 0.0 &&
m[2] == 0.0 &&
m[3] == 0.0 &&
431 m[4] == 0.0 &&
m[5] == 1.0 &&
m[6] == 0.0 &&
m[7] == 0.0 &&
432 m[8] == 0.0 &&
m[9] == 0.0 &&
m[10] == 1.0 &&
m[11] == 0.0 &&
443 m[0] != 0.0 &&
m[1] == 0.0 &&
m[2] == 0.0 &&
m[3] == 0.0 &&
444 m[4] == 0.0 &&
m[5] != 0.0 &&
m[6] == 0.0 &&
m[7] == 0.0 &&
445 m[8] == 0.0 &&
m[9] == 0.0 &&
m[10] != 0.0 &&
m[11] == 0.0 &&
451 std::optional<MatrixDecomposition>
Decompose()
const;
476 return vec[0] ==
m.vec[0]
477 &&
vec[1] ==
m.vec[1]
478 &&
vec[2] ==
m.vec[2]
479 &&
vec[3] ==
m.vec[3];
485 return vec[0] !=
m.vec[0]
486 ||
vec[1] !=
m.vec[1]
487 ||
vec[2] !=
m.vec[2]
488 ||
vec[3] !=
m.vec[3];
502 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9] + v.
w *
m[13],
503 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10] + v.
w *
m[14],
504 v.
x *
m[3] + v.
y *
m[7] + v.
z *
m[11] + v.
w *
m[15]);
510 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9] +
m[13],
511 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10] +
m[14]);
524 v.
x *
m[1] + v.
y *
m[5] +
m[13]);
536 v.
x *
m[1] + v.
y *
m[5] +
m[13],
537 v.
x *
m[3] + v.
y *
m[7] +
m[15]);
542 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9],
543 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10], v.
w);
548 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9],
549 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10]);
572 return translate * scale;
580 Scalar width = height * aspect_ratio;
584 1.0f / width, 0.0f, 0.0f, 0.0f,
585 0.0f, 1.0f / height, 0.0f, 0.0f,
586 0.0f, 0.0f, z_far / (z_far - z_near), 1.0f,
587 0.0f, 0.0f, -(z_far * z_near) / (z_far - z_near), 0.0f,
604 Vector3 forward = (target - position).Normalize();
606 up = forward.
Cross(right);
610 right.
x, up.
x, forward.
x, 0.0f,
611 right.
y, up.
y, forward.
y, 0.0f,
612 right.
z, up.
z, forward.
z, 0.0f,
613 -right.
Dot(position), -up.
Dot(position), -forward.
Dot(position), 1.0f
641 if (std::abs(sin) == 1.0f) {
646 if (std::abs(cos) == 1.0f) {
655 static_assert(
sizeof(
struct Matrix) ==
sizeof(
Scalar) * 16,
656 "The matrix must be of consistent size.");
662 out <<
"(" << std::endl << std::fixed;
663 for (
size_t i = 0; i < 4u; i++) {
664 for (
size_t j = 0; j < 4u; j++) {
665 out << std::setw(15) << m.
e[j][i] <<
",";
constexpr bool ScalarNearlyZero(Scalar x, Scalar tolerance=kEhCloseEnough)
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
std::array< Point, 4 > Quad
std::ostream & operator<<(std::ostream &out, const impeller::Arc &a)
A 4x4 matrix using column-major storage.
constexpr bool IsTranslationOnly() const
Returns true if the matrix has no entries other than translation components. Note that an identity ma...
static constexpr Matrix MakeOrthographic(TSize< T > size)
constexpr Matrix Multiply(const Matrix &o) const
constexpr bool IsAffine() const
static constexpr Matrix MakeTranslation(const Vector3 &t)
constexpr Vector3 GetBasisY() const
constexpr bool IsIdentity() const
constexpr bool IsTranslationScaleOnly() const
Returns true if the matrix has a scale-only basis and is non-projective. Note that an identity matrix...
constexpr bool HasTranslation() const
constexpr Matrix Translate(const Vector3 &t) const
bool IsInvertible() const
constexpr Vector2 TransformDirection(const Vector2 &v) const
static constexpr Matrix MakeScale(const Vector2 &s)
Matrix operator+(const Vector3 &t) const
Scalar GetDirectionScale(Vector3 direction) const
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
constexpr Matrix(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Matrix operator*(const Matrix &m) const
constexpr bool IsAligned(Scalar tolerance=0) const
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static Matrix MakeRotationY(Radians r)
constexpr Vector3 GetBasisZ() const
std::optional< MatrixDecomposition > Decompose() const
constexpr bool HasPerspective2D() const
Matrix operator-(const Vector3 &t) const
constexpr Vector4 operator*(const Vector4 &v) const
static Vector2 CosSin(Radians radians)
constexpr bool operator!=(const Matrix &m) const
static Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
constexpr Point operator*(const Point &v) const
constexpr Vector3 operator*(const Vector3 &v) const
constexpr Vector3 TransformDirection(const Vector3 &v) const
static constexpr Matrix MakeRow(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
constexpr Quad Transform(const Quad &quad) const
constexpr bool operator==(const Matrix &m) const
constexpr Matrix Scale(const Vector3 &s) const
constexpr Vector3 TransformHomogenous(const Point &v) const
static constexpr Matrix MakeTranslateScale(const Vector3 &s, const Vector3 &t)
static Matrix MakeRotationZ(Radians r)
static Matrix MakeRotation(Radians radians, const Vector4 &r)
static constexpr Matrix MakePerspective(Radians fov_y, TSize< T > size, Scalar z_near, Scalar z_far)
Scalar GetDeterminant() const
constexpr bool HasPerspective() const
static constexpr Matrix MakeScale(const Vector3 &s)
static Matrix MakeLookAt(Vector3 position, Vector3 target, Vector3 up)
constexpr Vector4 TransformDirection(const Vector4 &v) const
constexpr Vector3 GetBasisX() const
bool Equals(const Matrix &matrix, Scalar epsilon=1e-5f) const
constexpr Matrix To3x3() const
constexpr bool IsAligned2D(Scalar tolerance=0) const
static Matrix MakeRotation(Quaternion q)
constexpr Matrix Transpose() const
Scalar GetMaxBasisLengthXY() const
static Matrix MakeRotationX(Radians r)
Vector3 Normalize() const
constexpr Vector3 Cross(const Vector3 &other) const
constexpr Scalar Dot(const Vector3 &other) const
Vector4 Normalize() const