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

Unified Diff: cc/animation/transform_operation.cc

Issue 55763004: Allow the computation of inflated bounds for non matrix transform operations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 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/animation/layer_animation_controller_unittest.cc ('k') | cc/animation/transform_operations_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « cc/animation/layer_animation_controller_unittest.cc ('k') | cc/animation/transform_operations_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698