Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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/base/math_util.h" | 5 #include "cc/base/math_util.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 #include <limits> | 9 #include <limits> |
| 10 | 10 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 // p = (1-t) h1 + (t) h2. | 75 // p = (1-t) h1 + (t) h2. |
| 76 | 76 |
| 77 // Technically this is a special case of the following assertion, but its a | 77 // Technically this is a special case of the following assertion, but its a |
| 78 // good idea to keep it an explicit sanity check here. | 78 // good idea to keep it an explicit sanity check here. |
| 79 DCHECK_NE(h2.w(), h1.w()); | 79 DCHECK_NE(h2.w(), h1.w()); |
| 80 // Exactly one of h1 or h2 (but not both) must be on the negative side of the | 80 // Exactly one of h1 or h2 (but not both) must be on the negative side of the |
| 81 // w plane when this is called. | 81 // w plane when this is called. |
| 82 DCHECK(h1.ShouldBeClipped() ^ h2.ShouldBeClipped()); | 82 DCHECK(h1.ShouldBeClipped() ^ h2.ShouldBeClipped()); |
| 83 | 83 |
| 84 // ...or any positive non-zero small epsilon | 84 // ...or any positive non-zero small epsilon |
| 85 SkMScalar w = 0.00001f; | 85 SkMScalar w = 0.01f; |
|
enne (OOO)
2014/07/28 23:37:40
Just for the record (and to jog my memory), this w
troyhildebrandt
2014/07/29 19:57:17
It's necessary for the perf tests because without
| |
| 86 SkMScalar t = (w - h1.w()) / (h2.w() - h1.w()); | 86 SkMScalar t = (w - h1.w()) / (h2.w() - h1.w()); |
| 87 | 87 |
| 88 SkMScalar x = (SK_MScalar1 - t) * h1.x() + t * h2.x(); | 88 SkMScalar x = (SK_MScalar1 - t) * h1.x() + t * h2.x(); |
| 89 SkMScalar y = (SK_MScalar1 - t) * h1.y() + t * h2.y(); | 89 SkMScalar y = (SK_MScalar1 - t) * h1.y() + t * h2.y(); |
| 90 SkMScalar z = (SK_MScalar1 - t) * h1.z() + t * h2.z(); | 90 SkMScalar z = (SK_MScalar1 - t) * h1.z() + t * h2.z(); |
| 91 | 91 |
| 92 return HomogeneousCoordinate(x, y, z, w); | 92 return HomogeneousCoordinate(x, y, z, w); |
| 93 } | 93 } |
| 94 | 94 |
| 95 static inline void ExpandBoundsToIncludePoint(float* xmin, | 95 static inline void ExpandBoundsToIncludePoint(float* xmin, |
| 96 float* xmax, | 96 float* xmax, |
| 97 float* ymin, | 97 float* ymin, |
| 98 float* ymax, | 98 float* ymax, |
| 99 const gfx::PointF& p) { | 99 const gfx::PointF& p) { |
| 100 *xmin = std::min(p.x(), *xmin); | 100 *xmin = std::min(p.x(), *xmin); |
| 101 *xmax = std::max(p.x(), *xmax); | 101 *xmax = std::max(p.x(), *xmax); |
| 102 *ymin = std::min(p.y(), *ymin); | 102 *ymin = std::min(p.y(), *ymin); |
| 103 *ymax = std::max(p.y(), *ymax); | 103 *ymax = std::max(p.y(), *ymax); |
| 104 } | 104 } |
| 105 | 105 |
| 106 static inline void AddVertexToClippedQuad(const gfx::PointF& new_vertex, | 106 static inline void AddVertexToClippedQuad(const gfx::PointF& new_vertex, |
| 107 gfx::PointF clipped_quad[8], | 107 gfx::PointF clipped_quad[8], |
| 108 int* num_vertices_in_clipped_quad) { | 108 int* num_vertices_in_clipped_quad) { |
| 109 clipped_quad[*num_vertices_in_clipped_quad] = new_vertex; | 109 clipped_quad[*num_vertices_in_clipped_quad] = new_vertex; |
| 110 (*num_vertices_in_clipped_quad)++; | 110 (*num_vertices_in_clipped_quad)++; |
| 111 } | 111 } |
| 112 | 112 |
| 113 static inline void AddVertexToClippedQuad3d(const gfx::Point3F& new_vertex, | |
| 114 gfx::Point3F clipped_quad[8], | |
| 115 int* num_vertices_in_clipped_quad) { | |
| 116 clipped_quad[*num_vertices_in_clipped_quad] = new_vertex; | |
| 117 (*num_vertices_in_clipped_quad)++; | |
| 118 } | |
| 119 | |
| 113 gfx::Rect MathUtil::MapEnclosingClippedRect(const gfx::Transform& transform, | 120 gfx::Rect MathUtil::MapEnclosingClippedRect(const gfx::Transform& transform, |
| 114 const gfx::Rect& src_rect) { | 121 const gfx::Rect& src_rect) { |
| 115 if (transform.IsIdentityOrIntegerTranslation()) { | 122 if (transform.IsIdentityOrIntegerTranslation()) { |
| 116 return src_rect + | 123 return src_rect + |
| 117 gfx::Vector2d( | 124 gfx::Vector2d( |
| 118 static_cast<int>(SkMScalarToFloat(transform.matrix().get(0, 3))), | 125 static_cast<int>(SkMScalarToFloat(transform.matrix().get(0, 3))), |
| 119 static_cast<int>( | 126 static_cast<int>( |
| 120 SkMScalarToFloat(transform.matrix().get(1, 3)))); | 127 SkMScalarToFloat(transform.matrix().get(1, 3)))); |
| 121 } | 128 } |
| 122 return gfx::ToEnclosingRect(MapClippedRect(transform, gfx::RectF(src_rect))); | 129 return gfx::ToEnclosingRect(MapClippedRect(transform, gfx::RectF(src_rect))); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 if (h4.ShouldBeClipped() ^ h1.ShouldBeClipped()) { | 252 if (h4.ShouldBeClipped() ^ h1.ShouldBeClipped()) { |
| 246 AddVertexToClippedQuad( | 253 AddVertexToClippedQuad( |
| 247 ComputeClippedPointForEdge(h4, h1).CartesianPoint2d(), | 254 ComputeClippedPointForEdge(h4, h1).CartesianPoint2d(), |
| 248 clipped_quad, | 255 clipped_quad, |
| 249 num_vertices_in_clipped_quad); | 256 num_vertices_in_clipped_quad); |
| 250 } | 257 } |
| 251 | 258 |
| 252 DCHECK_LE(*num_vertices_in_clipped_quad, 8); | 259 DCHECK_LE(*num_vertices_in_clipped_quad, 8); |
| 253 } | 260 } |
| 254 | 261 |
| 262 bool MathUtil::MapClippedQuad3d(const gfx::Transform& transform, | |
| 263 const gfx::QuadF& src_quad, | |
| 264 gfx::Point3F clipped_quad[8], | |
| 265 int* num_vertices_in_clipped_quad) { | |
| 266 HomogeneousCoordinate h1 = | |
| 267 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p1())); | |
| 268 HomogeneousCoordinate h2 = | |
| 269 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p2())); | |
| 270 HomogeneousCoordinate h3 = | |
| 271 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p3())); | |
| 272 HomogeneousCoordinate h4 = | |
| 273 MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p4())); | |
| 274 | |
| 275 // The order of adding the vertices to the array is chosen so that | |
| 276 // clockwise / counter-clockwise orientation is retained. | |
| 277 | |
| 278 *num_vertices_in_clipped_quad = 0; | |
| 279 | |
| 280 if (!h1.ShouldBeClipped()) { | |
| 281 AddVertexToClippedQuad3d( | |
| 282 h1.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad); | |
| 283 } | |
| 284 | |
| 285 if (h1.ShouldBeClipped() ^ h2.ShouldBeClipped()) { | |
| 286 AddVertexToClippedQuad3d( | |
| 287 ComputeClippedPointForEdge(h1, h2).CartesianPoint3d(), | |
| 288 clipped_quad, | |
| 289 num_vertices_in_clipped_quad); | |
| 290 } | |
| 291 | |
| 292 if (!h2.ShouldBeClipped()) { | |
| 293 AddVertexToClippedQuad3d( | |
| 294 h2.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad); | |
| 295 } | |
| 296 | |
| 297 if (h2.ShouldBeClipped() ^ h3.ShouldBeClipped()) { | |
| 298 AddVertexToClippedQuad3d( | |
| 299 ComputeClippedPointForEdge(h2, h3).CartesianPoint3d(), | |
| 300 clipped_quad, | |
| 301 num_vertices_in_clipped_quad); | |
| 302 } | |
| 303 | |
| 304 if (!h3.ShouldBeClipped()) { | |
| 305 AddVertexToClippedQuad3d( | |
| 306 h3.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad); | |
| 307 } | |
| 308 | |
| 309 if (h3.ShouldBeClipped() ^ h4.ShouldBeClipped()) { | |
| 310 AddVertexToClippedQuad3d( | |
| 311 ComputeClippedPointForEdge(h3, h4).CartesianPoint3d(), | |
| 312 clipped_quad, | |
| 313 num_vertices_in_clipped_quad); | |
| 314 } | |
| 315 | |
| 316 if (!h4.ShouldBeClipped()) { | |
| 317 AddVertexToClippedQuad3d( | |
| 318 h4.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad); | |
| 319 } | |
| 320 | |
| 321 if (h4.ShouldBeClipped() ^ h1.ShouldBeClipped()) { | |
| 322 AddVertexToClippedQuad3d( | |
| 323 ComputeClippedPointForEdge(h4, h1).CartesianPoint3d(), | |
| 324 clipped_quad, | |
| 325 num_vertices_in_clipped_quad); | |
| 326 } | |
| 327 | |
| 328 DCHECK_LE(*num_vertices_in_clipped_quad, 8); | |
| 329 return (*num_vertices_in_clipped_quad >= 4); | |
| 330 } | |
| 331 | |
| 255 gfx::RectF MathUtil::ComputeEnclosingRectOfVertices( | 332 gfx::RectF MathUtil::ComputeEnclosingRectOfVertices( |
| 256 const gfx::PointF vertices[], | 333 const gfx::PointF vertices[], |
| 257 int num_vertices) { | 334 int num_vertices) { |
| 258 if (num_vertices < 2) | 335 if (num_vertices < 2) |
| 259 return gfx::RectF(); | 336 return gfx::RectF(); |
| 260 | 337 |
| 261 float xmin = std::numeric_limits<float>::max(); | 338 float xmin = std::numeric_limits<float>::max(); |
| 262 float xmax = -std::numeric_limits<float>::max(); | 339 float xmax = -std::numeric_limits<float>::max(); |
| 263 float ymin = std::numeric_limits<float>::max(); | 340 float ymin = std::numeric_limits<float>::max(); |
| 264 float ymax = -std::numeric_limits<float>::max(); | 341 float ymax = -std::numeric_limits<float>::max(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 h3.ShouldBeClipped() || h4.ShouldBeClipped(); | 455 h3.ShouldBeClipped() || h4.ShouldBeClipped(); |
| 379 | 456 |
| 380 // Result will be invalid if clipped == true. But, compute it anyway just in | 457 // Result will be invalid if clipped == true. But, compute it anyway just in |
| 381 // case, to emulate existing behavior. | 458 // case, to emulate existing behavior. |
| 382 return gfx::QuadF(h1.CartesianPoint2d(), | 459 return gfx::QuadF(h1.CartesianPoint2d(), |
| 383 h2.CartesianPoint2d(), | 460 h2.CartesianPoint2d(), |
| 384 h3.CartesianPoint2d(), | 461 h3.CartesianPoint2d(), |
| 385 h4.CartesianPoint2d()); | 462 h4.CartesianPoint2d()); |
| 386 } | 463 } |
| 387 | 464 |
| 465 gfx::QuadF MathUtil::MapQuad3d(const gfx::Transform& transform, | |
| 466 const gfx::QuadF& q, | |
| 467 gfx::Point3F* p, | |
| 468 bool* clipped) { | |
| 469 if (transform.IsIdentityOrTranslation()) { | |
| 470 gfx::QuadF mapped_quad(q); | |
| 471 mapped_quad += | |
| 472 gfx::Vector2dF(SkMScalarToFloat(transform.matrix().get(0, 3)), | |
| 473 SkMScalarToFloat(transform.matrix().get(1, 3))); | |
| 474 *clipped = false; | |
| 475 p[0] = gfx::Point3F(mapped_quad.p1().x(), mapped_quad.p1().y(), 0.0f); | |
| 476 p[1] = gfx::Point3F(mapped_quad.p2().x(), mapped_quad.p2().y(), 0.0f); | |
| 477 p[2] = gfx::Point3F(mapped_quad.p3().x(), mapped_quad.p3().y(), 0.0f); | |
| 478 p[3] = gfx::Point3F(mapped_quad.p4().x(), mapped_quad.p4().y(), 0.0f); | |
| 479 return mapped_quad; | |
| 480 } | |
| 481 | |
| 482 HomogeneousCoordinate h1 = | |
| 483 MapHomogeneousPoint(transform, gfx::Point3F(q.p1())); | |
| 484 HomogeneousCoordinate h2 = | |
| 485 MapHomogeneousPoint(transform, gfx::Point3F(q.p2())); | |
| 486 HomogeneousCoordinate h3 = | |
| 487 MapHomogeneousPoint(transform, gfx::Point3F(q.p3())); | |
| 488 HomogeneousCoordinate h4 = | |
| 489 MapHomogeneousPoint(transform, gfx::Point3F(q.p4())); | |
| 490 | |
| 491 *clipped = h1.ShouldBeClipped() || h2.ShouldBeClipped() || | |
| 492 h3.ShouldBeClipped() || h4.ShouldBeClipped(); | |
| 493 | |
| 494 // Result will be invalid if clipped == true. But, compute it anyway just in | |
| 495 // case, to emulate existing behavior. | |
| 496 p[0] = h1.CartesianPoint3d(); | |
| 497 p[1] = h2.CartesianPoint3d(); | |
| 498 p[2] = h3.CartesianPoint3d(); | |
| 499 p[3] = h4.CartesianPoint3d(); | |
| 500 | |
| 501 return gfx::QuadF(h1.CartesianPoint2d(), | |
| 502 h2.CartesianPoint2d(), | |
| 503 h3.CartesianPoint2d(), | |
| 504 h4.CartesianPoint2d()); | |
| 505 } | |
| 506 | |
| 388 gfx::PointF MathUtil::MapPoint(const gfx::Transform& transform, | 507 gfx::PointF MathUtil::MapPoint(const gfx::Transform& transform, |
| 389 const gfx::PointF& p, | 508 const gfx::PointF& p, |
| 390 bool* clipped) { | 509 bool* clipped) { |
| 391 HomogeneousCoordinate h = MapHomogeneousPoint(transform, gfx::Point3F(p)); | 510 HomogeneousCoordinate h = MapHomogeneousPoint(transform, gfx::Point3F(p)); |
| 392 | 511 |
| 393 if (h.w() > 0) { | 512 if (h.w() > 0) { |
| 394 *clipped = false; | 513 *clipped = false; |
| 395 return h.CartesianPoint2d(); | 514 return h.CartesianPoint2d(); |
| 396 } | 515 } |
| 397 | 516 |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 653 return scoped_ptr<base::Value>(new base::FundamentalValue( | 772 return scoped_ptr<base::Value>(new base::FundamentalValue( |
| 654 std::min(value, std::numeric_limits<double>::max()))); | 773 std::min(value, std::numeric_limits<double>::max()))); |
| 655 } | 774 } |
| 656 | 775 |
| 657 scoped_ptr<base::Value> MathUtil::AsValueSafely(float value) { | 776 scoped_ptr<base::Value> MathUtil::AsValueSafely(float value) { |
| 658 return scoped_ptr<base::Value>(new base::FundamentalValue( | 777 return scoped_ptr<base::Value>(new base::FundamentalValue( |
| 659 std::min(value, std::numeric_limits<float>::max()))); | 778 std::min(value, std::numeric_limits<float>::max()))); |
| 660 } | 779 } |
| 661 | 780 |
| 662 } // namespace cc | 781 } // namespace cc |
| OLD | NEW |