| Flutter Impeller |

Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
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
| Return the maximum scale applied specifically to either the X axis or Y axis unit vectors (the bases). The matrix might lengthen a non-axis-aligned vector by more than this value. More...
std::optional< Scalar > | GetMinScale2D () const
| Return the smaller of the two non-negative scales that will be applied to 2D coordinates by this matrix. If the matrix has perspective components, the method will return a nullopt. More...
std::optional< Scalar > | GetMaxScale2D () const
| Return the smaller of the two non-negative scales that will be applied to 2D coordinates by this matrix. If the matrix has perspective components, the method will return a nullopt. More...
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< MatrixDecomposition > | Decompose () const
std::optional< std::pair< Scalar, Scalar > > | GetScales2D () const
| Compute the two non-negative scales applied by this matrix to 2D coordinates and return them as an optional pair of Scalar values in any order. If the matrix has perspective elements, this method will return a nullopt. More...
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 | ( |  | ) |
| inline constexpr

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)} {}
impeller::Matrix::vec
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
| ) |  |
| inline constexpr

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 14 of file matrix.cc.

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

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 }
impeller::Matrix::m
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 | ) |
| inline static

Definition at line 685 of file matrix.h.

685 {
686 // The precision of a float around 1.0 is much lower than it is
687 // around 0.0, so we end up with cases on quadrant rotations where
688 // we get a +/-1.0 for one of the values and a non-zero value for
689 // the other. This happens around quadrant rotations which makes it
690 // especially common and results in unclean quadrant rotation
691 // matrices which do not return true from |IsAligned[2D]| even
692 // though that is exactly where you need them to exhibit that property.
693 // It also injects small floating point mantissa errors into the
694 // matrices whenever you concatenate them with a quadrant rotation.
695 //
696 // This issue is also exacerbated by the fact that, in radians, the
697 // angles for quadrant rotations are irrational numbers. The measuring
698 // error for representing 90 degree multiples is small enough that
699 // either sin or cos will return a value near +/-1.0, but not small
700 // enough that the other value will be a clean 0.0.
701 //
702 // Some geometry packages simply discard very small numbers from
703 // sin/cos, but the following approach specifically targets just the
704 // area around a quadrant rotation (where either the sin or cos are
705 // measuring as +/-1.0) for symmetry of precision.
706
707 Scalar sin = std::sin(radians.radians);
708 if (std::abs(sin) == 1.0f) {
709 // 90 or 270 degrees (mod 360)
710 return {0.0f, sin};
711 } else {
712 Scalar cos = std::cos(radians.radians);
713 if (std::abs(cos) == 1.0f) {
714 // 0 or 180 degrees (mod 360)
715 return {cos, 0.0f};
716 }
717 return {cos, sin};
718 }
719 }
impeller::Scalar
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 202 of file matrix.cc.

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

520 {
521 const Scalar* a = m;
522 const Scalar* b = matrix.m;
523 return ScalarNearlyEqual(a[0], b[0], epsilon) &&
524 ScalarNearlyEqual(a[1], b[1], epsilon) &&
525 ScalarNearlyEqual(a[2], b[2], epsilon) &&
526 ScalarNearlyEqual(a[3], b[3], epsilon) &&
527 ScalarNearlyEqual(a[4], b[4], epsilon) &&
528 ScalarNearlyEqual(a[5], b[5], epsilon) &&
529 ScalarNearlyEqual(a[6], b[6], epsilon) &&
530 ScalarNearlyEqual(a[7], b[7], epsilon) &&
531 ScalarNearlyEqual(a[8], b[8], epsilon) &&
532 ScalarNearlyEqual(a[9], b[9], epsilon) &&
533 ScalarNearlyEqual(a[10], b[10], epsilon) &&
534 ScalarNearlyEqual(a[11], b[11], epsilon) &&
535 ScalarNearlyEqual(a[12], b[12], epsilon) &&
536 ScalarNearlyEqual(a[13], b[13], epsilon) &&
537 ScalarNearlyEqual(a[14], b[14], epsilon) &&
538 ScalarNearlyEqual(a[15], b[15], epsilon);
539 }
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::ScalarNearlyEqual
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
| inline constexpr

Definition at line 388 of file matrix.h.

388 { 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
| inline constexpr

Definition at line 390 of file matrix.h.

390 { 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
| inline constexpr

Definition at line 392 of file matrix.h.

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

References m.

Referenced by GetScale().

## ◆ GetDeterminant()

Scalar impeller::Matrix::GetDeterminant | ( |  | ) | const

Definition at line 164 of file matrix.cc.

164 {
165 auto a00 = e[0][0];
166 auto a01 = e[0][1];
167 auto a02 = e[0][2];
168 auto a03 = e[0][3];
169 auto a10 = e[1][0];
170 auto a11 = e[1][1];
171 auto a12 = e[1][2];
172 auto a13 = e[1][3];
173 auto a20 = e[2][0];
174 auto a21 = e[2][1];
175 auto a22 = e[2][2];
176 auto a23 = e[2][3];
177 auto a30 = e[3][0];
178 auto a31 = e[3][1];
179 auto a32 = e[3][2];
180 auto a33 = e[3][3];
181
182 auto b00 = a00 * a11 - a01 * a10;
183 auto b01 = a00 * a12 - a02 * a10;
184 auto b02 = a00 * a13 - a03 * a10;
185 auto b03 = a01 * a12 - a02 * a11;
186 auto b04 = a01 * a13 - a03 * a11;
187 auto b05 = a02 * a13 - a03 * a12;
188 auto b06 = a20 * a31 - a21 * a30;
189 auto b07 = a20 * a32 - a22 * a30;
190 auto b08 = a20 * a33 - a23 * a30;
191 auto b09 = a21 * a32 - a22 * a31;
192 auto b10 = a21 * a33 - a23 * a31;
193 auto b11 = a22 * a33 - a23 * a32;
194
195 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
196 }

References e.

Referenced by IsInvertible().

## ◆ GetDirectionScale()

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

Definition at line 399 of file matrix.h.

399 {
400 return 1.0f / (this->Basis().Invert() * direction.Normalize()).GetLength() *
401 direction.GetLength();
402 }
impeller::Matrix::Basis
constexpr Matrix Basis() const
The Matrix without its w components (without translation).
Definition: matrix.h:239
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:99

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

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

## ◆ GetMaxBasisLengthXY()

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

Return the maximum scale applied specifically to either the X axis or Y axis unit vectors (the bases). The matrix might lengthen a non-axis-aligned vector by more than this value.

See also
  |GetMaxScale2D|

Definition at line 328 of file matrix.h.

328 {
329 // The full basis computation requires computing the squared scaling factor
330 // for translate/scale only matrices. This substantially limits the range of
331 // precision for small and large scales. Instead, check for the common cases
332 // and directly return the max scaling factor.
333 if (e[0][1] == 0 && e[1][0] == 0) {
334 return std::max(std::abs(e[0][0]), std::abs(e[1][1]));
335 }
336 return std::sqrt(std::max(e[0][0] * e[0][0] + e[0][1] * e[0][1],
337 e[1][0] * e[1][0] + e[1][1] * e[1][1]));
338 }

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().

## ◆ GetMaxScale2D()

std::optional<Scalar> impeller::Matrix::GetMaxScale2D | ( |  | ) | const
| inline

Return the smaller of the two non-negative scales that will be applied to 2D coordinates by this matrix. If the matrix has perspective components, the method will return a nullopt.

Note that negative scale factors really represent a positive scale factor with a flip, so the absolute value (the positive scale factor) is returned instead so that the results can be directly applied to rendering calculations to compute the potential size of an operation.

This method differs from the "basis length" methods in that those methods answer the question "how much does this transform stretch perfectly horizontal or vertical source vectors, whereas this method can answer "what's the largest scale applied to any vector regardless of direction".

See also
  |GetScales2D|

Definition at line 380 of file matrix.h.

380 {
381 auto scales = GetScales2D();
382 if (!scales.has_value()) {
383 return std::nullopt;
384 }
385 return std::max(scales->first, scales->second);
386 }
impeller::Matrix::GetScales2D
std::optional< std::pair< Scalar, Scalar > > GetScales2D() const
Compute the two non-negative scales applied by this matrix to 2D coordinates and return them as an op...
Definition: matrix.cc:363

References GetScales2D().

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

## ◆ GetMinScale2D()

std::optional<Scalar> impeller::Matrix::GetMinScale2D | ( |  | ) | const
| inline

Return the smaller of the two non-negative scales that will be applied to 2D coordinates by this matrix. If the matrix has perspective components, the method will return a nullopt.

Note that negative scale factors really represent a positive scale factor with a flip, so the absolute value (the positive scale factor) is returned instead so that the results can be directly applied to rendering calculations to compute the potential size of an operation.

This method differs from the "basis length" methods in that those methods answer the question "how much does this transform stretch perfectly horizontal or vertical source vectors, whereas this method can answer "what's the smallest scale applied to any vector regardless of direction".

See also
  |GetScales2D|

Definition at line 356 of file matrix.h.

356 {
357 auto scales = GetScales2D();
358 if (!scales.has_value()) {
359 return std::nullopt;
360 }
361 return std::min(scales->first, scales->second);
362 }

References GetScales2D().

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

## ◆ GetScale()

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

Definition at line 394 of file matrix.h.

394 {
395 return Vector3(GetBasisX().GetLength(), GetBasisY().GetLength(),
396 GetBasisZ().GetLength());
397 }
impeller::Matrix::GetBasisY
constexpr Vector3 GetBasisY() const
Definition: matrix.h:390
impeller::Matrix::GetBasisZ
constexpr Vector3 GetBasisZ() const
Definition: matrix.h:392
impeller::Matrix::GetBasisX
constexpr Vector3 GetBasisX() const
Definition: matrix.h:388

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

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

## ◆ GetScales2D()

std::optional< std::pair< Scalar, Scalar > > impeller::Matrix::GetScales2D | ( |  | ) | const

Compute the two non-negative scales applied by this matrix to 2D coordinates and return them as an optional pair of Scalar values in any order. If the matrix has perspective elements, this method will return a nullopt.

Note that negative scale factors really represent a positive scale factor with a flip, so the absolute value (the positive scale factor) is returned instead so that the results can be directly applied to rendering calculations to compute the potential size of an operation.

See also
  |GetMinScale2D|
  |GetMaxScale2D|

Definition at line 363 of file matrix.cc.

363 {
364 if (HasPerspective2D()) {
365 return std::nullopt;
366 }
367
368 // We only operate on the uppermost 2x2 matrix since those are the only
369 // values that can induce a scale on 2D coordinates.
370 // [ a b ]
371 // [ c d ]
372 double a = m[0];
373 double b = m[1];
374 double c = m[4];
375 double d = m[5];
376
377 if (b == 0.0f && c == 0.0f) {
378 return {{std::abs(a), std::abs(d)}};
379 }
380
381 if (a == 0.0f && d == 0.0f) {
382 return {{std::abs(b), std::abs(c)}};
383 }
384
385 // Compute eigenvalues for the matrix (transpose(A) * A):
386 // [ a2 b2 ] == [ a b ] [ a c ] == [ aa + bb ac + bd ]
387 // [ c2 d2 ] [ c d ] [ b d ] [ ac + bd cc + dd ]
388 // (note the reverse diagonal entries in the answer are identical)
389 double a2 = a * a + b * b;
390 double b2 = a * c + b * d;
391 double c2 = b2;
392 double d2 = c * c + d * d;
393
394 //
395 // If L is an eigenvalue, then
396 // det(this - L*Identity) == 0
397 // det([ a - L b ]
398 // [ c d - L ]) == 0
399 // (a - L) * (d - L) - bc == 0
400 // ad - aL - dL + L^2 - bc == 0
401 // L^2 + (-a + -d)L + ad - bc == 0
402 //
403 // Using quadratic equation for (Ax^2 + Bx + C):
404 // A == 1
405 // B == -(a2 + d2)
406 // C == a2d2 - b2c2
407 //
408 // (We use -B for calculations because the square is the same as B and we
409 // need -B for the final quadratic equation computations anyway.)
410 double minus_B = a2 + d2;
411 double C = a2 * d2 - b2 * c2;
412 double B_squared_minus_4AC = minus_B * minus_B - 4 * 1.0f * C;
413
414 double quadratic_sqrt;
415 if (B_squared_minus_4AC <= 0.0f) {
416 // This test should never fail, but we might be slightly negative
417 FML_DCHECK(B_squared_minus_4AC + kEhCloseEnough >= 0.0f);
418 // Uniform scales (possibly rotated) would tend to end up here
419 // in which case both eigenvalues are identical
420 quadratic_sqrt = 0.0f;
421 } else {
422 quadratic_sqrt = std::sqrt(B_squared_minus_4AC);
423 }
424
425 // Since this is returning the sqrt of the values, we can guarantee that
426 // the returned scales are non-negative.
427 FML_DCHECK(minus_B - quadratic_sqrt >= 0.0f);
428 FML_DCHECK(minus_B + quadratic_sqrt >= 0.0f);
429 return {{std::sqrt((minus_B - quadratic_sqrt) / 2.0f),
430 std::sqrt((minus_B + quadratic_sqrt) / 2.0f)}};
431 }
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:57
impeller::Matrix::HasPerspective2D
constexpr bool HasPerspective2D() const
Definition: matrix.h:414

References impeller::saturated::b, HasPerspective2D(), impeller::kEhCloseEnough, and m.

Referenced by GetMaxScale2D(), GetMinScale2D(), and impeller::testing::TEST().

## ◆ HasPerspective()

constexpr bool impeller::Matrix::HasPerspective | ( |  | ) | const
| inline constexpr

Definition at line 418 of file matrix.h.

418 {
419 return m[3] != 0 || m[7] != 0 || m[11] != 0 || m[15] != 1;
420 }

References m.

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

## ◆ HasPerspective2D()

constexpr bool impeller::Matrix::HasPerspective2D | ( |  | ) | const
| inline constexpr

Definition at line 414 of file matrix.h.

414 {
415 return m[3] != 0 || m[7] != 0 || m[15] != 1;
416 }

References m.

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

## ◆ HasTranslation()

constexpr bool impeller::Matrix::HasTranslation | ( |  | ) | const
| inline constexpr

Definition at line 422 of file matrix.h.

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

References m.

## ◆ Invert()

Matrix impeller::Matrix::Invert | ( |  | ) | const

Definition at line 99 of file matrix.cc.

99 {
100 Matrix tmp{
101 m[5] * m[10] * m[15] - m[5] * m[11] * m[14] - m[9] * m[6] * m[15] +
102 m[9] * m[7] * m[14] + m[13] * m[6] * m[11] - m[13] * m[7] * m[10],
103
104 -m[1] * m[10] * m[15] + m[1] * m[11] * m[14] + m[9] * m[2] * m[15] -
105 m[9] * m[3] * m[14] - m[13] * m[2] * m[11] + m[13] * m[3] * m[10],
106
107 m[1] * m[6] * m[15] - m[1] * m[7] * m[14] - m[5] * m[2] * m[15] +
108 m[5] * m[3] * m[14] + m[13] * m[2] * m[7] - m[13] * m[3] * m[6],
109
110 -m[1] * m[6] * m[11] + m[1] * m[7] * m[10] + m[5] * m[2] * m[11] -
111 m[5] * m[3] * m[10] - m[9] * m[2] * m[7] + m[9] * m[3] * m[6],
112
113 -m[4] * m[10] * m[15] + m[4] * m[11] * m[14] + m[8] * m[6] * m[15] -
114 m[8] * m[7] * m[14] - m[12] * m[6] * m[11] + m[12] * m[7] * m[10],
115
116 m[0] * m[10] * m[15] - m[0] * m[11] * m[14] - m[8] * m[2] * m[15] +
117 m[8] * m[3] * m[14] + m[12] * m[2] * m[11] - m[12] * m[3] * m[10],
118
119 -m[0] * m[6] * m[15] + m[0] * m[7] * m[14] + m[4] * m[2] * m[15] -
120 m[4] * m[3] * m[14] - m[12] * m[2] * m[7] + m[12] * m[3] * m[6],
121
122 m[0] * m[6] * m[11] - m[0] * m[7] * m[10] - m[4] * m[2] * m[11] +
123 m[4] * m[3] * m[10] + m[8] * m[2] * m[7] - m[8] * m[3] * m[6],
124
125 m[4] * m[9] * m[15] - m[4] * m[11] * m[13] - m[8] * m[5] * m[15] +
126 m[8] * m[7] * m[13] + m[12] * m[5] * m[11] - m[12] * m[7] * m[9],
127
128 -m[0] * m[9] * m[15] + m[0] * m[11] * m[13] + m[8] * m[1] * m[15] -
129 m[8] * m[3] * m[13] - m[12] * m[1] * m[11] + m[12] * m[3] * m[9],
130
131 m[0] * m[5] * m[15] - m[0] * m[7] * m[13] - m[4] * m[1] * m[15] +
132 m[4] * m[3] * m[13] + m[12] * m[1] * m[7] - m[12] * m[3] * m[5],
133
134 -m[0] * m[5] * m[11] + m[0] * m[7] * m[9] + m[4] * m[1] * m[11] -
135 m[4] * m[3] * m[9] - m[8] * m[1] * m[7] + m[8] * m[3] * m[5],
136
137 -m[4] * m[9] * m[14] + m[4] * m[10] * m[13] + m[8] * m[5] * m[14] -
138 m[8] * m[6] * m[13] - m[12] * m[5] * m[10] + m[12] * m[6] * m[9],
139
140 m[0] * m[9] * m[14] - m[0] * m[10] * m[13] - m[8] * m[1] * m[14] +
141 m[8] * m[2] * m[13] + m[12] * m[1] * m[10] - m[12] * m[2] * m[9],
142
143 -m[0] * m[5] * m[14] + m[0] * m[6] * m[13] + m[4] * m[1] * m[14] -
144 m[4] * m[2] * m[13] - m[12] * m[1] * m[6] + m[12] * m[2] * m[5],
145
146 m[0] * m[5] * m[10] - m[0] * m[6] * m[9] - m[4] * m[1] * m[10] +
147 m[4] * m[2] * m[9] + m[8] * m[1] * m[6] - m[8] * m[2] * m[5]};
148
149 Scalar det =
150 m[0] * tmp.m[0] + m[1] * tmp.m[4] + m[2] * tmp.m[8] + m[3] * tmp.m[12];
151
152 if (det == 0) {
153 return {};
154 }
155
156 det = 1.0 / det;
157
158 return {tmp.m[0] * det, tmp.m[1] * det, tmp.m[2] * det, tmp.m[3] * det,
159 tmp.m[4] * det, tmp.m[5] * det, tmp.m[6] * det, tmp.m[7] * det,
160 tmp.m[8] * det, tmp.m[9] * det, tmp.m[10] * det, tmp.m[11] * det,
161 tmp.m[12] * det, tmp.m[13] * det, tmp.m[14] * det, tmp.m[15] * det};
162 }

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
| inline constexpr

Definition at line 409 of file matrix.h.

409 {
410 return (m[2] == 0 && m[3] == 0 && m[6] == 0 && m[7] == 0 && m[8] == 0 &&
411 m[9] == 0 && m[10] == 1 && m[11] == 0 && m[14] == 0 && m[15] == 1);
412 }

References m.

## ◆ IsAligned()

constexpr bool impeller::Matrix::IsAligned | ( | Scalar | tolerance = `0` | ) | const
| inline constexpr

Definition at line 439 of file matrix.h.

439 {
440 if (HasPerspective()) {
441 return false;
442 }
443 int v[] = {!ScalarNearlyZero(m[0], tolerance), //
444 !ScalarNearlyZero(m[1], tolerance), //
445 !ScalarNearlyZero(m[2], tolerance), //
446 !ScalarNearlyZero(m[4], tolerance), //
447 !ScalarNearlyZero(m[5], tolerance), //
448 !ScalarNearlyZero(m[6], tolerance), //
449 !ScalarNearlyZero(m[8], tolerance), //
450 !ScalarNearlyZero(m[9], tolerance), //
451 !ScalarNearlyZero(m[10], tolerance)};
452 // Check if all three basis vectors are aligned to an axis.
453 if (v[0] + v[1] + v[2] != 1 || //
454 v[3] + v[4] + v[5] != 1 || //
455 v[6] + v[7] + v[8] != 1) {
456 return false;
457 }
458 // Ensure that none of the basis vectors overlap.
459 if (v[0] + v[3] + v[6] != 1 || //
460 v[1] + v[4] + v[7] != 1 || //
461 v[2] + v[5] + v[8] != 1) {
462 return false;
463 }
464 return true;
465 }
impeller::ScalarNearlyZero
constexpr bool ScalarNearlyZero(Scalar x, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:31
impeller::Matrix::HasPerspective
constexpr bool HasPerspective() const
Definition: matrix.h:418

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

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

## ◆ IsAligned2D()

constexpr bool impeller::Matrix::IsAligned2D | ( | Scalar | tolerance = `0` | ) | const
| inline constexpr

Definition at line 424 of file matrix.h.

424 {
425 if (HasPerspective2D()) {
426 return false;
427 }
428 if (ScalarNearlyZero(m[1], tolerance) &&
429 ScalarNearlyZero(m[4], tolerance)) {
430 return true;
431 }
432 if (ScalarNearlyZero(m[0], tolerance) &&
433 ScalarNearlyZero(m[5], tolerance)) {
434 return true;
435 }
436 return false;
437 }

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

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

## ◆ IsFinite()

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

Definition at line 404 of file matrix.h.

404 {
405 return vec[0].IsFinite() && vec[1].IsFinite() && vec[2].IsFinite() &&
406 vec[3].IsFinite();
407 }
impeller::Vector4::IsFinite
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
| inline constexpr

Definition at line 467 of file matrix.h.

467 {
468 return (
469 // clang-format off
470 m[0] == 1.0f && m[1] == 0.0f && m[2] == 0.0f && m[3] == 0.0f &&
471 m[4] == 0.0f && m[5] == 1.0f && m[6] == 0.0f && m[7] == 0.0f &&
472 m[8] == 0.0f && m[9] == 0.0f && m[10] == 1.0f && m[11] == 0.0f &&
473 m[12] == 0.0f && m[13] == 0.0f && m[14] == 0.0f && m[15] == 1.0f
474 // clang-format on
475 );
476 }

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; }
impeller::Matrix::GetDeterminant
Scalar GetDeterminant() const
Definition: matrix.cc:164

References GetDeterminant().

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

## ◆ IsTranslationOnly()

constexpr bool impeller::Matrix::IsTranslationOnly | ( |  | ) | const
| inline constexpr

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

Definition at line 480 of file matrix.h.

480 {
481 return (
482 // clang-format off
483 m[0] == 1.0 && m[1] == 0.0 && m[2] == 0.0 && m[3] == 0.0 &&
484 m[4] == 0.0 && m[5] == 1.0 && m[6] == 0.0 && m[7] == 0.0 &&
485 m[8] == 0.0 && m[9] == 0.0 && m[10] == 1.0 && m[11] == 0.0 &&
486 m[15] == 1.0
487 // clang-format on
488 );
489 }

References m.

## ◆ IsTranslationScaleOnly()

constexpr bool impeller::Matrix::IsTranslationScaleOnly | ( |  | ) | const
| inline constexpr

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 493 of file matrix.h.

493 {
494 return (
495 // clang-format off
496 m[0] != 0.0 && m[1] == 0.0 && m[2] == 0.0 && m[3] == 0.0 &&
497 m[4] == 0.0 && m[5] != 0.0 && m[6] == 0.0 && m[7] == 0.0 &&
498 m[8] == 0.0 && m[9] == 0.0 && m[10] != 0.0 && m[11] == 0.0 &&
499 m[15] == 1.0
500 // clang-format on
501 );
502 }

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
| ) |  |
| inline static constexpr

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
| ) |  |
| inline static

Definition at line 668 of file matrix.h.

670 {
671 Vector3 forward = (target - position).Normalize();
672 Vector3 right = up.Cross(forward);
673 up = forward.Cross(right);
674
675 // clang-format off
676 return {
677 right.x, up.x, forward.x, 0.0f,
678 right.y, up.y, forward.y, 0.0f,
679 right.z, up.z, forward.z, 0.0f,
680 -right.Dot(position), -up.Dot(position), -forward.Dot(position), 1.0f
681 };
682 // clang-format on
683 }

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 | ) |
| inline static constexpr

Definition at line 633 of file matrix.h.

633 {
634 // Per assumptions about NDC documented above.
635 const auto scale =
636 MakeScale({2.0f / static_cast<Scalar>(size.width),
637 -2.0f / static_cast<Scalar>(size.height), 0.0f});
638 const auto translate = MakeTranslation({-1.0f, 1.0f, 0.5f});
639 return translate * scale;
640 }
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Matrix::MakeScale
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
| ) |  |
| inline static

Definition at line 642 of file matrix.h.

645 {
646 Scalar height = std::tan(fov_y.radians * 0.5f);
647 Scalar width = height * aspect_ratio;
648
649 // clang-format off
650 return {
651 1.0f / width, 0.0f, 0.0f, 0.0f,
652 0.0f, 1.0f / height, 0.0f, 0.0f,
653 0.0f, 0.0f, z_far / (z_far - z_near), 1.0f,
654 0.0f, 0.0f, -(z_far * z_near) / (z_far - z_near), 0.0f,
655 };
656 // clang-format on
657 }

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
| ) |  |
| inline static constexpr

Definition at line 660 of file matrix.h.

663 {
664 return MakePerspective(fov_y, static_cast<Scalar>(size.width) / size.height,
665 z_near, z_far);
666 }
impeller::Matrix::MakePerspective
static Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
Definition: matrix.h:642

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

## ◆ MakeRotation() [1/2]

static Matrix impeller::Matrix::MakeRotation | ( | Quaternion | q | ) |
| inline static

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
| ) |  |
| inline static

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 }
impeller::Vector2
Point Vector2
Definition: point.h:331
impeller::Matrix::CosSin
static Vector2 CosSin(Radians radians)
Definition: matrix.h:685

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 | ) |
| inline static

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 | ) |
| inline static

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 | ) |
| inline static

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
| ) |  |
| inline static constexpr

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 | ) |
| inline static constexpr

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 | ) |
| inline static constexpr

Definition at line 104 of file matrix.h.

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

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

Referenced by impeller::GaussianBlurFilterContents::CalculateUVs(), impeller::TextContents::ComputeVertexData(), impeller::TRect< T >::GetNormalizingTransform(), impeller::Snapshot::GetUVTransform(), MakeOrthographic(), MakeScale(), impeller::TextureContents::RenderToSnapshot(), impeller::TiledTextureContents::RenderToSnapshot(), impeller::Canvas::Scale(), impeller::testing::TEST(), and impeller::testing::TEST_P().

## ◆ MakeSkew()

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

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
| ) |  |
| inline static constexpr

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()

static constexpr Matrix impeller::Matrix::MakeTranslation | ( | const Vector3 & | t | ) |
| inline static constexpr

Definition at line 95 of file matrix.h.

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

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

Referenced by impeller::AdvancedBlend(), impeller::Canvas::ClipGeometry(), impeller::DlDispatcherBase::drawShadow(), impeller::FirstPassDispatcher::drawText(), impeller::Canvas::DrawTextFrame(), impeller::TextFrame::GetOffsetTransform(), MakeOrthographic(), impeller::PipelineBlend(), impeller::SolidRRectLikeBlurContents::Render(), impeller::Contents::RenderToSnapshot(), impeller::TextureContents::RenderToSnapshot(), impeller::TiledTextureContents::RenderToSnapshot(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::testing::TEST(), impeller::testing::TEST_P(), and impeller::Canvas::Translate().

## ◆ Multiply()

constexpr Matrix impeller::Matrix::Multiply | ( | const Matrix & | o | ) | const
| inline constexpr

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
| inline constexpr

Definition at line 550 of file matrix.h.

550 {
551 // clang-format off
552 return vec[0] != m.vec[0]
553 || vec[1] != m.vec[1]
554 || vec[2] != m.vec[2]
555 || vec[3] != m.vec[3];
556 // clang-format on
557 }

References m, and vec.

## ◆ operator*() [1/4]

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

Definition at line 563 of file matrix.h.

563 { return Multiply(m); }
impeller::Matrix::Multiply
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
| inline constexpr

Definition at line 588 of file matrix.h.

588 {
589 Scalar w = v.x * m[3] + v.y * m[7] + m[15];
590 Point result(v.x * m[0] + v.y * m[4] + m[12],
591 v.x * m[1] + v.y * m[5] + m[13]);
592
593 // This is Skia's behavior, but it may be reasonable to allow UB for the w=0
594 // case.
595 if (w) {
596 w = 1 / w;
597 }
598 return result * w;
599 }
impeller::Point
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
| inline constexpr

Definition at line 574 of file matrix.h.

574 {
575 Scalar w = v.x * m[3] + v.y * m[7] + v.z * m[11] + m[15];
576 Vector3 result(v.x * m[0] + v.y * m[4] + v.z * m[8] + m[12],
577 v.x * m[1] + v.y * m[5] + v.z * m[9] + m[13],
578 v.x * m[2] + v.y * m[6] + v.z * m[10] + m[14]);
579
580 // This is Skia's behavior, but it may be reasonable to allow UB for the w=0
581 // case.
582 if (w) {
583 w = 1 / w;
584 }
585 return result * w;
586 }

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

## ◆ operator*() [4/4]

constexpr Vector4 impeller::Matrix::operator* | ( | const Vector4 & | v | ) | const
| inline constexpr

Definition at line 567 of file matrix.h.

567 {
568 return Vector4(v.x * m[0] + v.y * m[4] + v.z * m[8] + v.w * m[12],
569 v.x * m[1] + v.y * m[5] + v.z * m[9] + v.w * m[13],
570 v.x * m[2] + v.y * m[6] + v.z * m[10] + v.w * m[14],
571 v.x * m[3] + v.y * m[7] + v.z * m[11] + v.w * m[15]);
572 }

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 90 of file matrix.cc.

90 {
91 return Matrix(
92 m[0] + o.m[0], m[1] + o.m[1], m[2] + o.m[2], m[3] + o.m[3], //
93 m[4] + o.m[4], m[5] + o.m[5], m[6] + o.m[6], m[7] + o.m[7], //
94 m[8] + o.m[8], m[9] + o.m[9], m[10] + o.m[10], m[11] + o.m[11], //
95 m[12] + o.m[12], m[13] + o.m[13], m[14] + o.m[14], m[15] + o.m[15] //
96 );
97 }

References m, and Matrix().

## ◆ operator+() [2/2]

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

Definition at line 559 of file matrix.h.

559 { return Translate(t); }
impeller::Matrix::Translate
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 561 of file matrix.h.

561 { return Translate(-t); }

References Translate().

## ◆ operator==()

constexpr bool impeller::Matrix::operator== | ( | const Matrix & | m | ) | const
| inline constexpr

Definition at line 541 of file matrix.h.

541 {
542 // clang-format off
543 return vec[0] == m.vec[0]
544 && vec[1] == m.vec[1]
545 && vec[2] == m.vec[2]
546 && vec[3] == m.vec[3];
547 // clang-format on
548 }

References m, and vec.

## ◆ Scale()

constexpr Matrix impeller::Matrix::Scale | ( | const Vector3 & | s | ) | const
| inline constexpr

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
| inline constexpr

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
| inline constexpr

Definition at line 623 of file matrix.h.

623 {
624 return {
625 *this * quad[0],
626 *this * quad[1],
627 *this * quad[2],
628 *this * quad[3],
629 };
630 }

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

## ◆ TransformDirection() [1/3]

constexpr Vector2 impeller::Matrix::TransformDirection | ( | const Vector2 & | v | ) | const
| inline constexpr

Definition at line 619 of file matrix.h.

619 {
620 return Vector2(v.x * m[0] + v.y * m[4], v.x * m[1] + v.y * m[5]);
621 }

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

## ◆ TransformDirection() [2/3]

constexpr Vector3 impeller::Matrix::TransformDirection | ( | const Vector3 & | v | ) | const
| inline constexpr

Definition at line 613 of file matrix.h.

613 {
614 return Vector3(v.x * m[0] + v.y * m[4] + v.z * m[8],
615 v.x * m[1] + v.y * m[5] + v.z * m[9],
616 v.x * m[2] + v.y * m[6] + v.z * m[10]);
617 }

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

## ◆ TransformDirection() [3/3]

constexpr Vector4 impeller::Matrix::TransformDirection | ( | const Vector4 & | v | ) | const
| inline constexpr

Definition at line 607 of file matrix.h.

607 {
608 return Vector4(v.x * m[0] + v.y * m[4] + v.z * m[8],
609 v.x * m[1] + v.y * m[5] + v.z * m[9],
610 v.x * m[2] + v.y * m[6] + v.z * m[10], v.w);
611 }

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
| inline constexpr

Definition at line 601 of file matrix.h.

601 {
602 return Vector3(v.x * m[0] + v.y * m[4] + m[12],
603 v.x * m[1] + v.y * m[5] + m[13],
604 v.x * m[3] + v.y * m[7] + m[15]);
605 }

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
| inline constexpr

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
| inline constexpr

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]

Definition at line 40 of file matrix.h.

Referenced by Decompose(), GetDeterminant(), GetMaxBasisLengthXY(), Matrix(), std::operator<<(), and impeller::testing::TEST().

## ◆ m

Scalar impeller::Matrix::m[16]

Definition at line 39 of file matrix.h.

Referenced by Basis(), impeller::TextContents::ComputeVertexData(), Equals(), impeller::interop::FromImpellerType(), GetBasisX(), GetBasisY(), GetBasisZ(), GetScales2D(), HasPerspective(), HasPerspective2D(), HasTranslation(), Invert(), IsAffine(), IsAligned(), IsAligned2D(), IsIdentity(), IsTranslationOnly(), IsTranslationScaleOnly(), MatrixNear(), Multiply(), operator!=(), operator*(), operator+(), operator==(), Scale(), impeller::testing::TEST(), To3x3(), impeller::interop::ToSkMatrix(), TransformDirection(), TransformHomogenous(), Translate(), and Transpose().

## ◆ 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:

- impeller/geometry/matrix.h
- impeller/geometry/matrix.cc