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);
119 return Matrix(1.0f, sy , 0.0f, 0.0f,
120 sx , 1.0f, 0.0f, 0.0f,
121 0.0f, 0.0f, 1.0f, 0.0f,
122 0.0f, 0.0f, 0.0f, 1.0f);
129 1.0f - 2.0f * q.
y * q.
y - 2.0f * q.
z * q.
z,
130 2.0f * q.
x * q.
y + 2.0f * q.
z * q.
w,
131 2.0f * q.
x * q.
z - 2.0f * q.
y * q.
w,
134 2.0f * q.
x * q.
y - 2.0f * q.
z * q.
w,
135 1.0f - 2.0f * q.
x * q.
x - 2.0f * q.
z * q.
z,
136 2.0f * q.
y * q.
z + 2.0f * q.
x * q.
w,
139 2.0f * q.
x * q.
z + 2.0f * q.
y * q.
w,
140 2.0f * q.
y * q.
z - 2.0f * q.
x * q.
w,
141 1.0f - 2.0f * q.
x * q.
x - 2.0f * q.
y * q.
y,
154 const Vector2 cos_sin = CosSin(radians);
155 const Scalar cosine = cos_sin.
x;
156 const Scalar cosp = 1.0f - cosine;
161 cosine + cosp * v.
x * v.
x,
162 cosp * v.
x * v.
y + v.
z * sine,
163 cosp * v.
x * v.
z - v.
y * sine,
166 cosp * v.
x * v.
y - v.
z * sine,
167 cosine + cosp * v.
y * v.
y,
168 cosp * v.
y * v.
z + v.
x * sine,
171 cosp * v.
x * v.
z + v.
y * sine,
172 cosp * v.
y * v.
z - v.
x * sine,
173 cosine + cosp * v.
z * v.
z,
184 const Vector2 cos_sin = CosSin(r);
185 const Scalar cosine = cos_sin.
x;
190 1.0f, 0.0f, 0.0f, 0.0f,
191 0.0f, cosine, sine, 0.0f,
192 0.0f, -sine, cosine, 0.0f,
193 0.0f, 0.0f, 0.0f, 1.0f
199 const Vector2 cos_sin = CosSin(r);
200 const Scalar cosine = cos_sin.
x;
205 cosine, 0.0f, -sine, 0.0f,
206 0.0f, 1.0f, 0.0f, 0.0f,
207 sine, 0.0f, cosine, 0.0f,
208 0.0f, 0.0f, 0.0f, 1.0f
214 const Vector2 cos_sin = CosSin(r);
215 const Scalar cosine = cos_sin.
x;
220 cosine, sine, 0.0f, 0.0f,
221 -sine, cosine, 0.0f, 0.0f,
222 0.0f, 0.0f, 1.0f, 0.0f,
223 0.0f, 0.0f, 0.0f, 1.0
232 m[0],
m[1],
m[2], 0.0f,
233 m[4],
m[5],
m[6], 0.0f,
234 m[8],
m[9],
m[10], 0.0f,
235 0.0f, 0.0f, 0.0f, 1.0
243 m[4],
m[5],
m[6],
m[7],
244 m[8],
m[9],
m[10],
m[11],
245 m[0] * t.
x +
m[4] * t.
y +
m[8] * t.
z +
m[12],
246 m[1] * t.
x +
m[5] * t.
y +
m[9] * t.
z +
m[13],
247 m[2] * t.
x +
m[6] * t.
y +
m[10] * t.
z +
m[14],
256 m[8] *
s.z,
m[9] *
s.z,
m[10] *
s.z,
m[11] *
s.z,
257 m[12] ,
m[13] ,
m[14] ,
m[15] );
264 m[0] * o.
m[0] +
m[4] * o.
m[1] +
m[8] * o.
m[2] +
m[12] * o.
m[3],
265 m[1] * o.
m[0] +
m[5] * o.
m[1] +
m[9] * o.
m[2] +
m[13] * o.
m[3],
266 m[2] * o.
m[0] +
m[6] * o.
m[1] +
m[10] * o.
m[2] +
m[14] * o.
m[3],
267 m[3] * o.
m[0] +
m[7] * o.
m[1] +
m[11] * o.
m[2] +
m[15] * o.
m[3],
268 m[0] * o.
m[4] +
m[4] * o.
m[5] +
m[8] * o.
m[6] +
m[12] * o.
m[7],
269 m[1] * o.
m[4] +
m[5] * o.
m[5] +
m[9] * o.
m[6] +
m[13] * o.
m[7],
270 m[2] * o.
m[4] +
m[6] * o.
m[5] +
m[10] * o.
m[6] +
m[14] * o.
m[7],
271 m[3] * o.
m[4] +
m[7] * o.
m[5] +
m[11] * o.
m[6] +
m[15] * o.
m[7],
272 m[0] * o.
m[8] +
m[4] * o.
m[9] +
m[8] * o.
m[10] +
m[12] * o.
m[11],
273 m[1] * o.
m[8] +
m[5] * o.
m[9] +
m[9] * o.
m[10] +
m[13] * o.
m[11],
274 m[2] * o.
m[8] +
m[6] * o.
m[9] +
m[10] * o.
m[10] +
m[14] * o.
m[11],
275 m[3] * o.
m[8] +
m[7] * o.
m[9] +
m[11] * o.
m[10] +
m[15] * o.
m[11],
276 m[0] * o.
m[12] +
m[4] * o.
m[13] +
m[8] * o.
m[14] +
m[12] * o.
m[15],
277 m[1] * o.
m[12] +
m[5] * o.
m[13] +
m[9] * o.
m[14] +
m[13] * o.
m[15],
278 m[2] * o.
m[12] +
m[6] * o.
m[13] +
m[10] * o.
m[14] +
m[14] * o.
m[15],
279 m[3] * o.
m[12] +
m[7] * o.
m[13] +
m[11] * o.
m[14] +
m[15] * o.
m[15]);
286 m[0],
m[4],
m[8],
m[12],
287 m[1],
m[5],
m[9],
m[13],
288 m[2],
m[6],
m[10],
m[14],
289 m[3],
m[7],
m[11],
m[15],
301 return std::sqrt(std::max(
e[0][0] *
e[0][0] +
e[0][1] *
e[0][1],
302 e[1][0] *
e[1][0] +
e[1][1] *
e[1][1]));
322 return (
m[2] == 0 &&
m[3] == 0 &&
m[6] == 0 &&
m[7] == 0 &&
m[8] == 0 &&
323 m[9] == 0 &&
m[10] == 1 &&
m[11] == 0 &&
m[14] == 0 &&
m[15] == 1);
327 return m[3] != 0 ||
m[7] != 0 ||
m[15] != 1;
331 return m[3] != 0 ||
m[7] != 0 ||
m[11] != 0 ||
m[15] != 1;
363 if (v[0] + v[1] + v[2] != 1 ||
364 v[3] + v[4] + v[5] != 1 ||
365 v[6] + v[7] + v[8] != 1) {
369 if (v[0] + v[3] + v[6] != 1 ||
370 v[1] + v[4] + v[7] != 1 ||
371 v[2] + v[5] + v[8] != 1) {
380 m[0] == 1.0f &&
m[1] == 0.0f &&
m[2] == 0.0f &&
m[3] == 0.0f &&
381 m[4] == 0.0f &&
m[5] == 1.0f &&
m[6] == 0.0f &&
m[7] == 0.0f &&
382 m[8] == 0.0f &&
m[9] == 0.0f &&
m[10] == 1.0f &&
m[11] == 0.0f &&
383 m[12] == 0.0f &&
m[13] == 0.0f &&
m[14] == 0.0f &&
m[15] == 1.0f
393 m[0] != 0.0 &&
m[1] == 0.0 &&
m[2] == 0.0 &&
m[3] == 0.0 &&
394 m[4] == 0.0 &&
m[5] != 0.0 &&
m[6] == 0.0 &&
m[7] == 0.0 &&
395 m[8] == 0.0 &&
m[9] == 0.0 &&
m[10] != 0.0 &&
m[11] == 0.0 &&
401 std::optional<MatrixDecomposition>
Decompose()
const;
405 return vec[0] ==
m.vec[0]
406 &&
vec[1] ==
m.vec[1]
407 &&
vec[2] ==
m.vec[2]
408 &&
vec[3] ==
m.vec[3];
414 return vec[0] !=
m.vec[0]
415 ||
vec[1] !=
m.vec[1]
416 ||
vec[2] !=
m.vec[2]
417 ||
vec[3] !=
m.vec[3];
431 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9] + v.
w *
m[13],
432 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10] + v.
w *
m[14],
433 v.
x *
m[3] + v.
y *
m[7] + v.
z *
m[11] + v.
w *
m[15]);
439 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9] +
m[13],
440 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10] +
m[14]);
453 v.
x *
m[1] + v.
y *
m[5] +
m[13]);
465 v.
x *
m[1] + v.
y *
m[5] +
m[13],
466 v.
x *
m[3] + v.
y *
m[7] +
m[15]);
471 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9],
472 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10], v.
w);
477 v.
x *
m[1] + v.
y *
m[5] + v.
z *
m[9],
478 v.
x *
m[2] + v.
y *
m[6] + v.
z *
m[10]);
499 -2.0f /
static_cast<Scalar>(size.height), 0.0f});
501 return translate *
scale;
513 1.0f /
width, 0.0f, 0.0f, 0.0f,
514 0.0f, 1.0f /
height, 0.0f, 0.0f,
515 0.0f, 0.0f, z_far / (z_far - z_near), 1.0f,
516 0.0f, 0.0f, -(z_far * z_near) / (z_far - z_near), 0.0f,
540 right.y, up.
y, forward.
y, 0.0f,
541 right.z, up.
z, forward.
z, 0.0f,
542 -
right.Dot(position), -up.
Dot(position), -forward.
Dot(position), 1.0f
571 if (std::abs(sin) == 1.0f) {
576 if (std::abs(cos) == 1.0f) {
585static_assert(
sizeof(
struct Matrix) ==
sizeof(
Scalar) * 16,
586 "The matrix must be of consistent size.");
592 out <<
"(" << std::endl << std::fixed;
593 for (
size_t i = 0; i < 4u; i++) {
594 for (
size_t j = 0; j < 4u; j++) {
595 out << std::setw(15) << m.e[j][i] <<
",";
static bool right(const SkPoint &p0, const SkPoint &p1)
constexpr bool ScalarNearlyZero(Scalar x, Scalar tolerance=kEhCloseEnough)
std::array< Point, 4 > Quad
std::ostream & operator<<(std::ostream &out, const impeller::Color &c)
A 4x4 matrix using column-major storage.
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 Scalar GetMaxBasisLengthXY() const
static constexpr Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
constexpr Matrix Translate(const Vector3 &t) const
constexpr Vector3 GetScale() const
constexpr Vector2 TransformDirection(const Vector2 &v) const
static constexpr Matrix MakeScale(const Vector2 &s)
Matrix operator+(const Vector3 &t) 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
static constexpr Matrix MakeLookAt(Vector3 position, Vector3 target, Vector3 up)
std::optional< MatrixDecomposition > Decompose() const
constexpr bool HasPerspective2D() const
Matrix operator-(const Vector3 &t) const
constexpr Scalar GetDirectionScale(Vector3 direction) const
constexpr Vector4 operator*(const Vector4 &v) const
constexpr bool operator!=(const Matrix &m) const
constexpr Point operator*(const Point &v) const
constexpr Vector3 operator*(const Vector3 &v) const
Scalar GetMaxBasisLength() 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 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)
constexpr Vector4 TransformDirection(const Vector4 &v) const
constexpr Vector3 GetBasisX() const
constexpr bool IsAligned2D(Scalar tolerance=0) const
static Matrix MakeRotation(Quaternion q)
constexpr Matrix Transpose() const
static Matrix MakeRotationX(Radians r)
constexpr Vector3 Cross(const Vector3 &other) const
constexpr Vector3 Normalize() const
constexpr Scalar Length() const
constexpr Scalar Dot(const Vector3 &other) const
Vector4 Normalize() const