| Flutter Impeller |

matrix_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gtest/gtest.h"
6
7 #include "flutter/impeller/geometry/matrix.h"
8
9 #include "flutter/impeller/geometry/geometry_asserts.h"
10 #include "impeller/geometry/constants.h"
11
12 namespace impeller {
13 namespace testing {
14
15 TEST(MatrixTest, Multiply) {
16 Matrix x(0.0, 0.0, 0.0, 1.0, //
17 1.0, 0.0, 0.0, 1.0, //
18 0.0, 1.0, 0.0, 1.0, //
19 1.0, 1.0, 0.0, 1.0);
20 Matrix translate = Matrix::MakeTranslation({10, 20, 0});
21 Matrix result = translate * x;
22 EXPECT_TRUE(MatrixNear(result, Matrix(10.0, 20.0, 0.0, 1.0, //
23 11.0, 20.0, 0.0, 1.0, //
24 10.0, 21.0, 0.0, 1.0, //
25 11.0, 21.0, 0.0, 1.0)));
26 }
27
28 TEST(MatrixTest, Equals) {
29 Matrix x;
30 Matrix y = x;
31 EXPECT_TRUE(x.Equals(y));
32 }
33
34 TEST(MatrixTest, NotEquals) {
35 Matrix x;
36 Matrix y = x.Translate({1, 0, 0});
37 EXPECT_FALSE(x.Equals(y));
38 }
39
40 TEST(MatrixTest, HasPerspective2D) {
41 EXPECT_FALSE(Matrix().HasPerspective2D());
42
43 auto test = [](int index, bool expect) {
44 Matrix matrix;
45 EXPECT_FALSE(matrix.HasPerspective2D());
46 matrix.m[index] = 0.5f;
47 EXPECT_EQ(matrix.HasPerspective2D(), expect) << "index: " << index;
48 };
49
50 // clang-format off
51 test( 0, false); test( 1, false); test( 2, false); test( 3, true);
52 test( 4, false); test( 5, false); test( 6, false); test( 7, true);
53 test( 8, false); test( 9, false); test(10, false); test(11, false);
54 test(12, false); test(13, false); test(14, false); test(15, true);
55 // clang-format on
56 }
57
58 TEST(MatrixTest, HasPerspective) {
59 EXPECT_FALSE(Matrix().HasPerspective());
60
61 auto test = [](int index, bool expect) {
62 Matrix matrix;
63 EXPECT_FALSE(matrix.HasPerspective());
64 matrix.m[index] = 0.5f;
65 EXPECT_EQ(matrix.HasPerspective(), expect) << "index: " << index;
66 };
67
68 // clang-format off
69 test( 0, false); test( 1, false); test( 2, false); test( 3, true);
70 test( 4, false); test( 5, false); test( 6, false); test( 7, true);
71 test( 8, false); test( 9, false); test(10, false); test(11, true);
72 test(12, false); test(13, false); test(14, false); test(15, true);
73 // clang-format on
74 }
75
76 TEST(MatrixTest, HasTranslation) {
77 EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).HasTranslation());
78 EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).HasTranslation());
79 EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).HasTranslation());
80 EXPECT_FALSE(Matrix().HasTranslation());
81 }
82
83 TEST(MatrixTest, IsTranslationOnly) {
84 EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsTranslationOnly());
85 EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsTranslationScaleOnly());
86 EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).IsTranslationOnly());
87 EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).IsTranslationScaleOnly());
88 EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).IsTranslationOnly());
89 EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).IsTranslationScaleOnly());
90 EXPECT_TRUE(Matrix().IsTranslationOnly());
91 EXPECT_TRUE(Matrix().IsTranslationScaleOnly());
92 }
93
94 TEST(MatrixTest, IsTranslationScaleOnly) {
95 EXPECT_FALSE(Matrix::MakeScale({100, 100, 1}).IsTranslationOnly());
96 EXPECT_TRUE(Matrix::MakeScale({100, 100, 1}).IsTranslationScaleOnly());
97 EXPECT_FALSE(Matrix::MakeScale({1, 100, 1}).IsTranslationOnly());
98 EXPECT_TRUE(Matrix::MakeScale({1, 100, 1}).IsTranslationScaleOnly());
99 EXPECT_FALSE(Matrix::MakeScale({100, 1, 1}).IsTranslationOnly());
100 EXPECT_TRUE(Matrix::MakeScale({100, 1, 1}).IsTranslationScaleOnly());
101 EXPECT_TRUE(Matrix().IsTranslationOnly());
102 EXPECT_TRUE(Matrix().IsTranslationScaleOnly());
103 }
104
105 TEST(MatrixTest, IsInvertibleGetDeterminant) {
106 EXPECT_TRUE(Matrix().IsInvertible());
107 EXPECT_NE(Matrix().GetDeterminant(), 0.0f);
108
109 EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsInvertible());
110 EXPECT_NE(Matrix::MakeTranslation({100, 100, 0}).GetDeterminant(), 0.0f);
111
112 EXPECT_TRUE(Matrix::MakeScale({100, 100, 1}).IsInvertible());
113 EXPECT_NE(Matrix::MakeScale({100, 100, 1}).GetDeterminant(), 0.0f);
114
115 EXPECT_TRUE(Matrix::MakeRotationX(Degrees(30)).IsInvertible());
116 EXPECT_NE(Matrix::MakeRotationX(Degrees(30)).GetDeterminant(), 0.0f);
117
118 EXPECT_TRUE(Matrix::MakeRotationY(Degrees(30)).IsInvertible());
119 EXPECT_NE(Matrix::MakeRotationY(Degrees(30)).GetDeterminant(), 0.0f);
120
121 EXPECT_TRUE(Matrix::MakeRotationZ(Degrees(30)).IsInvertible());
122 EXPECT_NE(Matrix::MakeRotationZ(Degrees(30)).GetDeterminant(), 0.0f);
123
124 EXPECT_FALSE(Matrix::MakeScale({0, 1, 1}).IsInvertible());
125 EXPECT_EQ(Matrix::MakeScale({0, 1, 1}).GetDeterminant(), 0.0f);
126 EXPECT_FALSE(Matrix::MakeScale({1, 0, 1}).IsInvertible());
127 EXPECT_EQ(Matrix::MakeScale({1, 0, 1}).GetDeterminant(), 0.0f);
128 EXPECT_FALSE(Matrix::MakeScale({1, 1, 0}).IsInvertible());
129 EXPECT_EQ(Matrix::MakeScale({1, 1, 0}).GetDeterminant(), 0.0f);
130 }
131
132 TEST(MatrixTest, IsFinite) {
133 EXPECT_TRUE(Matrix().IsFinite());
134
135 EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsFinite());
136 EXPECT_TRUE(Matrix::MakeScale({100, 100, 1}).IsFinite());
137
138 EXPECT_TRUE(Matrix::MakeRotationX(Degrees(30)).IsFinite());
139 EXPECT_TRUE(Matrix::MakeRotationY(Degrees(30)).IsFinite());
140 EXPECT_TRUE(Matrix::MakeRotationZ(Degrees(30)).IsFinite());
141
142 EXPECT_TRUE(Matrix::MakeScale({0, 1, 1}).IsFinite());
143 EXPECT_TRUE(Matrix::MakeScale({1, 0, 1}).IsFinite());
144 EXPECT_TRUE(Matrix::MakeScale({1, 1, 0}).IsFinite());
145
146 for (int i = 0; i < 16; i++) {
147 {
148 Matrix matrix;
149 ASSERT_TRUE(matrix.IsFinite());
150 matrix.m[i] = std::numeric_limits<Scalar>::infinity();
151 ASSERT_FALSE(matrix.IsFinite());
152 }
153
154 {
155 Matrix matrix;
156 ASSERT_TRUE(matrix.IsFinite());
157 matrix.m[i] = -std::numeric_limits<Scalar>::infinity();
158 ASSERT_FALSE(matrix.IsFinite());
159 }
160
161 {
162 Matrix matrix;
163 ASSERT_TRUE(matrix.IsFinite());
164 matrix.m[i] = -std::numeric_limits<Scalar>::quiet_NaN();
165 ASSERT_FALSE(matrix.IsFinite());
166 }
167 }
168 }
169
170 TEST(MatrixTest, IsAligned2D) {
171 EXPECT_TRUE(Matrix().IsAligned2D());
172 EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned2D());
173
174 auto test = [](int index, bool expect) {
175 Matrix matrix;
176 EXPECT_TRUE(matrix.IsAligned2D());
177 matrix.m[index] = 0.5f;
178 EXPECT_EQ(matrix.IsAligned2D(), expect) << "index: " << index;
179 };
180
181 // clang-format off
182 test( 0, true); test( 1, false); test( 2, true); test( 3, false);
183 test( 4, false); test( 5, true); test( 6, true); test( 7, false);
184 test( 8, true); test( 9, true); test(10, true); test(11, true);
185 test(12, true); test(13, true); test(14, true); test(15, false);
186 // clang-format on
187
188 // True for quadrant rotations from -250 to +250 full circles
189 for (int i = -1000; i < 1000; i++) {
190 Degrees d = Degrees(i * 90);
191 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
192 EXPECT_TRUE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
193 }
194
195 // False for half degree rotations from -999.5 to +1000.5 degrees
196 for (int i = -1000; i < 1000; i++) {
197 Degrees d = Degrees(i + 0.5f);
198 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
199 EXPECT_FALSE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
200 }
201 }
202
203 TEST(MatrixTest, IsAligned) {
204 EXPECT_TRUE(Matrix().IsAligned());
205 EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned());
206
207 // Begin Legacy tests transferred over from geometry_unittests.cc
208 {
209 auto m = Matrix::MakeTranslation({1, 2, 3});
210 bool result = m.IsAligned();
211 ASSERT_TRUE(result);
212 }
213
214 {
215 auto m = Matrix::MakeRotationZ(Degrees{123});
216 bool result = m.IsAligned();
217 ASSERT_FALSE(result);
218 }
219 // End Legacy tests transferred over from geometry_unittests.cc
220
221 auto test = [](int index, bool expect) {
222 Matrix matrix;
223 EXPECT_TRUE(matrix.IsAligned());
224 matrix.m[index] = 0.5f;
225 EXPECT_EQ(matrix.IsAligned(), expect) << "index: " << index;
226 };
227
228 // clang-format off
229 test( 0, true); test( 1, false); test( 2, false); test( 3, false);
230 test( 4, false); test( 5, true); test( 6, false); test( 7, false);
231 test( 8, false); test( 9, false); test(10, true); test(11, false);
232 test(12, true); test(13, true); test(14, true); test(15, false);
233 // clang-format on
234
235 // True for quadrant rotations from -250 to +250 full circles
236 for (int i = -1000; i < 1000; i++) {
237 Degrees d = Degrees(i * 90);
238 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
239 EXPECT_TRUE(matrix.IsAligned()) << "degrees: " << d.degrees;
240 }
241
242 // False for half degree rotations from -999.5 to +1000.5 degrees
243 for (int i = -1000; i < 1000; i++) {
244 Degrees d = Degrees(i + 0.5f);
245 Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
246 EXPECT_FALSE(matrix.IsAligned()) << "degrees: " << d.degrees;
247 }
248 }
249
250 TEST(MatrixTest, TransformHomogenous) {
251 Matrix matrix = Matrix::MakeColumn(
252 // clang-format off
253 2.0f, 3.0f, 5.0f, 7.0f,
254 11.0f, 13.0f, 17.0f, 19.0f,
255 23.0f, 29.0f, 31.0f, 37.0f,
256 41.0f, 43.0f, 47.0f, 53.0f
257 // clang-format on
258 );
259 EXPECT_EQ(matrix.TransformHomogenous({1.0f, -1.0f}),
260 Vector3(32.0f, 33.0f, 41.0f));
261 }
262
263 TEST(MatrixTest, GetMaxBasisXYNegativeScale) {
264 Matrix m = Matrix::MakeScale({-2, 1, 1});
265
266 EXPECT_EQ(m.GetMaxBasisLengthXY(), 2);
267
268 m = Matrix::MakeScale({1, -3, 1});
269
270 EXPECT_EQ(m.GetMaxBasisLengthXY(), 3);
271 }
272
273 // Verifies a translate scale matrix doesn't need to compute sqrt(pow(scale, 2))
274 TEST(MatrixTest, GetMaxBasisXYWithLargeAndSmallScalingFactor) {
275 Matrix m = Matrix::MakeScale({2.625e+20, 2.625e+20, 1});
276 EXPECT_NEAR(m.GetMaxBasisLengthXY(), 2.625e+20, 1e+20);
277
278 m = Matrix::MakeScale({2.625e-20, 2.625e-20, 1});
279 EXPECT_NEAR(m.GetMaxBasisLengthXY(), 2.625e-20, 1e-20);
280 }
281
282 TEST(MatrixTest, GetMaxBasisXYWithLargeAndSmallScalingFactorNonScaleTranslate) {
283 Matrix m = Matrix::MakeScale({2.625e+20, 2.625e+20, 1});
284 m.e[0][1] = 2;
285
286 EXPECT_TRUE(std::isinf(m.GetMaxBasisLengthXY()));
287 }
288
289 TEST(MatrixTest, TranslateWithPerspective) {
290 Matrix m = Matrix::MakeRow(1.0, 0.0, 0.0, 10.0, //
291 0.0, 1.0, 0.0, 20.0, //
292 0.0, 0.0, 1.0, 0.0, //
293 0.0, 2.0, 0.0, 30.0);
294 Matrix result = m.Translate({100, 200});
295 EXPECT_TRUE(MatrixNear(result, Matrix::MakeRow(1.0, 0.0, 0.0, 110.0, //
296 0.0, 1.0, 0.0, 220.0, //
297 0.0, 0.0, 1.0, 0.0, //
298 0.0, 2.0, 0.0, 430.0)));
299 }
300
301 TEST(MatrixTest, MakeScaleTranslate) {
302 EXPECT_TRUE(MatrixNear(
303 Matrix::MakeTranslateScale({1, 1, 1.0 / 1024}, {10, 10, 1.0 / 1024}),
304 Matrix::MakeTranslation({10, 10, 1.0 / 1024}) *
305 Matrix::MakeScale({1, 1, 1.0 / 1024})));
306
307 EXPECT_TRUE(MatrixNear(
308 Matrix::MakeTranslateScale({2, 2, 2}, {10, 10, 0}),
309 Matrix::MakeTranslation({10, 10, 0}) * Matrix::MakeScale({2, 2, 2})));
310
311 EXPECT_TRUE(MatrixNear(
312 Matrix::MakeTranslateScale({0, 0, 0}, {0, 0, 0}),
313 Matrix::MakeTranslation({0, 0, 0}) * Matrix::MakeScale({0, 0, 0})));
314 }
315
316 TEST(MatrixTest, To3x3) {
317 Matrix x(1.0, 0.0, 4.0, 0.0, //
318 0.0, 1.0, 4.0, 0.0, //
319 6.0, 5.0, 111.0, 7.0, //
320 0.0, 0.0, 9.0, 1.0);
321
322 EXPECT_TRUE(MatrixNear(x.To3x3(), Matrix()));
323 }
324
325 TEST(MatrixTest, MinMaxScales2D) {
326 // The GetScales2D() method is allowed to return the scales in any
327 // order so we need to take special care in verifying the return
328 // value to test them in either order.
329 auto check_pair = [](const Matrix& matrix, Scalar scale1, Scalar scale2) {
330 auto pair = matrix.GetScales2D();
331 EXPECT_TRUE(pair.has_value())
332 << "Scales: " << scale1 << ", " << scale2 << ", " << matrix;
333 if (ScalarNearlyEqual(pair->first, scale1)) {
334 EXPECT_FLOAT_EQ(pair->first, scale1) << matrix;
335 EXPECT_FLOAT_EQ(pair->second, scale2) << matrix;
336 } else {
337 EXPECT_FLOAT_EQ(pair->first, scale2) << matrix;
338 EXPECT_FLOAT_EQ(pair->second, scale1) << matrix;
339 }
340 };
341
342 for (int i = 1; i < 10; i++) {
343 Scalar xScale = static_cast<Scalar>(i);
344 for (int j = 1; j < 10; j++) {
345 Scalar yScale = static_cast<Scalar>(j);
346 Scalar minScale = std::min(xScale, yScale);
347 Scalar maxScale = std::max(xScale, yScale);
348
349 {
350 // Simple scale
351 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
352 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
353 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
354 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
355 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
356 check_pair(matrix, xScale, yScale);
357 }
358
359 {
360 // Simple scale with Z scale
361 Matrix matrix = Matrix::MakeScale({xScale, yScale, 5.0f});
362 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
363 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
364 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
365 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
366 check_pair(matrix, xScale, yScale);
367 }
368
369 {
370 // Simple scale + translate
371 Matrix matrix = Matrix::MakeTranslateScale({xScale, yScale, 1.0f},
372 {10.0f, 15.0f, 2.0f});
373 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
374 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
375 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
376 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
377 check_pair(matrix, xScale, yScale);
378 }
379
380 for (int d = 45; d < 360; d += 45) {
381 {
382 // Rotation * Scale
383 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f}) *
384 Matrix::MakeRotationZ(Degrees(d));
385 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
386 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
387 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
388 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
389 check_pair(matrix, xScale, yScale);
390 }
391
392 {
393 // Scale * Rotation
394 Matrix matrix = Matrix::MakeRotationZ(Degrees(d)) *
395 Matrix::MakeScale({xScale, yScale, 1.0f});
396 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
397 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
398 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
399 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
400 check_pair(matrix, xScale, yScale);
401 }
402 }
403
404 {
405 // Scale + PerspectiveX (returns invalid values)
406 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
407 matrix.m[3] = 0.1;
408 EXPECT_FALSE(matrix.GetMinScale2D().has_value());
409 EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
410 EXPECT_FALSE(matrix.GetScales2D().has_value());
411 }
412
413 {
414 // Scale + PerspectiveY (returns invalid values)
415 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
416 matrix.m[7] = 0.1;
417 EXPECT_FALSE(matrix.GetMinScale2D().has_value());
418 EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
419 EXPECT_FALSE(matrix.GetScales2D().has_value());
420 }
421
422 {
423 // Scale + PerspectiveZ (Z ignored; returns actual scales)
424 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
425 matrix.m[11] = 0.1;
426 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
427 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
428 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
429 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
430 check_pair(matrix, xScale, yScale);
431 }
432
433 {
434 // Scale + PerspectiveW (returns invalid values)
435 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
436 matrix.m[15] = 0.1;
437 EXPECT_FALSE(matrix.GetMinScale2D().has_value());
438 EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
439 EXPECT_FALSE(matrix.GetScales2D().has_value());
440 }
441 }
442 }
443 }
444
445 } // namespace testing
446 } // namespace impeller
x
int32_t x
Definition: dl_golden_unittests.cc:458
constants.h
geometry_asserts.h
MatrixNear
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)
Definition: geometry_asserts.h:56
matrix.h
impeller::testing::TEST
TEST(AllocationSizeTest, CanCreateTypedAllocations)
Definition: allocation_size_unittests.cc:10
impeller
Definition: allocation.cc:12
impeller::Scalar
float Scalar
Definition: scalar.h:19
impeller::ScalarNearlyEqual
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:36
impeller::Degrees
Definition: scalar.h:66
impeller::Degrees::degrees
Scalar degrees
Definition: scalar.h:67
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Matrix::m
Scalar m[16]
Definition: matrix.h:39
impeller::Matrix::Translate
constexpr Matrix Translate(const Vector3 &t) const
Definition: matrix.h:263
impeller::Matrix::GetMinScale2D
std::optional< Scalar > GetMinScale2D() const
Return the smaller of the two non-negative scales that will be applied to 2D coordinates by this matr...
Definition: matrix.h:356
impeller::Matrix::IsAligned
constexpr bool IsAligned(Scalar tolerance=0) const
Definition: matrix.h:439
impeller::Matrix::MakeColumn
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition: matrix.h:69
impeller::Matrix::MakeRotationY
static Matrix MakeRotationY(Radians r)
Definition: matrix.h:208
impeller::Matrix::HasPerspective2D
constexpr bool HasPerspective2D() const
Definition: matrix.h:414
impeller::Matrix::IsFinite
bool IsFinite() const
Definition: matrix.h:404
impeller::Matrix::MakeRow
static constexpr Matrix MakeRow(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition: matrix.h:83
impeller::Matrix::TransformHomogenous
constexpr Vector3 TransformHomogenous(const Point &v) const
Definition: matrix.h:601
impeller::Matrix::MakeTranslateScale
static constexpr Matrix MakeTranslateScale(const Vector3 &s, const Vector3 &t)
Definition: matrix.h:113
impeller::Matrix::e
Scalar e[4][4]
Definition: matrix.h:40
impeller::Matrix::MakeRotationZ
static Matrix MakeRotationZ(Radians r)
Definition: matrix.h:223
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
impeller::Matrix::GetMaxScale2D
std::optional< Scalar > GetMaxScale2D() const
Return the smaller of the two non-negative scales that will be applied to 2D coordinates by this matr...
Definition: matrix.h:380
impeller::Matrix::HasPerspective
constexpr bool HasPerspective() const
Definition: matrix.h:418
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104
impeller::Matrix::IsAligned2D
constexpr bool IsAligned2D(Scalar tolerance=0) const
Definition: matrix.h:424
impeller::Matrix::GetMaxBasisLengthXY
Scalar GetMaxBasisLengthXY() const
Return the maximum scale applied specifically to either the X axis or Y axis unit vectors (the bases)...
Definition: matrix.h:328
impeller::Matrix::MakeRotationX
static Matrix MakeRotationX(Radians r)
Definition: matrix.h:193
impeller::Vector3
Definition: vector.h:20