Chromium Code Reviews| Index: cc/math_util.cc |
| diff --git a/cc/math_util.cc b/cc/math_util.cc |
| index 606f67bf482b34e7ffbb9cdf35ffb2d039ccb401..27066004e8b72be582e2f4f7ae8a8ed0038f3a1a 100644 |
| --- a/cc/math_util.cc |
| +++ b/cc/math_util.cc |
| @@ -395,4 +395,170 @@ 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(); |
| + |
| + // TODO (shawnsingh): we may need to check fuzzy against an epsilon here instead? |
|
danakj
2012/11/17 02:14:17
Is something random going to break and cause a rev
|
| + return determinant != 0; |
| +} |
| + |
| +bool MathUtil::isBackFaceVisible(const gfx::Transform&) |
| +{ |
| + DCHECK(false); // NOT YET IMPLEMENTED!! |
|
danakj
2012/11/17 02:14:17
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 |
|
danakj
2012/11/17 02:14:17
nit: the line wrapping is inconsistent here.
|
| + && 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::toGfxTransform(const WebKit::WebTransformationMatrix&) |
| +{ |
| + DCHECK(false); // NOT YET IMPLEMENTED!! |
|
danakj
2012/11/17 02:14:17
NOTREACHED() but..
We're going to need this to ev
shawnsingh
2012/11/17 05:42:41
OK I guess you've landed by now, but why is it imp
danakj
2012/11/17 08:27:21
It's in and waiting for roll.
Also, it's explicit
|
| + return gfx::Transform(); |
| +} |
| + |
| +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 |