5 #include "gtest/gtest.h"
10 #include <type_traits>
12 #include "flutter/fml/build_config.h"
13 #include "flutter/testing/testing.h"
35 1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
38 TEST(GeometryTest, MakeColumn) {
44 auto expect =
Matrix{1, 2, 3, 4,
49 ASSERT_TRUE(matrix == expect);
52 TEST(GeometryTest, MakeRow) {
58 auto expect =
Matrix{1, 5, 9, 13,
63 ASSERT_TRUE(matrix == expect);
66 TEST(GeometryTest, RotationMatrix) {
68 auto expect =
Matrix{0.707, 0.707, 0, 0,
75 TEST(GeometryTest, InvertMultMatrix) {
78 auto invert = rotation.
Invert();
79 auto expect =
Matrix{0.707, -0.707, 0, 0,
87 auto invert = scale.
Invert();
88 auto expect =
Matrix{0.5, 0, 0, 0,
96 TEST(GeometryTest, MatrixBasis) {
97 auto matrix =
Matrix{1, 2, 3, 4,
101 auto basis = matrix.
Basis();
102 auto expect =
Matrix{1, 2, 3, 0,
109 TEST(GeometryTest, MutliplicationMatrix) {
111 auto invert = rotation.
Invert();
115 TEST(GeometryTest, DeterminantTest) {
116 auto matrix =
Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
117 ASSERT_EQ(matrix.GetDeterminant(), -1889);
120 TEST(GeometryTest, InvertMatrix) {
121 auto inverted =
Matrix{10, -9, -12, 8,
128 438.0 / 85123.0, 1751.0 / 85123.0, -7783.0 / 85123.0, 4672.0 / 85123.0,
129 393.0 / 85123.0, -178.0 / 85123.0, -570.0 / 85123.0, 4192 / 85123.0,
130 -5230.0 / 85123.0, 2802.0 / 85123.0, -3461.0 / 85123.0, 962.0 / 85123.0,
131 2690.0 / 85123.0, 1814.0 / 85123.0, 3896.0 / 85123.0, 319.0 / 85123.0};
136 TEST(GeometryTest, TestDecomposition) {
141 ASSERT_TRUE(result.has_value());
149 TEST(GeometryTest, TestDecomposition2) {
154 auto result = (translated * rotated * scaled).Decompose();
156 ASSERT_TRUE(result.has_value());
168 ASSERT_FLOAT_EQ(res.
scale.
x, 2);
169 ASSERT_FLOAT_EQ(res.
scale.
y, 3);
170 ASSERT_FLOAT_EQ(res.
scale.
z, 1);
173 TEST(GeometryTest, TestRecomposition) {
181 ASSERT_TRUE(result.has_value());
195 TEST(GeometryTest, TestRecomposition2) {
202 ASSERT_TRUE(result.has_value());
207 TEST(GeometryTest, MatrixVectorMultiplication) {
212 auto vector =
Vector4(10, 20, 30, 2);
214 Vector4 result = matrix * vector;
215 auto expected =
Vector4(160, 220, 260, 2);
223 auto vector =
Vector3(10, 20, 30);
225 Vector3 result = matrix * vector;
226 auto expected =
Vector3(60, 120, 160);
234 auto vector =
Point(10, 20);
236 Point result = matrix * vector;
237 auto expected =
Point(60, 120);
244 auto vector =
Vector3(3, 3, -3);
246 Vector3 result = matrix * vector;
247 auto expected =
Vector3(-1, -1, 1.3468);
254 auto point =
Point(3, 3);
256 Point result = matrix * point;
257 auto expected =
Point(-1, -1);
264 auto point =
Point(3, 3);
266 Point result = matrix * point;
267 auto expected =
Point(0, 0);
272 TEST(GeometryTest, MatrixMakeRotationFromQuaternion) {
292 TEST(GeometryTest, MatrixTransformDirection) {
297 auto vector =
Vector4(10, 20, 30, 2);
299 Vector4 result = matrix.TransformDirection(vector);
300 auto expected =
Vector4(-40, 20, 60, 2);
308 auto vector =
Vector3(10, 20, 30);
310 Vector3 result = matrix.TransformDirection(vector);
311 auto expected =
Vector3(-40, 20, 60);
319 auto vector =
Point(10, 20);
321 Point result = matrix.TransformDirection(vector);
322 auto expected =
Point(-40, 20);
327 TEST(GeometryTest, MatrixGetMaxBasisLength) {
330 ASSERT_EQ(m.GetMaxBasisLength(), 3);
333 ASSERT_EQ(m.GetMaxBasisLength(), 5);
338 ASSERT_EQ(m.GetMaxBasisLength(), 4);
342 TEST(GeometryTest, MatrixGetMaxBasisLengthXY) {
345 ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
348 ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
353 ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
357 TEST(GeometryTest, MatrixMakeOrthographic) {
381 TEST(GeometryTest, MatrixMakePerspective) {
405 TEST(GeometryTest, MatrixGetBasisVectors) {
429 TEST(GeometryTest, MatrixGetDirectionScale) {
433 ASSERT_FLOAT_EQ(result, 1);
441 ASSERT_FLOAT_EQ(result, 1);
448 ASSERT_FLOAT_EQ(result, 8);
452 TEST(GeometryTest, MatrixIsAligned) {
462 ASSERT_FALSE(result);
466 TEST(GeometryTest, MatrixTranslationScaleOnly) {
469 bool result = m.IsTranslationScaleOnly();
475 bool result = m.IsTranslationScaleOnly();
481 bool result = m.IsTranslationScaleOnly();
487 bool result = m.IsTranslationScaleOnly();
488 ASSERT_FALSE(result);
492 TEST(GeometryTest, MatrixLookAt) {
538 TEST(GeometryTest, QuaternionLerp) {
542 auto q3 = q1.Slerp(q2, 0.5);
549 TEST(GeometryTest, QuaternionVectorMultiply) {
591 TEST(GeometryTest, CanGenerateMipCounts) {
604 TEST(GeometryTest, CanConvertTTypesExplicitly) {
615 ASSERT_EQ(s2.
width, 1u);
633 ASSERT_EQ(r2.
GetX(), 1u);
634 ASSERT_EQ(r2.
GetY(), 2u);
640 TEST(GeometryTest, CanPerformAlgebraicPointOps) {
670 TEST(GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes) {
702 TEST(GeometryTest, PointIntegerCoercesToFloat) {
707 ASSERT_FLOAT_EQ(p2.
x, 2u);
708 ASSERT_FLOAT_EQ(p2.
y, 4u);
714 ASSERT_FLOAT_EQ(p2.
x, 2u);
715 ASSERT_FLOAT_EQ(p2.
y, 4u);
721 ASSERT_FLOAT_EQ(p2.
x, 2u);
722 ASSERT_FLOAT_EQ(p2.
y, 6u);
728 ASSERT_FLOAT_EQ(p2.
x, 1u);
729 ASSERT_FLOAT_EQ(p2.
y, 2u);
736 ASSERT_FLOAT_EQ(p2.
x, 2u);
737 ASSERT_FLOAT_EQ(p2.
y, 4u);
743 ASSERT_FLOAT_EQ(p2.
x, 2u);
744 ASSERT_FLOAT_EQ(p2.
y, 4u);
750 ASSERT_FLOAT_EQ(p2.
x, 2u);
751 ASSERT_FLOAT_EQ(p2.
y, 6u);
757 ASSERT_FLOAT_EQ(p2.
x, 1u);
758 ASSERT_FLOAT_EQ(p2.
y, 2u);
762 TEST(GeometryTest, SizeCoercesToPoint) {
822 TEST(GeometryTest, CanUsePointAssignmentOperators) {
897 TEST(GeometryTest, PointDotProduct) {
901 ASSERT_FLOAT_EQ(s, -1);
907 ASSERT_FLOAT_EQ(s, 0);
913 ASSERT_FLOAT_EQ(s, -5);
917 TEST(GeometryTest, PointCrossProduct) {
921 ASSERT_FLOAT_EQ(s, 0);
927 ASSERT_FLOAT_EQ(s, -1);
933 ASSERT_FLOAT_EQ(s, -10);
937 TEST(GeometryTest, PointReflect) {
941 auto reflected = a.
Reflect(axis);
942 auto expected =
Point(2, -3);
949 auto reflected = a.
Reflect(axis);
950 auto expected =
Point(0, -1);
957 auto reflected = a.
Reflect(axis);
964 auto a_abs = a.
Abs();
965 auto expected =
Point(1, 2);
969 TEST(GeometryTest, PointAngleTo) {
1001 Point expected(0, 2);
1022 Point expected(1, 10);
1036 Vector4 expected(1, 10, 3, 4);
1043 Point expected(1, 2);
1055 Vector4 p(1.5, 2.3, 3.9, 4.0);
1064 Point expected(2, 3);
1076 Vector4 p(1.5, 2.3, 3.9, 4.0);
1085 Point expected(2, 2);
1097 Vector4 p(1.5, 2.3, 3.9, 4.0);
1106 Point expected(4, 8);
1120 Vector4 expected(4, 8, 12, 16);
1124 TEST(GeometryTest, CanUseVector3AssignmentOperators) {
1146 ASSERT_EQ(p.
z, 12u);
1174 TEST(GeometryTest, CanPerformAlgebraicVector3Ops) {
1178 ASSERT_EQ(p2.
x, 2u);
1179 ASSERT_EQ(p2.
y, 4u);
1180 ASSERT_EQ(p2.
z, 6u);
1186 ASSERT_EQ(p2.
x, 2u);
1187 ASSERT_EQ(p2.
y, 4u);
1188 ASSERT_EQ(p2.
z, 6u);
1194 ASSERT_EQ(p2.
x, 2u);
1195 ASSERT_EQ(p2.
y, 6u);
1196 ASSERT_EQ(p2.
z, 12u);
1202 ASSERT_EQ(p2.
x, 1u);
1203 ASSERT_EQ(p2.
y, 2u);
1204 ASSERT_EQ(p2.
z, 3u);
1208 TEST(GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes) {
1221 ASSERT_EQ(p2.
x, -1);
1256 ASSERT_EQ(p2.
z, -1);
1276 TEST(GeometryTest, ColorPremultiply) {
1278 Color a(1.0, 0.5, 0.2, 0.5);
1285 Color a(0.5, 0.25, 0.1, 0.5);
1292 Color a(0.5, 0.25, 0.1, 0.0);
1299 TEST(GeometryTest, ColorR8G8B8A8) {
1301 Color a(1.0, 0.5, 0.2, 0.5);
1302 std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1307 Color a(0.0, 0.0, 0.0, 0.0);
1308 std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1313 Color a(1.0, 1.0, 1.0, 1.0);
1314 std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1321 Color a(0.0, 0.0, 0.0, 0.0);
1322 Color b(1.0, 1.0, 1.0, 1.0);
1331 Color a(0.2, 0.4, 1.0, 0.5);
1332 Color b(0.4, 1.0, 0.2, 0.3);
1361 TEST(GeometryTest, ColorMakeRGBA8) {
1376 Color b(0.247059, 0.498039, 0.74902, 0.498039);
1381 TEST(GeometryTest, ColorApplyColorMatrix) {
1390 auto expected =
Color(1, 1, 1, 1);
1402 auto expected =
Color(0.11, 0.22, 0.33, 0.44);
1407 TEST(GeometryTest, ColorLinearToSRGB) {
1410 auto expected =
Color(1, 1, 1, 1);
1416 auto expected =
Color(0, 0, 0, 0);
1422 auto expected =
Color(0.484529, 0.665185, 0.797738, 0.8);
1427 TEST(GeometryTest, ColorSRGBToLinear) {
1430 auto expected =
Color(1, 1, 1, 1);
1436 auto expected =
Color(0, 0, 0, 0);
1442 auto expected =
Color(0.0331048, 0.132868, 0.318547, 0.8);
1447 #define _BLEND_MODE_NAME_CHECK(blend_mode) \
1448 case BlendMode::k##blend_mode: \
1449 ASSERT_STREQ(result, #blend_mode); \
1453 using BlendT = std::underlying_type_t<BlendMode>;
1461 TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
1473 auto u = a.
Union(b);
1481 auto u = a.
Union(b);
1489 auto u = a.
Union(b);
1497 auto u = a.
Union(b);
1509 EXPECT_FALSE(
Rect::Union(std::nullopt, std::nullopt).has_value());
1510 EXPECT_EQ(
Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1512 auto test1 = [](
const Rect& r) {
1514 EXPECT_TRUE(
Rect::Union(r, std::nullopt).has_value());
1515 EXPECT_EQ(
Rect::Union(r, std::nullopt).value(), r);
1518 EXPECT_TRUE(
Rect::Union(std::optional(r), std::nullopt).has_value());
1519 EXPECT_EQ(
Rect::Union(std::optional(r), std::nullopt).value(), r);
1522 EXPECT_TRUE(
Rect::Union(std::nullopt, r).has_value());
1523 EXPECT_EQ(
Rect::Union(std::nullopt, r).value(), r);
1526 EXPECT_TRUE(
Rect::Union(std::nullopt, std::optional(r)).has_value());
1527 EXPECT_EQ(
Rect::Union(std::nullopt, std::optional(r)).value(), r);
1534 auto test2 = [](
const Rect& a,
const Rect& b,
const Rect& u) {
1535 ASSERT_EQ(a.
Union(b), u);
1538 EXPECT_TRUE(
Rect::Union(a, std::optional(b)).has_value());
1539 EXPECT_EQ(
Rect::Union(a, std::optional(b)).value(), u);
1542 EXPECT_TRUE(
Rect::Union(std::optional(a), b).has_value());
1543 EXPECT_EQ(
Rect::Union(std::optional(a), b).value(), u);
1546 EXPECT_TRUE(
Rect::Union(std::optional(a), std::optional(b)).has_value());
1547 EXPECT_EQ(
Rect::Union(std::optional(a), std::optional(b)).value(), u);
1555 TEST(GeometryTest, RectIntersection) {
1561 ASSERT_FALSE(u.has_value());
1568 ASSERT_FALSE(u.has_value());
1575 ASSERT_TRUE(u.has_value());
1584 ASSERT_FALSE(u.has_value());
1604 TEST(GeometryTest, OptRectIntersection) {
1613 auto test1 = [](
const Rect& r) {
1635 auto test2 = [](
const Rect& a,
const Rect& b,
const Rect& i) {
1658 TEST(GeometryTest, RectIntersectsWithRect) {
1702 ASSERT_TRUE(u.has_value());
1711 ASSERT_FALSE(u.has_value());
1718 auto u = a.Cutout(b);
1720 ASSERT_TRUE(u.has_value());
1728 auto u = a.Cutout(b);
1730 ASSERT_TRUE(u.has_value());
1738 auto u = a.Cutout(b);
1740 ASSERT_TRUE(u.has_value());
1748 auto u = a.Cutout(b);
1750 ASSERT_TRUE(u.has_value());
1755 TEST(GeometryTest, RectContainsPoint) {
1786 TEST(GeometryTest, RectContainsRect) {
1823 TEST(GeometryTest, RectGetPoints) {
1836 ASSERT_EQ(points[0],
Point(-std::numeric_limits<float>::infinity(),
1837 -std::numeric_limits<float>::infinity()));
1838 ASSERT_EQ(points[1],
Point(std::numeric_limits<float>::infinity(),
1839 -std::numeric_limits<float>::infinity()));
1840 ASSERT_EQ(points[2],
Point(-std::numeric_limits<float>::infinity(),
1841 std::numeric_limits<float>::infinity()));
1842 ASSERT_EQ(points[3],
Point(std::numeric_limits<float>::infinity(),
1843 std::numeric_limits<float>::infinity()));
1854 TEST(GeometryTest, RectGetTransformedPoints) {
1863 TEST(GeometryTest, RectMakePointBounds) {
1865 std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
1871 std::vector<Point> points;
1873 ASSERT_FALSE(r.has_value());
1880 auto b = a.Expand(1);
1886 auto b = a.Expand(-1);
1893 auto b = a.Expand(1, 2, 3, 4);
1899 auto b = a.Expand(-1, -2, -3, -4);
1905 TEST(GeometryTest, RectGetPositive) {
1922 auto actual = r.Scale(0);
1928 auto actual = r.Scale(-2);
1934 auto actual = r.Scale(
Point{0, 0});
1940 auto actual = r.Scale(
Size{-1, -2});
1946 TEST(GeometryTest, RectDirections) {
1949 ASSERT_EQ(r.GetLeft(), 1);
1950 ASSERT_EQ(r.GetTop(), 2);
1951 ASSERT_EQ(r.GetRight(), 3);
1952 ASSERT_EQ(r.GetBottom(), 4);
1963 auto actual = r.Project(r);
1986 TEST(GeometryTest, MatrixPrinting) {
1988 std::stringstream stream;
1991 ASSERT_EQ(stream.str(), R
"((
1992 1.000000, 0.000000, 0.000000, 0.000000,
1993 0.000000, 1.000000, 0.000000, 0.000000,
1994 0.000000, 0.000000, 1.000000, 0.000000,
1995 0.000000, 0.000000, 0.000000, 1.000000,
2000 std::stringstream stream;
2004 ASSERT_EQ(stream.str(), R"((
2005 1.000000, 0.000000, 0.000000, 10.000000,
2006 0.000000, 1.000000, 0.000000, 20.000000,
2007 0.000000, 0.000000, 1.000000, 30.000000,
2008 0.000000, 0.000000, 0.000000, 1.000000,
2013 TEST(GeometryTest, PointPrinting) {
2015 std::stringstream stream;
2018 ASSERT_EQ(stream.str(), "(0, 0)");
2022 std::stringstream stream;
2025 ASSERT_EQ(stream.str(),
"(13, 37)");
2029 TEST(GeometryTest, Vector3Printing) {
2031 std::stringstream stream;
2034 ASSERT_EQ(stream.str(),
"(0, 0, 0)");
2038 std::stringstream stream;
2041 ASSERT_EQ(stream.str(),
"(1, 2, 3)");
2045 TEST(GeometryTest, Vector4Printing) {
2047 std::stringstream stream;
2050 ASSERT_EQ(stream.str(),
"(0, 0, 0, 1)");
2054 std::stringstream stream;
2057 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
2061 TEST(GeometryTest, ColorPrinting) {
2063 std::stringstream stream;
2066 ASSERT_EQ(stream.str(),
"(0, 0, 0, 0)");
2070 std::stringstream stream;
2071 Color m(1, 2, 3, 4);
2073 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
2088 std::vector<Scalar> stops = {0.0, 1.0};
2093 ASSERT_EQ(gradient.texture_size, 2u);
2100 std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
2103 ASSERT_EQ(gradient.texture_size, 5u);
2111 std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
2116 ASSERT_EQ(gradient.texture_size, 4u);
2122 std::vector<Scalar> stops = {0.0, 0.25, 1.0};
2126 std::vector<Color> lerped_colors = {
2134 ASSERT_EQ(gradient.texture_size, 5u);
2139 std::vector<Color> colors = {};
2140 std::vector<Scalar> stops = {};
2141 for (
auto i = 0u; i < 1025; i++) {
2143 stops.push_back(i / 1025.0);
2148 ASSERT_EQ(gradient.texture_size, 1024u);
2149 ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
2153 TEST(GeometryTest, HalfConversions) {
2155 GTEST_SKIP() <<
"Half-precision floats (IEEE 754) are not portable and "
2156 "unavailable on Windows.";
2181 ASSERT_EQ(
Half(0.5f),
Half(0.5f16));
2182 ASSERT_EQ(
Half(0.5),
Half(0.5f16));
2184 #endif // FML_OS_WIN