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

Side by Side Diff: cc/math_util.cc

Issue 11316043: Implement unit tests and temporary MathUtil wrappers for transform functionality (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: patch for landing Created 8 years, 1 month 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/math_util.h ('k') | cc/math_util_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 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/math_util.h" 5 #include "cc/math_util.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <limits> 8 #include <limits>
9 9
10 #include "ui/gfx/quad_f.h" 10 #include "ui/gfx/quad_f.h"
11 #include "ui/gfx/rect.h" 11 #include "ui/gfx/rect.h"
12 #include "ui/gfx/rect_conversions.h" 12 #include "ui/gfx/rect_conversions.h"
13 #include "ui/gfx/rect_f.h" 13 #include "ui/gfx/rect_f.h"
14 #include "ui/gfx/vector2d_f.h" 14 #include "ui/gfx/vector2d_f.h"
15 #include <public/WebTransformationMatrix.h> 15 #include <public/WebTransformationMatrix.h>
16 16
17 using WebKit::WebTransformationMatrix; 17 using WebKit::WebTransformationMatrix;
18 18
19 namespace cc { 19 namespace cc {
20 20
21 const double MathUtil::PI_DOUBLE = 3.14159265358979323846; 21 const double MathUtil::PI_DOUBLE = 3.14159265358979323846;
22 const float MathUtil::PI_FLOAT = 3.14159265358979323846f; 22 const float MathUtil::PI_FLOAT = 3.14159265358979323846f;
23 const double MathUtil::EPSILON = 1e-9;
23 24
24 static HomogeneousCoordinate projectHomogeneousPoint(const WebTransformationMatr ix& transform, const gfx::PointF& p) 25 static HomogeneousCoordinate projectHomogeneousPoint(const WebTransformationMatr ix& transform, const gfx::PointF& p)
25 { 26 {
26 // In this case, the layer we are trying to project onto is perpendicular to ray 27 // In this case, the layer we are trying to project onto is perpendicular to ray
27 // (point p and z-axis direction) that we are trying to project. This happen s when the 28 // (point p and z-axis direction) that we are trying to project. This happen s when the
28 // layer is rotated so that it is infinitesimally thin, or when it is co-pla nar with 29 // layer is rotated so that it is infinitesimally thin, or when it is co-pla nar with
29 // the camera origin -- i.e. when the layer is invisible anyway. 30 // the camera origin -- i.e. when the layer is invisible anyway.
30 if (!transform.m33()) 31 if (!transform.m33())
31 return HomogeneousCoordinate(0, 0, 0, 1); 32 return HomogeneousCoordinate(0, 0, 0, 1);
32 33
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 dotProduct = std::max(-1.0, std::min(1.0, dotProduct)); 389 dotProduct = std::max(-1.0, std::min(1.0, dotProduct));
389 return static_cast<float>(Rad2Deg(std::acos(dotProduct))); 390 return static_cast<float>(Rad2Deg(std::acos(dotProduct)));
390 } 391 }
391 392
392 gfx::Vector2dF MathUtil::projectVector(gfx::Vector2dF source, gfx::Vector2dF des tination) 393 gfx::Vector2dF MathUtil::projectVector(gfx::Vector2dF source, gfx::Vector2dF des tination)
393 { 394 {
394 float projectedLength = gfx::DotProduct(source, destination) / destination.L engthSquared(); 395 float projectedLength = gfx::DotProduct(source, destination) / destination.L engthSquared();
395 return gfx::Vector2dF(projectedLength * destination.x(), projectedLength * d estination.y()); 396 return gfx::Vector2dF(projectedLength * destination.x(), projectedLength * d estination.y());
396 } 397 }
397 398
399 bool MathUtil::isInvertible(const gfx::Transform& transform)
400 {
401 const SkMatrix44& matrix = transform.matrix();
402 double determinant = matrix.determinant();
403 return abs(determinant) > EPSILON;
404 }
405
406 bool MathUtil::isBackFaceVisible(const gfx::Transform&)
407 {
408 // TODO (shawnsingh): to be implemented in a follow up patch very soon.
409 NOTREACHED();
410 return false;
411 }
412
413 bool MathUtil::isIdentity(const gfx::Transform& transform)
414 {
415 return transform.matrix().isIdentity();
416 }
417
418 bool MathUtil::isIdentityOrTranslation(const gfx::Transform& transform)
419 {
420 const SkMatrix44& matrix = transform.matrix();
421
422 bool hasNoPerspective = !matrix.getDouble(3, 0) && !matrix.getDouble(3, 1) & & !matrix.getDouble(3, 2) && (matrix.getDouble(3, 3) == 1);
423 bool hasNoRotationOrSkew = !matrix.getDouble(0, 1) && !matrix.getDouble(0, 2 ) && !matrix.getDouble(1, 0) &&
424 !matrix.getDouble(1, 2) && !matrix.getDouble(2, 0) && !matrix.getDouble( 2, 1);
425 bool hasNoScale = matrix.getDouble(0, 0) == 1 && matrix.getDouble(1, 1) == 1 && matrix.getDouble(2, 2) == 1;
426
427 return hasNoPerspective && hasNoRotationOrSkew && hasNoScale;
428 }
429
430 bool MathUtil::hasPerspective(const gfx::Transform& transform)
431 {
432 // Mathematically it is a bit too strict to expect the 4th element to be
433 // equal to 1. However, the only non-perspective case where this element
434 // becomes non-1 is when it was explicitly initialized. In that case it
435 // still causes us to have a nontrivial divide-by-w, so we count it as
436 // being perspective here.
437 const SkMatrix44& matrix = transform.matrix();
438 return matrix.getDouble(3, 0) || matrix.getDouble(3, 1) || matrix.getDouble( 3, 2) || (matrix.getDouble(3, 3) != 1);
439 }
440
441 void MathUtil::makeIdentity(gfx::Transform* transform)
442 {
443 transform->matrix().setIdentity();
444 }
445
446 void MathUtil::rotateEulerAngles(gfx::Transform* transform, double eulerX, doubl e eulerY, double eulerZ)
447 {
448 // TODO (shawnsingh): make this implementation faster and more accurate by
449 // hard-coding each matrix instead of calling rotateAxisAngle().
450 gfx::Transform rotationAboutX;
451 gfx::Transform rotationAboutY;
452 gfx::Transform rotationAboutZ;
453
454 MathUtil::rotateAxisAngle(&rotationAboutX, 1, 0, 0, eulerX);
455 MathUtil::rotateAxisAngle(&rotationAboutY, 0, 1, 0, eulerY);
456 MathUtil::rotateAxisAngle(&rotationAboutZ, 0, 0, 1, eulerZ);
457
458 gfx::Transform composite = rotationAboutZ * rotationAboutY * rotationAboutX;
459 transform->PreconcatTransform(composite);
460 }
461
462 void MathUtil::rotateAxisAngle(gfx::Transform* transform, double i, double j, do uble k, double degrees)
463 {
464 // TODO (shawnsingh): fix gfx::Transform API to receive vector instead of
465 // point for the axis.
466 gfx::Point3F axis(i, j, k);
467 transform->PreconcatRotateAbout(axis, degrees);
468 }
469
470 gfx::Transform MathUtil::inverse(const gfx::Transform& transform)
471 {
472 gfx::Transform result;
473 bool invertedSuccessfully = transform.GetInverse(&result);
474
475 if (invertedSuccessfully)
476 return result;
477
478 // If transform was un-invertible, then just return identity.
479 return gfx::Transform();
480 }
481
482 gfx::Transform MathUtil::to2dTransform(const gfx::Transform& transform)
483 {
484 gfx::Transform result = transform;
485 SkMatrix44& matrix = result.matrix();
486 matrix.setDouble(0, 2, 0);
487 matrix.setDouble(1, 2, 0);
488 matrix.setDouble(2, 2, 1);
489 matrix.setDouble(3, 2, 0);
490
491 matrix.setDouble(2, 0, 0);
492 matrix.setDouble(2, 1, 0);
493 matrix.setDouble(2, 3, 0);
494
495 return result;
496 }
497
498 gfx::Transform MathUtil::createGfxTransform(double m11, double m12, double m13, double m14,
499 double m21, double m22, double m23, double m24,
500 double m31, double m32, double m33, double m34,
501 double m41, double m42, double m43, double m44)
502 {
503 gfx::Transform result;
504 SkMatrix44& matrix = result.matrix();
505
506 // Initialize column 1
507 matrix.setDouble(0, 0, m11);
508 matrix.setDouble(1, 0, m12);
509 matrix.setDouble(2, 0, m13);
510 matrix.setDouble(3, 0, m14);
511
512 // Initialize column 2
513 matrix.setDouble(0, 1, m21);
514 matrix.setDouble(1, 1, m22);
515 matrix.setDouble(2, 1, m23);
516 matrix.setDouble(3, 1, m24);
517
518 // Initialize column 3
519 matrix.setDouble(0, 2, m31);
520 matrix.setDouble(1, 2, m32);
521 matrix.setDouble(2, 2, m33);
522 matrix.setDouble(3, 2, m34);
523
524 // Initialize column 4
525 matrix.setDouble(0, 3, m41);
526 matrix.setDouble(1, 3, m42);
527 matrix.setDouble(2, 3, m43);
528 matrix.setDouble(3, 3, m44);
529
530 return result;
531 }
532
533 gfx::Transform MathUtil::createGfxTransform(double a, double b, double c,
534 double d, double e, double f)
535 {
536 gfx::Transform result;
537 SkMatrix44& matrix = result.matrix();
538 matrix.setDouble(0, 0, a);
539 matrix.setDouble(1, 0, b);
540 matrix.setDouble(0, 1, c);
541 matrix.setDouble(1, 1, d);
542 matrix.setDouble(0, 3, e);
543 matrix.setDouble(1, 3, f);
544
545 return result;
546 }
547
548 gfx::Transform operator*(const gfx::Transform& A, const gfx::Transform& B)
549 {
550 // Compute A * B.
551 gfx::Transform result = A;
552 result.PreconcatTransform(B);
553 return result;
554 }
555
398 } // namespace cc 556 } // namespace cc
OLDNEW
« no previous file with comments | « cc/math_util.h ('k') | cc/math_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698