| Index: cc/animation/transform_operation.cc
|
| diff --git a/cc/animation/transform_operation.cc b/cc/animation/transform_operation.cc
|
| index 889f7bd4104e8d3ee33dba2b620bea4f2c796a21..e4d0dadf0eb5189bd9ebe4e302f26526af24df74 100644
|
| --- a/cc/animation/transform_operation.cc
|
| +++ b/cc/animation/transform_operation.cc
|
| @@ -13,7 +13,9 @@
|
|
|
| #include "base/logging.h"
|
| #include "cc/animation/transform_operation.h"
|
| +#include "cc/animation/transform_operations.h"
|
| #include "ui/gfx/box_f.h"
|
| +#include "ui/gfx/transform_util.h"
|
| #include "ui/gfx/vector3d_f.h"
|
|
|
| namespace {
|
| @@ -198,30 +200,6 @@ bool TransformOperation::BlendTransformOperations(
|
| return true;
|
| }
|
|
|
| -static void ApplyScaleToBox(float x_scale,
|
| - float y_scale,
|
| - float z_scale,
|
| - gfx::BoxF* box) {
|
| - if (x_scale < 0)
|
| - box->set_x(-box->right());
|
| - if (y_scale < 0)
|
| - box->set_y(-box->bottom());
|
| - if (z_scale < 0)
|
| - box->set_z(-box->front());
|
| - box->Scale(std::abs(x_scale), std::abs(y_scale), std::abs(z_scale));
|
| -}
|
| -
|
| -static void UnionBoxWithZeroScale(gfx::BoxF* box) {
|
| - float min_x = std::min(box->x(), 0.f);
|
| - float min_y = std::min(box->y(), 0.f);
|
| - float min_z = std::min(box->z(), 0.f);
|
| - float max_x = std::max(box->right(), 0.f);
|
| - float max_y = std::max(box->bottom(), 0.f);
|
| - float max_z = std::max(box->front(), 0.f);
|
| - *box = gfx::BoxF(
|
| - min_x, min_y, min_z, max_x - min_x, max_y - min_y, max_z - min_z);
|
| -}
|
| -
|
| // If p = (px, py) is a point in the plane being rotated about (0, 0, nz), this
|
| // function computes the angles we would have to rotate from p to get to
|
| // (length(p), 0), (-length(p), 0), (0, length(p)), (0, -length(p)). If nz is
|
| @@ -250,20 +228,6 @@ static float DegreesToRadians(float degrees) {
|
| return (M_PI * degrees) / 180.f;
|
| }
|
|
|
| -// Div by zero doesn't always result in Inf as you might hope, so we'll do this
|
| -// explicitly here.
|
| -static float SafeDivide(float numerator, float denominator) {
|
| - if (numerator == 0.f)
|
| - return 0.f;
|
| -
|
| - if (denominator == 0.f) {
|
| - return numerator > 0.f ? std::numeric_limits<float>::infinity()
|
| - : -std::numeric_limits<float>::infinity();
|
| - }
|
| -
|
| - return numerator / denominator;
|
| -}
|
| -
|
| static void BoundingBoxForArc(const gfx::Point3F& point,
|
| const TransformOperation* from,
|
| const TransformOperation* to,
|
| @@ -291,6 +255,16 @@ static void BoundingBoxForArc(const gfx::Point3F& point,
|
| SkMScalar from_angle = from ? from->rotate.angle : 0.f;
|
| SkMScalar to_angle = to ? to->rotate.angle : 0.f;
|
|
|
| + // If the axes of rotation are pointing in opposite directions, we need to
|
| + // flip one of the angles. Note, if both |from| and |to| exist, then axis will
|
| + // correspond to |from|.
|
| + if (from && to) {
|
| + gfx::Vector3dF other_axis(
|
| + to->rotate.axis.x, to->rotate.axis.y, to->rotate.axis.z);
|
| + if (gfx::DotProduct(axis, other_axis) < 0.f)
|
| + to_angle *= -1.f;
|
| + }
|
| +
|
| float min_degrees =
|
| SkMScalarToFloat(BlendSkMScalars(from_angle, to_angle, min_progress));
|
| float max_degrees =
|
| @@ -360,16 +334,11 @@ static void BoundingBoxForArc(const gfx::Point3F& point,
|
| double phi_x = atan2(gfx::DotProduct(v2, vx), gfx::DotProduct(v1, vx));
|
| double phi_z = atan2(gfx::DotProduct(v2, vz), gfx::DotProduct(v1, vz));
|
|
|
| - // NB: it is fine if the denominators here are zero and these values go to
|
| - // infinity; atan can handle it.
|
| - double tan_theta1 = SafeDivide(normal.y(), (normal.x() * normal.z()));
|
| - double tan_theta2 = SafeDivide(-normal.z(), (normal.x() * normal.y()));
|
| -
|
| - candidates[0] = atan(tan_theta1) + phi_x;
|
| + candidates[0] = atan2(normal.y(), normal.x() * normal.z()) + phi_x;
|
| candidates[1] = candidates[0] + M_PI;
|
| - candidates[2] = atan(tan_theta2) + phi_x;
|
| + candidates[2] = atan2(-normal.z(), normal.x() * normal.y()) + phi_x;
|
| candidates[3] = candidates[2] + M_PI;
|
| - candidates[4] = atan(-tan_theta1) + phi_z;
|
| + candidates[4] = atan2(normal.y(), -normal.x() * normal.z()) + phi_z;
|
| candidates[5] = candidates[4] + M_PI;
|
| }
|
|
|
| @@ -415,78 +384,36 @@ bool TransformOperation::BlendedBoundsForBox(const gfx::BoxF& box,
|
| interpolation_type = to->type;
|
|
|
| switch (interpolation_type) {
|
| - case TransformOperation::TransformOperationTranslate: {
|
| - SkMScalar from_x, from_y, from_z;
|
| - if (is_identity_from) {
|
| - from_x = from_y = from_z = 0.0;
|
| - } else {
|
| - from_x = from->translate.x;
|
| - from_y = from->translate.y;
|
| - from_z = from->translate.z;
|
| - }
|
| - SkMScalar to_x, to_y, to_z;
|
| - if (is_identity_to) {
|
| - to_x = to_y = to_z = 0.0;
|
| - } else {
|
| - to_x = to->translate.x;
|
| - to_y = to->translate.y;
|
| - to_z = to->translate.z;
|
| - }
|
| + case TransformOperation::TransformOperationIdentity:
|
| *bounds = box;
|
| - *bounds += gfx::Vector3dF(BlendSkMScalars(from_x, to_x, min_progress),
|
| - BlendSkMScalars(from_y, to_y, min_progress),
|
| - BlendSkMScalars(from_z, to_z, min_progress));
|
| - gfx::BoxF bounds_max = box;
|
| - bounds_max += gfx::Vector3dF(BlendSkMScalars(from_x, to_x, max_progress),
|
| - BlendSkMScalars(from_y, to_y, max_progress),
|
| - BlendSkMScalars(from_z, to_z, max_progress));
|
| - bounds->Union(bounds_max);
|
| return true;
|
| - }
|
| + case TransformOperation::TransformOperationTranslate:
|
| + case TransformOperation::TransformOperationSkew:
|
| + case TransformOperation::TransformOperationPerspective:
|
| case TransformOperation::TransformOperationScale: {
|
| - SkMScalar from_x, from_y, from_z;
|
| - if (is_identity_from) {
|
| - from_x = from_y = from_z = 1.0;
|
| - } else {
|
| - from_x = from->scale.x;
|
| - from_y = from->scale.y;
|
| - from_z = from->scale.z;
|
| - }
|
| - SkMScalar to_x, to_y, to_z;
|
| - if (is_identity_to) {
|
| - to_x = to_y = to_z = 1.0;
|
| - } else {
|
| - to_x = to->scale.x;
|
| - to_y = to->scale.y;
|
| - to_z = to->scale.z;
|
| - }
|
| + gfx::Transform from_transform;
|
| + gfx::Transform to_transform;
|
| + if (!BlendTransformOperations(from, to, min_progress, &from_transform) ||
|
| + !BlendTransformOperations(from, to, max_progress, &to_transform))
|
| + return false;
|
| +
|
| *bounds = box;
|
| - ApplyScaleToBox(
|
| - SkMScalarToFloat(BlendSkMScalars(from_x, to_x, min_progress)),
|
| - SkMScalarToFloat(BlendSkMScalars(from_y, to_y, min_progress)),
|
| - SkMScalarToFloat(BlendSkMScalars(from_z, to_z, min_progress)),
|
| - bounds);
|
| - gfx::BoxF bounds_max = box;
|
| - ApplyScaleToBox(
|
| - SkMScalarToFloat(BlendSkMScalars(from_x, to_x, max_progress)),
|
| - SkMScalarToFloat(BlendSkMScalars(from_y, to_y, max_progress)),
|
| - SkMScalarToFloat(BlendSkMScalars(from_z, to_z, max_progress)),
|
| - &bounds_max);
|
| - if (!bounds->IsEmpty() && !bounds_max.IsEmpty()) {
|
| - bounds->Union(bounds_max);
|
| - } else if (!bounds->IsEmpty()) {
|
| - UnionBoxWithZeroScale(bounds);
|
| - } else if (!bounds_max.IsEmpty()) {
|
| - UnionBoxWithZeroScale(&bounds_max);
|
| - *bounds = bounds_max;
|
| - }
|
| + from_transform.TransformBox(bounds);
|
| +
|
| + gfx::BoxF to_box = box;
|
| + to_transform.TransformBox(&to_box);
|
| + bounds->ExpandTo(to_box);
|
|
|
| return true;
|
| }
|
| - case TransformOperation::TransformOperationIdentity:
|
| - *bounds = box;
|
| - return true;
|
| case TransformOperation::TransformOperationRotate: {
|
| + SkMScalar axis_x = 0;
|
| + SkMScalar axis_y = 0;
|
| + SkMScalar axis_z = 1;
|
| + SkMScalar from_angle = 0;
|
| + if (!ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle))
|
| + return false;
|
| +
|
| bool first_point = true;
|
| for (int i = 0; i < 8; ++i) {
|
| gfx::Point3F corner = box.origin();
|
| @@ -504,8 +431,6 @@ bool TransformOperation::BlendedBoundsForBox(const gfx::BoxF& box,
|
| }
|
| return true;
|
| }
|
| - case TransformOperation::TransformOperationSkew:
|
| - case TransformOperation::TransformOperationPerspective:
|
| case TransformOperation::TransformOperationMatrix:
|
| return false;
|
| }
|
|
|