| Flutter Impeller |

matrix.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_GEOMETRY_MATRIX_H_
6 #define FLUTTER_IMPELLER_GEOMETRY_MATRIX_H_
7
8 #include <cmath>
9 #include <iomanip>
10 #include <limits>
11 #include <optional>
12 #include <ostream>
13 #include <utility>
14
15 #include "impeller/geometry/matrix_decomposition.h"
16 #include "impeller/geometry/point.h"
17 #include "impeller/geometry/quaternion.h"
18 #include "impeller/geometry/scalar.h"
19 #include "impeller/geometry/shear.h"
20 #include "impeller/geometry/size.h"
21 #include "impeller/geometry/vector.h"
22
23 namespace impeller {
24
25 //------------------------------------------------------------------------------
26 /// @brief A 4x4 matrix using column-major storage.
27 ///
28 /// Utility methods that need to make assumptions about normalized
29 /// device coordinates must use the following convention:
30 /// * Left-handed coordinate system. Positive rotation is
31 /// clockwise about axis of rotation.
32 /// * Lower left corner is -1.0f, -1.0.
33 /// * Upper right corner is 1.0f, 1.0.
34 /// * Visible z-space is from 0.0 to 1.0.
35 /// * This is NOT the same as OpenGL! Be careful.
36 /// * NDC origin is at (0.0f, 0.0f, 0.5f).
37 struct Matrix {
38 union {
39 Scalar m[16];
40 Scalar e[4][4];
41 Vector4 vec[4];
42 };
43
44 //----------------------------------------------------------------------------
45 /// Constructs a default identity matrix.
46 ///
47 constexpr Matrix()
48 // clang-format off
49 : vec{ Vector4(1.0f, 0.0f, 0.0f, 0.0f),
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)} {}
53 // clang-format on
54
55 // clang-format off
56 constexpr Matrix(Scalar m0, Scalar m1, Scalar m2, Scalar m3,
57 Scalar m4, Scalar m5, Scalar m6, Scalar m7,
58 Scalar m8, Scalar m9, Scalar m10, Scalar m11,
59 Scalar m12, Scalar m13, Scalar m14, Scalar m15)
60 : vec{Vector4(m0, m1, m2, m3),
61 Vector4(m4, m5, m6, m7),
62 Vector4(m8, m9, m10, m11),
63 Vector4(m12, m13, m14, m15)} {}
64 // clang-format on
65
66 explicit Matrix(const MatrixDecomposition& decomposition);
67
68 // clang-format off
69 static constexpr Matrix MakeColumn(
70 Scalar m0, Scalar m1, Scalar m2, Scalar m3,
71 Scalar m4, Scalar m5, Scalar m6, Scalar m7,
72 Scalar m8, Scalar m9, Scalar m10, Scalar m11,
73 Scalar m12, Scalar m13, Scalar m14, Scalar m15){
74 return Matrix(m0, m1, m2, m3,
75 m4, m5, m6, m7,
76 m8, m9, m10, m11,
77 m12, m13, m14, m15);
78
79 }
80 // clang-format on
81
82 // clang-format off
83 static constexpr Matrix MakeRow(
84 Scalar m0, Scalar m1, Scalar m2, Scalar m3,
85 Scalar m4, Scalar m5, Scalar m6, Scalar m7,
86 Scalar m8, Scalar m9, Scalar m10, Scalar m11,
87 Scalar m12, Scalar m13, Scalar m14, Scalar m15){
88 return Matrix(m0, m4, m8, m12,
89 m1, m5, m9, m13,
90 m2, m6, m10, m14,
91 m3, m7, m11, m15);
92 }
93 // clang-format on
94
95 static constexpr Matrix MakeTranslation(const Vector3& t) {
96 // clang-format off
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);
101 // clang-format on
102 }
103
104 static constexpr Matrix MakeScale(const Vector3& s) {
105 // clang-format off
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);
110 // clang-format on
111 }
112
113 static constexpr Matrix MakeScale(const Vector2& s) {
114 return MakeScale(Vector3(s.x, s.y, 1.0f));
115 }
116
117 static constexpr Matrix MakeSkew(Scalar sx, Scalar sy) {
118 // clang-format off
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);
123 // clang-format on
124 }
125
126 static Matrix MakeRotation(Quaternion q) {
127 // clang-format off
128 return Matrix(
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,
132 0.0f,
133
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,
137 0.0f,
138
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,
142 0.0f,
143
144 0.0f,
145 0.0f,
146 0.0f,
147 1.0f);
148 // clang-format on
149 }
150
151 static Matrix MakeRotation(Radians radians, const Vector4& r) {
152 const Vector4 v = r.Normalize();
153
154 const Vector2 cos_sin = CosSin(radians);
155 const Scalar cosine = cos_sin.x;
156 const Scalar cosp = 1.0f - cosine;
157 const Scalar sine = cos_sin.y;
158
159 // clang-format off
160 return Matrix(
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,
164 0.0f,
165
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,
169 0.0f,
170
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,
174 0.0f,
175
176 0.0f,
177 0.0f,
178 0.0f,
179 1.0f);
180 // clang-format on
181 }
182
183 static Matrix MakeRotationX(Radians r) {
184 const Vector2 cos_sin = CosSin(r);
185 const Scalar cosine = cos_sin.x;
186 const Scalar sine = cos_sin.y;
187
188 // clang-format off
189 return Matrix(
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
194 );
195 // clang-format on
196 }
197
198 static Matrix MakeRotationY(Radians r) {
199 const Vector2 cos_sin = CosSin(r);
200 const Scalar cosine = cos_sin.x;
201 const Scalar sine = cos_sin.y;
202
203 // clang-format off
204 return Matrix(
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
209 );
210 // clang-format on
211 }
212
213 static Matrix MakeRotationZ(Radians r) {
214 const Vector2 cos_sin = CosSin(r);
215 const Scalar cosine = cos_sin.x;
216 const Scalar sine = cos_sin.y;
217
218 // clang-format off
219 return Matrix (
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
224 );
225 // clang-format on
226 }
227
228 /// The Matrix without its `w` components (without translation).
229 constexpr Matrix Basis() const {
230 // clang-format off
231 return Matrix(
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
236 );
237 // clang-format on
238 }
239
240 constexpr Matrix Translate(const Vector3& t) const {
241 // clang-format off
242 return Matrix(m[0], m[1], m[2], m[3],
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],
248 m[15]);
249 // clang-format on
250 }
251
252 constexpr Matrix Scale(const Vector3& s) const {
253 // clang-format off
254 return Matrix(m[0] * s.x, m[1] * s.x, m[2] * s.x, m[3] * s.x,
255 m[4] * s.y, m[5] * s.y, m[6] * s.y, m[7] * s.y,
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] );
258 // clang-format on
259 }
260
261 constexpr Matrix Multiply(const Matrix& o) const {
262 // clang-format off
263 return Matrix(
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]);
280 // clang-format on
281 }
282
283 constexpr Matrix Transpose() const {
284 // clang-format off
285 return {
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],
290 };
291 // clang-format on
292 }
293
294 Matrix Invert() const;
295
296 Scalar GetDeterminant() const;
297
298 Scalar GetMaxBasisLength() const;
299
300 constexpr Scalar GetMaxBasisLengthXY() const {
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]));
303 }
304
305 constexpr Vector3 GetBasisX() const { return Vector3(m[0], m[1], m[2]); }
306
307 constexpr Vector3 GetBasisY() const { return Vector3(m[4], m[5], m[6]); }
308
309 constexpr Vector3 GetBasisZ() const { return Vector3(m[8], m[9], m[10]); }
310
311 constexpr Vector3 GetScale() const {
312 return Vector3(GetBasisX().Length(), GetBasisY().Length(),
313 GetBasisZ().Length());
314 }
315
316 constexpr Scalar GetDirectionScale(Vector3 direction) const {
317 return 1.0f / (this->Basis().Invert() * direction.Normalize()).Length() *
318 direction.Length();
319 }
320
321 constexpr bool IsAffine() const {
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);
324 }
325
326 constexpr bool HasPerspective2D() const {
327 return m[3] != 0 || m[7] != 0 || m[15] != 1;
328 }
329
330 constexpr bool HasPerspective() const {
331 return m[3] != 0 || m[7] != 0 || m[11] != 0 || m[15] != 1;
332 }
333
334 constexpr bool HasTranslation() const { return m[12] != 0 || m[13] != 0; }
335
336 constexpr bool IsAligned2D(Scalar tolerance = 0) const {
337 if (HasPerspective2D()) {
338 return false;
339 }
340 if (ScalarNearlyZero(m[1], tolerance) &&
341 ScalarNearlyZero(m[4], tolerance)) {
342 return true;
343 }
344 if (ScalarNearlyZero(m[0], tolerance) &&
345 ScalarNearlyZero(m[5], tolerance)) {
346 return true;
347 }
348 return false;
349 }
350
351 constexpr bool IsAligned(Scalar tolerance = 0) const {
352 if (HasPerspective()) {
353 return false;
354 }
355 int v[] = {!ScalarNearlyZero(m[0], tolerance), //
356 !ScalarNearlyZero(m[1], tolerance), //
357 !ScalarNearlyZero(m[2], tolerance), //
358 !ScalarNearlyZero(m[4], tolerance), //
359 !ScalarNearlyZero(m[5], tolerance), //
360 !ScalarNearlyZero(m[6], tolerance), //
361 !ScalarNearlyZero(m[8], tolerance), //
362 !ScalarNearlyZero(m[9], tolerance), //
363 !ScalarNearlyZero(m[10], tolerance)};
364 // Check if all three basis vectors are aligned to an axis.
365 if (v[0] + v[1] + v[2] != 1 || //
366 v[3] + v[4] + v[5] != 1 || //
367 v[6] + v[7] + v[8] != 1) {
368 return false;
369 }
370 // Ensure that none of the basis vectors overlap.
371 if (v[0] + v[3] + v[6] != 1 || //
372 v[1] + v[4] + v[7] != 1 || //
373 v[2] + v[5] + v[8] != 1) {
374 return false;
375 }
376 return true;
377 }
378
379 constexpr bool IsIdentity() const {
380 return (
381 // clang-format off
382 m[0] == 1.0f && m[1] == 0.0f && m[2] == 0.0f && m[3] == 0.0f &&
383 m[4] == 0.0f && m[5] == 1.0f && m[6] == 0.0f && m[7] == 0.0f &&
384 m[8] == 0.0f && m[9] == 0.0f && m[10] == 1.0f && m[11] == 0.0f &&
385 m[12] == 0.0f && m[13] == 0.0f && m[14] == 0.0f && m[15] == 1.0f
386 // clang-format on
387 );
388 }
389
390 /// @brief Returns true if the matrix has a scale-only basis and is
391 /// non-projective. Note that an identity matrix meets this criteria.
392 constexpr bool IsTranslationScaleOnly() const {
393 return (
394 // clang-format off
395 m[0] != 0.0 && m[1] == 0.0 && m[2] == 0.0 && m[3] == 0.0 &&
396 m[4] == 0.0 && m[5] != 0.0 && m[6] == 0.0 && m[7] == 0.0 &&
397 m[8] == 0.0 && m[9] == 0.0 && m[10] != 0.0 && m[11] == 0.0 &&
398 m[15] == 1.0
399 // clang-format on
400 );
401 }
402
403 std::optional<MatrixDecomposition> Decompose() const;
404
405 constexpr bool operator==(const Matrix& m) const {
406 // clang-format off
407 return vec[0] == m.vec[0]
408 && vec[1] == m.vec[1]
409 && vec[2] == m.vec[2]
410 && vec[3] == m.vec[3];
411 // clang-format on
412 }
413
414 constexpr bool operator!=(const Matrix& m) const {
415 // clang-format off
416 return vec[0] != m.vec[0]
417 || vec[1] != m.vec[1]
418 || vec[2] != m.vec[2]
419 || vec[3] != m.vec[3];
420 // clang-format on
421 }
422
423 Matrix operator+(const Vector3& t) const { return Translate(t); }
424
425 Matrix operator-(const Vector3& t) const { return Translate(-t); }
426
427 Matrix operator*(const Matrix& m) const { return Multiply(m); }
428
429 Matrix operator+(const Matrix& m) const;
430
431 constexpr Vector4 operator*(const Vector4& v) const {
432 return Vector4(v.x * m[0] + v.y * m[4] + v.z * m[8] + v.w * m[12],
433 v.x * m[1] + v.y * m[5] + v.z * m[9] + v.w * m[13],
434 v.x * m[2] + v.y * m[6] + v.z * m[10] + v.w * m[14],
435 v.x * m[3] + v.y * m[7] + v.z * m[11] + v.w * m[15]);
436 }
437
438 constexpr Vector3 operator*(const Vector3& v) const {
439 Scalar w = v.x * m[3] + v.y * m[7] + v.z * m[11] + m[15];
440 Vector3 result(v.x * m[0] + v.y * m[4] + v.z * m[8] + m[12],
441 v.x * m[1] + v.y * m[5] + v.z * m[9] + m[13],
442 v.x * m[2] + v.y * m[6] + v.z * m[10] + m[14]);
443
444 // This is Skia's behavior, but it may be reasonable to allow UB for the w=0
445 // case.
446 if (w) {
447 w = 1 / w;
448 }
449 return result * w;
450 }
451
452 constexpr Point operator*(const Point& v) const {
453 Scalar w = v.x * m[3] + v.y * m[7] + m[15];
454 Point result(v.x * m[0] + v.y * m[4] + m[12],
455 v.x * m[1] + v.y * m[5] + m[13]);
456
457 // This is Skia's behavior, but it may be reasonable to allow UB for the w=0
458 // case.
459 if (w) {
460 w = 1 / w;
461 }
462 return result * w;
463 }
464
465 constexpr Vector3 TransformHomogenous(const Point& v) const {
466 return Vector3(v.x * m[0] + v.y * m[4] + m[12],
467 v.x * m[1] + v.y * m[5] + m[13],
468 v.x * m[3] + v.y * m[7] + m[15]);
469 }
470
471 constexpr Vector4 TransformDirection(const Vector4& v) const {
472 return Vector4(v.x * m[0] + v.y * m[4] + v.z * m[8],
473 v.x * m[1] + v.y * m[5] + v.z * m[9],
474 v.x * m[2] + v.y * m[6] + v.z * m[10], v.w);
475 }
476
477 constexpr Vector3 TransformDirection(const Vector3& v) const {
478 return Vector3(v.x * m[0] + v.y * m[4] + v.z * m[8],
479 v.x * m[1] + v.y * m[5] + v.z * m[9],
480 v.x * m[2] + v.y * m[6] + v.z * m[10]);
481 }
482
483 constexpr Vector2 TransformDirection(const Vector2& v) const {
484 return Vector2(v.x * m[0] + v.y * m[4], v.x * m[1] + v.y * m[5]);
485 }
486
487 constexpr Quad Transform(const Quad& quad) const {
488 return {
489 *this * quad[0],
490 *this * quad[1],
491 *this * quad[2],
492 *this * quad[3],
493 };
494 }
495
496 template <class T>
497 static constexpr Matrix MakeOrthographic(TSize<T> size) {
498 // Per assumptions about NDC documented above.
499 const auto scale =
500 MakeScale({2.0f / static_cast<Scalar>(size.width),
501 -2.0f / static_cast<Scalar>(size.height), 0.0f});
502 const auto translate = MakeTranslation({-1.0f, 1.0f, 0.5f});
503 return translate * scale;
504 }
505
506 static constexpr Matrix MakePerspective(Radians fov_y,
507 Scalar aspect_ratio,
508 Scalar z_near,
509 Scalar z_far) {
510 Scalar height = std::tan(fov_y.radians * 0.5f);
511 Scalar width = height * aspect_ratio;
512
513 // clang-format off
514 return {
515 1.0f / width, 0.0f, 0.0f, 0.0f,
516 0.0f, 1.0f / height, 0.0f, 0.0f,
517 0.0f, 0.0f, z_far / (z_far - z_near), 1.0f,
518 0.0f, 0.0f, -(z_far * z_near) / (z_far - z_near), 0.0f,
519 };
520 // clang-format on
521 }
522
523 template <class T>
524 static constexpr Matrix MakePerspective(Radians fov_y,
525 TSize<T> size,
526 Scalar z_near,
527 Scalar z_far) {
528 return MakePerspective(fov_y, static_cast<Scalar>(size.width) / size.height,
529 z_near, z_far);
530 }
531
532 static constexpr Matrix MakeLookAt(Vector3 position,
533 Vector3 target,
534 Vector3 up) {
535 Vector3 forward = (target - position).Normalize();
536 Vector3 right = up.Cross(forward);
537 up = forward.Cross(right);
538
539 // clang-format off
540 return {
541 right.x, up.x, forward.x, 0.0f,
542 right.y, up.y, forward.y, 0.0f,
543 right.z, up.z, forward.z, 0.0f,
544 -right.Dot(position), -up.Dot(position), -forward.Dot(position), 1.0f
545 };
546 // clang-format on
547 }
548
549 private:
550 static constexpr Vector2 CosSin(Radians radians) {
551 // The precision of a float around 1.0 is much lower than it is
552 // around 0.0, so we end up with cases on quadrant rotations where
553 // we get a +/-1.0 for one of the values and a non-zero value for
554 // the other. This happens around quadrant rotations which makes it
555 // especially common and results in unclean quadrant rotation
556 // matrices which do not return true from |IsAligned[2D]| even
557 // though that is exactly where you need them to exhibit that property.
558 // It also injects small floating point mantissa errors into the
559 // matrices whenever you concatenate them with a quadrant rotation.
560 //
561 // This issue is also exacerbated by the fact that, in radians, the
562 // angles for quadrant rotations are irrational numbers. The measuring
563 // error for representing 90 degree multiples is small enough that
564 // either sin or cos will return a value near +/-1.0, but not small
565 // enough that the other value will be a clean 0.0.
566 //
567 // Some geometry packages simply discard very small numbers from
568 // sin/cos, but the following approach specifically targets just the
569 // area around a quadrant rotation (where either the sin or cos are
570 // measuring as +/-1.0) for symmetry of precision.
571
572 Scalar sin = std::sin(radians.radians);
573 if (std::abs(sin) == 1.0f) {
574 // 90 or 270 degrees (mod 360)
575 return {0.0f, sin};
576 } else {
577 Scalar cos = std::cos(radians.radians);
578 if (std::abs(cos) == 1.0f) {
579 // 0 or 180 degrees (mod 360)
580 return {cos, 0.0f};
581 }
582 return {cos, sin};
583 }
584 }
585 };
586
587 static_assert(sizeof(struct Matrix) == sizeof(Scalar) * 16,
588 "The matrix must be of consistent size.");
589
590 } // namespace impeller
591
592 namespace std {
593 inline std::ostream& operator<<(std::ostream& out, const impeller::Matrix& m) {
594 out << "(" << std::endl << std::fixed;
595 for (size_t i = 0; i < 4u; i++) {
596 for (size_t j = 0; j < 4u; j++) {
597 out << std::setw(15) << m.e[j][i] << ",";
598 }
599 out << std::endl;
600 }
601 out << ")";
602 return out;
603 }
604
605 } // namespace std
606
607 #endif // FLUTTER_IMPELLER_GEOMETRY_MATRIX_H_
impeller::Matrix::MakeSkew
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition: matrix.h:117
impeller::Matrix::HasPerspective
constexpr bool HasPerspective() const
Definition: matrix.h:330
impeller::Matrix::operator+
Matrix operator+(const Vector3 &t) const
Definition: matrix.h:423
impeller::Matrix::m
Scalar m[16]
Definition: matrix.h:39
impeller::Vector3::Dot
constexpr Scalar Dot(const Vector3 &other) const
Definition: vector.h:54
impeller::Matrix::TransformHomogenous
constexpr Vector3 TransformHomogenous(const Point &v) const
Definition: matrix.h:465
impeller::Matrix::Decompose
std::optional< MatrixDecomposition > Decompose() const
Definition: matrix.cc:209
impeller::Matrix::MakeRotationX
static Matrix MakeRotationX(Radians r)
Definition: matrix.h:183
impeller::Matrix::Matrix
constexpr Matrix()
Definition: matrix.h:47
impeller::Quaternion::z
Scalar z
Definition: quaternion.h:19
point.h
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Vector3::Cross
constexpr Vector3 Cross(const Vector3 &other) const
Definition: vector.h:62
impeller::Matrix::MakePerspective
static constexpr Matrix MakePerspective(Radians fov_y, TSize< T > size, Scalar z_near, Scalar z_far)
Definition: matrix.h:524
impeller::Vector4::Normalize
Vector4 Normalize() const
Definition: vector.h:258
impeller::Quaternion::w
Scalar w
Definition: quaternion.h:20
impeller::Matrix::operator-
Matrix operator-(const Vector3 &t) const
Definition: matrix.h:425
impeller::Matrix::operator*
constexpr Point operator*(const Point &v) const
Definition: matrix.h:452
impeller::Vector4
Definition: vector.h:232
impeller::Matrix::MakeRotation
static Matrix MakeRotation(Quaternion q)
Definition: matrix.h:126
impeller::Vector2
Point Vector2
Definition: point.h:326
impeller::Matrix::MakeRotationY
static Matrix MakeRotationY(Radians r)
Definition: matrix.h:198
impeller::Matrix::GetDeterminant
Scalar GetDeterminant() const
Definition: matrix.cc:162
quaternion.h
std::operator<<
std::ostream & operator<<(std::ostream &out, const impeller::Color &c)
Definition: color.h:961
impeller::Matrix::operator*
Matrix operator*(const Matrix &m) const
Definition: matrix.h:427
impeller::Radians::radians
Scalar radians
Definition: scalar.h:39
impeller::Matrix::MakeRow
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)
Definition: matrix.h:83
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Vector3::x
Scalar x
Definition: vector.h:23
impeller::Matrix::MakeRotation
static Matrix MakeRotation(Radians radians, const Vector4 &r)
Definition: matrix.h:151
impeller::Quaternion::x
Scalar x
Definition: quaternion.h:17
impeller::Matrix::e
Scalar e[4][4]
Definition: matrix.h:40
impeller::Matrix::vec
Vector4 vec[4]
Definition: matrix.h:41
impeller::Matrix::MakeLookAt
static constexpr Matrix MakeLookAt(Vector3 position, Vector3 target, Vector3 up)
Definition: matrix.h:532
impeller::Matrix::MakePerspective
static constexpr Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
Definition: matrix.h:506
impeller::Matrix::Basis
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
Definition: matrix.h:229
impeller::TSize
Definition: size.h:19
impeller::Matrix::TransformDirection
constexpr Vector3 TransformDirection(const Vector3 &v) const
Definition: matrix.h:477
impeller::Quaternion
Definition: quaternion.h:14
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:327
impeller::Matrix::Multiply
constexpr Matrix Multiply(const Matrix &o) const
Definition: matrix.h:261
impeller::Matrix::GetScale
constexpr Vector3 GetScale() const
Definition: matrix.h:311
impeller::Matrix::operator==
constexpr bool operator==(const Matrix &m) const
Definition: matrix.h:405
impeller::Matrix::Transpose
constexpr Matrix Transpose() const
Definition: matrix.h:283
impeller::Matrix::GetMaxBasisLength
Scalar GetMaxBasisLength() const
Definition: matrix.cc:196
impeller::Matrix::operator*
constexpr Vector4 operator*(const Vector4 &v) const
Definition: matrix.h:431
impeller::Matrix::IsTranslationScaleOnly
constexpr bool IsTranslationScaleOnly() const
Returns true if the matrix has a scale-only basis and is non-projective. Note that an identity matrix...
Definition: matrix.h:392
impeller::Matrix::Translate
constexpr Matrix Translate(const Vector3 &t) const
Definition: matrix.h:240
impeller::Matrix::Matrix
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)
Definition: matrix.h:56
impeller::Matrix::MakeColumn
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)
Definition: matrix.h:69
impeller::Matrix::TransformDirection
constexpr Vector2 TransformDirection(const Vector2 &v) const
Definition: matrix.h:483
impeller::Vector3::z
Scalar z
Definition: vector.h:25
impeller::Matrix::IsAffine
constexpr bool IsAffine() const
Definition: matrix.h:321
impeller::Radians
Definition: scalar.h:38
impeller::ScalarNearlyZero
constexpr bool ScalarNearlyZero(Scalar x, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:25
impeller::Vector3::Length
constexpr Scalar Length() const
Definition: vector.h:47
impeller::Vector4::x
Scalar x
Definition: vector.h:235
impeller::Vector3::y
Scalar y
Definition: vector.h:24
impeller::Matrix::GetBasisZ
constexpr Vector3 GetBasisZ() const
Definition: matrix.h:309
impeller::TSize::width
Type width
Definition: size.h:22
impeller::Matrix::Transform
constexpr Quad Transform(const Quad &quad) const
Definition: matrix.h:487
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:97
impeller::TPoint::x
Type x
Definition: point.h:30
impeller::Matrix::HasTranslation
constexpr bool HasTranslation() const
Definition: matrix.h:334
impeller::Matrix::IsIdentity
constexpr bool IsIdentity() const
Definition: matrix.h:379
impeller::Matrix::GetDirectionScale
constexpr Scalar GetDirectionScale(Vector3 direction) const
Definition: matrix.h:316
scalar.h
impeller::Vector3::Normalize
constexpr Vector3 Normalize() const
Definition: vector.h:49
impeller::Matrix::TransformDirection
constexpr Vector4 TransformDirection(const Vector4 &v) const
Definition: matrix.h:471
impeller::Vector4::w
Scalar w
Definition: vector.h:238
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:213
vector.h
impeller::Matrix::GetMaxBasisLengthXY
constexpr Scalar GetMaxBasisLengthXY() const
Definition: matrix.h:300
std
Definition: comparable.h:95
impeller::Vector4::y
Scalar y
Definition: vector.h:236
shear.h
impeller::TPoint< Scalar >
impeller::Matrix::operator*
constexpr Vector3 operator*(const Vector3 &v) const
Definition: matrix.h:438
impeller::Matrix::operator!=
constexpr bool operator!=(const Matrix &m) const
Definition: matrix.h:414
impeller::Quaternion::y
Scalar y
Definition: quaternion.h:18
scale
const Scalar scale
Definition: stroke_path_geometry.cc:308
impeller::Matrix::MakeOrthographic
static constexpr Matrix MakeOrthographic(TSize< T > size)
Definition: matrix.h:497
matrix_decomposition.h
impeller::TSize::height
Type height
Definition: size.h:23
impeller::Matrix::GetBasisY
constexpr Vector3 GetBasisY() const
Definition: matrix.h:307
impeller::Vector4::z
Scalar z
Definition: vector.h:237
impeller
Definition: aiks_blend_unittests.cc:18
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104
impeller::Matrix::IsAligned2D
constexpr bool IsAligned2D(Scalar tolerance=0) const
Definition: matrix.h:336
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector2 &s)
Definition: matrix.h:113
impeller::Matrix::GetBasisX
constexpr Vector3 GetBasisX() const
Definition: matrix.h:305
impeller::Matrix::HasPerspective2D
constexpr bool HasPerspective2D() const
Definition: matrix.h:326
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Vector3
Definition: vector.h:20
size.h
impeller::Matrix::Scale
constexpr Matrix Scale(const Vector3 &s) const
Definition: matrix.h:252
impeller::Matrix::IsAligned
constexpr bool IsAligned(Scalar tolerance=0) const
Definition: matrix.h:351