Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: cc/quads/draw_polygon_unittest.cc

Issue 2408203005: Add tests where we split near an edge. (Closed)
Patch Set: Fix Windows truncation error Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/quads/draw_polygon.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // We would like to use M_PI on windows too. 5 // We would like to use M_PI on windows too.
6 #ifdef _WIN32 6 #ifdef _WIN32
7 #define _USE_MATH_DEFINES 7 #define _USE_MATH_DEFINES
8 #endif 8 #endif
9 9
10 #include <stddef.h> 10 #include <stddef.h>
11 11
12 #include <limits> 12 #include <limits>
13 #include <vector> 13 #include <vector>
14 14
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "cc/output/bsp_compare_result.h" 16 #include "cc/output/bsp_compare_result.h"
17 #include "cc/quads/draw_polygon.h" 17 #include "cc/quads/draw_polygon.h"
18 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/gfx/transform.h" 19 #include "ui/gfx/transform.h"
20 20
21 namespace cc { 21 namespace cc {
22 22
23 #if !defined(OS_WIN) 23 #if !defined(OS_WIN)
24 void DrawPolygon::RecomputeNormalForTesting() { 24 void DrawPolygon::RecomputeNormalForTesting() {
25 ConstructNormal(); 25 ConstructNormal();
26 } 26 }
27
28 static int sign(float v) {
29 static const float epsilon = 0.00001f;
30
31 if (v > epsilon)
32 return 1;
33 if (v < -epsilon)
34 return -1;
35 return 0;
36 }
37
38 bool DrawPolygon::IsPlanarForTesting() const {
39 static const float epsilon = 0.00001f;
40 for (size_t i = 1; i < points_.size(); i++) {
41 if (gfx::DotProduct(points_[i] - points_[0], normal_) > epsilon)
42 return false;
43 }
44 return true;
45 }
46
47 bool DrawPolygon::IsConvexForTesting() const {
48 if (points_.size() < 3)
49 return true;
50
51 gfx::Vector3dF prev =
52 points_[points_.size() - 1] - points_[points_.size() - 2];
53 gfx::Vector3dF next = points_[0] - points_[points_.size() - 1];
54 int ccw = sign(gfx::DotProduct(CrossProduct(prev, next), normal_));
55 for (size_t i = 1; i < points_.size(); i++) {
56 prev = next;
57 next = points_[i] - points_[i - 1];
58 int next_sign = sign(gfx::DotProduct(CrossProduct(prev, next), normal_));
59 if (ccw == 0)
60 ccw = next_sign;
61 if (next_sign != 0 && next_sign != ccw)
62 return false;
63 }
64 return true;
65 }
27 #endif 66 #endif
28 67
29 namespace { 68 namespace {
30 69
31 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ 70 #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \
32 DrawPolygon name(NULL, points_vector, normal, polygon_id) 71 DrawPolygon name(NULL, points_vector, normal, polygon_id)
33 72
34 #define CREATE_NEW_DRAW_POLYGON_PTR(name, points_vector, normal, polygon_id) \ 73 #define CREATE_NEW_DRAW_POLYGON_PTR(name, points_vector, normal, polygon_id) \
35 std::unique_ptr<DrawPolygon> name(base::MakeUnique<DrawPolygon>( \ 74 std::unique_ptr<DrawPolygon> name(base::MakeUnique<DrawPolygon>( \
36 nullptr, points_vector, normal, polygon_id)) 75 nullptr, points_vector, normal, polygon_id))
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f)); 349 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f));
311 350
312 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 351 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a,
313 gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); 352 gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
314 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b, 353 CREATE_NEW_DRAW_POLYGON(polygon_b, vertices_b,
315 gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1); 354 gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
316 355
317 EXPECT_EQ(BSP_BACK, SideCompare(polygon_b, polygon_a)); 356 EXPECT_EQ(BSP_BACK, SideCompare(polygon_b, polygon_a));
318 } 357 }
319 358
359 // One quad intersects a pent with an occluded side.
360 TEST(DrawPolygonSplitTest, SlimClip) {
361 std::vector<gfx::Point3F> vertices_a;
362 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
363 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
364 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
365 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
366 std::vector<gfx::Point3F> vertices_b;
367 vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, 5.000f));
368 vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.001f));
369 vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.000f));
370 vertices_b.push_back(gfx::Point3F(1.002f, 1.002f, -0.005f));
371 vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, -4.000f));
372
373 CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a,
374 gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
375 CREATE_NEW_DRAW_POLYGON_PTR(
376 polygon_b, vertices_b,
377 gfx::Vector3dF(sqrt(2) / 2, -sqrt(2) / 2, 0.000000), 1);
378
379 // These are well formed, convex polygons.
380 #if !defined(OS_WIN)
enne (OOO) 2016/10/14 18:04:59 These are well-formed polygons, except on Windows.
flackr 2016/10/14 18:12:32 They're well-formed on Windows too, but defining D
381 EXPECT_TRUE(polygon_a->IsPlanarForTesting());
382 EXPECT_TRUE(polygon_a->IsConvexForTesting());
383 EXPECT_TRUE(polygon_b->IsPlanarForTesting());
384 EXPECT_TRUE(polygon_b->IsConvexForTesting());
385 #endif
386
387 std::unique_ptr<DrawPolygon> front_polygon;
388 std::unique_ptr<DrawPolygon> back_polygon;
389 bool is_coplanar;
390
391 polygon_a->SplitPolygon(std::move(polygon_b), &front_polygon, &back_polygon,
392 &is_coplanar);
393
394 EXPECT_FALSE(is_coplanar);
395 EXPECT_TRUE(front_polygon != nullptr);
396 EXPECT_TRUE(back_polygon != nullptr);
397 }
398
320 // One quad intersects another and becomes two pieces. 399 // One quad intersects another and becomes two pieces.
321 TEST(DrawPolygonSplitTest, BasicSplit) { 400 TEST(DrawPolygonSplitTest, BasicSplit) {
322 std::vector<gfx::Point3F> vertices_a; 401 std::vector<gfx::Point3F> vertices_a;
323 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); 402 vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
324 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); 403 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
325 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); 404 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
326 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); 405 vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
327 std::vector<gfx::Point3F> vertices_b; 406 std::vector<gfx::Point3F> vertices_b;
328 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f)); 407 vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f));
329 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f)); 408 vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f));
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f)); 478 test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f));
400 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); 479 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
401 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); 480 test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
402 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); 481 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
403 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f)); 482 test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f));
404 483
405 ValidatePointsWithinDeltaOf(*(front_polygon.get()), test_points_a, 1e-6f); 484 ValidatePointsWithinDeltaOf(*(front_polygon.get()), test_points_a, 1e-6f);
406 ValidatePointsWithinDeltaOf(*(back_polygon.get()), test_points_b, 1e-6f); 485 ValidatePointsWithinDeltaOf(*(back_polygon.get()), test_points_b, 1e-6f);
407 } 486 }
408 487
488 // In this test we cut the corner of a quad so that it creates a triangle and
489 // a pentagon as a result, and then cut the pentagon.
490 TEST(DrawPolygonSplitTest, DoubleSplit) {
491 std::vector<gfx::Point3F> vertices_a;
492 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
493 vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
494 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
495 vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
496 std::vector<gfx::Point3F> vertices_b;
497 vertices_b.push_back(gfx::Point3F(2.0f, 5.0f, 1.0f));
498 vertices_b.push_back(gfx::Point3F(2.0f, -5.0f, 1.0f));
499 vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f));
500 vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f));
501
502 CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a,
503 gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0);
504 CREATE_NEW_DRAW_POLYGON_PTR(polygon_b, vertices_b,
505 gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2),
506 1);
507
508 std::unique_ptr<DrawPolygon> front_polygon;
509 std::unique_ptr<DrawPolygon> back_polygon;
510 bool is_coplanar;
511
512 polygon_b->SplitPolygon(std::move(polygon_a), &front_polygon, &back_polygon,
513 &is_coplanar);
514 EXPECT_FALSE(is_coplanar);
515 EXPECT_TRUE(front_polygon != nullptr);
516 EXPECT_TRUE(back_polygon != nullptr);
517
518 EXPECT_EQ(3u, front_polygon->points().size());
519 EXPECT_EQ(5u, back_polygon->points().size());
520
521 std::vector<gfx::Point3F> vertices_c;
522 vertices_c.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
523 vertices_c.push_back(gfx::Point3F(1.0f, -0.05f, 0.0f));
524 vertices_c.push_back(gfx::Point3F(10.0f, 0.05f, 9.0f));
525
526 CREATE_NEW_DRAW_POLYGON_PTR(polygon_c, vertices_c,
527 gfx::Vector3dF(0.0055f, -0.999f, 0.0055f), 0);
528
529 std::unique_ptr<DrawPolygon> second_front_polygon;
530 std::unique_ptr<DrawPolygon> second_back_polygon;
531
532 polygon_c->SplitPolygon(std::move(back_polygon), &second_front_polygon,
533 &second_back_polygon, &is_coplanar);
534 EXPECT_FALSE(is_coplanar);
535 EXPECT_TRUE(second_front_polygon != nullptr);
536 EXPECT_TRUE(second_back_polygon != nullptr);
537
538 EXPECT_EQ(3u, second_front_polygon->points().size());
539 EXPECT_EQ(3u, second_back_polygon->points().size());
540 }
541
409 TEST(DrawPolygonTransformTest, TransformNormal) { 542 TEST(DrawPolygonTransformTest, TransformNormal) {
410 std::vector<gfx::Point3F> vertices_a; 543 std::vector<gfx::Point3F> vertices_a;
411 vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f)); 544 vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f));
412 vertices_a.push_back(gfx::Point3F(-1.0f, 0.0f, -1.0f)); 545 vertices_a.push_back(gfx::Point3F(-1.0f, 0.0f, -1.0f));
413 vertices_a.push_back(gfx::Point3F(0.0f, 1.0f, 0.0f)); 546 vertices_a.push_back(gfx::Point3F(0.0f, 1.0f, 0.0f));
414 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a, 547 CREATE_NEW_DRAW_POLYGON(polygon_a, vertices_a,
415 gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2), 0); 548 gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2), 0);
416 EXPECT_NORMAL(polygon_a, sqrt(2) / 2, 0.0f, -sqrt(2) / 2); 549 EXPECT_NORMAL(polygon_a, sqrt(2) / 2, 0.0f, -sqrt(2) / 2);
417 550
418 gfx::Transform transform; 551 gfx::Transform transform;
419 transform.RotateAboutYAxis(45.0f); 552 transform.RotateAboutYAxis(45.0f);
420 // This would transform the vertices as well, but we are transforming a 553 // This would transform the vertices as well, but we are transforming a
421 // DrawPolygon with 0 vertices just to make sure our normal transformation 554 // DrawPolygon with 0 vertices just to make sure our normal transformation
422 // using the inverse tranpose matrix gives us the right result. 555 // using the inverse tranpose matrix gives us the right result.
423 polygon_a.TransformToScreenSpace(transform); 556 polygon_a.TransformToScreenSpace(transform);
424 557
425 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here 558 // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here
426 // because some architectures (e.g., Arm64) employ a fused multiply-add 559 // because some architectures (e.g., Arm64) employ a fused multiply-add
427 // instruction which causes rounding asymmetry and reduces precision. 560 // instruction which causes rounding asymmetry and reduces precision.
428 // http://crbug.com/401117. 561 // http://crbug.com/401117.
429 EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f); 562 EXPECT_NORMAL(polygon_a, 0.0f, 0.0f, -1.0f);
430 } 563 }
431 564
432 } // namespace 565 } // namespace
433 } // namespace cc 566 } // namespace cc
OLDNEW
« no previous file with comments | « cc/quads/draw_polygon.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698