Flutter Impeller
impeller::Matrix Struct Reference

A 4x4 matrix using column-major storage. More...

#include <matrix.h>

Public Member Functions

constexpr 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)
 
 Matrix (const MatrixDecomposition &decomposition)
 
constexpr Matrix Basis () const
 The Matrix without its w components (without translation). More...
 
constexpr Matrix To3x3 () const
 
constexpr Matrix Translate (const Vector3 &t) const
 
constexpr Matrix Scale (const Vector3 &s) const
 
constexpr Matrix Multiply (const Matrix &o) const
 
constexpr Matrix Transpose () const
 
Matrix Invert () const
 
Scalar GetDeterminant () const
 
bool IsInvertible () const
 
Scalar GetMaxBasisLengthXY () const
 
constexpr Vector3 GetBasisX () const
 
constexpr Vector3 GetBasisY () const
 
constexpr Vector3 GetBasisZ () const
 
Vector3 GetScale () const
 
Scalar GetDirectionScale (Vector3 direction) const
 
bool IsFinite () const
 
constexpr bool IsAffine () const
 
constexpr bool HasPerspective2D () const
 
constexpr bool HasPerspective () const
 
constexpr bool HasTranslation () const
 
constexpr bool IsAligned2D (Scalar tolerance=0) const
 
constexpr bool IsAligned (Scalar tolerance=0) const
 
constexpr bool IsIdentity () const
 
constexpr bool IsTranslationOnly () const
 Returns true if the matrix has no entries other than translation components. Note that an identity matrix meets this criteria. More...
 
constexpr bool IsTranslationScaleOnly () const
 Returns true if the matrix has a scale-only basis and is non-projective. Note that an identity matrix meets this criteria. More...
 
std::optional< MatrixDecompositionDecompose () const
 
bool Equals (const Matrix &matrix, Scalar epsilon=1e-5f) const
 
constexpr bool operator== (const Matrix &m) const
 
constexpr bool operator!= (const Matrix &m) const
 
Matrix operator+ (const Vector3 &t) const
 
Matrix operator- (const Vector3 &t) const
 
Matrix operator* (const Matrix &m) const
 
Matrix operator+ (const Matrix &m) const
 
constexpr Vector4 operator* (const Vector4 &v) const
 
constexpr Vector3 operator* (const Vector3 &v) const
 
constexpr Point operator* (const Point &v) const
 
constexpr Vector3 TransformHomogenous (const Point &v) const
 
constexpr Vector4 TransformDirection (const Vector4 &v) const
 
constexpr Vector3 TransformDirection (const Vector3 &v) const
 
constexpr Vector2 TransformDirection (const Vector2 &v) const
 
constexpr Quad Transform (const Quad &quad) const
 

Static Public Member Functions

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 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 MakeTranslation (const Vector3 &t)
 
static constexpr Matrix MakeScale (const Vector3 &s)
 
static constexpr Matrix MakeTranslateScale (const Vector3 &s, const Vector3 &t)
 
static constexpr Matrix MakeScale (const Vector2 &s)
 
static constexpr Matrix MakeSkew (Scalar sx, Scalar sy)
 
static Matrix MakeRotation (Quaternion q)
 
static Matrix MakeRotation (Radians radians, const Vector4 &r)
 
static Matrix MakeRotationX (Radians r)
 
static Matrix MakeRotationY (Radians r)
 
static Matrix MakeRotationZ (Radians r)
 
template<class T >
static constexpr Matrix MakeOrthographic (TSize< T > size)
 
static Matrix MakePerspective (Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
 
template<class T >
static constexpr Matrix MakePerspective (Radians fov_y, TSize< T > size, Scalar z_near, Scalar z_far)
 
static Matrix MakeLookAt (Vector3 position, Vector3 target, Vector3 up)
 
static Vector2 CosSin (Radians radians)
 

Public Attributes

union {
   Scalar   m [16]
 
   Scalar   e [4][4]
 
   Vector4   vec [4]
 
}; 
 

Detailed Description

A 4x4 matrix using column-major storage.

        Utility methods that need to make assumptions about normalized
        device coordinates must use the following convention:
          * Left-handed coordinate system. Positive rotation is
            clockwise about axis of rotation.
          * Lower left corner is -1.0f, -1.0.
          * Upper right corner is  1.0f,  1.0.
          * Visible z-space is from 0.0 to 1.0.
            * This is NOT the same as OpenGL! Be careful.
          * NDC origin is at (0.0f, 0.0f, 0.5f). 

Definition at line 37 of file matrix.h.

Constructor & Destructor Documentation

◆ Matrix() [1/3]

constexpr impeller::Matrix::Matrix ( )
inlineconstexpr

Constructs a default identity matrix.

Definition at line 47 of file matrix.h.

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)} {}
Vector4 vec[4]
Definition: matrix.h:41

Referenced by Basis(), MakeColumn(), MakeRotation(), MakeRotationX(), MakeRotationY(), MakeRotationZ(), MakeRow(), MakeScale(), MakeSkew(), MakeTranslateScale(), MakeTranslation(), Multiply(), operator+(), Scale(), To3x3(), and Translate().

◆ Matrix() [2/3]

constexpr impeller::Matrix::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 
)
inlineconstexpr

Definition at line 56 of file matrix.h.

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)} {}

◆ Matrix() [3/3]

impeller::Matrix::Matrix ( const MatrixDecomposition decomposition)
explicit

Definition at line 12 of file matrix.cc.

12  : Matrix() {
13  /*
14  * Apply perspective.
15  */
16  for (int i = 0; i < 4; i++) {
17  e[i][3] = d.perspective.e[i];
18  }
19 
20  /*
21  * Apply translation.
22  */
23  for (int i = 0; i < 3; i++) {
24  for (int j = 0; j < 3; j++) {
25  e[3][i] += d.translation.e[j] * e[j][i];
26  }
27  }
28 
29  /*
30  * Apply rotation.
31  */
32 
33  Matrix rotation;
34 
35  const auto x = -d.rotation.x;
36  const auto y = -d.rotation.y;
37  const auto z = -d.rotation.z;
38  const auto w = d.rotation.w;
39 
40  /*
41  * Construct a composite rotation matrix from the quaternion values.
42  */
43 
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);
53 
54  *this = *this * rotation;
55 
56  /*
57  * Apply shear.
58  */
59  Matrix shear;
60 
61  if (d.shear.e[2] != 0) {
62  shear.e[2][1] = d.shear.e[2];
63  *this = *this * shear;
64  }
65 
66  if (d.shear.e[1] != 0) {
67  shear.e[2][1] = 0.0;
68  shear.e[2][0] = d.shear.e[1];
69  *this = *this * shear;
70  }
71 
72  if (d.shear.e[0] != 0) {
73  shear.e[2][0] = 0.0;
74  shear.e[1][0] = d.shear.e[0];
75  *this = *this * shear;
76  }
77 
78  /*
79  * Apply scale.
80  */
81  for (int i = 0; i < 3; i++) {
82  for (int j = 0; j < 3; j++) {
83  e[i][j] *= d.scale.e[i];
84  }
85  }
86 }
int32_t x
constexpr Matrix()
Definition: matrix.h:47
Scalar e[4][4]
Definition: matrix.h:40

References impeller::Shear::e, impeller::Vector3::e, impeller::Vector4::e, e, impeller::MatrixDecomposition::perspective, impeller::MatrixDecomposition::rotation, impeller::MatrixDecomposition::scale, impeller::MatrixDecomposition::shear, impeller::MatrixDecomposition::translation, impeller::Quaternion::w, x, impeller::Quaternion::x, impeller::Quaternion::y, and impeller::Quaternion::z.

Member Function Documentation

◆ Basis()

constexpr Matrix impeller::Matrix::Basis ( ) const
inlineconstexpr

The Matrix without its w components (without translation).

Definition at line 239 of file matrix.h.

239  {
240  // clang-format off
241  return Matrix(
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
246  );
247  // clang-format on
248  }
Scalar m[16]
Definition: matrix.h:39

References m, and Matrix().

Referenced by impeller::TextContents::ComputeVertexData(), GetDirectionScale(), impeller::DirectionalMorphologyFilterContents::GetFilterCoverage(), impeller::GaussianBlurFilterContents::GetFilterSourceCoverage(), impeller::LocalMatrixFilterContents::GetFilterSourceCoverage(), impeller::SolidRRectLikeBlurContents::Render(), and impeller::testing::TEST().

◆ CosSin()

static Vector2 impeller::Matrix::CosSin ( Radians  radians)
inlinestatic

Definition at line 618 of file matrix.h.

618  {
619  // The precision of a float around 1.0 is much lower than it is
620  // around 0.0, so we end up with cases on quadrant rotations where
621  // we get a +/-1.0 for one of the values and a non-zero value for
622  // the other. This happens around quadrant rotations which makes it
623  // especially common and results in unclean quadrant rotation
624  // matrices which do not return true from |IsAligned[2D]| even
625  // though that is exactly where you need them to exhibit that property.
626  // It also injects small floating point mantissa errors into the
627  // matrices whenever you concatenate them with a quadrant rotation.
628  //
629  // This issue is also exacerbated by the fact that, in radians, the
630  // angles for quadrant rotations are irrational numbers. The measuring
631  // error for representing 90 degree multiples is small enough that
632  // either sin or cos will return a value near +/-1.0, but not small
633  // enough that the other value will be a clean 0.0.
634  //
635  // Some geometry packages simply discard very small numbers from
636  // sin/cos, but the following approach specifically targets just the
637  // area around a quadrant rotation (where either the sin or cos are
638  // measuring as +/-1.0) for symmetry of precision.
639 
640  Scalar sin = std::sin(radians.radians);
641  if (std::abs(sin) == 1.0f) {
642  // 90 or 270 degrees (mod 360)
643  return {0.0f, sin};
644  } else {
645  Scalar cos = std::cos(radians.radians);
646  if (std::abs(cos) == 1.0f) {
647  // 0 or 180 degrees (mod 360)
648  return {cos, 0.0f};
649  }
650  return {cos, sin};
651  }
652  }
float Scalar
Definition: scalar.h:19

References impeller::Radians::radians.

Referenced by impeller::Arc::ComputeIterations(), impeller::Arc::GetTightArcBounds(), impeller::RSTransform::Make(), MakeRotation(), MakeRotationX(), MakeRotationY(), and MakeRotationZ().

◆ Decompose()

std::optional< MatrixDecomposition > impeller::Matrix::Decompose ( ) const

Definition at line 200 of file matrix.cc.

200  {
201  /*
202  * Normalize the matrix.
203  */
204  Matrix self = *this;
205 
206  if (self.e[3][3] == 0) {
207  return std::nullopt;
208  }
209 
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];
213  }
214  }
215 
216  /*
217  * `perspectiveMatrix` is used to solve for perspective, but it also provides
218  * an easy way to test for singularity of the upper 3x3 component.
219  */
220  Matrix perpectiveMatrix = self;
221  for (int i = 0; i < 3; i++) {
222  perpectiveMatrix.e[i][3] = 0;
223  }
224 
225  perpectiveMatrix.e[3][3] = 1;
226 
227  if (!perpectiveMatrix.IsInvertible()) {
228  return std::nullopt;
229  }
230 
231  MatrixDecomposition result;
232 
233  /*
234  * ==========================================================================
235  * First, isolate perspective.
236  * ==========================================================================
237  */
238  if (self.e[0][3] != 0.0 || self.e[1][3] != 0.0 || self.e[2][3] != 0.0) {
239  /*
240  * prhs is the right hand side of the equation.
241  */
242  const Vector4 rightHandSide(self.e[0][3], //
243  self.e[1][3], //
244  self.e[2][3], //
245  self.e[3][3]);
246 
247  /*
248  * Solve the equation by inverting `perspectiveMatrix` and multiplying
249  * prhs by the inverse.
250  */
251 
252  result.perspective = perpectiveMatrix.Invert().Transpose() * rightHandSide;
253 
254  /*
255  * Clear the perspective partition.
256  */
257  self.e[0][3] = self.e[1][3] = self.e[2][3] = 0;
258  self.e[3][3] = 1;
259  }
260 
261  /*
262  * ==========================================================================
263  * Next, the translation.
264  * ==========================================================================
265  */
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;
268 
269  /*
270  * ==========================================================================
271  * Next, the scale and shear.
272  * ==========================================================================
273  */
274  Vector3 row[3];
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];
279  }
280 
281  /*
282  * Compute X scale factor and normalize first row.
283  */
284  result.scale.x = row[0].GetLength();
285  row[0] = row[0].Normalize();
286 
287  /*
288  * Compute XY shear factor and make 2nd row orthogonal to 1st.
289  */
290  result.shear.xy = row[0].Dot(row[1]);
291  row[1] = Vector3::Combine(row[1], 1.0, row[0], -result.shear.xy);
292 
293  /*
294  * Compute Y scale and normalize 2nd row.
295  */
296  result.scale.y = row[1].GetLength();
297  row[1] = row[1].Normalize();
298  result.shear.xy /= result.scale.y;
299 
300  /*
301  * Compute XZ and YZ shears, orthogonalize 3rd row.
302  */
303  result.shear.xz = row[0].Dot(row[2]);
304  row[2] = Vector3::Combine(row[2], 1.0, row[0], -result.shear.xz);
305  result.shear.yz = row[1].Dot(row[2]);
306  row[2] = Vector3::Combine(row[2], 1.0, row[1], -result.shear.yz);
307 
308  /*
309  * Next, get Z scale and normalize 3rd row.
310  */
311  result.scale.z = row[2].GetLength();
312  row[2] = row[2].Normalize();
313 
314  result.shear.xz /= result.scale.z;
315  result.shear.yz /= result.scale.z;
316 
317  /*
318  * At this point, the matrix (in rows[]) is orthonormal.
319  * Check for a coordinate system flip. If the determinant
320  * is -1, then negate the matrix and the scaling factors.
321  */
322  if (row[0].Dot(row[1].Cross(row[2])) < 0) {
323  result.scale.x *= -1;
324  result.scale.y *= -1;
325  result.scale.z *= -1;
326 
327  for (int i = 0; i < 3; i++) {
328  row[i].x *= -1;
329  row[i].y *= -1;
330  row[i].z *= -1;
331  }
332  }
333 
334  /*
335  * ==========================================================================
336  * Finally, get the rotations out.
337  * ==========================================================================
338  */
339  result.rotation.x =
340  0.5 * sqrt(fmax(1.0 + row[0].x - row[1].y - row[2].z, 0.0));
341  result.rotation.y =
342  0.5 * sqrt(fmax(1.0 - row[0].x + row[1].y - row[2].z, 0.0));
343  result.rotation.z =
344  0.5 * sqrt(fmax(1.0 - row[0].x - row[1].y + row[2].z, 0.0));
345  result.rotation.w =
346  0.5 * sqrt(fmax(1.0 + row[0].x + row[1].y + row[2].z, 0.0));
347 
348  if (row[2].y > row[1].z) {
349  result.rotation.x = -result.rotation.x;
350  }
351  if (row[0].z > row[2].x) {
352  result.rotation.y = -result.rotation.y;
353  }
354  if (row[1].x > row[0].y) {
355  result.rotation.z = -result.rotation.z;
356  }
357 
358  return result;
359 }
static constexpr Vector3 Combine(const Vector3 &a, Scalar aScale, const Vector3 &b, Scalar bScale)
Definition: vector.h:192

References impeller::Vector3::Combine(), impeller::Vector3::Dot(), impeller::Vector3::e, impeller::Vector4::e, e, impeller::Vector3::GetLength(), Invert(), IsInvertible(), impeller::Vector3::Normalize(), impeller::MatrixDecomposition::perspective, impeller::MatrixDecomposition::rotation, impeller::MatrixDecomposition::scale, impeller::MatrixDecomposition::shear, impeller::MatrixDecomposition::translation, Transpose(), impeller::Quaternion::w, x, impeller::Quaternion::x, impeller::Vector3::x, impeller::Shear::xy, impeller::Shear::xz, impeller::Quaternion::y, impeller::Vector3::y, impeller::Shear::yz, impeller::Quaternion::z, and impeller::Vector3::z.

Referenced by impeller::testing::TEST().

◆ Equals()

bool impeller::Matrix::Equals ( const Matrix matrix,
Scalar  epsilon = 1e-5f 
) const
inline

Definition at line 453 of file matrix.h.

453  {
454  const Scalar* a = m;
455  const Scalar* b = matrix.m;
456  return ScalarNearlyEqual(a[0], b[0], epsilon) &&
457  ScalarNearlyEqual(a[1], b[1], epsilon) &&
458  ScalarNearlyEqual(a[2], b[2], epsilon) &&
459  ScalarNearlyEqual(a[3], b[3], epsilon) &&
460  ScalarNearlyEqual(a[4], b[4], epsilon) &&
461  ScalarNearlyEqual(a[5], b[5], epsilon) &&
462  ScalarNearlyEqual(a[6], b[6], epsilon) &&
463  ScalarNearlyEqual(a[7], b[7], epsilon) &&
464  ScalarNearlyEqual(a[8], b[8], epsilon) &&
465  ScalarNearlyEqual(a[9], b[9], epsilon) &&
466  ScalarNearlyEqual(a[10], b[10], epsilon) &&
467  ScalarNearlyEqual(a[11], b[11], epsilon) &&
468  ScalarNearlyEqual(a[12], b[12], epsilon) &&
469  ScalarNearlyEqual(a[13], b[13], epsilon) &&
470  ScalarNearlyEqual(a[14], b[14], epsilon) &&
471  ScalarNearlyEqual(a[15], b[15], epsilon);
472  }
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:36

References impeller::saturated::b, m, and impeller::ScalarNearlyEqual().

◆ GetBasisX()

constexpr Vector3 impeller::Matrix::GetBasisX ( ) const
inlineconstexpr

Definition at line 335 of file matrix.h.

335 { return Vector3(m[0], m[1], m[2]); }

References m.

Referenced by impeller::Paint::MaskBlurDescriptor::CreateMaskBlur(), and GetScale().

◆ GetBasisY()

constexpr Vector3 impeller::Matrix::GetBasisY ( ) const
inlineconstexpr

Definition at line 337 of file matrix.h.

337 { return Vector3(m[4], m[5], m[6]); }

References m.

Referenced by impeller::Paint::MaskBlurDescriptor::CreateMaskBlur(), and GetScale().

◆ GetBasisZ()

constexpr Vector3 impeller::Matrix::GetBasisZ ( ) const
inlineconstexpr

Definition at line 339 of file matrix.h.

339 { return Vector3(m[8], m[9], m[10]); }

References m.

Referenced by GetScale().

◆ GetDeterminant()

Scalar impeller::Matrix::GetDeterminant ( ) const

Definition at line 162 of file matrix.cc.

162  {
163  auto a00 = e[0][0];
164  auto a01 = e[0][1];
165  auto a02 = e[0][2];
166  auto a03 = e[0][3];
167  auto a10 = e[1][0];
168  auto a11 = e[1][1];
169  auto a12 = e[1][2];
170  auto a13 = e[1][3];
171  auto a20 = e[2][0];
172  auto a21 = e[2][1];
173  auto a22 = e[2][2];
174  auto a23 = e[2][3];
175  auto a30 = e[3][0];
176  auto a31 = e[3][1];
177  auto a32 = e[3][2];
178  auto a33 = e[3][3];
179 
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;
192 
193  return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
194 }

References e.

Referenced by IsInvertible().

◆ GetDirectionScale()

Scalar impeller::Matrix::GetDirectionScale ( Vector3  direction) const
inline

Definition at line 346 of file matrix.h.

346  {
347  return 1.0f / (this->Basis().Invert() * direction.Normalize()).GetLength() *
348  direction.GetLength();
349  }
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
Definition: matrix.h:239
Matrix Invert() const
Definition: matrix.cc:97

References Basis(), impeller::Vector3::GetLength(), Invert(), and impeller::Vector3::Normalize().

Referenced by impeller::testing::TEST().

◆ GetMaxBasisLengthXY()

Scalar impeller::Matrix::GetMaxBasisLengthXY ( ) const
inline

Definition at line 323 of file matrix.h.

323  {
324  // The full basis computation requires computing the squared scaling factor
325  // for translate/scale only matrices. This substantially limits the range of
326  // precision for small and large scales. Instead, check for the common cases
327  // and directly return the max scaling factor.
328  if (e[0][1] == 0 && e[1][0] == 0) {
329  return std::max(std::abs(e[0][0]), std::abs(e[1][1]));
330  }
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]));
333  }

References e.

Referenced by impeller::LineContents::CalculatePerVertex(), impeller::Canvas::DrawTextFrame(), impeller::Tessellator::FilledArc(), impeller::Tessellator::FilledCircle(), impeller::Tessellator::FilledEllipse(), impeller::Tessellator::FilledRoundRect(), impeller::StrokeRectGeometry::GetPositionBuffer(), impeller::LineContents::Render(), impeller::Tessellator::RoundCapLine(), impeller::Tessellator::StrokedArc(), impeller::Tessellator::StrokedCircle(), and impeller::testing::TEST().

◆ GetScale()

Vector3 impeller::Matrix::GetScale ( ) const
inline

Definition at line 341 of file matrix.h.

341  {
342  return Vector3(GetBasisX().GetLength(), GetBasisY().GetLength(),
343  GetBasisZ().GetLength());
344  }
constexpr Vector3 GetBasisY() const
Definition: matrix.h:337
constexpr Vector3 GetBasisZ() const
Definition: matrix.h:339
constexpr Vector3 GetBasisX() const
Definition: matrix.h:335

References GetBasisX(), GetBasisY(), and GetBasisZ().

Referenced by impeller::DlDispatcherBase::drawShadow().

◆ HasPerspective()

constexpr bool impeller::Matrix::HasPerspective ( ) const
inlineconstexpr

Definition at line 365 of file matrix.h.

365  {
366  return m[3] != 0 || m[7] != 0 || m[11] != 0 || m[15] != 1;
367  }

References m.

Referenced by impeller::DlDispatcherBase::drawDisplayList(), impeller::FirstPassDispatcher::drawDisplayList(), IsAligned(), and impeller::testing::TEST().

◆ HasPerspective2D()

constexpr bool impeller::Matrix::HasPerspective2D ( ) const
inlineconstexpr

Definition at line 361 of file matrix.h.

361  {
362  return m[3] != 0 || m[7] != 0 || m[15] != 1;
363  }

References m.

Referenced by IsAligned2D(), and impeller::testing::TEST().

◆ HasTranslation()

constexpr bool impeller::Matrix::HasTranslation ( ) const
inlineconstexpr

Definition at line 369 of file matrix.h.

369 { return m[12] != 0 || m[13] != 0; }

References m.

◆ Invert()

Matrix impeller::Matrix::Invert ( ) const

Definition at line 97 of file matrix.cc.

97  {
98  Matrix tmp{
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],
101 
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],
104 
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],
107 
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],
110 
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],
113 
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],
116 
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],
119 
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],
122 
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],
125 
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],
128 
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],
131 
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],
134 
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],
137 
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],
140 
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],
143 
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]};
146 
147  Scalar det =
148  m[0] * tmp.m[0] + m[1] * tmp.m[4] + m[2] * tmp.m[8] + m[3] * tmp.m[12];
149 
150  if (det == 0) {
151  return {};
152  }
153 
154  det = 1.0 / det;
155 
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};
160 }

References m.

Referenced by Decompose(), GetDirectionScale(), impeller::MatrixFilterContents::GetFilterCoverage(), impeller::LocalMatrixFilterContents::GetFilterSourceCoverage(), impeller::Snapshot::GetUVTransform(), impeller::TextShadowCache::Lookup(), impeller::SolidRRectLikeBlurContents::Render(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::ColorSourceContents::SetEffectTransform(), impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ IsAffine()

constexpr bool impeller::Matrix::IsAffine ( ) const
inlineconstexpr

Definition at line 356 of file matrix.h.

356  {
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);
359  }

References m.

◆ IsAligned()

constexpr bool impeller::Matrix::IsAligned ( Scalar  tolerance = 0) const
inlineconstexpr

Definition at line 386 of file matrix.h.

386  {
387  if (HasPerspective()) {
388  return false;
389  }
390  int v[] = {!ScalarNearlyZero(m[0], tolerance), //
391  !ScalarNearlyZero(m[1], tolerance), //
392  !ScalarNearlyZero(m[2], tolerance), //
393  !ScalarNearlyZero(m[4], tolerance), //
394  !ScalarNearlyZero(m[5], tolerance), //
395  !ScalarNearlyZero(m[6], tolerance), //
396  !ScalarNearlyZero(m[8], tolerance), //
397  !ScalarNearlyZero(m[9], tolerance), //
398  !ScalarNearlyZero(m[10], tolerance)};
399  // Check if all three basis vectors are aligned to an axis.
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) {
403  return false;
404  }
405  // Ensure that none of the basis vectors overlap.
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) {
409  return false;
410  }
411  return true;
412  }
constexpr bool ScalarNearlyZero(Scalar x, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:31
constexpr bool HasPerspective() const
Definition: matrix.h:365

References HasPerspective(), m, and impeller::ScalarNearlyZero().

Referenced by impeller::testing::TEST().

◆ IsAligned2D()

constexpr bool impeller::Matrix::IsAligned2D ( Scalar  tolerance = 0) const
inlineconstexpr

Definition at line 371 of file matrix.h.

371  {
372  if (HasPerspective2D()) {
373  return false;
374  }
375  if (ScalarNearlyZero(m[1], tolerance) &&
376  ScalarNearlyZero(m[4], tolerance)) {
377  return true;
378  }
379  if (ScalarNearlyZero(m[0], tolerance) &&
380  ScalarNearlyZero(m[5], tolerance)) {
381  return true;
382  }
383  return false;
384  }
constexpr bool HasPerspective2D() const
Definition: matrix.h:361

References HasPerspective2D(), m, and impeller::ScalarNearlyZero().

Referenced by impeller::testing::TEST().

◆ IsFinite()

bool impeller::Matrix::IsFinite ( ) const
inline

Definition at line 351 of file matrix.h.

351  {
352  return vec[0].IsFinite() && vec[1].IsFinite() && vec[2].IsFinite() &&
353  vec[3].IsFinite();
354  }
bool IsFinite() const
Definition: vector.h:258

References impeller::Vector4::IsFinite(), and vec.

Referenced by impeller::testing::TEST().

◆ IsIdentity()

constexpr bool impeller::Matrix::IsIdentity ( ) const
inlineconstexpr

Definition at line 414 of file matrix.h.

414  {
415  return (
416  // clang-format off
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
421  // clang-format on
422  );
423  }

References m.

Referenced by impeller::testing::TEST_P(), and impeller::interop::testing::TEST_P().

◆ IsInvertible()

bool impeller::Matrix::IsInvertible ( ) const
inline

Definition at line 321 of file matrix.h.

321 { return GetDeterminant() != 0; }
Scalar GetDeterminant() const
Definition: matrix.cc:162

References GetDeterminant().

Referenced by Decompose(), and impeller::testing::TEST_P().

◆ IsTranslationOnly()

constexpr bool impeller::Matrix::IsTranslationOnly ( ) const
inlineconstexpr

Returns true if the matrix has no entries other than translation components. Note that an identity matrix meets this criteria.

Definition at line 427 of file matrix.h.

427  {
428  return (
429  // clang-format off
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 &&
433  m[15] == 1.0
434  // clang-format on
435  );
436  }

References m.

◆ IsTranslationScaleOnly()

constexpr bool impeller::Matrix::IsTranslationScaleOnly ( ) const
inlineconstexpr

Returns true if the matrix has a scale-only basis and is non-projective. Note that an identity matrix meets this criteria.

Definition at line 440 of file matrix.h.

440  {
441  return (
442  // clang-format off
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 &&
446  m[15] == 1.0
447  // clang-format on
448  );
449  }

References m.

Referenced by impeller::TextContents::ComputeVertexData(), and impeller::TextContents::Render().

◆ MakeColumn()

static constexpr Matrix impeller::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 
)
inlinestaticconstexpr

Definition at line 69 of file matrix.h.

73  {
74  return Matrix(m0, m1, m2, m3,
75  m4, m5, m6, m7,
76  m8, m9, m10, m11,
77  m12, m13, m14, m15);
78 
79  }

References Matrix().

Referenced by impeller::testing::TEST(), impeller::FirstPassDispatcher::transform2DAffine(), and impeller::FirstPassDispatcher::transformFullPerspective().

◆ MakeLookAt()

static Matrix impeller::Matrix::MakeLookAt ( Vector3  position,
Vector3  target,
Vector3  up 
)
inlinestatic

Definition at line 601 of file matrix.h.

603  {
604  Vector3 forward = (target - position).Normalize();
605  Vector3 right = up.Cross(forward);
606  up = forward.Cross(right);
607 
608  // clang-format off
609  return {
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
614  };
615  // clang-format on
616  }

References impeller::Vector3::Cross(), impeller::Vector3::Dot(), impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

Referenced by impeller::testing::TEST().

◆ MakeOrthographic()

template<class T >
static constexpr Matrix impeller::Matrix::MakeOrthographic ( TSize< T >  size)
inlinestaticconstexpr

Definition at line 566 of file matrix.h.

566  {
567  // Per assumptions about NDC documented above.
568  const auto scale =
569  MakeScale({2.0f / static_cast<Scalar>(size.width),
570  -2.0f / static_cast<Scalar>(size.height), 0.0f});
571  const auto translate = MakeTranslation({-1.0f, 1.0f, 0.5f});
572  return translate * scale;
573  }
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104

References impeller::TSize< T >::height, MakeScale(), MakeTranslation(), and impeller::TSize< T >::width.

Referenced by ImGui_ImplImpeller_RenderDrawData(), impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ MakePerspective() [1/2]

static Matrix impeller::Matrix::MakePerspective ( Radians  fov_y,
Scalar  aspect_ratio,
Scalar  z_near,
Scalar  z_far 
)
inlinestatic

Definition at line 575 of file matrix.h.

578  {
579  Scalar height = std::tan(fov_y.radians * 0.5f);
580  Scalar width = height * aspect_ratio;
581 
582  // clang-format off
583  return {
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,
588  };
589  // clang-format on
590  }

References impeller::Radians::radians.

Referenced by MakePerspective(), impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ MakePerspective() [2/2]

template<class T >
static constexpr Matrix impeller::Matrix::MakePerspective ( Radians  fov_y,
TSize< T >  size,
Scalar  z_near,
Scalar  z_far 
)
inlinestaticconstexpr

Definition at line 593 of file matrix.h.

596  {
597  return MakePerspective(fov_y, static_cast<Scalar>(size.width) / size.height,
598  z_near, z_far);
599  }
static Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
Definition: matrix.h:575

References impeller::TSize< T >::height, MakePerspective(), and impeller::TSize< T >::width.

◆ MakeRotation() [1/2]

static Matrix impeller::Matrix::MakeRotation ( Quaternion  q)
inlinestatic

Definition at line 136 of file matrix.h.

136  {
137  // clang-format off
138  return Matrix(
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,
142  0.0f,
143 
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,
147  0.0f,
148 
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,
152  0.0f,
153 
154  0.0f,
155  0.0f,
156  0.0f,
157  1.0f);
158  // clang-format on
159  }

References Matrix(), impeller::Quaternion::w, impeller::Quaternion::x, impeller::Quaternion::y, and impeller::Quaternion::z.

Referenced by impeller::testing::TEST().

◆ MakeRotation() [2/2]

static Matrix impeller::Matrix::MakeRotation ( Radians  radians,
const Vector4 r 
)
inlinestatic

Definition at line 161 of file matrix.h.

161  {
162  const Vector4 v = r.Normalize();
163 
164  const Vector2 cos_sin = CosSin(radians);
165  const Scalar cosine = cos_sin.x;
166  const Scalar cosp = 1.0f - cosine;
167  const Scalar sine = cos_sin.y;
168 
169  // clang-format off
170  return Matrix(
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,
174  0.0f,
175 
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,
179  0.0f,
180 
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,
184  0.0f,
185 
186  0.0f,
187  0.0f,
188  0.0f,
189  1.0f);
190  // clang-format on
191  }
Point Vector2
Definition: point.h:331
static Vector2 CosSin(Radians radians)
Definition: matrix.h:618

References CosSin(), Matrix(), impeller::Vector4::Normalize(), impeller::TPoint< T >::x, impeller::Vector4::x, impeller::TPoint< T >::y, impeller::Vector4::y, and impeller::Vector4::z.

◆ MakeRotationX()

static Matrix impeller::Matrix::MakeRotationX ( Radians  r)
inlinestatic

Definition at line 193 of file matrix.h.

193  {
194  const Vector2 cos_sin = CosSin(r);
195  const Scalar cosine = cos_sin.x;
196  const Scalar sine = cos_sin.y;
197 
198  // clang-format off
199  return Matrix(
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
204  );
205  // clang-format on
206  }

References CosSin(), Matrix(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ MakeRotationY()

static Matrix impeller::Matrix::MakeRotationY ( Radians  r)
inlinestatic

Definition at line 208 of file matrix.h.

208  {
209  const Vector2 cos_sin = CosSin(r);
210  const Scalar cosine = cos_sin.x;
211  const Scalar sine = cos_sin.y;
212 
213  // clang-format off
214  return Matrix(
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
219  );
220  // clang-format on
221  }

References CosSin(), Matrix(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ MakeRotationZ()

static Matrix impeller::Matrix::MakeRotationZ ( Radians  r)
inlinestatic

Definition at line 223 of file matrix.h.

223  {
224  const Vector2 cos_sin = CosSin(r);
225  const Scalar cosine = cos_sin.x;
226  const Scalar sine = cos_sin.y;
227 
228  // clang-format off
229  return Matrix (
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
234  );
235  // clang-format on
236  }

References CosSin(), Matrix(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::FirstPassDispatcher::rotate(), impeller::Canvas::Rotate(), impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ MakeRow()

static constexpr Matrix impeller::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 
)
inlinestaticconstexpr

Definition at line 83 of file matrix.h.

87  {
88  return Matrix(m0, m4, m8, m12,
89  m1, m5, m9, m13,
90  m2, m6, m10, m14,
91  m3, m7, m11, m15);
92  }

References Matrix().

Referenced by impeller::RSTransform::GetMatrix(), impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ MakeScale() [1/2]

static constexpr Matrix impeller::Matrix::MakeScale ( const Vector2 s)
inlinestaticconstexpr

Definition at line 123 of file matrix.h.

123  {
124  return MakeScale(Vector3(s.x, s.y, 1.0f));
125  }

References MakeScale(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ MakeScale() [2/2]

static constexpr Matrix impeller::Matrix::MakeScale ( const Vector3 s)
inlinestaticconstexpr

◆ MakeSkew()

static constexpr Matrix impeller::Matrix::MakeSkew ( Scalar  sx,
Scalar  sy 
)
inlinestaticconstexpr

Definition at line 127 of file matrix.h.

127  {
128  // clang-format off
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);
133  // clang-format on
134  }

References Matrix().

Referenced by impeller::FirstPassDispatcher::skew(), impeller::Canvas::Skew(), impeller::testing::TEST(), and impeller::testing::TEST_P().

◆ MakeTranslateScale()

static constexpr Matrix impeller::Matrix::MakeTranslateScale ( const Vector3 s,
const Vector3 t 
)
inlinestaticconstexpr

Definition at line 113 of file matrix.h.

114  {
115  // clang-format off
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);
120  // clang-format on
121  }

References Matrix(), impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

Referenced by impeller::Canvas::DrawImageRect(), impeller::Entity::GetShaderTransform(), and impeller::testing::TEST().

◆ MakeTranslation()

◆ Multiply()

constexpr Matrix impeller::Matrix::Multiply ( const Matrix o) const
inlineconstexpr

Definition at line 284 of file matrix.h.

284  {
285  // clang-format off
286  return Matrix(
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]);
303  // clang-format on
304  }

References m, and Matrix().

Referenced by operator*().

◆ operator!=()

constexpr bool impeller::Matrix::operator!= ( const Matrix m) const
inlineconstexpr

Definition at line 483 of file matrix.h.

483  {
484  // clang-format off
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];
489  // clang-format on
490  }

References m, and vec.

◆ operator*() [1/4]

Matrix impeller::Matrix::operator* ( const Matrix m) const
inline

Definition at line 496 of file matrix.h.

496 { return Multiply(m); }
constexpr Matrix Multiply(const Matrix &o) const
Definition: matrix.h:284

References m, and Multiply().

◆ operator*() [2/4]

constexpr Point impeller::Matrix::operator* ( const Point v) const
inlineconstexpr

Definition at line 521 of file matrix.h.

521  {
522  Scalar w = v.x * m[3] + v.y * m[7] + m[15];
523  Point result(v.x * m[0] + v.y * m[4] + m[12],
524  v.x * m[1] + v.y * m[5] + m[13]);
525 
526  // This is Skia's behavior, but it may be reasonable to allow UB for the w=0
527  // case.
528  if (w) {
529  w = 1 / w;
530  }
531  return result * w;
532  }
TPoint< Scalar > Point
Definition: point.h:327

References m, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ operator*() [3/4]

constexpr Vector3 impeller::Matrix::operator* ( const Vector3 v) const
inlineconstexpr

Definition at line 507 of file matrix.h.

507  {
508  Scalar w = v.x * m[3] + v.y * m[7] + v.z * m[11] + m[15];
509  Vector3 result(v.x * m[0] + v.y * m[4] + v.z * m[8] + m[12],
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]);
512 
513  // This is Skia's behavior, but it may be reasonable to allow UB for the w=0
514  // case.
515  if (w) {
516  w = 1 / w;
517  }
518  return result * w;
519  }

References m, impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ operator*() [4/4]

constexpr Vector4 impeller::Matrix::operator* ( const Vector4 v) const
inlineconstexpr

Definition at line 500 of file matrix.h.

500  {
501  return Vector4(v.x * m[0] + v.y * m[4] + v.z * m[8] + v.w * m[12],
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]);
505  }

References m, impeller::Vector4::w, impeller::Vector4::x, impeller::Vector4::y, and impeller::Vector4::z.

◆ operator+() [1/2]

Matrix impeller::Matrix::operator+ ( const Matrix m) const

Definition at line 88 of file matrix.cc.

88  {
89  return Matrix(
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] //
94  );
95 }

References m, and Matrix().

◆ operator+() [2/2]

Matrix impeller::Matrix::operator+ ( const Vector3 t) const
inline

Definition at line 492 of file matrix.h.

492 { return Translate(t); }
constexpr Matrix Translate(const Vector3 &t) const
Definition: matrix.h:263

References Translate().

◆ operator-()

Matrix impeller::Matrix::operator- ( const Vector3 t) const
inline

Definition at line 494 of file matrix.h.

494 { return Translate(-t); }

References Translate().

◆ operator==()

constexpr bool impeller::Matrix::operator== ( const Matrix m) const
inlineconstexpr

Definition at line 474 of file matrix.h.

474  {
475  // clang-format off
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];
480  // clang-format on
481  }

References m, and vec.

◆ Scale()

constexpr Matrix impeller::Matrix::Scale ( const Vector3 s) const
inlineconstexpr

Definition at line 275 of file matrix.h.

275  {
276  // clang-format off
277  return Matrix(m[0] * s.x, m[1] * s.x, m[2] * s.x, m[3] * s.x,
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] );
281  // clang-format on
282  }

References m, Matrix(), impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

Referenced by impeller::FirstPassDispatcher::scale(), and impeller::testing::TEST_P().

◆ To3x3()

constexpr Matrix impeller::Matrix::To3x3 ( ) const
inlineconstexpr

Definition at line 252 of file matrix.h.

252  {
253  // clang-format off
254  return Matrix(
255  m[0], m[1], 0, m[3],
256  m[4], m[5], 0, m[7],
257  0, 0, 1, 0,
258  m[12], m[13], 0, m[15]
259  );
260  // clang-format on
261  }

References m, and Matrix().

◆ Transform()

constexpr Quad impeller::Matrix::Transform ( const Quad quad) const
inlineconstexpr

Definition at line 556 of file matrix.h.

556  {
557  return {
558  *this * quad[0],
559  *this * quad[1],
560  *this * quad[2],
561  *this * quad[3],
562  };
563  }

Referenced by impeller::GaussianBlurFilterContents::CalculateUVs(), and impeller::testing::TEST_P().

◆ TransformDirection() [1/3]

constexpr Vector2 impeller::Matrix::TransformDirection ( const Vector2 v) const
inlineconstexpr

Definition at line 552 of file matrix.h.

552  {
553  return Vector2(v.x * m[0] + v.y * m[4], v.x * m[1] + v.y * m[5]);
554  }

References m, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TransformDirection() [2/3]

constexpr Vector3 impeller::Matrix::TransformDirection ( const Vector3 v) const
inlineconstexpr

Definition at line 546 of file matrix.h.

546  {
547  return Vector3(v.x * m[0] + v.y * m[4] + v.z * m[8],
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]);
550  }

References m, impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TransformDirection() [3/3]

constexpr Vector4 impeller::Matrix::TransformDirection ( const Vector4 v) const
inlineconstexpr

Definition at line 540 of file matrix.h.

540  {
541  return Vector4(v.x * m[0] + v.y * m[4] + v.z * m[8],
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);
544  }

References m, impeller::Vector4::w, impeller::Vector4::x, impeller::Vector4::y, and impeller::Vector4::z.

Referenced by impeller::BorderMaskBlurFilterContents::GetFilterSourceCoverage(), and impeller::DirectionalMorphologyFilterContents::GetFilterSourceCoverage().

◆ TransformHomogenous()

constexpr Vector3 impeller::Matrix::TransformHomogenous ( const Point v) const
inlineconstexpr

Definition at line 534 of file matrix.h.

534  {
535  return Vector3(v.x * m[0] + v.y * m[4] + m[12],
536  v.x * m[1] + v.y * m[5] + m[13],
537  v.x * m[3] + v.y * m[7] + m[15]);
538  }

References m, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::testing::TEST().

◆ Translate()

constexpr Matrix impeller::Matrix::Translate ( const Vector3 t) const
inlineconstexpr

Definition at line 263 of file matrix.h.

263  {
264  // clang-format off
265  return Matrix(m[0], m[1], m[2], m[3],
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]);
272  // clang-format on
273  }

References m, Matrix(), impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

Referenced by ImGui_ImplImpeller_RenderDrawData(), operator+(), operator-(), impeller::testing::TEST(), impeller::testing::TEST_P(), and impeller::FirstPassDispatcher::translate().

◆ Transpose()

constexpr Matrix impeller::Matrix::Transpose ( ) const
inlineconstexpr

Definition at line 306 of file matrix.h.

306  {
307  // clang-format off
308  return {
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],
313  };
314  // clang-format on
315  }

References m.

Referenced by Decompose().

Member Data Documentation

◆ 

union { ... }

◆ e

Scalar impeller::Matrix::e[4][4]

◆ m

◆ vec

Vector4 impeller::Matrix::vec[4]

Definition at line 41 of file matrix.h.

Referenced by IsFinite(), operator!=(), operator==(), and impeller::testing::TEST_P().


The documentation for this struct was generated from the following files: