diff options
author | petermayo <petermayo@chromium.org> | 2015-12-10 07:42:05 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-10 15:42:56 +0000 |
commit | 5240189cba88ed90ef654310c064d588c022f837 (patch) | |
tree | 831e35e47ac508f3ec9906f6653ac954f7bad6e7 /cc/quads/draw_polygon.cc | |
parent | 096b91575a69187a3f9e7b6484db5ac8ee9ed452 (diff) | |
download | chromium_src-5240189cba88ed90ef654310c064d588c022f837.zip chromium_src-5240189cba88ed90ef654310c064d588c022f837.tar.gz chromium_src-5240189cba88ed90ef654310c064d588c022f837.tar.bz2 |
Replace inverse transform with Cross-product computation.
This changes how we compute the 3d normals for quads moved into a
3d context.
The inverse transform approach seems to suffer numeric
instability around small Y rotations that invert the normal, causing
artifacts during rotation animations.
BUG=565758
TEST=observe 565758#2 html, and see no flicker at the start of
the twist.
R=vollick@chromium.org
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1497153002
Cr-Commit-Position: refs/heads/master@{#364367}
Diffstat (limited to 'cc/quads/draw_polygon.cc')
-rw-r--r-- | cc/quads/draw_polygon.cc | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/cc/quads/draw_polygon.cc b/cc/quads/draw_polygon.cc index b4f132a..b279fe6 100644 --- a/cc/quads/draw_polygon.cc +++ b/cc/quads/draw_polygon.cc @@ -70,7 +70,7 @@ DrawPolygon::DrawPolygon(const DrawQuad* original_ref, for (int i = 0; i < num_vertices_in_clipped_quad; i++) { points_.push_back(points[i]); } - ApplyTransformToNormal(transform); + ConstructNormal(); } DrawPolygon::~DrawPolygon() { @@ -88,6 +88,37 @@ scoped_ptr<DrawPolygon> DrawPolygon::CreateCopy() { return new_polygon; } +// +// If this were to be more generally used and expected to be applicable +// replacing this with Newell's algorithm (or an improvement thereof) +// would be preferable, but usually this is coming in from a rectangle +// that has been transformed to screen space and clipped. +// Averaging a few near diagonal cross products is pretty good in that case. +// +void DrawPolygon::ConstructNormal() { + normal_.set_x(0.0f); + normal_.set_y(0.0f); + normal_.set_z(0.0f); + int delta = points_.size() / 2; + for (size_t i = 1; i + delta < points_.size(); i++) { + normal_ += + CrossProduct(points_[i] - points_[0], points_[i + delta] - points_[0]); + } + float normal_magnitude = normal_.Length(); + if (normal_magnitude != 0 && normal_magnitude != 1) { + normal_.Scale(1.0f / normal_magnitude); + } +} + +#if defined(OS_WIN) +// +// Allows the unittest to invoke this for the more general constructor. +// +void DrawPolygon::RecomputeNormalForTesting() { + ConstructNormal(); +} +#endif + float DrawPolygon::SignedPointDistance(const gfx::Point3F& point) const { return gfx::DotProduct(point - points_[0], normal_); } @@ -210,7 +241,7 @@ void DrawPolygon::ApplyTransform(const gfx::Transform& transform) { // be transformed along with the vertices. void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) { ApplyTransform(transform); - ApplyTransformToNormal(transform); + ConstructNormal(); } // In the case of TransformToLayerSpace, we assume that we are giving the |