5 #include "gtest/gtest.h"
11 #include <type_traits>
13 #include "flutter/fml/build_config.h"
14 #include "flutter/testing/testing.h"
37 1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
40 TEST(GeometryTest, MakeColumn) {
46 auto expect =
Matrix{1, 2, 3, 4,
51 ASSERT_TRUE(matrix == expect);
54 TEST(GeometryTest, MakeRow) {
60 auto expect =
Matrix{1, 5, 9, 13,
65 ASSERT_TRUE(matrix == expect);
68 TEST(GeometryTest, RotationMatrix) {
79 TEST(GeometryTest, InvertMultMatrix) {
82 auto invert = rotation.
Invert();
93 auto invert =
scale.Invert();
94 auto expect =
Matrix{0.5, 0, 0, 0,
102 TEST(GeometryTest, MatrixBasis) {
103 auto matrix =
Matrix{1, 2, 3, 4,
107 auto basis = matrix.
Basis();
108 auto expect =
Matrix{1, 2, 3, 0,
115 TEST(GeometryTest, MutliplicationMatrix) {
117 auto invert = rotation.
Invert();
121 TEST(GeometryTest, DeterminantTest) {
122 auto matrix =
Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
123 ASSERT_EQ(matrix.GetDeterminant(), -1889);
126 TEST(GeometryTest, InvertMatrix) {
127 auto inverted =
Matrix{10, -9, -12, 8,
134 438.0 / 85123.0, 1751.0 / 85123.0, -7783.0 / 85123.0, 4672.0 / 85123.0,
135 393.0 / 85123.0, -178.0 / 85123.0, -570.0 / 85123.0, 4192 / 85123.0,
136 -5230.0 / 85123.0, 2802.0 / 85123.0, -3461.0 / 85123.0, 962.0 / 85123.0,
137 2690.0 / 85123.0, 1814.0 / 85123.0, 3896.0 / 85123.0, 319.0 / 85123.0};
142 TEST(GeometryTest, TestDecomposition) {
147 ASSERT_TRUE(result.has_value());
155 TEST(GeometryTest, TestDecomposition2) {
160 auto result = (translated * rotated * scaled).Decompose();
162 ASSERT_TRUE(result.has_value());
174 ASSERT_FLOAT_EQ(res.
scale.
x, 2);
175 ASSERT_FLOAT_EQ(res.
scale.
y, 3);
176 ASSERT_FLOAT_EQ(res.
scale.
z, 1);
179 TEST(GeometryTest, TestRecomposition) {
187 ASSERT_TRUE(result.has_value());
201 TEST(GeometryTest, TestRecomposition2) {
208 ASSERT_TRUE(result.has_value());
213 TEST(GeometryTest, MatrixVectorMultiplication) {
218 auto vector =
Vector4(10, 20, 30, 2);
220 Vector4 result = matrix * vector;
221 auto expected =
Vector4(160, 220, 260, 2);
229 auto vector =
Vector3(10, 20, 30);
231 Vector3 result = matrix * vector;
232 auto expected =
Vector3(60, 120, 160);
240 auto vector =
Point(10, 20);
242 Point result = matrix * vector;
243 auto expected =
Point(60, 120);
250 auto vector =
Vector3(3, 3, -3);
252 Vector3 result = matrix * vector;
253 auto expected =
Vector3(-1, -1, 1.3468);
260 auto point =
Point(3, 3);
262 Point result = matrix * point;
263 auto expected =
Point(-1, -1);
270 auto point =
Point(3, 3);
272 Point result = matrix * point;
273 auto expected =
Point(0, 0);
278 TEST(GeometryTest, MatrixMakeRotationFromQuaternion) {
298 TEST(GeometryTest, MatrixTransformDirection) {
303 auto vector =
Vector4(10, 20, 30, 2);
305 Vector4 result = matrix.TransformDirection(vector);
306 auto expected =
Vector4(-40, 20, 60, 2);
314 auto vector =
Vector3(10, 20, 30);
316 Vector3 result = matrix.TransformDirection(vector);
317 auto expected =
Vector3(-40, 20, 60);
325 auto vector =
Point(10, 20);
327 Point result = matrix.TransformDirection(vector);
328 auto expected =
Point(-40, 20);
333 TEST(GeometryTest, MatrixGetMaxBasisLengthXY) {
336 ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
339 ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
344 ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
350 1.0f, 0.0f, 0.0f, 0.0f,
351 0.0f, 1.0f, 0.0f, 0.0f,
352 4.0f, 0.0f, 1.0f, 0.0f,
353 0.0f, 0.0f, 0.0f, 1.0f
356 ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
360 TEST(GeometryTest, MatrixMakeOrthographic) {
384 TEST(GeometryTest, MatrixMakePerspective) {
408 TEST(GeometryTest, MatrixGetBasisVectors) {
432 TEST(GeometryTest, MatrixGetDirectionScale) {
436 ASSERT_FLOAT_EQ(result, 1);
444 ASSERT_FLOAT_EQ(result, 1);
451 ASSERT_FLOAT_EQ(result, 8);
455 TEST(GeometryTest, MatrixTranslationScaleOnly) {
458 bool result = m.IsTranslationScaleOnly();
464 bool result = m.IsTranslationScaleOnly();
470 bool result = m.IsTranslationScaleOnly();
476 bool result = m.IsTranslationScaleOnly();
477 ASSERT_FALSE(result);
481 TEST(GeometryTest, MatrixLookAt) {
527 TEST(GeometryTest, QuaternionLerp) {
531 auto q3 = q1.Slerp(q2, 0.5);
538 TEST(GeometryTest, QuaternionVectorMultiply) {
580 TEST(GeometryTest, CanGenerateMipCounts) {
593 TEST(GeometryTest, CanConvertTTypesExplicitly) {
604 ASSERT_EQ(s2.
width, 1u);
616 TEST(GeometryTest, CanPerformAlgebraicPointOps) {
646 TEST(GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes) {
678 TEST(GeometryTest, PointIntegerCoercesToFloat) {
683 ASSERT_FLOAT_EQ(p2.
x, 2u);
684 ASSERT_FLOAT_EQ(p2.
y, 4u);
690 ASSERT_FLOAT_EQ(p2.
x, 2u);
691 ASSERT_FLOAT_EQ(p2.
y, 4u);
697 ASSERT_FLOAT_EQ(p2.
x, 2u);
698 ASSERT_FLOAT_EQ(p2.
y, 6u);
704 ASSERT_FLOAT_EQ(p2.
x, 1u);
705 ASSERT_FLOAT_EQ(p2.
y, 2u);
712 ASSERT_FLOAT_EQ(p2.
x, 2u);
713 ASSERT_FLOAT_EQ(p2.
y, 4u);
719 ASSERT_FLOAT_EQ(p2.
x, 2u);
720 ASSERT_FLOAT_EQ(p2.
y, 4u);
726 ASSERT_FLOAT_EQ(p2.
x, 2u);
727 ASSERT_FLOAT_EQ(p2.
y, 6u);
733 ASSERT_FLOAT_EQ(p2.
x, 1u);
734 ASSERT_FLOAT_EQ(p2.
y, 2u);
738 TEST(GeometryTest, SizeCoercesToPoint) {
798 TEST(GeometryTest, CanUsePointAssignmentOperators) {
873 TEST(GeometryTest, PointDotProduct) {
877 ASSERT_FLOAT_EQ(s, -1);
883 ASSERT_FLOAT_EQ(s, 0);
889 ASSERT_FLOAT_EQ(s, -5);
893 TEST(GeometryTest, PointCrossProduct) {
897 ASSERT_FLOAT_EQ(s, 0);
903 ASSERT_FLOAT_EQ(s, -1);
909 ASSERT_FLOAT_EQ(s, -10);
913 TEST(GeometryTest, PointReflect) {
917 auto reflected = a.
Reflect(axis);
918 auto expected =
Point(2, -3);
925 auto reflected = a.
Reflect(axis);
926 auto expected =
Point(0, -1);
933 auto reflected = a.
Reflect(axis);
940 auto a_abs = a.
Abs();
941 auto expected =
Point(1, 2);
945 TEST(GeometryTest, PointRotate) {
949 auto expected =
Point(0, 1);
956 auto expected =
Point(0, -1);
963 auto expected =
Point(-1, 0);
970 auto expected =
Point(0, -1);
975 TEST(GeometryTest, PointAngleTo) {
1007 Point expected(0, 2);
1028 Point expected(1, 10);
1042 Vector4 expected(1, 10, 3, 4);
1049 Point expected(1, 2);
1061 Vector4 p(1.5, 2.3, 3.9, 4.0);
1070 Point expected(2, 3);
1082 Vector4 p(1.5, 2.3, 3.9, 4.0);
1091 Point expected(2, 2);
1103 Vector4 p(1.5, 2.3, 3.9, 4.0);
1112 Point expected(4, 8);
1126 Vector4 expected(4, 8, 12, 16);
1130 TEST(GeometryTest, SeparatedVector2NormalizesWithConstructor) {
1136 TEST(GeometryTest, SeparatedVector2GetVector) {
1141 TEST(GeometryTest, SeparatedVector2GetAlignment) {
1164 TEST(GeometryTest, SeparatedVector2AngleTo) {
1180 TEST(GeometryTest, CanUseVector3AssignmentOperators) {
1202 ASSERT_EQ(p.
z, 12u);
1230 TEST(GeometryTest, CanPerformAlgebraicVector3Ops) {
1234 ASSERT_EQ(p2.
x, 2u);
1235 ASSERT_EQ(p2.
y, 4u);
1236 ASSERT_EQ(p2.
z, 6u);
1242 ASSERT_EQ(p2.
x, 2u);
1243 ASSERT_EQ(p2.
y, 4u);
1244 ASSERT_EQ(p2.
z, 6u);
1250 ASSERT_EQ(p2.
x, 2u);
1251 ASSERT_EQ(p2.
y, 6u);
1252 ASSERT_EQ(p2.
z, 12u);
1258 ASSERT_EQ(p2.
x, 1u);
1259 ASSERT_EQ(p2.
y, 2u);
1260 ASSERT_EQ(p2.
z, 3u);
1264 TEST(GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes) {
1277 ASSERT_EQ(p2.
x, -1);
1312 ASSERT_EQ(p2.
z, -1);
1332 TEST(GeometryTest, ColorPremultiply) {
1334 Color a(1.0, 0.5, 0.2, 0.5);
1341 Color a(0.5, 0.25, 0.1, 0.5);
1348 Color a(0.5, 0.25, 0.1, 0.0);
1355 TEST(GeometryTest, ColorR8G8B8A8) {
1357 Color a(1.0, 0.5, 0.2, 0.5);
1358 std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1363 Color a(0.0, 0.0, 0.0, 0.0);
1364 std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1369 Color a(1.0, 1.0, 1.0, 1.0);
1370 std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1377 Color a(0.0, 0.0, 0.0, 0.0);
1378 Color b(1.0, 1.0, 1.0, 1.0);
1387 Color a(0.2, 0.4, 1.0, 0.5);
1388 Color b(0.4, 1.0, 0.2, 0.3);
1417 TEST(GeometryTest, ColorMakeRGBA8) {
1432 Color b(0.247059, 0.498039, 0.74902, 0.498039);
1437 TEST(GeometryTest, ColorApplyColorMatrix) {
1446 auto expected =
Color(1, 1, 1, 1);
1458 auto expected =
Color(0.11, 0.22, 0.33, 0.44);
1463 TEST(GeometryTest, ColorLinearToSRGB) {
1466 auto expected =
Color(1, 1, 1, 1);
1472 auto expected =
Color(0, 0, 0, 0);
1478 auto expected =
Color(0.484529, 0.665185, 0.797738, 0.8);
1483 TEST(GeometryTest, ColorSRGBToLinear) {
1486 auto expected =
Color(1, 1, 1, 1);
1492 auto expected =
Color(0, 0, 0, 0);
1498 auto expected =
Color(0.0331048, 0.132868, 0.318547, 0.8);
1510 static const std::map<BlendMode, Color>
1640 #define _BLEND_MODE_RESULT_CHECK(blend_mode) \
1641 expected = ColorBlendTestData::kExpectedResults[source_i] \
1642 .find(BlendMode::k##blend_mode) \
1644 EXPECT_COLOR_NEAR(dst.Blend(src, BlendMode::k##blend_mode), expected);
1646 TEST(GeometryTest, ColorBlendReturnsExpectedResults) {
1648 for (
size_t source_i = 0;
1658 #define _BLEND_MODE_NAME_CHECK(blend_mode) \
1659 case BlendMode::k##blend_mode: \
1660 ASSERT_STREQ(result, #blend_mode); \
1664 using BlendT = std::underlying_type_t<BlendMode>;
1672 TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
1680 TEST(GeometryTest, MatrixPrinting) {
1682 std::stringstream stream;
1685 ASSERT_EQ(stream.str(), R
"((
1686 1.000000, 0.000000, 0.000000, 0.000000,
1687 0.000000, 1.000000, 0.000000, 0.000000,
1688 0.000000, 0.000000, 1.000000, 0.000000,
1689 0.000000, 0.000000, 0.000000, 1.000000,
1694 std::stringstream stream;
1698 ASSERT_EQ(stream.str(), R"((
1699 1.000000, 0.000000, 0.000000, 10.000000,
1700 0.000000, 1.000000, 0.000000, 20.000000,
1701 0.000000, 0.000000, 1.000000, 30.000000,
1702 0.000000, 0.000000, 0.000000, 1.000000,
1707 TEST(GeometryTest, PointPrinting) {
1709 std::stringstream stream;
1712 ASSERT_EQ(stream.str(), "(0, 0)");
1716 std::stringstream stream;
1719 ASSERT_EQ(stream.str(),
"(13, 37)");
1723 TEST(GeometryTest, Vector3Printing) {
1725 std::stringstream stream;
1728 ASSERT_EQ(stream.str(),
"(0, 0, 0)");
1732 std::stringstream stream;
1735 ASSERT_EQ(stream.str(),
"(1, 2, 3)");
1739 TEST(GeometryTest, Vector4Printing) {
1741 std::stringstream stream;
1744 ASSERT_EQ(stream.str(),
"(0, 0, 0, 1)");
1748 std::stringstream stream;
1751 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1755 TEST(GeometryTest, ColorPrinting) {
1757 std::stringstream stream;
1760 ASSERT_EQ(stream.str(),
"(0, 0, 0, 0)");
1764 std::stringstream stream;
1765 Color m(1, 2, 3, 4);
1767 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1782 std::vector<Scalar> stops = {0.0, 1.0};
1787 ASSERT_EQ(gradient.texture_size, 2u);
1794 std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1797 ASSERT_EQ(gradient.texture_size, 5u);
1805 std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1810 ASSERT_EQ(gradient.texture_size, 4u);
1816 std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1820 std::vector<Color> lerped_colors = {
1828 ASSERT_EQ(gradient.texture_size, 5u);
1833 std::vector<Color> colors = {};
1834 std::vector<Scalar> stops = {};
1835 for (
auto i = 0u; i < 1025; i++) {
1837 stops.push_back(i / 1025.0);
1842 ASSERT_EQ(gradient.texture_size, 1024u);
1843 ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1847 TEST(GeometryTest, HalfConversions) {
1848 #if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1849 defined(FML_OS_IOS_SIMULATOR)
1873 ASSERT_EQ(
Half(0.5f),
Half(0.5f16));
1874 ASSERT_EQ(
Half(0.5),
Half(0.5f16));
1877 GTEST_SKIP() <<
"Half-precision floats (IEEE 754) are not portable and "
1878 "only used on Apple platforms.";
1879 #endif // FML_OS_MACOSX || FML_OS_IOS || FML_OS_IOS_SIMULATOR