Index: cc/quads/draw_polygon_unittest.cc |
diff --git a/cc/quads/draw_polygon_unittest.cc b/cc/quads/draw_polygon_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d3a2007ec0f5d9d46758b91164381a4cb97f5bc5 |
--- /dev/null |
+++ b/cc/quads/draw_polygon_unittest.cc |
@@ -0,0 +1,254 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <vector> |
+ |
+#include "cc/output/bsp_compare_result.h" |
+#include "cc/quads/draw_polygon.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/gfx/transform.h" |
+ |
+namespace cc { |
+namespace { |
+ |
+#define CREATE_NEW_DRAW_POLYGON(name, points_vector, polygon_id) \ |
+ DrawPolygon name(NULL, points_vector, polygon_id) |
+ |
+#define EXPECT_POINT_EQ(point_a, point_b) \ |
+ EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \ |
+ EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \ |
+ EXPECT_FLOAT_EQ(point_a.z(), point_b.z()); |
+ |
+static void ValidatePoints(const DrawPolygon& polygon, |
+ const std::vector<gfx::Point3F>& points) { |
+ EXPECT_EQ(polygon.points.size(), points.size()); |
+ for (unsigned int i = 0; i < points.size(); i++) { |
+ EXPECT_POINT_EQ(polygon.points[i], points[i]); |
+ } |
+} |
+ |
+// Two quads are definitely not touching and so no split should occur. |
+TEST(DrawPolygonSplitTest, NotTouchingNoSplit) { |
+ 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(5.0f, 10.0f, 5.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); |
+ |
+ CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 0); |
+ CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, 1); |
+ |
+ EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_FRONT); |
+} |
+ |
+// One quad is resting against another, but doesn't cross its plane so no split |
+// should occur. |
+TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) { |
+ 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(5.0f, 10.0f, 0.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); |
+ |
+ CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 0); |
+ CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, 1); |
+ |
+ EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_BACK); |
+} |
+ |
+// One quad intersects another and becomes two pieces. |
+TEST(DrawPolygonSplitTest, BasicSplit) { |
+ 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(5.0f, 10.0f, -5.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); |
+ |
+ CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 0); |
+ CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, 1); |
+ |
+ EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_SPLIT); |
+ |
+ scoped_ptr<DrawPolygon> front_polygon; |
+ scoped_ptr<DrawPolygon> back_polygon; |
+ polygon_b.Split(polygon_a, &front_polygon, &back_polygon); |
+ EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_a), BSP_FRONT); |
+ EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_a), BSP_BACK); |
+ |
+ std::vector<gfx::Point3F> test_points_a; |
+ test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); |
+ test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f)); |
+ test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); |
+ test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); |
+ std::vector<gfx::Point3F> test_points_b; |
+ test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f)); |
+ test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f)); |
+ test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); |
+ ValidatePoints(*(front_polygon.get()), test_points_a); |
+ ValidatePoints(*(back_polygon.get()), test_points_b); |
+ |
+ EXPECT_EQ(front_polygon->points.size(), static_cast<unsigned int>(4)); |
+ EXPECT_EQ(back_polygon->points.size(), static_cast<unsigned int>(4)); |
+} |
+ |
+// A "wave" shape of points that do not make up those of a convex polygon |
+// crossing the boundaries of another polygon. This should not cause a problem |
+// and should still result in two different pieces of geometry on either side. |
+TEST(DrawPolygonSplitTest, NonConvexSplit) { |
+ std::vector<gfx::Point3F> vertices_a; |
+ vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, -5.0f)); |
+ vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, -5.0f)); |
+ vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 5.0f)); |
+ vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 5.0f)); |
+ std::vector<gfx::Point3F> vertices_b; |
+ vertices_b.push_back(gfx::Point3F(-3.0f, 10.0f, 0.0f)); |
+ vertices_b.push_back(gfx::Point3F(-1.0f, 7.5f, 0.0f)); |
+ vertices_b.push_back(gfx::Point3F(1.0f, 5.0f, 0.0f)); |
+ vertices_b.push_back(gfx::Point3F(3.0f, 7.5f, 0.0f)); |
+ vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); |
+ vertices_b.push_back(gfx::Point3F(7.0f, 7.5f, 0.0f)); |
+ |
+ CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 0); |
+ CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, 1); |
+ |
+ EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_SPLIT); |
+ |
+ scoped_ptr<DrawPolygon> front_polygon; |
+ scoped_ptr<DrawPolygon> back_polygon; |
+ polygon_b.Split(polygon_a, &front_polygon, &back_polygon); |
+ EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_a), BSP_FRONT); |
+ EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_a), BSP_BACK); |
+ |
+ std::vector<gfx::Point3F> test_points_a; |
+ test_points_a.push_back(gfx::Point3F(0.0f, 9.25f, 0.0f)); |
+ test_points_a.push_back(gfx::Point3F(-3.0f, 10.0f, 0.0f)); |
+ test_points_a.push_back(gfx::Point3F(-1.0f, 7.5f, 0.0f)); |
+ test_points_a.push_back(gfx::Point3F(0.0f, 6.25f, 0.0f)); |
+ std::vector<gfx::Point3F> test_points_b; |
+ test_points_b.push_back(gfx::Point3F(0.0f, 6.25f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(1.0f, 5.0f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(3.0f, 7.5f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(7.0f, 7.5f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(0.0f, 9.25f, 0.0f)); |
+ |
+ ValidatePoints(*(front_polygon.get()), test_points_a); |
+ ValidatePoints(*(back_polygon.get()), test_points_b); |
+} |
+ |
+// In this test we cut the corner of a quad so that it creates a triangle and |
+// a pentagon as a result. |
+TEST(DrawPolygonSplitTest, AngledSplit) { |
+ 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(polygon_a, vertices_a, 0); |
+ CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, 1); |
+ |
+ EXPECT_EQ(DrawPolygon::SideCompare(polygon_a, polygon_b), BSP_SPLIT); |
+ |
+ scoped_ptr<DrawPolygon> front_polygon; |
+ scoped_ptr<DrawPolygon> back_polygon; |
+ polygon_a.Split(polygon_b, &front_polygon, &back_polygon); |
+ EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_b), BSP_FRONT); |
+ EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_b), BSP_BACK); |
+ |
+ EXPECT_EQ(front_polygon->points.size(), static_cast<unsigned int>(3)); |
+ EXPECT_EQ(back_polygon->points.size(), static_cast<unsigned int>(5)); |
+ |
+ std::vector<gfx::Point3F> test_points_a; |
+ test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); |
+ test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); |
+ test_points_a.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f)); |
+ std::vector<gfx::Point3F> test_points_b; |
+ test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); |
+ test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); |
+ test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); |
+ test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); |
+ |
+ ValidatePoints(*(front_polygon.get()), test_points_a); |
+ ValidatePoints(*(back_polygon.get()), test_points_b); |
+} |
+ |
+// Testing the area calculation on a basic flat 10x10 quad. |
+TEST(DrawPolygonAreaTest, Basic) { |
+ 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)); |
+ |
+ CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 0); |
+ |
+ EXPECT_EQ(polygon_a.area, 100.0f); |
+} |
+ |
+// Test the area of an octagon. It can be seen as a quad with the the corners |
+// all chopped off, removing 0.5 of the area at each corner from the previous |
+// test. |
+TEST(DrawPolygonAreaTest, OctagonArea) { |
+ std::vector<gfx::Point3F> vertices_a; |
+ vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f)); |
+ vertices_a.push_back(gfx::Point3F(9.0f, 0.0f, 0.0f)); |
+ vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 1.0f)); |
+ vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); |
+ vertices_a.push_back(gfx::Point3F(9.0f, 0.0f, 10.0f)); |
+ vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 10.0f)); |
+ vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 9.0f)); |
+ vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 1.0f)); |
+ |
+ CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 0); |
+ |
+ EXPECT_EQ(polygon_a.area, 98.0f); |
+} |
+ |
+// Same quad as before, but with transformations applied to it. This shows that |
+// the area calculation works on arbitrarily transformed geometry. |
+TEST(DrawPolygonAreaTest, TransformedPolygon) { |
+ 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)); |
+ |
+ gfx::Transform transform; |
+ transform.RotateAboutXAxis(30.0); |
+ transform.RotateAboutYAxis(40.0); |
+ transform.RotateAboutZAxis(50.0); |
+ for (int i = 0; i < 4; i++) { |
+ transform.TransformPoint(&vertices_a[i]); |
+ } |
+ |
+ CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 0); |
+ |
+ EXPECT_EQ(polygon_a.area, 100.0f); |
+} |
+ |
+} // namespace |
+} // namespace cc |