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

Side by Side Diff: ui/gfx/interpolated_transform.cc

Issue 11418040: gfx::Transform API clean-up (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/gfx/interpolated_transform.h" 5 #include "ui/gfx/interpolated_transform.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #ifndef M_PI 9 #ifndef M_PI
10 #define M_PI 3.14159265358979323846 10 #define M_PI 3.14159265358979323846
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 if (child_.get()) { 97 if (child_.get()) {
98 result.ConcatTransform(child_->Interpolate(t)); 98 result.ConcatTransform(child_->Interpolate(t));
99 } 99 }
100 return result; 100 return result;
101 } 101 }
102 102
103 void InterpolatedTransform::SetChild(InterpolatedTransform* child) { 103 void InterpolatedTransform::SetChild(InterpolatedTransform* child) {
104 child_.reset(child); 104 child_.reset(child);
105 } 105 }
106 106
107 bool InterpolatedTransform::FactorTRS(const gfx::Transform& transform,
108 gfx::Point* translation,
109 float* rotation,
110 gfx::Point3F* scale) {
111 const SkMatrix44& m = transform.matrix();
112 double m00 = SkMScalarToDouble(m.get(0, 0));
113 double m01 = SkMScalarToDouble(m.get(0, 1));
114 double m10 = SkMScalarToDouble(m.get(1, 0));
115 double m11 = SkMScalarToDouble(m.get(1, 1));
116
117 // A factorable 2D TRS matrix must be of the form:
118 // [ sx*cos_theta -(sy*sin_theta) 0 tx ]
119 // [ sx*sin_theta sy*cos_theta 0 ty ]
120 // [ 0 0 1 0 ]
121 // [ 0 0 0 1 ]
122 if (!IsApproximatelyZero(SkMScalarToDouble(m.get(0, 2))) ||
123 !IsApproximatelyZero(SkMScalarToDouble(m.get(1, 2))) ||
124 !IsApproximatelyZero(SkMScalarToDouble(m.get(2, 0))) ||
125 !IsApproximatelyZero(SkMScalarToDouble(m.get(2, 1))) ||
126 !IsApproximatelyZero(SkMScalarToDouble(m.get(2, 2)) - 1) ||
127 !IsApproximatelyZero(SkMScalarToDouble(m.get(2, 3))) ||
128 !IsApproximatelyZero(SkMScalarToDouble(m.get(3, 0))) ||
129 !IsApproximatelyZero(SkMScalarToDouble(m.get(3, 1))) ||
130 !IsApproximatelyZero(SkMScalarToDouble(m.get(3, 2))) ||
131 !IsApproximatelyZero(SkMScalarToDouble(m.get(3, 3)) - 1)) {
132 return false;
133 }
134
135 double scale_x = std::sqrt(m00 * m00 + m10 * m10);
136 double scale_y = std::sqrt(m01 * m01 + m11 * m11);
137
138 if (scale_x == 0 || scale_y == 0)
139 return false;
140
141 double cos_theta = m00 / scale_x;
142 double sin_theta = m10 / scale_x;
143
144 if (!IsApproximatelyZero(cos_theta - (m11 / scale_y)) ||
145 !IsApproximatelyZero(sin_theta + (m01 / scale_y)) ||
146 !IsApproximatelyZero(cos_theta*cos_theta + sin_theta*sin_theta - 1.0f))
147 return false;
148
149 double radians = std::atan2(sin_theta, cos_theta);
150
151 if (translation)
152 *translation = gfx::Point(SkMScalarToFloat(m.get(0, 3)),
153 SkMScalarToFloat(m.get(1, 3)));
154 if (rotation)
155 *rotation = static_cast<float>(radians * 180.0 / M_PI);
156 if (scale)
157 *scale = gfx::Point3F(static_cast<float>(scale_x),
158 static_cast<float>(scale_y),
159 1.0f);
160 return true;
161 }
162
163 inline float InterpolatedTransform::ValueBetween(float time, 107 inline float InterpolatedTransform::ValueBetween(float time,
164 float start_value, 108 float start_value,
165 float end_value) const { 109 float end_value) const {
166 // can't handle NaN 110 // can't handle NaN
167 DCHECK(time == time && start_time_ == start_time_ && end_time_ == end_time_); 111 DCHECK(time == time && start_time_ == start_time_ && end_time_ == end_time_);
168 if (time != time || start_time_ != start_time_ || end_time_ != end_time_) 112 if (time != time || start_time_ != start_time_ || end_time_ != end_time_)
169 return start_value; 113 return start_value;
170 114
171 // Ok if equal -- we'll get a step function. Note: if end_time_ == 115 // Ok if equal -- we'll get a step function. Note: if end_time_ ==
172 // start_time_ == x, then if none of the numbers are NaN, then it 116 // start_time_ == x, then if none of the numbers are NaN, then it
(...skipping 29 matching lines...) Expand all
202 : InterpolatedTransform(start_time, end_time), 146 : InterpolatedTransform(start_time, end_time),
203 start_degrees_(start_degrees), 147 start_degrees_(start_degrees),
204 end_degrees_(end_degrees) { 148 end_degrees_(end_degrees) {
205 } 149 }
206 150
207 InterpolatedRotation::~InterpolatedRotation() {} 151 InterpolatedRotation::~InterpolatedRotation() {}
208 152
209 gfx::Transform InterpolatedRotation::InterpolateButDoNotCompose(float t) const { 153 gfx::Transform InterpolatedRotation::InterpolateButDoNotCompose(float t) const {
210 gfx::Transform result; 154 gfx::Transform result;
211 float interpolated_degrees = ValueBetween(t, start_degrees_, end_degrees_); 155 float interpolated_degrees = ValueBetween(t, start_degrees_, end_degrees_);
212 result.SetRotate(interpolated_degrees); 156 result.Rotate(interpolated_degrees);
danakj 2012/11/16 19:46:12 I didn't like this change with Set at first, but s
213 if (t == 0.0f || t == 1.0f) 157 if (t == 0.0f || t == 1.0f)
214 MassageRotationIfMultipleOfNinetyDegrees(&result, interpolated_degrees); 158 MassageRotationIfMultipleOfNinetyDegrees(&result, interpolated_degrees);
215 return result; 159 return result;
216 } 160 }
217 161
218 /////////////////////////////////////////////////////////////////////////////// 162 ///////////////////////////////////////////////////////////////////////////////
219 // InterpolatedAxisAngleRotation 163 // InterpolatedAxisAngleRotation
220 // 164 //
221 165
222 InterpolatedAxisAngleRotation::InterpolatedAxisAngleRotation( 166 InterpolatedAxisAngleRotation::InterpolatedAxisAngleRotation(
223 gfx::Point3F axis, 167 gfx::Vector3dF axis,
danakj 2012/11/16 19:46:12 const&
Ian Vollick 2012/11/16 21:51:24 Done, here and in the other spots.
224 float start_degrees, 168 float start_degrees,
225 float end_degrees) 169 float end_degrees)
226 : InterpolatedTransform(), 170 : InterpolatedTransform(),
227 axis_(axis), 171 axis_(axis),
228 start_degrees_(start_degrees), 172 start_degrees_(start_degrees),
229 end_degrees_(end_degrees) { 173 end_degrees_(end_degrees) {
230 } 174 }
231 175
232 InterpolatedAxisAngleRotation::InterpolatedAxisAngleRotation( 176 InterpolatedAxisAngleRotation::InterpolatedAxisAngleRotation(
233 gfx::Point3F axis, 177 gfx::Vector3dF axis,
danakj 2012/11/16 19:46:12 const&
234 float start_degrees, 178 float start_degrees,
235 float end_degrees, 179 float end_degrees,
236 float start_time, 180 float start_time,
237 float end_time) 181 float end_time)
238 : InterpolatedTransform(start_time, end_time), 182 : InterpolatedTransform(start_time, end_time),
239 axis_(axis), 183 axis_(axis),
240 start_degrees_(start_degrees), 184 start_degrees_(start_degrees),
241 end_degrees_(end_degrees) { 185 end_degrees_(end_degrees) {
242 } 186 }
243 187
244 InterpolatedAxisAngleRotation::~InterpolatedAxisAngleRotation() {} 188 InterpolatedAxisAngleRotation::~InterpolatedAxisAngleRotation() {}
245 189
246 gfx::Transform 190 gfx::Transform
247 InterpolatedAxisAngleRotation::InterpolateButDoNotCompose(float t) const { 191 InterpolatedAxisAngleRotation::InterpolateButDoNotCompose(float t) const {
248 gfx::Transform result; 192 gfx::Transform result;
249 result.SetRotateAbout(axis_, ValueBetween(t, start_degrees_, end_degrees_)); 193 result.RotateAbout(axis_, ValueBetween(t, start_degrees_, end_degrees_));
250 return result; 194 return result;
251 } 195 }
252 196
253 /////////////////////////////////////////////////////////////////////////////// 197 ///////////////////////////////////////////////////////////////////////////////
254 // InterpolatedScale 198 // InterpolatedScale
255 // 199 //
256 200
257 InterpolatedScale::InterpolatedScale(float start_scale, float end_scale) 201 InterpolatedScale::InterpolatedScale(float start_scale, float end_scale)
258 : InterpolatedTransform(), 202 : InterpolatedTransform(),
259 start_scale_(gfx::Point3F(start_scale, start_scale, start_scale)), 203 start_scale_(gfx::Point3F(start_scale, start_scale, start_scale)),
(...skipping 23 matching lines...) Expand all
283 end_scale_(end_scale) { 227 end_scale_(end_scale) {
284 } 228 }
285 229
286 InterpolatedScale::~InterpolatedScale() {} 230 InterpolatedScale::~InterpolatedScale() {}
287 231
288 gfx::Transform InterpolatedScale::InterpolateButDoNotCompose(float t) const { 232 gfx::Transform InterpolatedScale::InterpolateButDoNotCompose(float t) const {
289 gfx::Transform result; 233 gfx::Transform result;
290 float scale_x = ValueBetween(t, start_scale_.x(), end_scale_.x()); 234 float scale_x = ValueBetween(t, start_scale_.x(), end_scale_.x());
291 float scale_y = ValueBetween(t, start_scale_.y(), end_scale_.y()); 235 float scale_y = ValueBetween(t, start_scale_.y(), end_scale_.y());
292 // TODO(vollick) 3d xforms. 236 // TODO(vollick) 3d xforms.
293 result.SetScale(scale_x, scale_y); 237 result.Scale(scale_x, scale_y);
294 return result; 238 return result;
295 } 239 }
296 240
297 /////////////////////////////////////////////////////////////////////////////// 241 ///////////////////////////////////////////////////////////////////////////////
298 // InterpolatedTranslation 242 // InterpolatedTranslation
299 // 243 //
300 244
301 InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos, 245 InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos,
302 const gfx::Point& end_pos) 246 const gfx::Point& end_pos)
303 : InterpolatedTransform(), 247 : InterpolatedTransform(),
304 start_pos_(start_pos), 248 start_pos_(start_pos),
305 end_pos_(end_pos) { 249 end_pos_(end_pos) {
306 } 250 }
307 251
308 InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos, 252 InterpolatedTranslation::InterpolatedTranslation(const gfx::Point& start_pos,
309 const gfx::Point& end_pos, 253 const gfx::Point& end_pos,
310 float start_time, 254 float start_time,
311 float end_time) 255 float end_time)
312 : InterpolatedTransform(start_time, end_time), 256 : InterpolatedTransform(start_time, end_time),
313 start_pos_(start_pos), 257 start_pos_(start_pos),
314 end_pos_(end_pos) { 258 end_pos_(end_pos) {
315 } 259 }
316 260
317 InterpolatedTranslation::~InterpolatedTranslation() {} 261 InterpolatedTranslation::~InterpolatedTranslation() {}
318 262
319 gfx::Transform 263 gfx::Transform
320 InterpolatedTranslation::InterpolateButDoNotCompose(float t) const { 264 InterpolatedTranslation::InterpolateButDoNotCompose(float t) const {
321 gfx::Transform result; 265 gfx::Transform result;
322 // TODO(vollick) 3d xforms. 266 // TODO(vollick) 3d xforms.
323 result.SetTranslate(ValueBetween(t, start_pos_.x(), end_pos_.x()), 267 result.Translate(ValueBetween(t, start_pos_.x(), end_pos_.x()),
324 ValueBetween(t, start_pos_.y(), end_pos_.y())); 268 ValueBetween(t, start_pos_.y(), end_pos_.y()));
325 return result; 269 return result;
326 } 270 }
327 271
328 /////////////////////////////////////////////////////////////////////////////// 272 ///////////////////////////////////////////////////////////////////////////////
329 // InterpolatedConstantTransform 273 // InterpolatedConstantTransform
330 // 274 //
331 275
332 InterpolatedConstantTransform::InterpolatedConstantTransform( 276 InterpolatedConstantTransform::InterpolatedConstantTransform(
333 const gfx::Transform& transform) 277 const gfx::Transform& transform)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 if (transform_.get()) { 313 if (transform_.get()) {
370 return transform_->Interpolate(t); 314 return transform_->Interpolate(t);
371 } 315 }
372 return gfx::Transform(); 316 return gfx::Transform();
373 } 317 }
374 318
375 void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot, 319 void InterpolatedTransformAboutPivot::Init(const gfx::Point& pivot,
376 InterpolatedTransform* xform) { 320 InterpolatedTransform* xform) {
377 gfx::Transform to_pivot; 321 gfx::Transform to_pivot;
378 gfx::Transform from_pivot; 322 gfx::Transform from_pivot;
379 to_pivot.SetTranslate(-pivot.x(), -pivot.y()); 323 to_pivot.Translate(-pivot.x(), -pivot.y());
380 from_pivot.SetTranslate(pivot.x(), pivot.y()); 324 from_pivot.Translate(pivot.x(), pivot.y());
381 325
382 scoped_ptr<InterpolatedTransform> pre_transform( 326 scoped_ptr<InterpolatedTransform> pre_transform(
383 new InterpolatedConstantTransform(to_pivot)); 327 new InterpolatedConstantTransform(to_pivot));
384 scoped_ptr<InterpolatedTransform> post_transform( 328 scoped_ptr<InterpolatedTransform> post_transform(
385 new InterpolatedConstantTransform(from_pivot)); 329 new InterpolatedConstantTransform(from_pivot));
386 330
387 pre_transform->SetChild(xform); 331 pre_transform->SetChild(xform);
388 xform->SetChild(post_transform.release()); 332 xform->SetChild(post_transform.release());
389 transform_.reset(pre_transform.release()); 333 transform_.reset(pre_transform.release());
390 } 334 }
391 335
392 InterpolatedTRSTransform::InterpolatedTRSTransform( 336 InterpolatedMatrixTransform::InterpolatedMatrixTransform(
393 const gfx::Transform& start_transform, 337 const gfx::Transform& start_transform,
394 const gfx::Transform& end_transform) 338 const gfx::Transform& end_transform)
395 : InterpolatedTransform() { 339 : InterpolatedTransform() {
396 Init(start_transform, end_transform); 340 Init(start_transform, end_transform);
397 } 341 }
398 342
399 InterpolatedTRSTransform::InterpolatedTRSTransform( 343 InterpolatedMatrixTransform::InterpolatedMatrixTransform(
400 const gfx::Transform& start_transform, 344 const gfx::Transform& start_transform,
401 const gfx::Transform& end_transform, 345 const gfx::Transform& end_transform,
402 float start_time, 346 float start_time,
403 float end_time) 347 float end_time)
404 : InterpolatedTransform() { 348 : InterpolatedTransform() {
405 Init(start_transform, end_transform); 349 Init(start_transform, end_transform);
406 } 350 }
407 351
408 InterpolatedTRSTransform::~InterpolatedTRSTransform() {} 352 InterpolatedMatrixTransform::~InterpolatedMatrixTransform() {}
409 353
410 gfx::Transform 354 gfx::Transform
411 InterpolatedTRSTransform::InterpolateButDoNotCompose(float t) const { 355 InterpolatedMatrixTransform::InterpolateButDoNotCompose(float t) const {
danakj 2012/11/16 19:46:12 Shawn can you double check the mathy bits here? I
shawnsingh 2012/11/16 20:51:25 It seems like the implementation of this function
Ian Vollick 2012/11/16 21:51:24 This class is analogous to WebTransformOperations.
412 if (transform_.get()) { 356 gfx::DecomposedTransform blended;
413 return transform_->Interpolate(t); 357 bool success = gfx::BlendDecomposedTransforms(&blended,
414 } 358 end_decomp_,
415 return gfx::Transform(); 359 start_decomp_,
360 t);
361 DCHECK(success);
362 return gfx::ComposeTransform(blended);
416 } 363 }
417 364
418 void InterpolatedTRSTransform::Init(const gfx::Transform& start_transform, 365 void InterpolatedMatrixTransform::Init(const gfx::Transform& start_transform,
419 const gfx::Transform& end_transform) { 366 const gfx::Transform& end_transform) {
420 gfx::Point start_translation, end_translation; 367 bool success = gfx::DecomposeTransform(&start_decomp_, start_transform);
421 gfx::Point3F start_scale, end_scale; 368 DCHECK(success);
422 float start_degrees, end_degrees; 369 success = gfx::DecomposeTransform(&end_decomp_, end_transform);
423 if (FactorTRS(start_transform, 370 DCHECK(success);
424 &start_translation,
425 &start_degrees,
426 &start_scale) &&
427 FactorTRS(end_transform,
428 &end_translation,
429 &end_degrees,
430 &end_scale)) {
431 scoped_ptr<InterpolatedTranslation> translation(
432 new InterpolatedTranslation(start_translation, end_translation,
433 start_time(), end_time()));
434
435 scoped_ptr<InterpolatedScale> scale(
436 new InterpolatedScale(start_scale, end_scale,
437 start_time(), end_time()));
438
439 scoped_ptr<InterpolatedRotation> rotation(
440 new InterpolatedRotation(start_degrees, end_degrees,
441 start_time(), end_time()));
442
443 rotation->SetChild(translation.release());
444 scale->SetChild(rotation.release());
445 transform_.reset(scale.release());
446 } else {
447 transform_.reset(new InterpolatedConstantTransform(end_transform));
448 }
449 } 371 }
450 372
451 } // namespace ui 373 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698