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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/math_util.h ('k') | cc/math_util_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/math_util.cc
diff --git a/cc/math_util.cc b/cc/math_util.cc
index 606f67bf482b34e7ffbb9cdf35ffb2d039ccb401..2f885f865c2b0be25dd81655164e4a40fa295000 100644
--- a/cc/math_util.cc
+++ b/cc/math_util.cc
@@ -20,6 +20,7 @@ namespace cc {
const double MathUtil::PI_DOUBLE = 3.14159265358979323846;
const float MathUtil::PI_FLOAT = 3.14159265358979323846f;
+const double MathUtil::EPSILON = 1e-9;
static HomogeneousCoordinate projectHomogeneousPoint(const WebTransformationMatrix& transform, const gfx::PointF& p)
{
@@ -395,4 +396,161 @@ gfx::Vector2dF MathUtil::projectVector(gfx::Vector2dF source, gfx::Vector2dF des
return gfx::Vector2dF(projectedLength * destination.x(), projectedLength * destination.y());
}
+bool MathUtil::isInvertible(const gfx::Transform& transform)
+{
+ const SkMatrix44& matrix = transform.matrix();
+ double determinant = matrix.determinant();
+ return abs(determinant) > EPSILON;
+}
+
+bool MathUtil::isBackFaceVisible(const gfx::Transform&)
+{
+ // TODO (shawnsingh): to be implemented in a follow up patch very soon.
+ NOTREACHED();
+ return false;
+}
+
+bool MathUtil::isIdentity(const gfx::Transform& transform)
+{
+ return transform.matrix().isIdentity();
+}
+
+bool MathUtil::isIdentityOrTranslation(const gfx::Transform& transform)
+{
+ const SkMatrix44& matrix = transform.matrix();
+
+ bool hasNoPerspective = !matrix.getDouble(3, 0) && !matrix.getDouble(3, 1) && !matrix.getDouble(3, 2) && (matrix.getDouble(3, 3) == 1);
+ bool hasNoRotationOrSkew = !matrix.getDouble(0, 1) && !matrix.getDouble(0, 2) && !matrix.getDouble(1, 0) &&
+ !matrix.getDouble(1, 2) && !matrix.getDouble(2, 0) && !matrix.getDouble(2, 1);
+ bool hasNoScale = matrix.getDouble(0, 0) == 1 && matrix.getDouble(1, 1) == 1 && matrix.getDouble(2, 2) == 1;
+
+ return hasNoPerspective && hasNoRotationOrSkew && hasNoScale;
+}
+
+bool MathUtil::hasPerspective(const gfx::Transform& transform)
+{
+ // Mathematically it is a bit too strict to expect the 4th element to be
+ // equal to 1. However, the only non-perspective case where this element
+ // becomes non-1 is when it was explicitly initialized. In that case it
+ // still causes us to have a nontrivial divide-by-w, so we count it as
+ // being perspective here.
+ const SkMatrix44& matrix = transform.matrix();
+ return matrix.getDouble(3, 0) || matrix.getDouble(3, 1) || matrix.getDouble(3, 2) || (matrix.getDouble(3, 3) != 1);
+}
+
+void MathUtil::makeIdentity(gfx::Transform* transform)
+{
+ transform->matrix().setIdentity();
+}
+
+void MathUtil::rotateEulerAngles(gfx::Transform* transform, double eulerX, double eulerY, double eulerZ)
+{
+ // TODO (shawnsingh): make this implementation faster and more accurate by
+ // hard-coding each matrix instead of calling rotateAxisAngle().
+ gfx::Transform rotationAboutX;
+ gfx::Transform rotationAboutY;
+ gfx::Transform rotationAboutZ;
+
+ MathUtil::rotateAxisAngle(&rotationAboutX, 1, 0, 0, eulerX);
+ MathUtil::rotateAxisAngle(&rotationAboutY, 0, 1, 0, eulerY);
+ MathUtil::rotateAxisAngle(&rotationAboutZ, 0, 0, 1, eulerZ);
+
+ gfx::Transform composite = rotationAboutZ * rotationAboutY * rotationAboutX;
+ transform->PreconcatTransform(composite);
+}
+
+void MathUtil::rotateAxisAngle(gfx::Transform* transform, double i, double j, double k, double degrees)
+{
+ // TODO (shawnsingh): fix gfx::Transform API to receive vector instead of
+ // point for the axis.
+ gfx::Point3F axis(i, j, k);
+ transform->PreconcatRotateAbout(axis, degrees);
+}
+
+gfx::Transform MathUtil::inverse(const gfx::Transform& transform)
+{
+ gfx::Transform result;
+ bool invertedSuccessfully = transform.GetInverse(&result);
+
+ if (invertedSuccessfully)
+ return result;
+
+ // If transform was un-invertible, then just return identity.
+ return gfx::Transform();
+}
+
+gfx::Transform MathUtil::to2dTransform(const gfx::Transform& transform)
+{
+ gfx::Transform result = transform;
+ SkMatrix44& matrix = result.matrix();
+ matrix.setDouble(0, 2, 0);
+ matrix.setDouble(1, 2, 0);
+ matrix.setDouble(2, 2, 1);
+ matrix.setDouble(3, 2, 0);
+
+ matrix.setDouble(2, 0, 0);
+ matrix.setDouble(2, 1, 0);
+ matrix.setDouble(2, 3, 0);
+
+ return result;
+}
+
+gfx::Transform MathUtil::createGfxTransform(double m11, double m12, double m13, double m14,
+ double m21, double m22, double m23, double m24,
+ double m31, double m32, double m33, double m34,
+ double m41, double m42, double m43, double m44)
+{
+ gfx::Transform result;
+ SkMatrix44& matrix = result.matrix();
+
+ // Initialize column 1
+ matrix.setDouble(0, 0, m11);
+ matrix.setDouble(1, 0, m12);
+ matrix.setDouble(2, 0, m13);
+ matrix.setDouble(3, 0, m14);
+
+ // Initialize column 2
+ matrix.setDouble(0, 1, m21);
+ matrix.setDouble(1, 1, m22);
+ matrix.setDouble(2, 1, m23);
+ matrix.setDouble(3, 1, m24);
+
+ // Initialize column 3
+ matrix.setDouble(0, 2, m31);
+ matrix.setDouble(1, 2, m32);
+ matrix.setDouble(2, 2, m33);
+ matrix.setDouble(3, 2, m34);
+
+ // Initialize column 4
+ matrix.setDouble(0, 3, m41);
+ matrix.setDouble(1, 3, m42);
+ matrix.setDouble(2, 3, m43);
+ matrix.setDouble(3, 3, m44);
+
+ return result;
+}
+
+gfx::Transform MathUtil::createGfxTransform(double a, double b, double c,
+ double d, double e, double f)
+{
+ gfx::Transform result;
+ SkMatrix44& matrix = result.matrix();
+ matrix.setDouble(0, 0, a);
+ matrix.setDouble(1, 0, b);
+ matrix.setDouble(0, 1, c);
+ matrix.setDouble(1, 1, d);
+ matrix.setDouble(0, 3, e);
+ matrix.setDouble(1, 3, f);
+
+ return result;
+}
+
+gfx::Transform operator*(const gfx::Transform& A, const gfx::Transform& B)
+{
+ // Compute A * B.
+ gfx::Transform result = A;
+ result.PreconcatTransform(B);
+ return result;
+}
+
} // namespace cc
« 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