OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <limits> | |
6 #include <vector> | |
7 | |
8 #include "cc/output/bsp_compare_result.h" | |
9 #include "cc/quads/draw_polygon.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 #include "ui/gfx/transform.h" | |
12 | |
13 namespace cc { | |
14 namespace { | |
15 | |
16 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ | |
17 DrawPolygon name(NULL, points_vector, normal, polygon_id) | |
18 | |
19 #define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \ | |
20 EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon()); | |
21 | |
22 #define EXPECT_POINT_EQ(point_a, point_b) \ | |
23 EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \ | |
24 EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \ | |
25 EXPECT_FLOAT_EQ(point_a.z(), point_b.z()); | |
26 | |
27 static void ValidatePoints(const DrawPolygon& polygon, | |
28 const std::vector<gfx::Point3F>& points) { | |
29 EXPECT_EQ(polygon.points().size(), points.size()); | |
30 for (size_t i = 0; i < points.size(); i++) { | |
31 EXPECT_POINT_EQ(polygon.points()[i], points[i]); | |
32 } | |
33 } | |
34 | |
35 // Two quads are definitely not touching and so no split should occur. | |
36 TEST(DrawPolygonSplitTest, NotTouchingNoSplit) { | |
37 std::vector<gfx::Point3F> vertices_a; | |
38 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | |
39 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
40 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
41 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); | |
42 std::vector<gfx::Point3F> vertices_b; | |
43 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); | |
44 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f)); | |
45 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f)); | |
46 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); | |
47 | |
48 CREATE_NEW_DRAW_POLYGON( | |
49 polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); | |
50 CREATE_NEW_DRAW_POLYGON( | |
51 polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); | |
52 | |
53 EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_FRONT); | |
54 } | |
55 | |
56 // One quad is resting against another, but doesn't cross its plane so no split | |
57 // should occur. | |
58 TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) { | |
59 std::vector<gfx::Point3F> vertices_a; | |
60 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | |
61 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
62 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
63 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); | |
64 std::vector<gfx::Point3F> vertices_b; | |
65 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); | |
66 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f)); | |
67 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f)); | |
68 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); | |
69 | |
70 CREATE_NEW_DRAW_POLYGON( | |
71 polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); | |
72 CREATE_NEW_DRAW_POLYGON( | |
73 polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); | |
74 | |
75 EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_BACK); | |
76 } | |
77 | |
78 // One quad intersects another and becomes two pieces. | |
79 TEST(DrawPolygonSplitTest, BasicSplit) { | |
80 std::vector<gfx::Point3F> vertices_a; | |
81 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); | |
82 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
83 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
84 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); | |
85 std::vector<gfx::Point3F> vertices_b; | |
86 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f)); | |
87 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f)); | |
88 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f)); | |
89 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); | |
90 | |
91 CREATE_NEW_DRAW_POLYGON( | |
92 polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); | |
93 CREATE_NEW_DRAW_POLYGON( | |
94 polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); | |
95 | |
96 EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_SPLIT); | |
97 | |
98 scoped_ptr<DrawPolygon> front_polygon; | |
99 scoped_ptr<DrawPolygon> back_polygon; | |
100 polygon_b.Split(polygon_a, &front_polygon, &back_polygon); | |
101 EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_a), BSP_FRONT); | |
102 EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_a), BSP_BACK); | |
103 | |
104 std::vector<gfx::Point3F> test_points_a; | |
105 test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); | |
106 test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f)); | |
107 test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f)); | |
108 test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); | |
109 std::vector<gfx::Point3F> test_points_b; | |
110 test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f)); | |
111 test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f)); | |
112 test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f)); | |
113 test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); | |
114 ValidatePoints(*(front_polygon.get()), test_points_a); | |
115 ValidatePoints(*(back_polygon.get()), test_points_b); | |
116 | |
117 EXPECT_EQ(front_polygon->points().size(), 4u); | |
118 EXPECT_EQ(back_polygon->points().size(), 4u); | |
119 } | |
120 | |
121 // In this test we cut the corner of a quad so that it creates a triangle and | |
122 // a pentagon as a result. | |
123 TEST(DrawPolygonSplitTest, AngledSplit) { | |
124 std::vector<gfx::Point3F> vertices_a; | |
125 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
126 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); | |
127 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); | |
128 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
129 std::vector<gfx::Point3F> vertices_b; | |
130 vertices_b.push_back(gfx::Point3F(2.0f, 5.0f, 1.0f)); | |
131 vertices_b.push_back(gfx::Point3F(2.0f, -5.0f, 1.0f)); | |
132 vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f)); | |
133 vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f)); | |
134 | |
135 CREATE_NEW_DRAW_POLYGON( | |
136 polygon_a, vertices_a, gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0); | |
137 CREATE_NEW_DRAW_POLYGON( | |
138 polygon_b, vertices_b, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 1); | |
139 | |
140 EXPECT_EQ(DrawPolygon::SideCompare(polygon_a, polygon_b), BSP_SPLIT); | |
141 | |
142 scoped_ptr<DrawPolygon> front_polygon; | |
143 scoped_ptr<DrawPolygon> back_polygon; | |
144 polygon_a.Split(polygon_b, &front_polygon, &back_polygon); | |
145 EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_b), BSP_FRONT); | |
146 EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_b), BSP_BACK); | |
147 | |
148 EXPECT_EQ(front_polygon->points().size(), 3u); | |
149 EXPECT_EQ(back_polygon->points().size(), 5u); | |
150 | |
151 std::vector<gfx::Point3F> test_points_a; | |
152 test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); | |
153 test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); | |
154 test_points_a.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f)); | |
155 std::vector<gfx::Point3F> test_points_b; | |
156 test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f)); | |
157 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); | |
158 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); | |
159 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); | |
160 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); | |
161 | |
162 ValidatePoints(*(front_polygon.get()), test_points_a); | |
163 ValidatePoints(*(back_polygon.get()), test_points_b); | |
164 } | |
165 | |
166 TEST(DrawPolygonTransformTest, TransformNormal) { | |
167 // We give this polygon no actual vertices because we're not interested | |
168 // in actually transforming any points, just the normal. | |
169 std::vector<gfx::Point3F> vertices_a; | |
170 CREATE_NEW_DRAW_POLYGON( | |
171 polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0); | |
172 | |
173 gfx::Transform transform; | |
174 transform.RotateAboutYAxis(45.0); | |
175 // This would transform the vertices as well, but we are transforming a | |
176 // DrawPolygon with 0 vertices just to make sure our normal transformation | |
177 // using the inverse tranpose matrix gives us the right result. | |
178 polygon_a.TransformToScreenSpace(transform); | |
179 | |
180 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here | |
181 // because some architectures (e.g., Arm64) employ a fused multiply-add | |
182 // instruction which causes rounding asymmetry and reduces precision. | |
183 // http://crbug.com/401117. | |
184 EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().x(), 0); | |
185 EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().y(), 0); | |
186 EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().z(), -1); | |
187 } | |
188 | |
189 } // namespace | |
190 } // namespace cc | |
OLD | NEW |