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, MatrixGetMaxBasisLength) {
336 ASSERT_EQ(m.GetMaxBasisLength(), 3);
339 ASSERT_EQ(m.GetMaxBasisLength(), 5);
344 ASSERT_EQ(m.GetMaxBasisLength(), 4);
348 TEST(GeometryTest, MatrixGetMaxBasisLengthXY) {
351 ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
354 ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
359 ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
365 1.0f, 0.0f, 0.0f, 0.0f,
366 0.0f, 1.0f, 0.0f, 0.0f,
367 4.0f, 0.0f, 1.0f, 0.0f,
368 0.0f, 0.0f, 0.0f, 1.0f
371 ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
375 TEST(GeometryTest, MatrixMakeOrthographic) {
399 TEST(GeometryTest, MatrixMakePerspective) {
423 TEST(GeometryTest, MatrixGetBasisVectors) {
447 TEST(GeometryTest, MatrixGetDirectionScale) {
451 ASSERT_FLOAT_EQ(result, 1);
459 ASSERT_FLOAT_EQ(result, 1);
466 ASSERT_FLOAT_EQ(result, 8);
470 TEST(GeometryTest, MatrixTranslationScaleOnly) {
473 bool result = m.IsTranslationScaleOnly();
479 bool result = m.IsTranslationScaleOnly();
485 bool result = m.IsTranslationScaleOnly();
491 bool result = m.IsTranslationScaleOnly();
492 ASSERT_FALSE(result);
496 TEST(GeometryTest, MatrixLookAt) {
542 TEST(GeometryTest, QuaternionLerp) {
546 auto q3 = q1.Slerp(q2, 0.5);
553 TEST(GeometryTest, QuaternionVectorMultiply) {
595 TEST(GeometryTest, CanGenerateMipCounts) {
608 TEST(GeometryTest, CanConvertTTypesExplicitly) {
619 ASSERT_EQ(s2.
width, 1u);
631 TEST(GeometryTest, CanPerformAlgebraicPointOps) {
661 TEST(GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes) {
693 TEST(GeometryTest, PointIntegerCoercesToFloat) {
698 ASSERT_FLOAT_EQ(p2.
x, 2u);
699 ASSERT_FLOAT_EQ(p2.
y, 4u);
705 ASSERT_FLOAT_EQ(p2.
x, 2u);
706 ASSERT_FLOAT_EQ(p2.
y, 4u);
712 ASSERT_FLOAT_EQ(p2.
x, 2u);
713 ASSERT_FLOAT_EQ(p2.
y, 6u);
719 ASSERT_FLOAT_EQ(p2.
x, 1u);
720 ASSERT_FLOAT_EQ(p2.
y, 2u);
727 ASSERT_FLOAT_EQ(p2.
x, 2u);
728 ASSERT_FLOAT_EQ(p2.
y, 4u);
734 ASSERT_FLOAT_EQ(p2.
x, 2u);
735 ASSERT_FLOAT_EQ(p2.
y, 4u);
741 ASSERT_FLOAT_EQ(p2.
x, 2u);
742 ASSERT_FLOAT_EQ(p2.
y, 6u);
748 ASSERT_FLOAT_EQ(p2.
x, 1u);
749 ASSERT_FLOAT_EQ(p2.
y, 2u);
753 TEST(GeometryTest, SizeCoercesToPoint) {
813 TEST(GeometryTest, CanUsePointAssignmentOperators) {
888 TEST(GeometryTest, PointDotProduct) {
892 ASSERT_FLOAT_EQ(s, -1);
898 ASSERT_FLOAT_EQ(s, 0);
904 ASSERT_FLOAT_EQ(s, -5);
908 TEST(GeometryTest, PointCrossProduct) {
912 ASSERT_FLOAT_EQ(s, 0);
918 ASSERT_FLOAT_EQ(s, -1);
924 ASSERT_FLOAT_EQ(s, -10);
928 TEST(GeometryTest, PointReflect) {
932 auto reflected = a.
Reflect(axis);
933 auto expected =
Point(2, -3);
940 auto reflected = a.
Reflect(axis);
941 auto expected =
Point(0, -1);
948 auto reflected = a.
Reflect(axis);
955 auto a_abs = a.
Abs();
956 auto expected =
Point(1, 2);
960 TEST(GeometryTest, PointRotate) {
964 auto expected =
Point(0, 1);
971 auto expected =
Point(0, -1);
978 auto expected =
Point(-1, 0);
985 auto expected =
Point(0, -1);
990 TEST(GeometryTest, PointAngleTo) {
1022 Point expected(0, 2);
1043 Point expected(1, 10);
1057 Vector4 expected(1, 10, 3, 4);
1064 Point expected(1, 2);
1076 Vector4 p(1.5, 2.3, 3.9, 4.0);
1085 Point expected(2, 3);
1097 Vector4 p(1.5, 2.3, 3.9, 4.0);
1106 Point expected(2, 2);
1118 Vector4 p(1.5, 2.3, 3.9, 4.0);
1127 Point expected(4, 8);
1141 Vector4 expected(4, 8, 12, 16);
1145 TEST(GeometryTest, SeparatedVector2NormalizesWithConstructor) {
1151 TEST(GeometryTest, SeparatedVector2GetVector) {
1156 TEST(GeometryTest, SeparatedVector2GetAlignment) {
1179 TEST(GeometryTest, SeparatedVector2AngleTo) {
1195 TEST(GeometryTest, CanUseVector3AssignmentOperators) {
1217 ASSERT_EQ(p.
z, 12u);
1245 TEST(GeometryTest, CanPerformAlgebraicVector3Ops) {
1249 ASSERT_EQ(p2.
x, 2u);
1250 ASSERT_EQ(p2.
y, 4u);
1251 ASSERT_EQ(p2.
z, 6u);
1257 ASSERT_EQ(p2.
x, 2u);
1258 ASSERT_EQ(p2.
y, 4u);
1259 ASSERT_EQ(p2.
z, 6u);
1265 ASSERT_EQ(p2.
x, 2u);
1266 ASSERT_EQ(p2.
y, 6u);
1267 ASSERT_EQ(p2.
z, 12u);
1273 ASSERT_EQ(p2.
x, 1u);
1274 ASSERT_EQ(p2.
y, 2u);
1275 ASSERT_EQ(p2.
z, 3u);
1279 TEST(GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes) {
1292 ASSERT_EQ(p2.
x, -1);
1327 ASSERT_EQ(p2.
z, -1);
1347 TEST(GeometryTest, ColorPremultiply) {
1349 Color a(1.0, 0.5, 0.2, 0.5);
1356 Color a(0.5, 0.25, 0.1, 0.5);
1363 Color a(0.5, 0.25, 0.1, 0.0);
1370 TEST(GeometryTest, ColorR8G8B8A8) {
1372 Color a(1.0, 0.5, 0.2, 0.5);
1373 std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1378 Color a(0.0, 0.0, 0.0, 0.0);
1379 std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1384 Color a(1.0, 1.0, 1.0, 1.0);
1385 std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1392 Color a(0.0, 0.0, 0.0, 0.0);
1393 Color b(1.0, 1.0, 1.0, 1.0);
1402 Color a(0.2, 0.4, 1.0, 0.5);
1403 Color b(0.4, 1.0, 0.2, 0.3);
1432 TEST(GeometryTest, ColorMakeRGBA8) {
1447 Color b(0.247059, 0.498039, 0.74902, 0.498039);
1452 TEST(GeometryTest, ColorApplyColorMatrix) {
1461 auto expected =
Color(1, 1, 1, 1);
1473 auto expected =
Color(0.11, 0.22, 0.33, 0.44);
1478 TEST(GeometryTest, ColorLinearToSRGB) {
1481 auto expected =
Color(1, 1, 1, 1);
1487 auto expected =
Color(0, 0, 0, 0);
1493 auto expected =
Color(0.484529, 0.665185, 0.797738, 0.8);
1498 TEST(GeometryTest, ColorSRGBToLinear) {
1501 auto expected =
Color(1, 1, 1, 1);
1507 auto expected =
Color(0, 0, 0, 0);
1513 auto expected =
Color(0.0331048, 0.132868, 0.318547, 0.8);
1525 static const std::map<BlendMode, Color>
1655 #define _BLEND_MODE_RESULT_CHECK(blend_mode) \
1656 expected = ColorBlendTestData::kExpectedResults[source_i] \
1657 .find(BlendMode::k##blend_mode) \
1659 EXPECT_COLOR_NEAR(dst.Blend(src, BlendMode::k##blend_mode), expected);
1661 TEST(GeometryTest, ColorBlendReturnsExpectedResults) {
1663 for (
size_t source_i = 0;
1673 #define _BLEND_MODE_NAME_CHECK(blend_mode) \
1674 case BlendMode::k##blend_mode: \
1675 ASSERT_STREQ(result, #blend_mode); \
1679 using BlendT = std::underlying_type_t<BlendMode>;
1687 TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
1695 TEST(GeometryTest, MatrixPrinting) {
1697 std::stringstream stream;
1700 ASSERT_EQ(stream.str(), R
"((
1701 1.000000, 0.000000, 0.000000, 0.000000,
1702 0.000000, 1.000000, 0.000000, 0.000000,
1703 0.000000, 0.000000, 1.000000, 0.000000,
1704 0.000000, 0.000000, 0.000000, 1.000000,
1709 std::stringstream stream;
1713 ASSERT_EQ(stream.str(), R"((
1714 1.000000, 0.000000, 0.000000, 10.000000,
1715 0.000000, 1.000000, 0.000000, 20.000000,
1716 0.000000, 0.000000, 1.000000, 30.000000,
1717 0.000000, 0.000000, 0.000000, 1.000000,
1722 TEST(GeometryTest, PointPrinting) {
1724 std::stringstream stream;
1727 ASSERT_EQ(stream.str(), "(0, 0)");
1731 std::stringstream stream;
1734 ASSERT_EQ(stream.str(),
"(13, 37)");
1738 TEST(GeometryTest, Vector3Printing) {
1740 std::stringstream stream;
1743 ASSERT_EQ(stream.str(),
"(0, 0, 0)");
1747 std::stringstream stream;
1750 ASSERT_EQ(stream.str(),
"(1, 2, 3)");
1754 TEST(GeometryTest, Vector4Printing) {
1756 std::stringstream stream;
1759 ASSERT_EQ(stream.str(),
"(0, 0, 0, 1)");
1763 std::stringstream stream;
1766 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1770 TEST(GeometryTest, ColorPrinting) {
1772 std::stringstream stream;
1775 ASSERT_EQ(stream.str(),
"(0, 0, 0, 0)");
1779 std::stringstream stream;
1780 Color m(1, 2, 3, 4);
1782 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1797 std::vector<Scalar> stops = {0.0, 1.0};
1802 ASSERT_EQ(gradient.texture_size, 2u);
1809 std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1812 ASSERT_EQ(gradient.texture_size, 5u);
1820 std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1825 ASSERT_EQ(gradient.texture_size, 4u);
1831 std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1835 std::vector<Color> lerped_colors = {
1843 ASSERT_EQ(gradient.texture_size, 5u);
1848 std::vector<Color> colors = {};
1849 std::vector<Scalar> stops = {};
1850 for (
auto i = 0u; i < 1025; i++) {
1852 stops.push_back(i / 1025.0);
1857 ASSERT_EQ(gradient.texture_size, 1024u);
1858 ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1862 TEST(GeometryTest, HalfConversions) {
1863 #if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1864 defined(FML_OS_IOS_SIMULATOR)
1888 ASSERT_EQ(
Half(0.5f),
Half(0.5f16));
1889 ASSERT_EQ(
Half(0.5),
Half(0.5f16));
1892 GTEST_SKIP() <<
"Half-precision floats (IEEE 754) are not portable and "
1893 "only used on Apple platforms.";
1894 #endif // FML_OS_MACOSX || FML_OS_IOS || FML_OS_IOS_SIMULATOR