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

Side by Side Diff: cc/animation/transform_operation.cc

Issue 2971503002: Transform animations should not collapse by default when interpolating (Closed)
Patch Set: . Created 3 years, 5 months 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 unified diff | Download patch
« no previous file with comments | « cc/animation/transform_operation.h ('k') | cc/animation/transform_operations.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Needed on Windows to get |M_PI| from <cmath> 5 // Needed on Windows to get |M_PI| from <cmath>
6 #ifdef _WIN32 6 #ifdef _WIN32
7 #define _USE_MATH_DEFINES 7 #define _USE_MATH_DEFINES
8 #endif 8 #endif
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 } 83 }
84 return result; 84 return result;
85 } 85 }
86 86
87 static SkMScalar BlendSkMScalars(SkMScalar from, 87 static SkMScalar BlendSkMScalars(SkMScalar from,
88 SkMScalar to, 88 SkMScalar to,
89 SkMScalar progress) { 89 SkMScalar progress) {
90 return from * (1 - progress) + to * progress; 90 return from * (1 - progress) + to * progress;
91 } 91 }
92 92
93 void TransformOperation::Bake() {
94 matrix.MakeIdentity();
95 switch (type) {
96 case TransformOperation::TRANSFORM_OPERATION_TRANSLATE:
97 matrix.Translate3d(translate.x, translate.y, translate.z);
98 break;
99 case TransformOperation::TRANSFORM_OPERATION_ROTATE:
100 matrix.RotateAbout(
101 gfx::Vector3dF(rotate.axis.x, rotate.axis.y, rotate.axis.z),
102 rotate.angle);
103 break;
104 case TransformOperation::TRANSFORM_OPERATION_SCALE:
105 matrix.Scale3d(scale.x, scale.y, scale.z);
106 break;
107 case TransformOperation::TRANSFORM_OPERATION_SKEW:
108 matrix.Skew(skew.x, skew.y);
109 break;
110 case TransformOperation::TRANSFORM_OPERATION_PERSPECTIVE:
111 matrix.ApplyPerspectiveDepth(perspective_depth);
112 break;
113 case TransformOperation::TRANSFORM_OPERATION_MATRIX:
114 case TransformOperation::TRANSFORM_OPERATION_IDENTITY:
115 break;
116 }
117 }
118
93 bool TransformOperation::BlendTransformOperations( 119 bool TransformOperation::BlendTransformOperations(
94 const TransformOperation* from, 120 const TransformOperation* from,
95 const TransformOperation* to, 121 const TransformOperation* to,
96 SkMScalar progress, 122 SkMScalar progress,
97 gfx::Transform* result) { 123 TransformOperation* result) {
98 if (IsOperationIdentity(from) && IsOperationIdentity(to)) 124 if (IsOperationIdentity(from) && IsOperationIdentity(to))
99 return true; 125 return true;
100 126
101 TransformOperation::Type interpolation_type = 127 TransformOperation::Type interpolation_type =
102 TransformOperation::TRANSFORM_OPERATION_IDENTITY; 128 TransformOperation::TRANSFORM_OPERATION_IDENTITY;
103 if (IsOperationIdentity(to)) 129 if (IsOperationIdentity(to))
104 interpolation_type = from->type; 130 interpolation_type = from->type;
105 else 131 else
106 interpolation_type = to->type; 132 interpolation_type = to->type;
133 result->type = interpolation_type;
107 134
108 switch (interpolation_type) { 135 switch (interpolation_type) {
109 case TransformOperation::TRANSFORM_OPERATION_TRANSLATE: { 136 case TransformOperation::TRANSFORM_OPERATION_TRANSLATE: {
110 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->translate.x; 137 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->translate.x;
111 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->translate.y; 138 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->translate.y;
112 SkMScalar from_z = IsOperationIdentity(from) ? 0 : from->translate.z; 139 SkMScalar from_z = IsOperationIdentity(from) ? 0 : from->translate.z;
113 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->translate.x; 140 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->translate.x;
114 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->translate.y; 141 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->translate.y;
115 SkMScalar to_z = IsOperationIdentity(to) ? 0 : to->translate.z; 142 SkMScalar to_z = IsOperationIdentity(to) ? 0 : to->translate.z;
116 result->Translate3d(BlendSkMScalars(from_x, to_x, progress), 143 result->translate.x = BlendSkMScalars(from_x, to_x, progress),
117 BlendSkMScalars(from_y, to_y, progress), 144 result->translate.y = BlendSkMScalars(from_y, to_y, progress),
118 BlendSkMScalars(from_z, to_z, progress)); 145 result->translate.z = BlendSkMScalars(from_z, to_z, progress),
119 break; 146 result->Bake();
120 } 147 break;
121 case TransformOperation::TRANSFORM_OPERATION_ROTATE: { 148 }
122 SkMScalar axis_x = 0; 149 case TransformOperation::TRANSFORM_OPERATION_ROTATE: {
123 SkMScalar axis_y = 0; 150 SkMScalar axis_x = 0;
124 SkMScalar axis_z = 1; 151 SkMScalar axis_y = 0;
125 SkMScalar from_angle = 0; 152 SkMScalar axis_z = 1;
126 SkMScalar to_angle = IsOperationIdentity(to) ? 0 : to->rotate.angle; 153 SkMScalar from_angle = 0;
127 if (ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle)) { 154 SkMScalar to_angle = IsOperationIdentity(to) ? 0 : to->rotate.angle;
128 result->RotateAbout(gfx::Vector3dF(axis_x, axis_y, axis_z), 155 if (ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle)) {
129 BlendSkMScalars(from_angle, to_angle, progress)); 156 result->rotate.axis.x = axis_x;
130 } else { 157 result->rotate.axis.y = axis_y;
131 gfx::Transform to_matrix; 158 result->rotate.axis.z = axis_z;
159 result->rotate.angle = BlendSkMScalars(from_angle, to_angle, progress);
160 result->Bake();
161 } else {
162 if (!IsOperationIdentity(to))
163 result->matrix = to->matrix;
164 gfx::Transform from_matrix;
165 if (!IsOperationIdentity(from))
166 from_matrix = from->matrix;
167 if (!result->matrix.Blend(from_matrix, progress))
168 return false;
169 }
170 break;
171 }
172 case TransformOperation::TRANSFORM_OPERATION_SCALE: {
173 SkMScalar from_x = IsOperationIdentity(from) ? 1 : from->scale.x;
174 SkMScalar from_y = IsOperationIdentity(from) ? 1 : from->scale.y;
175 SkMScalar from_z = IsOperationIdentity(from) ? 1 : from->scale.z;
176 SkMScalar to_x = IsOperationIdentity(to) ? 1 : to->scale.x;
177 SkMScalar to_y = IsOperationIdentity(to) ? 1 : to->scale.y;
178 SkMScalar to_z = IsOperationIdentity(to) ? 1 : to->scale.z;
179 result->scale.x = BlendSkMScalars(from_x, to_x, progress);
180 result->scale.y = BlendSkMScalars(from_y, to_y, progress);
181 result->scale.z = BlendSkMScalars(from_z, to_z, progress);
182 result->Bake();
183 break;
184 }
185 case TransformOperation::TRANSFORM_OPERATION_SKEW: {
186 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->skew.x;
187 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->skew.y;
188 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->skew.x;
189 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->skew.y;
190 result->skew.x = BlendSkMScalars(from_x, to_x, progress);
191 result->skew.y = BlendSkMScalars(from_y, to_y, progress);
192 result->Bake();
193 break;
194 }
195 case TransformOperation::TRANSFORM_OPERATION_PERSPECTIVE: {
196 SkMScalar from_perspective_depth =
197 IsOperationIdentity(from) ? std::numeric_limits<SkMScalar>::max()
198 : from->perspective_depth;
199 SkMScalar to_perspective_depth =
200 IsOperationIdentity(to) ? std::numeric_limits<SkMScalar>::max()
201 : to->perspective_depth;
202 if (from_perspective_depth == 0.f || to_perspective_depth == 0.f)
203 return false;
204
205 SkMScalar blended_perspective_depth = BlendSkMScalars(
206 1.f / from_perspective_depth, 1.f / to_perspective_depth, progress);
207
208 if (blended_perspective_depth == 0.f)
209 return false;
210
211 result->perspective_depth = 1.f / blended_perspective_depth;
212 result->Bake();
213 break;
214 }
215 case TransformOperation::TRANSFORM_OPERATION_MATRIX: {
132 if (!IsOperationIdentity(to)) 216 if (!IsOperationIdentity(to))
133 to_matrix = to->matrix; 217 result->matrix = to->matrix;
134 gfx::Transform from_matrix; 218 gfx::Transform from_matrix;
135 if (!IsOperationIdentity(from)) 219 if (!IsOperationIdentity(from))
136 from_matrix = from->matrix; 220 from_matrix = from->matrix;
137 *result = to_matrix; 221 if (!result->matrix.Blend(from_matrix, progress))
138 if (!result->Blend(from_matrix, progress))
139 return false; 222 return false;
223 break;
140 } 224 }
141 break; 225 case TransformOperation::TRANSFORM_OPERATION_IDENTITY:
142 } 226 // Do nothing.
143 case TransformOperation::TRANSFORM_OPERATION_SCALE: { 227 break;
144 SkMScalar from_x = IsOperationIdentity(from) ? 1 : from->scale.x;
145 SkMScalar from_y = IsOperationIdentity(from) ? 1 : from->scale.y;
146 SkMScalar from_z = IsOperationIdentity(from) ? 1 : from->scale.z;
147 SkMScalar to_x = IsOperationIdentity(to) ? 1 : to->scale.x;
148 SkMScalar to_y = IsOperationIdentity(to) ? 1 : to->scale.y;
149 SkMScalar to_z = IsOperationIdentity(to) ? 1 : to->scale.z;
150 result->Scale3d(BlendSkMScalars(from_x, to_x, progress),
151 BlendSkMScalars(from_y, to_y, progress),
152 BlendSkMScalars(from_z, to_z, progress));
153 break;
154 }
155 case TransformOperation::TRANSFORM_OPERATION_SKEW: {
156 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->skew.x;
157 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->skew.y;
158 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->skew.x;
159 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->skew.y;
160 result->Skew(BlendSkMScalars(from_x, to_x, progress),
161 BlendSkMScalars(from_y, to_y, progress));
162 break;
163 }
164 case TransformOperation::TRANSFORM_OPERATION_PERSPECTIVE: {
165 SkMScalar from_perspective_depth =
166 IsOperationIdentity(from) ? std::numeric_limits<SkMScalar>::max()
167 : from->perspective_depth;
168 SkMScalar to_perspective_depth =
169 IsOperationIdentity(to) ? std::numeric_limits<SkMScalar>::max()
170 : to->perspective_depth;
171 if (from_perspective_depth == 0.f || to_perspective_depth == 0.f)
172 return false;
173
174 SkMScalar blended_perspective_depth = BlendSkMScalars(
175 1.f / from_perspective_depth, 1.f / to_perspective_depth, progress);
176
177 if (blended_perspective_depth == 0.f)
178 return false;
179
180 result->ApplyPerspectiveDepth(1.f / blended_perspective_depth);
181 break;
182 }
183 case TransformOperation::TRANSFORM_OPERATION_MATRIX: {
184 gfx::Transform to_matrix;
185 if (!IsOperationIdentity(to))
186 to_matrix = to->matrix;
187 gfx::Transform from_matrix;
188 if (!IsOperationIdentity(from))
189 from_matrix = from->matrix;
190 *result = to_matrix;
191 if (!result->Blend(from_matrix, progress))
192 return false;
193 break;
194 }
195 case TransformOperation::TRANSFORM_OPERATION_IDENTITY:
196 // Do nothing.
197 break;
198 } 228 }
199 229
200 return true; 230 return true;
201 } 231 }
202 232
203 // If p = (px, py) is a point in the plane being rotated about (0, 0, nz), this 233 // If p = (px, py) is a point in the plane being rotated about (0, 0, nz), this
204 // function computes the angles we would have to rotate from p to get to 234 // function computes the angles we would have to rotate from p to get to
205 // (length(p), 0), (-length(p), 0), (0, length(p)), (0, -length(p)). If nz is 235 // (length(p), 0), (-length(p), 0), (0, length(p)), (0, -length(p)). If nz is
206 // negative, these angles will need to be reversed. 236 // negative, these angles will need to be reversed.
207 static void FindCandidatesInPlane(float px, 237 static void FindCandidatesInPlane(float px,
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 interpolation_type = to->type; 412 interpolation_type = to->type;
383 413
384 switch (interpolation_type) { 414 switch (interpolation_type) {
385 case TransformOperation::TRANSFORM_OPERATION_IDENTITY: 415 case TransformOperation::TRANSFORM_OPERATION_IDENTITY:
386 *bounds = box; 416 *bounds = box;
387 return true; 417 return true;
388 case TransformOperation::TRANSFORM_OPERATION_TRANSLATE: 418 case TransformOperation::TRANSFORM_OPERATION_TRANSLATE:
389 case TransformOperation::TRANSFORM_OPERATION_SKEW: 419 case TransformOperation::TRANSFORM_OPERATION_SKEW:
390 case TransformOperation::TRANSFORM_OPERATION_PERSPECTIVE: 420 case TransformOperation::TRANSFORM_OPERATION_PERSPECTIVE:
391 case TransformOperation::TRANSFORM_OPERATION_SCALE: { 421 case TransformOperation::TRANSFORM_OPERATION_SCALE: {
392 gfx::Transform from_transform; 422 TransformOperation from_operation;
393 gfx::Transform to_transform; 423 TransformOperation to_operation;
394 if (!BlendTransformOperations(from, to, min_progress, &from_transform) || 424 if (!BlendTransformOperations(from, to, min_progress, &from_operation) ||
395 !BlendTransformOperations(from, to, max_progress, &to_transform)) 425 !BlendTransformOperations(from, to, max_progress, &to_operation))
396 return false; 426 return false;
397 427
398 *bounds = box; 428 *bounds = box;
399 from_transform.TransformBox(bounds); 429 from_operation.matrix.TransformBox(bounds);
400 430
401 gfx::BoxF to_box = box; 431 gfx::BoxF to_box = box;
402 to_transform.TransformBox(&to_box); 432 to_operation.matrix.TransformBox(&to_box);
403 bounds->ExpandTo(to_box); 433 bounds->ExpandTo(to_box);
404 434
405 return true; 435 return true;
406 } 436 }
407 case TransformOperation::TRANSFORM_OPERATION_ROTATE: { 437 case TransformOperation::TRANSFORM_OPERATION_ROTATE: {
408 SkMScalar axis_x = 0; 438 SkMScalar axis_x = 0;
409 SkMScalar axis_y = 0; 439 SkMScalar axis_y = 0;
410 SkMScalar axis_z = 1; 440 SkMScalar axis_z = 1;
411 SkMScalar from_angle = 0; 441 SkMScalar from_angle = 0;
412 if (!ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle)) 442 if (!ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle))
(...skipping 17 matching lines...) Expand all
430 return true; 460 return true;
431 } 461 }
432 case TransformOperation::TRANSFORM_OPERATION_MATRIX: 462 case TransformOperation::TRANSFORM_OPERATION_MATRIX:
433 return false; 463 return false;
434 } 464 }
435 NOTREACHED(); 465 NOTREACHED();
436 return false; 466 return false;
437 } 467 }
438 468
439 } // namespace cc 469 } // namespace cc
OLDNEW
« no previous file with comments | « cc/animation/transform_operation.h ('k') | cc/animation/transform_operations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698