OLD | NEW |
---|---|
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 #include <algorithm> | 5 #include <algorithm> |
6 #include <cmath> | 6 #include <cmath> |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "cc/animation/transform_operation.h" | 10 #include "cc/animation/transform_operation.h" |
11 #include "ui/gfx/box_f.h" | 11 #include "ui/gfx/box_f.h" |
12 #include "ui/gfx/vector3d_f.h" | 12 #include "ui/gfx/vector3d_f.h" |
13 | 13 |
14 namespace { | 14 namespace { |
15 const double kAngleEpsilon = 1e-4; | 15 const SkMScalar kAngleEpsilon = 1e-4; |
16 } | 16 } |
17 | 17 |
18 namespace cc { | 18 namespace cc { |
19 | 19 |
20 bool TransformOperation::IsIdentity() const { | 20 bool TransformOperation::IsIdentity() const { |
21 return matrix.IsIdentity(); | 21 return matrix.IsIdentity(); |
22 } | 22 } |
23 | 23 |
24 static bool IsOperationIdentity(const TransformOperation* operation) { | 24 static bool IsOperationIdentity(const TransformOperation* operation) { |
25 return !operation || operation->IsIdentity(); | 25 return !operation || operation->IsIdentity(); |
26 } | 26 } |
27 | 27 |
28 static bool ShareSameAxis(const TransformOperation* from, | 28 static bool ShareSameAxis(const TransformOperation* from, |
29 const TransformOperation* to, | 29 const TransformOperation* to, |
30 double* axis_x, | 30 SkMScalar* axis_x, |
31 double* axis_y, | 31 SkMScalar* axis_y, |
32 double* axis_z, | 32 SkMScalar* axis_z, |
33 double* angle_from) { | 33 SkMScalar* angle_from) { |
34 if (IsOperationIdentity(from) && IsOperationIdentity(to)) | 34 if (IsOperationIdentity(from) && IsOperationIdentity(to)) |
35 return false; | 35 return false; |
36 | 36 |
37 if (IsOperationIdentity(from) && !IsOperationIdentity(to)) { | 37 if (IsOperationIdentity(from) && !IsOperationIdentity(to)) { |
38 *axis_x = to->rotate.axis.x; | 38 *axis_x = to->rotate.axis.x; |
39 *axis_y = to->rotate.axis.y; | 39 *axis_y = to->rotate.axis.y; |
40 *axis_z = to->rotate.axis.z; | 40 *axis_z = to->rotate.axis.z; |
41 *angle_from = 0; | 41 *angle_from = 0; |
42 return true; | 42 return true; |
43 } | 43 } |
44 | 44 |
45 if (!IsOperationIdentity(from) && IsOperationIdentity(to)) { | 45 if (!IsOperationIdentity(from) && IsOperationIdentity(to)) { |
46 *axis_x = from->rotate.axis.x; | 46 *axis_x = from->rotate.axis.x; |
47 *axis_y = from->rotate.axis.y; | 47 *axis_y = from->rotate.axis.y; |
48 *axis_z = from->rotate.axis.z; | 48 *axis_z = from->rotate.axis.z; |
49 *angle_from = from->rotate.angle; | 49 *angle_from = from->rotate.angle; |
50 return true; | 50 return true; |
51 } | 51 } |
52 | 52 |
53 double length_2 = from->rotate.axis.x * from->rotate.axis.x + | 53 SkMScalar length_2 = from->rotate.axis.x * from->rotate.axis.x + |
54 from->rotate.axis.y * from->rotate.axis.y + | 54 from->rotate.axis.y * from->rotate.axis.y + |
55 from->rotate.axis.z * from->rotate.axis.z; | 55 from->rotate.axis.z * from->rotate.axis.z; |
56 double other_length_2 = to->rotate.axis.x * to->rotate.axis.x + | 56 SkMScalar other_length_2 = to->rotate.axis.x * to->rotate.axis.x + |
57 to->rotate.axis.y * to->rotate.axis.y + | 57 to->rotate.axis.y * to->rotate.axis.y + |
58 to->rotate.axis.z * to->rotate.axis.z; | 58 to->rotate.axis.z * to->rotate.axis.z; |
59 | 59 |
60 if (length_2 <= kAngleEpsilon || other_length_2 <= kAngleEpsilon) | 60 if (length_2 <= kAngleEpsilon || other_length_2 <= kAngleEpsilon) |
61 return false; | 61 return false; |
62 | 62 |
63 double dot = to->rotate.axis.x * from->rotate.axis.x + | 63 SkMScalar dot = to->rotate.axis.x * from->rotate.axis.x + |
64 to->rotate.axis.y * from->rotate.axis.y + | 64 to->rotate.axis.y * from->rotate.axis.y + |
65 to->rotate.axis.z * from->rotate.axis.z; | 65 to->rotate.axis.z * from->rotate.axis.z; |
66 double error = std::abs(1.0 - (dot * dot) / (length_2 * other_length_2)); | 66 SkMScalar error = std::abs(1.0 - (dot * dot) / (length_2 * other_length_2)); |
danakj
2013/09/09 17:57:45
s/1.0/SK_MScalar1/?
enne (OOO)
2013/09/10 22:32:32
Done.
| |
67 bool result = error < kAngleEpsilon; | 67 bool result = error < kAngleEpsilon; |
68 if (result) { | 68 if (result) { |
69 *axis_x = to->rotate.axis.x; | 69 *axis_x = to->rotate.axis.x; |
70 *axis_y = to->rotate.axis.y; | 70 *axis_y = to->rotate.axis.y; |
71 *axis_z = to->rotate.axis.z; | 71 *axis_z = to->rotate.axis.z; |
72 // If the axes are pointing in opposite directions, we need to reverse | 72 // If the axes are pointing in opposite directions, we need to reverse |
73 // the angle. | 73 // the angle. |
74 *angle_from = dot > 0 ? from->rotate.angle : -from->rotate.angle; | 74 *angle_from = dot > 0 ? from->rotate.angle : -from->rotate.angle; |
75 } | 75 } |
76 return result; | 76 return result; |
77 } | 77 } |
78 | 78 |
79 static double BlendDoubles(double from, double to, double progress) { | 79 static SkMScalar BlendSkMScalars(SkMScalar from, |
80 SkMScalar to, | |
81 double progress) { | |
80 return from * (1 - progress) + to * progress; | 82 return from * (1 - progress) + to * progress; |
danakj
2013/09/09 17:57:45
this should be doing SkDoubleToMScalar() on its re
enne (OOO)
2013/09/10 22:32:32
progress here should really just be an SkMScalar.
| |
81 } | 83 } |
82 | 84 |
83 bool TransformOperation::BlendTransformOperations( | 85 bool TransformOperation::BlendTransformOperations( |
84 const TransformOperation* from, | 86 const TransformOperation* from, |
85 const TransformOperation* to, | 87 const TransformOperation* to, |
86 double progress, | 88 double progress, |
87 gfx::Transform* result) { | 89 gfx::Transform* result) { |
88 if (IsOperationIdentity(from) && IsOperationIdentity(to)) | 90 if (IsOperationIdentity(from) && IsOperationIdentity(to)) |
89 return true; | 91 return true; |
90 | 92 |
91 TransformOperation::Type interpolation_type = | 93 TransformOperation::Type interpolation_type = |
92 TransformOperation::TransformOperationIdentity; | 94 TransformOperation::TransformOperationIdentity; |
93 if (IsOperationIdentity(to)) | 95 if (IsOperationIdentity(to)) |
94 interpolation_type = from->type; | 96 interpolation_type = from->type; |
95 else | 97 else |
96 interpolation_type = to->type; | 98 interpolation_type = to->type; |
97 | 99 |
98 switch (interpolation_type) { | 100 switch (interpolation_type) { |
99 case TransformOperation::TransformOperationTranslate: { | 101 case TransformOperation::TransformOperationTranslate: { |
100 double from_x = IsOperationIdentity(from) ? 0 : from->translate.x; | 102 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->translate.x; |
101 double from_y = IsOperationIdentity(from) ? 0 : from->translate.y; | 103 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->translate.y; |
102 double from_z = IsOperationIdentity(from) ? 0 : from->translate.z; | 104 SkMScalar from_z = IsOperationIdentity(from) ? 0 : from->translate.z; |
103 double to_x = IsOperationIdentity(to) ? 0 : to->translate.x; | 105 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->translate.x; |
104 double to_y = IsOperationIdentity(to) ? 0 : to->translate.y; | 106 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->translate.y; |
105 double to_z = IsOperationIdentity(to) ? 0 : to->translate.z; | 107 SkMScalar to_z = IsOperationIdentity(to) ? 0 : to->translate.z; |
106 result->Translate3d(BlendDoubles(from_x, to_x, progress), | 108 result->Translate3d(BlendSkMScalars(from_x, to_x, progress), |
107 BlendDoubles(from_y, to_y, progress), | 109 BlendSkMScalars(from_y, to_y, progress), |
108 BlendDoubles(from_z, to_z, progress)); | 110 BlendSkMScalars(from_z, to_z, progress)); |
109 break; | 111 break; |
110 } | 112 } |
111 case TransformOperation::TransformOperationRotate: { | 113 case TransformOperation::TransformOperationRotate: { |
112 double axis_x = 0; | 114 SkMScalar axis_x = 0; |
113 double axis_y = 0; | 115 SkMScalar axis_y = 0; |
114 double axis_z = 1; | 116 SkMScalar axis_z = 1; |
115 double from_angle = 0; | 117 SkMScalar from_angle = 0; |
116 double to_angle = IsOperationIdentity(to) ? 0 : to->rotate.angle; | 118 SkMScalar to_angle = IsOperationIdentity(to) ? 0 : to->rotate.angle; |
117 if (ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle)) { | 119 if (ShareSameAxis(from, to, &axis_x, &axis_y, &axis_z, &from_angle)) { |
118 result->RotateAbout(gfx::Vector3dF(axis_x, axis_y, axis_z), | 120 result->RotateAbout(gfx::Vector3dF(axis_x, axis_y, axis_z), |
119 BlendDoubles(from_angle, to_angle, progress)); | 121 BlendSkMScalars(from_angle, to_angle, progress)); |
120 } else { | 122 } else { |
121 gfx::Transform to_matrix; | 123 gfx::Transform to_matrix; |
122 if (!IsOperationIdentity(to)) | 124 if (!IsOperationIdentity(to)) |
123 to_matrix = to->matrix; | 125 to_matrix = to->matrix; |
124 gfx::Transform from_matrix; | 126 gfx::Transform from_matrix; |
125 if (!IsOperationIdentity(from)) | 127 if (!IsOperationIdentity(from)) |
126 from_matrix = from->matrix; | 128 from_matrix = from->matrix; |
127 *result = to_matrix; | 129 *result = to_matrix; |
128 if (!result->Blend(from_matrix, progress)) | 130 if (!result->Blend(from_matrix, progress)) |
129 return false; | 131 return false; |
130 } | 132 } |
131 break; | 133 break; |
132 } | 134 } |
133 case TransformOperation::TransformOperationScale: { | 135 case TransformOperation::TransformOperationScale: { |
134 double from_x = IsOperationIdentity(from) ? 1 : from->scale.x; | 136 SkMScalar from_x = IsOperationIdentity(from) ? 1 : from->scale.x; |
135 double from_y = IsOperationIdentity(from) ? 1 : from->scale.y; | 137 SkMScalar from_y = IsOperationIdentity(from) ? 1 : from->scale.y; |
136 double from_z = IsOperationIdentity(from) ? 1 : from->scale.z; | 138 SkMScalar from_z = IsOperationIdentity(from) ? 1 : from->scale.z; |
137 double to_x = IsOperationIdentity(to) ? 1 : to->scale.x; | 139 SkMScalar to_x = IsOperationIdentity(to) ? 1 : to->scale.x; |
138 double to_y = IsOperationIdentity(to) ? 1 : to->scale.y; | 140 SkMScalar to_y = IsOperationIdentity(to) ? 1 : to->scale.y; |
139 double to_z = IsOperationIdentity(to) ? 1 : to->scale.z; | 141 SkMScalar to_z = IsOperationIdentity(to) ? 1 : to->scale.z; |
140 result->Scale3d(BlendDoubles(from_x, to_x, progress), | 142 result->Scale3d(BlendSkMScalars(from_x, to_x, progress), |
141 BlendDoubles(from_y, to_y, progress), | 143 BlendSkMScalars(from_y, to_y, progress), |
142 BlendDoubles(from_z, to_z, progress)); | 144 BlendSkMScalars(from_z, to_z, progress)); |
143 break; | 145 break; |
144 } | 146 } |
145 case TransformOperation::TransformOperationSkew: { | 147 case TransformOperation::TransformOperationSkew: { |
146 double from_x = IsOperationIdentity(from) ? 0 : from->skew.x; | 148 SkMScalar from_x = IsOperationIdentity(from) ? 0 : from->skew.x; |
147 double from_y = IsOperationIdentity(from) ? 0 : from->skew.y; | 149 SkMScalar from_y = IsOperationIdentity(from) ? 0 : from->skew.y; |
148 double to_x = IsOperationIdentity(to) ? 0 : to->skew.x; | 150 SkMScalar to_x = IsOperationIdentity(to) ? 0 : to->skew.x; |
149 double to_y = IsOperationIdentity(to) ? 0 : to->skew.y; | 151 SkMScalar to_y = IsOperationIdentity(to) ? 0 : to->skew.y; |
150 result->SkewX(BlendDoubles(from_x, to_x, progress)); | 152 result->SkewX(BlendSkMScalars(from_x, to_x, progress)); |
151 result->SkewY(BlendDoubles(from_y, to_y, progress)); | 153 result->SkewY(BlendSkMScalars(from_y, to_y, progress)); |
152 break; | 154 break; |
153 } | 155 } |
154 case TransformOperation::TransformOperationPerspective: { | 156 case TransformOperation::TransformOperationPerspective: { |
155 double from_perspective_depth = IsOperationIdentity(from) ? | 157 SkMScalar from_perspective_depth = |
156 std::numeric_limits<double>::max() : from->perspective_depth; | 158 IsOperationIdentity(from) ? std::numeric_limits<SkMScalar>::max() |
157 double to_perspective_depth = IsOperationIdentity(to) ? | 159 : from->perspective_depth; |
158 std::numeric_limits<double>::max() : to->perspective_depth; | 160 SkMScalar to_perspective_depth = IsOperationIdentity(to) |
159 result->ApplyPerspectiveDepth( | 161 ? std::numeric_limits<SkMScalar>::max() |
160 BlendDoubles(from_perspective_depth, to_perspective_depth, progress)); | 162 : to->perspective_depth; |
163 result->ApplyPerspectiveDepth(BlendSkMScalars( | |
164 from_perspective_depth, to_perspective_depth, progress)); | |
161 break; | 165 break; |
162 } | 166 } |
163 case TransformOperation::TransformOperationMatrix: { | 167 case TransformOperation::TransformOperationMatrix: { |
164 gfx::Transform to_matrix; | 168 gfx::Transform to_matrix; |
165 if (!IsOperationIdentity(to)) | 169 if (!IsOperationIdentity(to)) |
166 to_matrix = to->matrix; | 170 to_matrix = to->matrix; |
167 gfx::Transform from_matrix; | 171 gfx::Transform from_matrix; |
168 if (!IsOperationIdentity(from)) | 172 if (!IsOperationIdentity(from)) |
169 from_matrix = from->matrix; | 173 from_matrix = from->matrix; |
170 *result = to_matrix; | 174 *result = to_matrix; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 | 223 |
220 TransformOperation::Type interpolation_type = | 224 TransformOperation::Type interpolation_type = |
221 TransformOperation::TransformOperationIdentity; | 225 TransformOperation::TransformOperationIdentity; |
222 if (is_identity_to) | 226 if (is_identity_to) |
223 interpolation_type = from->type; | 227 interpolation_type = from->type; |
224 else | 228 else |
225 interpolation_type = to->type; | 229 interpolation_type = to->type; |
226 | 230 |
227 switch (interpolation_type) { | 231 switch (interpolation_type) { |
228 case TransformOperation::TransformOperationTranslate: { | 232 case TransformOperation::TransformOperationTranslate: { |
229 double from_x, from_y, from_z; | 233 SkMScalar from_x, from_y, from_z; |
230 if (is_identity_from) { | 234 if (is_identity_from) { |
231 from_x = from_y = from_z = 0.0; | 235 from_x = from_y = from_z = 0.0; |
232 } else { | 236 } else { |
233 from_x = from->translate.x; | 237 from_x = from->translate.x; |
234 from_y = from->translate.y; | 238 from_y = from->translate.y; |
235 from_z = from->translate.z; | 239 from_z = from->translate.z; |
236 } | 240 } |
237 double to_x, to_y, to_z; | 241 SkMScalar to_x, to_y, to_z; |
238 if (is_identity_to) { | 242 if (is_identity_to) { |
239 to_x = to_y = to_z = 0.0; | 243 to_x = to_y = to_z = 0.0; |
240 } else { | 244 } else { |
241 to_x = to->translate.x; | 245 to_x = to->translate.x; |
242 to_y = to->translate.y; | 246 to_y = to->translate.y; |
243 to_z = to->translate.z; | 247 to_z = to->translate.z; |
244 } | 248 } |
245 *bounds = box; | 249 *bounds = box; |
246 *bounds += gfx::Vector3dF(BlendDoubles(from_x, to_x, min_progress), | 250 *bounds += gfx::Vector3dF(BlendSkMScalars(from_x, to_x, min_progress), |
247 BlendDoubles(from_y, to_y, min_progress), | 251 BlendSkMScalars(from_y, to_y, min_progress), |
248 BlendDoubles(from_z, to_z, min_progress)); | 252 BlendSkMScalars(from_z, to_z, min_progress)); |
249 gfx::BoxF bounds_max = box; | 253 gfx::BoxF bounds_max = box; |
250 bounds_max += gfx::Vector3dF(BlendDoubles(from_x, to_x, max_progress), | 254 bounds_max += gfx::Vector3dF(BlendSkMScalars(from_x, to_x, max_progress), |
251 BlendDoubles(from_y, to_y, max_progress), | 255 BlendSkMScalars(from_y, to_y, max_progress), |
252 BlendDoubles(from_z, to_z, max_progress)); | 256 BlendSkMScalars(from_z, to_z, max_progress)); |
253 bounds->Union(bounds_max); | 257 bounds->Union(bounds_max); |
254 return true; | 258 return true; |
255 } | 259 } |
256 case TransformOperation::TransformOperationScale: { | 260 case TransformOperation::TransformOperationScale: { |
257 double from_x, from_y, from_z; | 261 SkMScalar from_x, from_y, from_z; |
258 if (is_identity_from) { | 262 if (is_identity_from) { |
259 from_x = from_y = from_z = 1.0; | 263 from_x = from_y = from_z = 1.0; |
260 } else { | 264 } else { |
261 from_x = from->scale.x; | 265 from_x = from->scale.x; |
262 from_y = from->scale.y; | 266 from_y = from->scale.y; |
263 from_z = from->scale.z; | 267 from_z = from->scale.z; |
264 } | 268 } |
265 double to_x, to_y, to_z; | 269 SkMScalar to_x, to_y, to_z; |
266 if (is_identity_to) { | 270 if (is_identity_to) { |
267 to_x = to_y = to_z = 1.0; | 271 to_x = to_y = to_z = 1.0; |
268 } else { | 272 } else { |
269 to_x = to->scale.x; | 273 to_x = to->scale.x; |
270 to_y = to->scale.y; | 274 to_y = to->scale.y; |
271 to_z = to->scale.z; | 275 to_z = to->scale.z; |
272 } | 276 } |
273 *bounds = box; | 277 *bounds = box; |
274 ApplyScaleToBox(BlendDoubles(from_x, to_x, min_progress), | 278 ApplyScaleToBox(BlendSkMScalars(from_x, to_x, min_progress), |
danakj
2013/09/09 17:57:45
These values should be SkMScalarToFloat()'d
enne (OOO)
2013/09/10 22:32:32
Done.
| |
275 BlendDoubles(from_y, to_y, min_progress), | 279 BlendSkMScalars(from_y, to_y, min_progress), |
276 BlendDoubles(from_z, to_z, min_progress), | 280 BlendSkMScalars(from_z, to_z, min_progress), |
277 bounds); | 281 bounds); |
278 gfx::BoxF bounds_max = box; | 282 gfx::BoxF bounds_max = box; |
279 ApplyScaleToBox(BlendDoubles(from_x, to_x, max_progress), | 283 ApplyScaleToBox(BlendSkMScalars(from_x, to_x, max_progress), |
danakj
2013/09/09 17:57:45
As should these.
enne (OOO)
2013/09/10 22:32:32
Done.
| |
280 BlendDoubles(from_y, to_y, max_progress), | 284 BlendSkMScalars(from_y, to_y, max_progress), |
281 BlendDoubles(from_z, to_z, max_progress), | 285 BlendSkMScalars(from_z, to_z, max_progress), |
282 &bounds_max); | 286 &bounds_max); |
283 if (!bounds->IsEmpty() && !bounds_max.IsEmpty()) { | 287 if (!bounds->IsEmpty() && !bounds_max.IsEmpty()) { |
284 bounds->Union(bounds_max); | 288 bounds->Union(bounds_max); |
285 } else if (!bounds->IsEmpty()) { | 289 } else if (!bounds->IsEmpty()) { |
286 UnionBoxWithZeroScale(bounds); | 290 UnionBoxWithZeroScale(bounds); |
287 } else if (!bounds_max.IsEmpty()) { | 291 } else if (!bounds_max.IsEmpty()) { |
288 UnionBoxWithZeroScale(&bounds_max); | 292 UnionBoxWithZeroScale(&bounds_max); |
289 *bounds = bounds_max; | 293 *bounds = bounds_max; |
290 } | 294 } |
291 | 295 |
292 return true; | 296 return true; |
293 } | 297 } |
294 case TransformOperation::TransformOperationIdentity: | 298 case TransformOperation::TransformOperationIdentity: |
295 *bounds = box; | 299 *bounds = box; |
296 return true; | 300 return true; |
297 case TransformOperation::TransformOperationRotate: | 301 case TransformOperation::TransformOperationRotate: |
298 case TransformOperation::TransformOperationSkew: | 302 case TransformOperation::TransformOperationSkew: |
299 case TransformOperation::TransformOperationPerspective: | 303 case TransformOperation::TransformOperationPerspective: |
300 case TransformOperation::TransformOperationMatrix: | 304 case TransformOperation::TransformOperationMatrix: |
301 return false; | 305 return false; |
302 } | 306 } |
303 NOTREACHED(); | 307 NOTREACHED(); |
304 return false; | 308 return false; |
305 } | 309 } |
306 | 310 |
307 } // namespace cc | 311 } // namespace cc |
OLD | NEW |