Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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
8
11
12namespace impeller {
13namespace testing {
14
15TEST(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
28TEST(MatrixTest, Equals) {
29 Matrix x;
30 Matrix y = x;
31 EXPECT_TRUE(x.Equals(y));
32}
33
34TEST(MatrixTest, NotEquals) {
35 Matrix x;
36 Matrix y = x.Translate({1, 0, 0});
37 EXPECT_FALSE(x.Equals(y));
38}
39
40TEST(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
58TEST(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
76TEST(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
83TEST(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
94TEST(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
105TEST(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
132TEST(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
170TEST(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);
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);
199 EXPECT_FALSE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
200 }
201}
202
203TEST(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);
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);
246 EXPECT_FALSE(matrix.IsAligned()) << "degrees: " << d.degrees;
247 }
248}
249
250TEST(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
263TEST(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))
274TEST(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
282TEST(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
289TEST(MatrixTest, GetBasisXYScale2D) {
290 Matrix m = Matrix::MakeScale({5.0f, 3.0f, 1.0f});
291 EXPECT_POINT_NEAR(m.GetBasisX2D(), Vector2(5.0f, 0.0f));
292 EXPECT_POINT_NEAR(m.GetBasisY2D(), Vector2(0.0f, 3.0f));
293 EXPECT_POINT_NEAR(m.GetBasisScaleXY(), Vector2(5.0f, 3.0f));
294
296 // clang-format off
297 2.0f, 3.0f, 0.0f, 0.0f,
298 5.0f, 7.0f, 0.0f, 0.0f,
299 0.0f, 0.0f, 1.0f, 0.0f,
300 0.0f, 0.0f, 0.0f, 1.0f
301 // clang-format on
302 );
303 EXPECT_POINT_NEAR(m2.GetBasisX2D(), Vector2(2.0f, 3.0f));
304 EXPECT_POINT_NEAR(m2.GetBasisY2D(), Vector2(5.0f, 7.0f));
305 EXPECT_POINT_NEAR(m2.GetBasisScaleXY(), Vector2(sqrt(13.0f), sqrt(74.0f)));
306
308 // clang-format off
309 2.0f, 3.0f, 4.0f, 11.0f,
310 5.0f, 7.0f, 6.0f, 13.0f,
311 1.0f, 8.0f, 9.0f, 15.0f,
312 1.0f, 1.0f, 1.0f, 17.0f
313 // clang-format on
314 );
315 EXPECT_POINT_NEAR(m3.GetBasisX2D(), Vector2(2.0f, 3.0f));
316 EXPECT_POINT_NEAR(m3.GetBasisY2D(), Vector2(5.0f, 7.0f));
317 EXPECT_POINT_NEAR(m2.GetBasisScaleXY(), Vector2(sqrt(13.0f), sqrt(74.0f)));
318}
319
320TEST(MatrixTest, TranslateWithPerspective) {
321 Matrix m = Matrix::MakeRow(1.0, 0.0, 0.0, 10.0, //
322 0.0, 1.0, 0.0, 20.0, //
323 0.0, 0.0, 1.0, 0.0, //
324 0.0, 2.0, 0.0, 30.0);
325 Matrix result = m.Translate({100, 200});
326 EXPECT_TRUE(MatrixNear(result, Matrix::MakeRow(1.0, 0.0, 0.0, 110.0, //
327 0.0, 1.0, 0.0, 220.0, //
328 0.0, 0.0, 1.0, 0.0, //
329 0.0, 2.0, 0.0, 430.0)));
330}
331
332TEST(MatrixTest, MakeScaleTranslate) {
333 EXPECT_TRUE(MatrixNear(
334 Matrix::MakeTranslateScale({1, 1, 1.0 / 1024}, {10, 10, 1.0 / 1024}),
335 Matrix::MakeTranslation({10, 10, 1.0 / 1024}) *
336 Matrix::MakeScale({1, 1, 1.0 / 1024})));
337
338 EXPECT_TRUE(MatrixNear(
339 Matrix::MakeTranslateScale({2, 2, 2}, {10, 10, 0}),
340 Matrix::MakeTranslation({10, 10, 0}) * Matrix::MakeScale({2, 2, 2})));
341
342 EXPECT_TRUE(MatrixNear(
343 Matrix::MakeTranslateScale({0, 0, 0}, {0, 0, 0}),
344 Matrix::MakeTranslation({0, 0, 0}) * Matrix::MakeScale({0, 0, 0})));
345}
346
347TEST(MatrixTest, To3x3) {
348 Matrix x(1.0, 0.0, 4.0, 0.0, //
349 0.0, 1.0, 4.0, 0.0, //
350 6.0, 5.0, 111.0, 7.0, //
351 0.0, 0.0, 9.0, 1.0);
352
353 EXPECT_TRUE(MatrixNear(x.To3x3(), Matrix()));
354}
355
356TEST(MatrixTest, MinMaxScales2D) {
357 // The GetScales2D() method is allowed to return the scales in any
358 // order so we need to take special care in verifying the return
359 // value to test them in either order.
360 auto check_pair = [](const Matrix& matrix, Scalar scale1, Scalar scale2) {
361 auto pair = matrix.GetScales2D();
362 EXPECT_TRUE(pair.has_value())
363 << "Scales: " << scale1 << ", " << scale2 << ", " << matrix;
364 if (ScalarNearlyEqual(pair->first, scale1)) {
365 EXPECT_FLOAT_EQ(pair->first, scale1) << matrix;
366 EXPECT_FLOAT_EQ(pair->second, scale2) << matrix;
367 } else {
368 EXPECT_FLOAT_EQ(pair->first, scale2) << matrix;
369 EXPECT_FLOAT_EQ(pair->second, scale1) << matrix;
370 }
371 };
372
373 for (int i = 1; i < 10; i++) {
374 Scalar xScale = static_cast<Scalar>(i);
375 for (int j = 1; j < 10; j++) {
376 Scalar yScale = static_cast<Scalar>(j);
377 Scalar minScale = std::min(xScale, yScale);
378 Scalar maxScale = std::max(xScale, yScale);
379
380 {
381 // Simple scale
382 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
383 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
384 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
385 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
386 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
387 check_pair(matrix, xScale, yScale);
388 }
389
390 {
391 // Simple scale with Z scale
392 Matrix matrix = Matrix::MakeScale({xScale, yScale, 5.0f});
393 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
394 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
395 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
396 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
397 check_pair(matrix, xScale, yScale);
398 }
399
400 {
401 // Simple scale + translate
402 Matrix matrix = Matrix::MakeTranslateScale({xScale, yScale, 1.0f},
403 {10.0f, 15.0f, 2.0f});
404 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
405 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
406 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
407 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
408 check_pair(matrix, xScale, yScale);
409 }
410
411 for (int d = 45; d < 360; d += 45) {
412 {
413 // Rotation * Scale
414 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f}) *
416 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
417 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
418 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
419 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
420 check_pair(matrix, xScale, yScale);
421 }
422
423 {
424 // Scale * Rotation
426 Matrix::MakeScale({xScale, yScale, 1.0f});
427 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
428 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
429 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
430 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
431 check_pair(matrix, xScale, yScale);
432 }
433 }
434
435 {
436 // Scale + PerspectiveX (returns invalid values)
437 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
438 matrix.m[3] = 0.1;
439 EXPECT_FALSE(matrix.GetMinScale2D().has_value());
440 EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
441 EXPECT_FALSE(matrix.GetScales2D().has_value());
442 }
443
444 {
445 // Scale + PerspectiveY (returns invalid values)
446 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
447 matrix.m[7] = 0.1;
448 EXPECT_FALSE(matrix.GetMinScale2D().has_value());
449 EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
450 EXPECT_FALSE(matrix.GetScales2D().has_value());
451 }
452
453 {
454 // Scale + PerspectiveZ (Z ignored; returns actual scales)
455 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
456 matrix.m[11] = 0.1;
457 EXPECT_TRUE(matrix.GetMinScale2D().has_value());
458 EXPECT_TRUE(matrix.GetMaxScale2D().has_value());
459 EXPECT_FLOAT_EQ(matrix.GetMinScale2D().value_or(-1.0f), minScale);
460 EXPECT_FLOAT_EQ(matrix.GetMaxScale2D().value_or(-1.0f), maxScale);
461 check_pair(matrix, xScale, yScale);
462 }
463
464 {
465 // Scale + PerspectiveW (returns invalid values)
466 Matrix matrix = Matrix::MakeScale({xScale, yScale, 1.0f});
467 matrix.m[15] = 0.1;
468 EXPECT_FALSE(matrix.GetMinScale2D().has_value());
469 EXPECT_FALSE(matrix.GetMaxScale2D().has_value());
470 EXPECT_FALSE(matrix.GetScales2D().has_value());
471 }
472 }
473 }
474}
475
476} // namespace testing
477} // namespace impeller
int32_t x
auto & d
Definition main.cc:28
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)
#define EXPECT_POINT_NEAR(a, b)
double y
TEST(FrameTimingsRecorderTest, RecordVsync)
bool Equals(const T *a, const U *b)
bool NotEquals(const T *a, const U *b)
float Scalar
Definition scalar.h:19
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition scalar.h:36
A 4x4 matrix using column-major storage.
Definition matrix.h:37
Vector2 GetBasisScaleXY() const
Definition matrix.h:403
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
Scalar m[16]
Definition matrix.h:39
constexpr Matrix Translate(const Vector3 &t) const
Definition matrix.h:263
constexpr bool IsAligned(Scalar tolerance=0) const
Definition matrix.h:447
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
static Matrix MakeRotationY(Radians r)
Definition matrix.h:208
constexpr bool HasPerspective2D() const
Definition matrix.h:422
bool IsFinite() const
Definition matrix.h:412
constexpr Vector2 GetBasisX2D() const
Definition matrix.h:399
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
constexpr Vector3 TransformHomogenous(const Point &v) const
Definition matrix.h:609
static constexpr Matrix MakeTranslateScale(const Vector3 &s, const Vector3 &t)
Definition matrix.h:113
Scalar e[4][4]
Definition matrix.h:40
static Matrix MakeRotationZ(Radians r)
Definition matrix.h:223
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
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
constexpr Vector2 GetBasisY2D() const
Definition matrix.h:401
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
constexpr bool HasPerspective() const
Definition matrix.h:426
static constexpr Matrix MakeScale(const Vector3 &s)
Definition matrix.h:104
constexpr bool IsAligned2D(Scalar tolerance=0) const
Definition matrix.h:432
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
static Matrix MakeRotationX(Radians r)
Definition matrix.h:193