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 
20 #include "impeller/geometry/size.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];
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 
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 
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 
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 
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