Chromium Code Reviews| Index: cc/quads/draw_polygon_unittest.cc |
| diff --git a/cc/quads/draw_polygon_unittest.cc b/cc/quads/draw_polygon_unittest.cc |
| index 40090ec765910296f43d9834e955e8c31f2302aa..d3e421a5bf1e801a7a23ac05d325ae1b47cfd979 100644 |
| --- a/cc/quads/draw_polygon_unittest.cc |
| +++ b/cc/quads/draw_polygon_unittest.cc |
| @@ -24,6 +24,45 @@ namespace cc { |
| void DrawPolygon::RecomputeNormalForTesting() { |
| ConstructNormal(); |
| } |
| + |
| +static int sign(float v) { |
| + static const float epsilon = 0.00001f; |
| + |
| + if (v > epsilon) |
| + return 1; |
| + if (v < -epsilon) |
| + return -1; |
| + return 0; |
| +} |
| + |
| +bool DrawPolygon::IsPlanarForTesting() const { |
| + static const float epsilon = 0.00001f; |
| + for (size_t i = 1; i < points_.size(); i++) { |
| + if (gfx::DotProduct(points_[i] - points_[0], normal_) > epsilon) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +bool DrawPolygon::IsConvexForTesting() const { |
| + if (points_.size() < 3) |
| + return true; |
| + |
| + gfx::Vector3dF prev = |
| + points_[points_.size() - 1] - points_[points_.size() - 2]; |
| + gfx::Vector3dF next = points_[0] - points_[points_.size() - 1]; |
| + int ccw = sign(gfx::DotProduct(CrossProduct(prev, next), normal_)); |
| + for (size_t i = 1; i < points_.size(); i++) { |
| + prev = next; |
| + next = points_[i] - points_[i - 1]; |
| + int next_sign = sign(gfx::DotProduct(CrossProduct(prev, next), normal_)); |
| + if (ccw == 0) |
| + ccw = next_sign; |
| + if (next_sign != 0 && next_sign != ccw) |
| + return false; |
| + } |
| + return true; |
| +} |
| #endif |
| namespace { |
| @@ -317,6 +356,45 @@ TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) { |
| EXPECT_EQ(BSP_BACK, SideCompare(polygon_b, polygon_a)); |
| } |
| +// One quad intersects a pent with an occluded side. |
| +TEST(DrawPolygonSplitTest, SlimClip) { |
| + std::vector<gfx::Point3F> vertices_a; |
| + vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); |
| + vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| + vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); |
| + vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); |
| + std::vector<gfx::Point3F> vertices_b; |
| + vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, 5.000f)); |
| + vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.001f)); |
| + vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.000f)); |
| + vertices_b.push_back(gfx::Point3F(1.002f, 1.002f, -0.005f)); |
| + vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, -4.000f)); |
| + |
| + CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a, |
| + gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); |
| + CREATE_NEW_DRAW_POLYGON_PTR(polygon_b, vertices_b, |
| + gfx::Vector3dF(0.707107, -0.707107, 0.000000), 1); |
| + |
| +// These are well formed, convex polygons. |
| +#if !defined(OS_WIN) |
|
flackr
2016/10/13 18:42:26
I agree this ensures that the polygons are indeed
flackr
2016/10/13 18:49:30
Nevermind, thanks for pointing out we declare Draw
|
| + EXPECT_EQ(polygon_a->IsPlanarForTesting(), true); |
| + EXPECT_EQ(polygon_a->IsConvexForTesting(), true); |
| + EXPECT_EQ(polygon_b->IsPlanarForTesting(), true); |
| + EXPECT_EQ(polygon_b->IsConvexForTesting(), true); |
| +#endif |
| + |
| + std::unique_ptr<DrawPolygon> front_polygon; |
| + std::unique_ptr<DrawPolygon> back_polygon; |
| + bool is_coplanar; |
| + |
| + polygon_a->SplitPolygon(std::move(polygon_b), &front_polygon, &back_polygon, |
| + &is_coplanar); |
| + |
| + EXPECT_FALSE(is_coplanar); |
| + EXPECT_TRUE(front_polygon != nullptr); |
| + EXPECT_TRUE(back_polygon != nullptr); |
| +} |
| + |
| // One quad intersects another and becomes two pieces. |
| TEST(DrawPolygonSplitTest, BasicSplit) { |
| std::vector<gfx::Point3F> vertices_a; |
| @@ -406,6 +484,60 @@ TEST(DrawPolygonSplitTest, AngledSplit) { |
| ValidatePointsWithinDeltaOf(*(back_polygon.get()), test_points_b, 1e-6f); |
| } |
| +// In this test we cut the corner of a quad so that it creates a triangle and |
| +// a pentagon as a result, and then cut the pentagon. |
| +TEST(DrawPolygonSplitTest, DoubleSplit) { |
| + std::vector<gfx::Point3F> vertices_a; |
| + vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
| + vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); |
| + vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); |
| + vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); |
| + std::vector<gfx::Point3F> vertices_b; |
| + vertices_b.push_back(gfx::Point3F(2.0f, 5.0f, 1.0f)); |
| + vertices_b.push_back(gfx::Point3F(2.0f, -5.0f, 1.0f)); |
| + vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f)); |
| + vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f)); |
| + |
| + CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a, |
| + gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0); |
| + CREATE_NEW_DRAW_POLYGON_PTR(polygon_b, vertices_b, |
| + gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2), |
| + 1); |
| + |
| + std::unique_ptr<DrawPolygon> front_polygon; |
| + std::unique_ptr<DrawPolygon> back_polygon; |
| + bool is_coplanar; |
| + |
| + polygon_b->SplitPolygon(std::move(polygon_a), &front_polygon, &back_polygon, |
| + &is_coplanar); |
| + EXPECT_FALSE(is_coplanar); |
| + EXPECT_TRUE(front_polygon != nullptr); |
| + EXPECT_TRUE(back_polygon != nullptr); |
| + |
| + EXPECT_EQ(3u, front_polygon->points().size()); |
| + EXPECT_EQ(5u, back_polygon->points().size()); |
| + |
| + std::vector<gfx::Point3F> vertices_c; |
| + vertices_c.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); |
| + vertices_c.push_back(gfx::Point3F(1.0f, -0.05f, 0.0f)); |
| + vertices_c.push_back(gfx::Point3F(10.0f, 0.05f, 9.0f)); |
| + |
| + CREATE_NEW_DRAW_POLYGON_PTR(polygon_c, vertices_c, |
| + gfx::Vector3dF(0.0055f, -0.999f, 0.0055f), 0); |
| + |
| + std::unique_ptr<DrawPolygon> second_front_polygon; |
| + std::unique_ptr<DrawPolygon> second_back_polygon; |
| + |
| + polygon_c->SplitPolygon(std::move(back_polygon), &second_front_polygon, |
| + &second_back_polygon, &is_coplanar); |
| + EXPECT_FALSE(is_coplanar); |
| + EXPECT_TRUE(second_front_polygon != nullptr); |
| + EXPECT_TRUE(second_back_polygon != nullptr); |
| + |
| + EXPECT_EQ(3u, second_front_polygon->points().size()); |
| + EXPECT_EQ(3u, second_back_polygon->points().size()); |
| +} |
| + |
| TEST(DrawPolygonTransformTest, TransformNormal) { |
| std::vector<gfx::Point3F> vertices_a; |
| vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f)); |