5#include "gtest/gtest.h"
13#include "flutter/fml/build_config.h"
14#include "flutter/testing/testing.h"
36 1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
39TEST(GeometryTest, MakeColumn) {
45 auto expect =
Matrix{1, 2, 3, 4,
50 ASSERT_TRUE(matrix == expect);
53TEST(GeometryTest, MakeRow) {
59 auto expect =
Matrix{1, 5, 9, 13,
64 ASSERT_TRUE(matrix == expect);
67TEST(GeometryTest, RotationMatrix) {
78TEST(GeometryTest, InvertMultMatrix) {
93 auto expect =
Matrix{0.5, 0, 0, 0,
101TEST(GeometryTest, MatrixBasis) {
102 auto matrix =
Matrix{1, 2, 3, 4,
106 auto basis = matrix.Basis();
107 auto expect =
Matrix{1, 2, 3, 0,
114TEST(GeometryTest, MutliplicationMatrix) {
120TEST(GeometryTest, DeterminantTest) {
121 auto matrix =
Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
122 ASSERT_EQ(matrix.GetDeterminant(), -1889);
125TEST(GeometryTest, InvertMatrix) {
126 auto inverted =
Matrix{10, -9, -12, 8,
133 438.0 / 85123.0, 1751.0 / 85123.0, -7783.0 / 85123.0, 4672.0 / 85123.0,
134 393.0 / 85123.0, -178.0 / 85123.0, -570.0 / 85123.0, 4192 / 85123.0,
135 -5230.0 / 85123.0, 2802.0 / 85123.0, -3461.0 / 85123.0, 962.0 / 85123.0,
136 2690.0 / 85123.0, 1814.0 / 85123.0, 3896.0 / 85123.0, 319.0 / 85123.0};
141TEST(GeometryTest, TestDecomposition) {
146 ASSERT_TRUE(
result.has_value());
154TEST(GeometryTest, TestDecomposition2) {
159 auto result = (translated * rotated * scaled).Decompose();
161 ASSERT_TRUE(
result.has_value());
173 ASSERT_FLOAT_EQ(res.
scale.
x, 2);
174 ASSERT_FLOAT_EQ(res.
scale.
y, 3);
175 ASSERT_FLOAT_EQ(res.
scale.
z, 1);
178TEST(GeometryTest, TestRecomposition) {
186 ASSERT_TRUE(
result.has_value());
200TEST(GeometryTest, TestRecomposition2) {
205 auto result = matrix.Decompose();
207 ASSERT_TRUE(
result.has_value());
212TEST(GeometryTest, MatrixVectorMultiplication) {
217 auto vector =
Vector4(10, 20, 30, 2);
220 auto expected =
Vector4(160, 220, 260, 2);
228 auto vector =
Vector3(10, 20, 30);
231 auto expected =
Vector3(60, 120, 160);
239 auto vector =
Point(10, 20);
242 auto expected =
Point(60, 120);
249 auto vector =
Vector3(3, 3, -3);
252 auto expected =
Vector3(-1, -1, 1.3468);
259 auto point =
Point(3, 3);
262 auto expected =
Point(-1, -1);
269 auto point =
Point(3, 3);
272 auto expected =
Point(0, 0);
277TEST(GeometryTest, MatrixMakeRotationFromQuaternion) {
297TEST(GeometryTest, MatrixTransformDirection) {
302 auto vector =
Vector4(10, 20, 30, 2);
305 auto expected =
Vector4(-40, 20, 60, 2);
313 auto vector =
Vector3(10, 20, 30);
316 auto expected =
Vector3(-40, 20, 60);
324 auto vector =
Point(10, 20);
327 auto expected =
Point(-40, 20);
332TEST(GeometryTest, MatrixGetMaxBasisLength) {
335 ASSERT_EQ(m.GetMaxBasisLength(), 3);
338 ASSERT_EQ(m.GetMaxBasisLength(), 5);
343 ASSERT_EQ(m.GetMaxBasisLength(), 4);
347TEST(GeometryTest, MatrixGetMaxBasisLengthXY) {
350 ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
353 ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
358 ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
364 1.0f, 0.0f, 0.0f, 0.0f,
365 0.0f, 1.0f, 0.0f, 0.0f,
366 4.0f, 0.0f, 1.0f, 0.0f,
367 0.0f, 0.0f, 0.0f, 1.0f
370 ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
374TEST(GeometryTest, MatrixMakeOrthographic) {
398TEST(GeometryTest, MatrixMakePerspective) {
422TEST(GeometryTest, MatrixGetBasisVectors) {
446TEST(GeometryTest, MatrixGetDirectionScale) {
450 ASSERT_FLOAT_EQ(
result, 1);
458 ASSERT_FLOAT_EQ(
result, 1);
465 ASSERT_FLOAT_EQ(
result, 8);
469TEST(GeometryTest, MatrixTranslationScaleOnly) {
472 bool result = m.IsTranslationScaleOnly();
478 bool result = m.IsTranslationScaleOnly();
484 bool result = m.IsTranslationScaleOnly();
490 bool result = m.IsTranslationScaleOnly();
495TEST(GeometryTest, MatrixLookAt) {
541TEST(GeometryTest, QuaternionLerp) {
545 auto q3 = q1.
Slerp(q2, 0.5);
552TEST(GeometryTest, QuaternionVectorMultiply) {
594TEST(GeometryTest, CanGenerateMipCounts) {
607TEST(GeometryTest, CanConvertTTypesExplicitly) {
618 ASSERT_EQ(s2.
width, 1u);
630TEST(GeometryTest, CanPerformAlgebraicPointOps) {
660TEST(GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes) {
692TEST(GeometryTest, PointIntegerCoercesToFloat) {
697 ASSERT_FLOAT_EQ(p2.
x, 2u);
698 ASSERT_FLOAT_EQ(p2.
y, 4u);
704 ASSERT_FLOAT_EQ(p2.
x, 2u);
705 ASSERT_FLOAT_EQ(p2.
y, 4u);
711 ASSERT_FLOAT_EQ(p2.
x, 2u);
712 ASSERT_FLOAT_EQ(p2.
y, 6u);
718 ASSERT_FLOAT_EQ(p2.
x, 1u);
719 ASSERT_FLOAT_EQ(p2.
y, 2u);
726 ASSERT_FLOAT_EQ(p2.
x, 2u);
727 ASSERT_FLOAT_EQ(p2.
y, 4u);
733 ASSERT_FLOAT_EQ(p2.
x, 2u);
734 ASSERT_FLOAT_EQ(p2.
y, 4u);
740 ASSERT_FLOAT_EQ(p2.
x, 2u);
741 ASSERT_FLOAT_EQ(p2.
y, 6u);
747 ASSERT_FLOAT_EQ(p2.
x, 1u);
748 ASSERT_FLOAT_EQ(p2.
y, 2u);
752TEST(GeometryTest, SizeCoercesToPoint) {
812TEST(GeometryTest, CanUsePointAssignmentOperators) {
887TEST(GeometryTest, PointDotProduct) {
891 ASSERT_FLOAT_EQ(
s, -1);
897 ASSERT_FLOAT_EQ(
s, 0);
903 ASSERT_FLOAT_EQ(
s, -5);
907TEST(GeometryTest, PointCrossProduct) {
911 ASSERT_FLOAT_EQ(
s, 0);
917 ASSERT_FLOAT_EQ(
s, -1);
923 ASSERT_FLOAT_EQ(
s, -10);
927TEST(GeometryTest, PointReflect) {
931 auto reflected =
a.Reflect(axis);
932 auto expected =
Point(2, -3);
939 auto reflected =
a.Reflect(axis);
940 auto expected =
Point(0, -1);
947 auto reflected =
a.Reflect(axis);
954 auto a_abs =
a.Abs();
955 auto expected =
Point(1, 2);
959TEST(GeometryTest, PointAngleTo) {
991 Point expected(0, 2);
995TEST(GeometryTest, Vector3Min) {
1012 Point expected(1, 10);
1026 Vector4 expected(1, 10, 3, 4);
1033 Point expected(1, 2);
1045 Vector4 p(1.5, 2.3, 3.9, 4.0);
1054 Point expected(2, 3);
1066 Vector4 p(1.5, 2.3, 3.9, 4.0);
1075 Point expected(2, 2);
1087 Vector4 p(1.5, 2.3, 3.9, 4.0);
1096 Point expected(4, 8);
1110 Vector4 expected(4, 8, 12, 16);
1114TEST(GeometryTest, CanUseVector3AssignmentOperators) {
1136 ASSERT_EQ(p.z, 12u);
1164TEST(GeometryTest, CanPerformAlgebraicVector3Ops) {
1168 ASSERT_EQ(p2.
x, 2u);
1169 ASSERT_EQ(p2.
y, 4u);
1170 ASSERT_EQ(p2.
z, 6u);
1176 ASSERT_EQ(p2.
x, 2u);
1177 ASSERT_EQ(p2.
y, 4u);
1178 ASSERT_EQ(p2.
z, 6u);
1184 ASSERT_EQ(p2.
x, 2u);
1185 ASSERT_EQ(p2.
y, 6u);
1186 ASSERT_EQ(p2.
z, 12u);
1192 ASSERT_EQ(p2.
x, 1u);
1193 ASSERT_EQ(p2.
y, 2u);
1194 ASSERT_EQ(p2.
z, 3u);
1198TEST(GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes) {
1211 ASSERT_EQ(p2.
x, -1);
1246 ASSERT_EQ(p2.
z, -1);
1266TEST(GeometryTest, ColorPremultiply) {
1268 Color a(1.0, 0.5, 0.2, 0.5);
1269 Color premultiplied =
a.Premultiply();
1275 Color a(0.5, 0.25, 0.1, 0.5);
1276 Color unpremultiplied =
a.Unpremultiply();
1282 Color a(0.5, 0.25, 0.1, 0.0);
1283 Color unpremultiplied =
a.Unpremultiply();
1291 Color a(1.0, 0.5, 0.2, 0.5);
1292 std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1297 Color a(0.0, 0.0, 0.0, 0.0);
1298 std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1303 Color a(1.0, 1.0, 1.0, 1.0);
1304 std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1311 Color a(0.0, 0.0, 0.0, 0.0);
1312 Color b(1.0, 1.0, 1.0, 1.0);
1321 Color a(0.2, 0.4, 1.0, 0.5);
1322 Color b(0.4, 1.0, 0.2, 0.3);
1351TEST(GeometryTest, ColorMakeRGBA8) {
1366 Color b(0.247059, 0.498039, 0.74902, 0.498039);
1371TEST(GeometryTest, ColorApplyColorMatrix) {
1380 auto expected =
Color(1, 1, 1, 1);
1392 auto expected =
Color(0.11, 0.22, 0.33, 0.44);
1397TEST(GeometryTest, ColorLinearToSRGB) {
1400 auto expected =
Color(1, 1, 1, 1);
1406 auto expected =
Color(0, 0, 0, 0);
1412 auto expected =
Color(0.484529, 0.665185, 0.797738, 0.8);
1417TEST(GeometryTest, ColorSRGBToLinear) {
1420 auto expected =
Color(1, 1, 1, 1);
1426 auto expected =
Color(0, 0, 0, 0);
1432 auto expected =
Color(0.0331048, 0.132868, 0.318547, 0.8);
1444 static const std::map<BlendMode, Color>
1574#define _BLEND_MODE_RESULT_CHECK(blend_mode) \
1575 expected = ColorBlendTestData::kExpectedResults[source_i] \
1576 .find(BlendMode::k##blend_mode) \
1578 EXPECT_COLOR_NEAR(dst.Blend(src, BlendMode::k##blend_mode), expected);
1580TEST(GeometryTest, ColorBlendReturnsExpectedResults) {
1582 for (
size_t source_i = 0;
1592#define _BLEND_MODE_NAME_CHECK(blend_mode) \
1593 case BlendMode::k##blend_mode: \
1594 ASSERT_STREQ(result, #blend_mode); \
1598 using BlendT = std::underlying_type_t<BlendMode>;
1606TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
1614TEST(GeometryTest, MatrixPrinting) {
1616 std::stringstream stream;
1619 ASSERT_EQ(stream.str(), R
"((
1620 1.000000, 0.000000, 0.000000, 0.000000,
1621 0.000000, 1.000000, 0.000000, 0.000000,
1622 0.000000, 0.000000, 1.000000, 0.000000,
1623 0.000000, 0.000000, 0.000000, 1.000000,
1628 std::stringstream stream;
1632 ASSERT_EQ(stream.str(), R"((
1633 1.000000, 0.000000, 0.000000, 10.000000,
1634 0.000000, 1.000000, 0.000000, 20.000000,
1635 0.000000, 0.000000, 1.000000, 30.000000,
1636 0.000000, 0.000000, 0.000000, 1.000000,
1643 std::stringstream stream;
1646 ASSERT_EQ(stream.str(), "(0, 0)");
1650 std::stringstream stream;
1653 ASSERT_EQ(stream.str(),
"(13, 37)");
1657TEST(GeometryTest, Vector3Printing) {
1659 std::stringstream stream;
1662 ASSERT_EQ(stream.str(),
"(0, 0, 0)");
1666 std::stringstream stream;
1669 ASSERT_EQ(stream.str(),
"(1, 2, 3)");
1673TEST(GeometryTest, Vector4Printing) {
1675 std::stringstream stream;
1678 ASSERT_EQ(stream.str(),
"(0, 0, 0, 1)");
1682 std::stringstream stream;
1685 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1691 std::stringstream stream;
1694 ASSERT_EQ(stream.str(),
"(0, 0, 0, 0)");
1698 std::stringstream stream;
1699 Color m(1, 2, 3, 4);
1701 ASSERT_EQ(stream.str(),
"(1, 2, 3, 4)");
1716 std::vector<Scalar> stops = {0.0, 1.0};
1721 ASSERT_EQ(gradient.texture_size, 2u);
1728 std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1731 ASSERT_EQ(gradient.texture_size, 5u);
1739 std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1744 ASSERT_EQ(gradient.texture_size, 4u);
1750 std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1754 std::vector<Color> lerped_colors = {
1762 ASSERT_EQ(gradient.texture_size, 5u);
1767 std::vector<Color> colors = {};
1768 std::vector<Scalar> stops = {};
1769 for (
auto i = 0u; i < 1025; i++) {
1771 stops.push_back(i / 1025.0);
1776 ASSERT_EQ(gradient.texture_size, 1024u);
1777 ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1781TEST(GeometryTest, HalfConversions) {
1782#if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1783 defined(FML_OS_IOS_SIMULATOR)
1807 ASSERT_EQ(
Half(0.5f),
Half(0.5f16));
1808 ASSERT_EQ(
Half(0.5),
Half(0.5f16));
1811 GTEST_SKIP() <<
"Half-precision floats (IEEE 754) are not portable and "
1812 "only used on Apple platforms.";
#define TEST(S, s, D, expected)
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
#define ASSERT_VECTOR4_NEAR(a, b)
#define ASSERT_MATRIX_NEAR(a, b)
#define ASSERT_QUATERNION_NEAR(a, b)
#define ASSERT_COLOR_NEAR(a, b)
#define ASSERT_POINT_NEAR(a, b)
#define ASSERT_ARRAY_4_NEAR(a, b)
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
#define ASSERT_VECTOR3_NEAR(a, b)
#define _BLEND_MODE_RESULT_CHECK(blend_mode)
#define _BLEND_MODE_NAME_CHECK(blend_mode)
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
const char * BlendModeToString(BlendMode blend_mode)
GradientData CreateGradientBuffer(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the interpolated color bytes for the linear gradient described by colors and s...
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
constexpr float k1OverSqrt2
static constexpr uint32_t ToIColor(Color color)
Convert this color to a 32-bit representation.
static constexpr Color LimeGreen()
static constexpr Color BlackTransparent()
Color LinearToSRGB() const
Convert the color from linear space to sRGB space.
static constexpr Color Black()
static constexpr Color CornflowerBlue()
static constexpr Color White()
constexpr Color WithAlpha(Scalar new_alpha) const
Color ApplyColorMatrix(const ColorMatrix &color_matrix) const
A color filter that transforms colors through a 4x5 color matrix.
static constexpr Color Red()
static constexpr Color MakeRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
constexpr Color Clamp01() const
static constexpr Color Lerp(Color a, Color b, Scalar t)
Return a color that is linearly interpolated between colors a and b, according to the value of t.
static constexpr Color Yellow()
Color SRGBToLinear() const
Convert the color from sRGB space to linear space.
static constexpr Color Blue()
static constexpr Color Green()
A storage only class for half precision floating point vector 2.
A storage only class for half precision floating point vector 3.
A storage only class for half precision floating point vector 4.
A storage only class for half precision floating point.
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeOrthographic(TSize< T > size)
static constexpr Matrix MakeTranslation(const Vector3 &t)
static constexpr Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
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)
static Matrix MakeRotationY(Radians r)
static constexpr Matrix MakeLookAt(Vector3 position, Vector3 target, Vector3 up)
std::optional< MatrixDecomposition > Decompose() const
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)
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
static Matrix MakeRotationZ(Radians r)
static constexpr Matrix MakeScale(const Vector3 &s)
static Matrix MakeRotation(Quaternion q)
static Matrix MakeRotationX(Radians r)
Quaternion Slerp(const Quaternion &to, double time) const
constexpr TPoint Normalize() const
constexpr size_t MipCount() const
static constexpr Color kDestinationColor
static const std::map< BlendMode, Color > kExpectedResults[sizeof(kSourceColors)]
static constexpr Color kSourceColors[]