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

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

Issue 1883623002: Correct normal computation for inverted polygons. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 | « no previous file | cc/quads/draw_polygon_unittest.cc » ('j') | 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 #include "cc/quads/draw_polygon.h" 5 #include "cc/quads/draw_polygon.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
(...skipping 27 matching lines...) Expand all
38 38
39 DrawPolygon::DrawPolygon(const DrawQuad* original, 39 DrawPolygon::DrawPolygon(const DrawQuad* original,
40 const std::vector<gfx::Point3F>& in_points, 40 const std::vector<gfx::Point3F>& in_points,
41 const gfx::Vector3dF& normal, 41 const gfx::Vector3dF& normal,
42 int draw_order_index) 42 int draw_order_index)
43 : order_index_(draw_order_index), original_ref_(original), is_split_(true) { 43 : order_index_(draw_order_index), original_ref_(original), is_split_(true) {
44 for (size_t i = 0; i < in_points.size(); i++) { 44 for (size_t i = 0; i < in_points.size(); i++) {
45 points_.push_back(in_points[i]); 45 points_.push_back(in_points[i]);
46 } 46 }
47 normal_ = normal; 47 normal_ = normal;
48 DCHECK_LE((ConstructNormal(), (normal_ - normal).Length()),
49 normalized_threshold);
48 } 50 }
49 51
50 // This takes the original DrawQuad that this polygon should be based on, 52 // This takes the original DrawQuad that this polygon should be based on,
51 // a visible content rect to make the 4 corner points from, and a transformation 53 // a visible content rect to make the 4 corner points from, and a transformation
52 // to move it and its normal into screen space. 54 // to move it and its normal into screen space.
53 DrawPolygon::DrawPolygon(const DrawQuad* original_ref, 55 DrawPolygon::DrawPolygon(const DrawQuad* original_ref,
54 const gfx::RectF& visible_layer_rect, 56 const gfx::RectF& visible_layer_rect,
55 const gfx::Transform& transform, 57 const gfx::Transform& transform,
56 int draw_order_index) 58 int draw_order_index)
57 : normal_(0.0f, 0.0f, 1.0f), 59 : normal_(0.0f, 0.0f, 1.0f),
58 order_index_(draw_order_index), 60 order_index_(draw_order_index),
59 original_ref_(original_ref), 61 original_ref_(original_ref),
60 is_split_(false) { 62 is_split_(false) {
61 gfx::Point3F points[8]; 63 gfx::Point3F points[8];
62 int num_vertices_in_clipped_quad; 64 int num_vertices_in_clipped_quad;
63 gfx::QuadF send_quad(visible_layer_rect); 65 gfx::QuadF send_quad(visible_layer_rect);
64 66
65 // Doing this mapping here is very important, since we can't just transform 67 // Doing this mapping here is very important, since we can't just transform
66 // the points without clipping and not run into strange geometry issues when 68 // the points without clipping and not run into strange geometry issues when
67 // crossing w = 0. At this point, in the constructor, we know that we're 69 // crossing w = 0. At this point, in the constructor, we know that we're
68 // working with a quad, so we can reuse the MathUtil::MapClippedQuad3d 70 // working with a quad, so we can reuse the MathUtil::MapClippedQuad3d
69 // function instead of writing a generic polygon version of it. 71 // function instead of writing a generic polygon version of it.
70 MathUtil::MapClippedQuad3d( 72 MathUtil::MapClippedQuad3d(
71 transform, send_quad, points, &num_vertices_in_clipped_quad); 73 transform, send_quad, points, &num_vertices_in_clipped_quad);
72 for (int i = 0; i < num_vertices_in_clipped_quad; i++) { 74 for (int i = 0; i < num_vertices_in_clipped_quad; i++) {
73 points_.push_back(points[i]); 75 points_.push_back(points[i]);
74 } 76 }
77 transform.TransformVector(&normal_);
75 ConstructNormal(); 78 ConstructNormal();
76 } 79 }
77 80
78 DrawPolygon::~DrawPolygon() { 81 DrawPolygon::~DrawPolygon() {
79 } 82 }
80 83
81 std::unique_ptr<DrawPolygon> DrawPolygon::CreateCopy() { 84 std::unique_ptr<DrawPolygon> DrawPolygon::CreateCopy() {
82 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon()); 85 std::unique_ptr<DrawPolygon> new_polygon(new DrawPolygon());
83 new_polygon->order_index_ = order_index_; 86 new_polygon->order_index_ = order_index_;
84 new_polygon->original_ref_ = original_ref_; 87 new_polygon->original_ref_ = original_ref_;
85 new_polygon->points_.reserve(points_.size()); 88 new_polygon->points_.reserve(points_.size());
86 new_polygon->points_ = points_; 89 new_polygon->points_ = points_;
87 new_polygon->normal_.set_x(normal_.x()); 90 new_polygon->normal_.set_x(normal_.x());
88 new_polygon->normal_.set_y(normal_.y()); 91 new_polygon->normal_.set_y(normal_.y());
89 new_polygon->normal_.set_z(normal_.z()); 92 new_polygon->normal_.set_z(normal_.z());
90 return new_polygon; 93 return new_polygon;
91 } 94 }
92 95
93 // 96 //
94 // If this were to be more generally used and expected to be applicable 97 // If this were to be more generally used and expected to be applicable
95 // replacing this with Newell's algorithm (or an improvement thereof) 98 // replacing this with Newell's algorithm (or an improvement thereof)
96 // would be preferable, but usually this is coming in from a rectangle 99 // would be preferable, but usually this is coming in from a rectangle
97 // that has been transformed to screen space and clipped. 100 // that has been transformed to screen space and clipped.
98 // Averaging a few near diagonal cross products is pretty good in that case. 101 // Averaging a few near diagonal cross products is pretty good in that case.
99 // 102 //
100 void DrawPolygon::ConstructNormal() { 103 void DrawPolygon::ConstructNormal() {
101 normal_.set_x(0.0f); 104 gfx::Vector3dF new_normal(0.0f, 0.0f, 0.0f);
102 normal_.set_y(0.0f);
103 normal_.set_z(0.0f);
104 int delta = points_.size() / 2; 105 int delta = points_.size() / 2;
105 for (size_t i = 1; i + delta < points_.size(); i++) { 106 for (size_t i = 1; i + delta < points_.size(); i++) {
106 normal_ += 107 new_normal +=
107 CrossProduct(points_[i] - points_[0], points_[i + delta] - points_[0]); 108 CrossProduct(points_[i] - points_[0], points_[i + delta] - points_[0]);
108 } 109 }
109 float normal_magnitude = normal_.Length(); 110 float normal_magnitude = new_normal.Length();
111 // Here we constrain the new normal to point in the same sense as the old one.
112 // This allows us to handle winding-reversing transforms better.
113 if (gfx::DotProduct(normal_, new_normal) < 0.0) {
114 normal_magnitude *= -1.0;
115 }
110 if (normal_magnitude != 0 && normal_magnitude != 1) { 116 if (normal_magnitude != 0 && normal_magnitude != 1) {
111 normal_.Scale(1.0f / normal_magnitude); 117 new_normal.Scale(1.0f / normal_magnitude);
112 } 118 }
119 normal_ = new_normal;
113 } 120 }
114 121
115 #if defined(OS_WIN) 122 #if defined(OS_WIN)
116 // 123 //
117 // Allows the unittest to invoke this for the more general constructor. 124 // Allows the unittest to invoke this for the more general constructor.
118 // 125 //
119 void DrawPolygon::RecomputeNormalForTesting() { 126 void DrawPolygon::RecomputeNormalForTesting() {
120 ConstructNormal(); 127 ConstructNormal();
121 } 128 }
122 #endif 129 #endif
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 for (size_t i = 0; i < points_.size(); i++) { 243 for (size_t i = 0; i < points_.size(); i++) {
237 transform.TransformPoint(&points_[i]); 244 transform.TransformPoint(&points_[i]);
238 } 245 }
239 } 246 }
240 247
241 // TransformToScreenSpace assumes we're moving a layer from its layer space 248 // TransformToScreenSpace assumes we're moving a layer from its layer space
242 // into 3D screen space, which for sorting purposes requires the normal to 249 // into 3D screen space, which for sorting purposes requires the normal to
243 // be transformed along with the vertices. 250 // be transformed along with the vertices.
244 void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) { 251 void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) {
245 ApplyTransform(transform); 252 ApplyTransform(transform);
253 transform.TransformVector(&normal_);
246 ConstructNormal(); 254 ConstructNormal();
247 } 255 }
248 256
249 // In the case of TransformToLayerSpace, we assume that we are giving the 257 // In the case of TransformToLayerSpace, we assume that we are giving the
250 // inverse transformation back to the polygon to move it back into layer space 258 // inverse transformation back to the polygon to move it back into layer space
251 // but we can ignore the costly process of applying the inverse to the normal 259 // but we can ignore the costly process of applying the inverse to the normal
252 // since we know the normal will just reset to its original state. 260 // since we know the normal will just reset to its original state.
253 void DrawPolygon::TransformToLayerSpace( 261 void DrawPolygon::TransformToLayerSpace(
254 const gfx::Transform& inverse_transform) { 262 const gfx::Transform& inverse_transform) {
255 ApplyTransform(inverse_transform); 263 ApplyTransform(inverse_transform);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 quads->push_back( 371 quads->push_back(
364 gfx::QuadF(first, 372 gfx::QuadF(first,
365 gfx::PointF(points_[offset].x(), points_[offset].y()), 373 gfx::PointF(points_[offset].x(), points_[offset].y()),
366 gfx::PointF(points_[op1].x(), points_[op1].y()), 374 gfx::PointF(points_[op1].x(), points_[op1].y()),
367 gfx::PointF(points_[op2].x(), points_[op2].y()))); 375 gfx::PointF(points_[op2].x(), points_[op2].y())));
368 offset = op2; 376 offset = op2;
369 } 377 }
370 } 378 }
371 379
372 } // namespace cc 380 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | cc/quads/draw_polygon_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698