Chromium Code Reviews| Index: cc/math_util.cc |
| diff --git a/cc/math_util.cc b/cc/math_util.cc |
| index 2f885f865c2b0be25dd81655164e4a40fa295000..1e8e098a06a1ac961392adde13705286bdc63533 100644 |
| --- a/cc/math_util.cc |
| +++ b/cc/math_util.cc |
| @@ -11,10 +11,10 @@ |
| #include "ui/gfx/rect.h" |
| #include "ui/gfx/rect_conversions.h" |
| #include "ui/gfx/rect_f.h" |
| +#include "ui/gfx/transform.h" |
| #include "ui/gfx/vector2d_f.h" |
| -#include <public/WebTransformationMatrix.h> |
| -using WebKit::WebTransformationMatrix; |
| +using gfx::Transform; |
| namespace cc { |
| @@ -22,39 +22,39 @@ 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) |
| +static HomogeneousCoordinate projectHomogeneousPoint(const Transform& transform, const gfx::PointF& p) |
| { |
| // In this case, the layer we are trying to project onto is perpendicular to ray |
| // (point p and z-axis direction) that we are trying to project. This happens when the |
| // layer is rotated so that it is infinitesimally thin, or when it is co-planar with |
| // the camera origin -- i.e. when the layer is invisible anyway. |
| - if (!transform.m33()) |
| + if (!transform.matrix().getDouble(2, 2)) |
| return HomogeneousCoordinate(0, 0, 0, 1); |
| double x = p.x(); |
| double y = p.y(); |
| - double z = -(transform.m13() * x + transform.m23() * y + transform.m43()) / transform.m33(); |
| + double z = -(transform.matrix().getDouble(2, 0) * x + transform.matrix().getDouble(2, 1) * y + transform.matrix().getDouble(2, 3)) / transform.matrix().getDouble(2, 2); |
| // implicit definition of w = 1; |
| - double outX = x * transform.m11() + y * transform.m21() + z * transform.m31() + transform.m41(); |
| - double outY = x * transform.m12() + y * transform.m22() + z * transform.m32() + transform.m42(); |
| - double outZ = x * transform.m13() + y * transform.m23() + z * transform.m33() + transform.m43(); |
| - double outW = x * transform.m14() + y * transform.m24() + z * transform.m34() + transform.m44(); |
| + double outX = x * transform.matrix().getDouble(0, 0) + y * transform.matrix().getDouble(0, 1) + z * transform.matrix().getDouble(0, 2) + transform.matrix().getDouble(0, 3); |
| + double outY = x * transform.matrix().getDouble(1, 0) + y * transform.matrix().getDouble(1, 1) + z * transform.matrix().getDouble(1, 2) + transform.matrix().getDouble(1, 3); |
| + double outZ = x * transform.matrix().getDouble(2, 0) + y * transform.matrix().getDouble(2, 1) + z * transform.matrix().getDouble(2, 2) + transform.matrix().getDouble(2, 3); |
| + double outW = x * transform.matrix().getDouble(3, 0) + y * transform.matrix().getDouble(3, 1) + z * transform.matrix().getDouble(3, 2) + transform.matrix().getDouble(3, 3); |
| return HomogeneousCoordinate(outX, outY, outZ, outW); |
| } |
| -static HomogeneousCoordinate mapHomogeneousPoint(const WebTransformationMatrix& transform, const gfx::Point3F& p) |
| +static HomogeneousCoordinate mapHomogeneousPoint(const Transform& transform, const gfx::Point3F& p) |
| { |
| double x = p.x(); |
| double y = p.y(); |
| double z = p.z(); |
| // implicit definition of w = 1; |
| - double outX = x * transform.m11() + y * transform.m21() + z * transform.m31() + transform.m41(); |
| - double outY = x * transform.m12() + y * transform.m22() + z * transform.m32() + transform.m42(); |
| - double outZ = x * transform.m13() + y * transform.m23() + z * transform.m33() + transform.m43(); |
| - double outW = x * transform.m14() + y * transform.m24() + z * transform.m34() + transform.m44(); |
| + double outX = x * transform.matrix().getDouble(0, 0) + y * transform.matrix().getDouble(0, 1) + z * transform.matrix().getDouble(0, 2) + transform.matrix().getDouble(0, 3); |
| + double outY = x * transform.matrix().getDouble(1, 0) + y * transform.matrix().getDouble(1, 1) + z * transform.matrix().getDouble(1, 2) + transform.matrix().getDouble(1, 3); |
| + double outZ = x * transform.matrix().getDouble(2, 0) + y * transform.matrix().getDouble(2, 1) + z * transform.matrix().getDouble(2, 2) + transform.matrix().getDouble(2, 3); |
| + double outW = x * transform.matrix().getDouble(3, 0) + y * transform.matrix().getDouble(3, 1) + z * transform.matrix().getDouble(3, 2) + transform.matrix().getDouble(3, 3); |
| return HomogeneousCoordinate(outX, outY, outZ, outW); |
| } |
| @@ -102,15 +102,15 @@ static inline void addVertexToClippedQuad(const gfx::PointF& newVertex, gfx::Poi |
| numVerticesInClippedQuad++; |
| } |
| -gfx::Rect MathUtil::mapClippedRect(const WebTransformationMatrix& transform, const gfx::Rect& srcRect) |
| +gfx::Rect MathUtil::mapClippedRect(const Transform& transform, const gfx::Rect& srcRect) |
| { |
| return gfx::ToEnclosingRect(mapClippedRect(transform, gfx::RectF(srcRect))); |
| } |
| -gfx::RectF MathUtil::mapClippedRect(const WebTransformationMatrix& transform, const gfx::RectF& srcRect) |
| +gfx::RectF MathUtil::mapClippedRect(const Transform& transform, const gfx::RectF& srcRect) |
| { |
| - if (transform.isIdentityOrTranslation()) |
| - return srcRect + gfx::Vector2dF(static_cast<float>(transform.m41()), static_cast<float>(transform.m42())); |
| + if (MathUtil::isIdentityOrTranslation(transform)) |
| + return srcRect + gfx::Vector2dF(static_cast<float>(transform.matrix().getDouble(0, 3)), static_cast<float>(transform.matrix().getDouble(1, 3))); |
| // Apply the transform, but retain the result in homogeneous coordinates. |
| gfx::QuadF q = gfx::QuadF(srcRect); |
| @@ -122,10 +122,10 @@ gfx::RectF MathUtil::mapClippedRect(const WebTransformationMatrix& transform, co |
| return computeEnclosingClippedRect(h1, h2, h3, h4); |
| } |
| -gfx::RectF MathUtil::projectClippedRect(const WebTransformationMatrix& transform, const gfx::RectF& srcRect) |
| +gfx::RectF MathUtil::projectClippedRect(const Transform& transform, const gfx::RectF& srcRect) |
| { |
| - if (transform.isIdentityOrTranslation()) |
| - return srcRect + gfx::Vector2dF(static_cast<float>(transform.m41()), static_cast<float>(transform.m42())); |
| + if (MathUtil::isIdentityOrTranslation(transform)) |
| + return srcRect + gfx::Vector2dF(static_cast<float>(transform.matrix().getDouble(0, 3)), static_cast<float>(transform.matrix().getDouble(1, 3))); |
| // Perform the projection, but retain the result in homogeneous coordinates. |
| gfx::QuadF q = gfx::QuadF(srcRect); |
| @@ -137,7 +137,7 @@ gfx::RectF MathUtil::projectClippedRect(const WebTransformationMatrix& transform |
| return computeEnclosingClippedRect(h1, h2, h3, h4); |
| } |
| -void MathUtil::mapClippedQuad(const WebTransformationMatrix& transform, const gfx::QuadF& srcQuad, gfx::PointF clippedQuad[8], int& numVerticesInClippedQuad) |
| +void MathUtil::mapClippedQuad(const Transform& transform, const gfx::QuadF& srcQuad, gfx::PointF clippedQuad[8], int& numVerticesInClippedQuad) |
| { |
| HomogeneousCoordinate h1 = mapHomogeneousPoint(transform, gfx::Point3F(srcQuad.p1())); |
| HomogeneousCoordinate h2 = mapHomogeneousPoint(transform, gfx::Point3F(srcQuad.p2())); |
| @@ -241,11 +241,11 @@ gfx::RectF MathUtil::computeEnclosingClippedRect(const HomogeneousCoordinate& h1 |
| return gfx::RectF(gfx::PointF(xmin, ymin), gfx::SizeF(xmax - xmin, ymax - ymin)); |
| } |
| -gfx::QuadF MathUtil::mapQuad(const WebTransformationMatrix& transform, const gfx::QuadF& q, bool& clipped) |
| +gfx::QuadF MathUtil::mapQuad(const Transform& transform, const gfx::QuadF& q, bool& clipped) |
| { |
| - if (transform.isIdentityOrTranslation()) { |
| + if (MathUtil::isIdentityOrTranslation(transform)) { |
| gfx::QuadF mappedQuad(q); |
| - mappedQuad += gfx::Vector2dF(static_cast<float>(transform.m41()), static_cast<float>(transform.m42())); |
| + mappedQuad += gfx::Vector2dF(static_cast<float>(transform.matrix().getDouble(0, 3)), static_cast<float>(transform.matrix().getDouble(1, 3))); |
| clipped = false; |
| return mappedQuad; |
| } |
| @@ -261,7 +261,7 @@ gfx::QuadF MathUtil::mapQuad(const WebTransformationMatrix& transform, const gfx |
| return gfx::QuadF(h1.cartesianPoint2d(), h2.cartesianPoint2d(), h3.cartesianPoint2d(), h4.cartesianPoint2d()); |
| } |
| -gfx::PointF MathUtil::mapPoint(const WebTransformationMatrix& transform, const gfx::PointF& p, bool& clipped) |
| +gfx::PointF MathUtil::mapPoint(const Transform& transform, const gfx::PointF& p, bool& clipped) |
| { |
| HomogeneousCoordinate h = mapHomogeneousPoint(transform, gfx::Point3F(p)); |
| @@ -284,7 +284,7 @@ gfx::PointF MathUtil::mapPoint(const WebTransformationMatrix& transform, const g |
| return h.cartesianPoint2d(); |
| } |
| -gfx::Point3F MathUtil::mapPoint(const WebTransformationMatrix& transform, const gfx::Point3F& p, bool& clipped) |
| +gfx::Point3F MathUtil::mapPoint(const Transform& transform, const gfx::Point3F& p, bool& clipped) |
| { |
| HomogeneousCoordinate h = mapHomogeneousPoint(transform, p); |
| @@ -307,7 +307,7 @@ gfx::Point3F MathUtil::mapPoint(const WebTransformationMatrix& transform, const |
| return h.cartesianPoint3d(); |
| } |
| -gfx::QuadF MathUtil::projectQuad(const WebTransformationMatrix& transform, const gfx::QuadF& q, bool& clipped) |
| +gfx::QuadF MathUtil::projectQuad(const Transform& transform, const gfx::QuadF& q, bool& clipped) |
| { |
| gfx::QuadF projectedQuad; |
| bool clippedPoint; |
| @@ -323,7 +323,7 @@ gfx::QuadF MathUtil::projectQuad(const WebTransformationMatrix& transform, const |
| return projectedQuad; |
| } |
| -gfx::PointF MathUtil::projectPoint(const WebTransformationMatrix& transform, const gfx::PointF& p, bool& clipped) |
| +gfx::PointF MathUtil::projectPoint(const Transform& transform, const gfx::PointF& p, bool& clipped) |
| { |
| HomogeneousCoordinate h = projectHomogeneousPoint(transform, p); |
| @@ -347,7 +347,7 @@ gfx::PointF MathUtil::projectPoint(const WebTransformationMatrix& transform, con |
| return h.cartesianPoint2d(); |
| } |
| -void MathUtil::flattenTransformTo2d(WebTransformationMatrix& transform) |
| +void MathUtil::flattenTransformTo2d(Transform& transform) |
| { |
| // Set both the 3rd row and 3rd column to (0, 0, 1, 0). |
| // |
| @@ -359,13 +359,13 @@ void MathUtil::flattenTransformTo2d(WebTransformationMatrix& transform) |
| // - Because of linearity of transforms, this flattened transform also preserves the |
| // effect that any subsequent (post-multiplied) transforms would have on z values. |
| // |
| - transform.setM13(0); |
| - transform.setM23(0); |
| - transform.setM31(0); |
| - transform.setM32(0); |
| - transform.setM33(1); |
| - transform.setM34(0); |
| - transform.setM43(0); |
| + transform.matrix().setDouble(2, 0, 0); |
| + transform.matrix().setDouble(2, 1, 0); |
| + transform.matrix().setDouble(0, 2, 0); |
| + transform.matrix().setDouble(1, 2, 0); |
| + transform.matrix().setDouble(2, 2, 1); |
| + transform.matrix().setDouble(3, 2, 0); |
| + transform.matrix().setDouble(2, 3, 0); |
| } |
| static inline float scaleOnAxis(double a, double b, double c) |
| @@ -373,12 +373,12 @@ static inline float scaleOnAxis(double a, double b, double c) |
| return std::sqrt(a * a + b * b + c * c); |
| } |
| -gfx::Vector2dF MathUtil::computeTransform2dScaleComponents(const WebTransformationMatrix& transform) |
| +gfx::Vector2dF MathUtil::computeTransform2dScaleComponents(const Transform& transform) |
| { |
| - if (transform.hasPerspective()) |
| + if (hasPerspective(transform)) |
| return gfx::Vector2dF(1, 1); |
| - float xScale = scaleOnAxis(transform.m11(), transform.m12(), transform.m13()); |
| - float yScale = scaleOnAxis(transform.m21(), transform.m22(), transform.m23()); |
| + float xScale = scaleOnAxis(transform.matrix().getDouble(0, 0), transform.matrix().getDouble(1, 0), transform.matrix().getDouble(2, 0)); |
| + float yScale = scaleOnAxis(transform.matrix().getDouble(0, 1), transform.matrix().getDouble(1, 1), transform.matrix().getDouble(2, 1)); |
| return gfx::Vector2dF(xScale, yScale); |
| } |
| @@ -396,23 +396,22 @@ 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) |
| +bool MathUtil::isBackFaceVisible(const gfx::Transform& transform) |
| { |
| - const SkMatrix44& matrix = transform.matrix(); |
| - double determinant = matrix.determinant(); |
| - return abs(determinant) > EPSILON; |
| -} |
| + // Compute whether a layer with a forward-facing normal of (0, 0, 1) would |
| + // have its back face visible after applying the transform. |
| + // |
| + // This is done by transforming the normal and seeing if the resulting z |
| + // value is positive or negative. However, note that transforming a normal |
| + // actually requires using the inverse-transpose of the original transform. |
| -bool MathUtil::isBackFaceVisible(const gfx::Transform&) |
| -{ |
| - // TODO (shawnsingh): to be implemented in a follow up patch very soon. |
| - NOTREACHED(); |
| - return false; |
| -} |
| + // TODO (shawnsingh) make this perform more efficiently - we do not |
| + // actually need to instantiate/invert/transpose any matrices, exploiting the |
| + // fact that we only need to transform (0, 0, 1, 0). |
| + gfx::Transform inverseTransform = MathUtil::inverse(transform); |
| + const SkMatrix44& mInv = inverseTransform.matrix(); |
| -bool MathUtil::isIdentity(const gfx::Transform& transform) |
| -{ |
| - return transform.matrix().isIdentity(); |
| + return mInv.getDouble(2, 2) < 0; |
|
danakj
2012/11/24 02:34:54
This is a lot simpler than WebCore::Transformation
shawnsingh
2012/11/24 02:56:14
The difference is in the TODO. We should be able
danakj
2012/11/24 03:20:09
I see, okay.
|
| } |
| bool MathUtil::isIdentityOrTranslation(const gfx::Transform& transform) |
| @@ -438,11 +437,6 @@ bool MathUtil::hasPerspective(const gfx::Transform& transform) |
| 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 |