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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 |