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

Side by Side Diff: cc/transform_operation.cc

Issue 11876016: Define cc::TransformOperations and webkit::WebTransformOperationsImpl (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Put TransformOperation into its own header Created 7 years, 11 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/transform_operation.h ('k') | cc/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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <cmath>
6 #include <limits>
7
8 #include "cc/transform_operation.h"
9
10 using WebKit::WebTransformationMatrix;
11
12 namespace {
13 const double kAngleEpsilon = 1e-4;
14 }
15
16 namespace cc {
17
18 bool TransformOperation::IsIdentity() const {
19 return matrix.isIdentity();
20 }
21
22 static bool IsOperationIdentity(const TransformOperation* operation) {
23 return !operation || operation->IsIdentity();
24 }
25
26 static bool ShareSameAxis(const TransformOperation* from,
27 const TransformOperation* to,
28 double& axis_x, double& axis_y, double& axis_z,
29 double& angle_from) {
30 if (IsOperationIdentity(from) && IsOperationIdentity(to))
31 return false;
32
33 if (IsOperationIdentity(from) && !IsOperationIdentity(to)) {
34 axis_x = to->rotate.axis.x;
35 axis_y = to->rotate.axis.y;
36 axis_z = to->rotate.axis.z;
37 angle_from = 0;
38 return true;
39 }
40
41 if (!IsOperationIdentity(from) && IsOperationIdentity(to)) {
42 axis_x = from->rotate.axis.x;
43 axis_y = from->rotate.axis.y;
44 axis_z = from->rotate.axis.z;
45 angle_from = from->rotate.angle;
46 return true;
47 }
48
49 double length_2 = from->rotate.axis.x * from->rotate.axis.x +
50 from->rotate.axis.y * from->rotate.axis.y +
51 from->rotate.axis.z * from->rotate.axis.z;
52 double other_length_2 = to->rotate.axis.x * to->rotate.axis.x +
53 to->rotate.axis.y * to->rotate.axis.y +
54 to->rotate.axis.z * to->rotate.axis.z;
55
56 if (length_2 <= kAngleEpsilon || other_length_2 <= kAngleEpsilon)
57 return false;
58
59 double dot = to->rotate.axis.x * from->rotate.axis.x +
60 to->rotate.axis.y * from->rotate.axis.y +
61 to->rotate.axis.z * from->rotate.axis.z;
62 double error = std::fabs(1.0 - (dot * dot) / (length_2 * other_length_2));
63 bool result = error < kAngleEpsilon;
64 if (result) {
65 axis_x = to->rotate.axis.x;
66 axis_y = to->rotate.axis.y;
67 axis_z = to->rotate.axis.z;
68 // If the axes are pointing in opposite directions, we need to reverse
69 // the angle.
70 angle_from = dot > 0 ? from->rotate.angle : -from->rotate.angle;
71 }
72 return result;
73 }
74
75 static double BlendDoubles(double from, double to, double progress) {
76 return from * (1 - progress) + to * progress;
77 }
78
79 bool TransformOperation::BlendTransformOperations(
80 const TransformOperation* from,
81 const TransformOperation* to,
82 double progress,
83 WebTransformationMatrix& result) {
84 if (IsOperationIdentity(from) && IsOperationIdentity(to))
85 return true;
86
87 TransformOperation::Type interpolation_type =
88 TransformOperation::TransformOperationIdentity;
89 if (IsOperationIdentity(to))
90 interpolation_type = from->type;
91 else
92 interpolation_type = to->type;
93
94 switch (interpolation_type) {
95 case TransformOperation::TransformOperationTranslate: {
96 double from_x = IsOperationIdentity(from) ? 0 : from->translate.x;
97 double from_y = IsOperationIdentity(from) ? 0 : from->translate.y;
98 double from_z = IsOperationIdentity(from) ? 0 : from->translate.z;
99 double to_x = IsOperationIdentity(to) ? 0 : to->translate.x;
100 double to_y = IsOperationIdentity(to) ? 0 : to->translate.y;
101 double to_z = IsOperationIdentity(to) ? 0 : to->translate.z;
102 result.translate3d(BlendDoubles(from_x, to_x, progress),
103 BlendDoubles(from_y, to_y, progress),
104 BlendDoubles(from_z, to_z, progress));
105 break;
106 }
107 case TransformOperation::TransformOperationRotate: {
108 double axis_x = 0;
109 double axis_y = 0;
110 double axis_z = 1;
111 double from_angle = 0;
112 double to_angle = IsOperationIdentity(to) ? 0 : to->rotate.angle;
113 if (ShareSameAxis(from, to, axis_x, axis_y, axis_z, from_angle))
114 result.rotate3d(axis_x, axis_y, axis_z,
115 BlendDoubles(from_angle, to_angle, progress));
116 else {
117 WebTransformationMatrix to_matrix;
118 if (!IsOperationIdentity(to))
119 to_matrix = to->matrix;
120 WebTransformationMatrix from_matrix;
121 if (!IsOperationIdentity(from))
122 from_matrix = from->matrix;
123 result = to_matrix;
124 if (!result.blend(from_matrix, progress))
125 return false;
126 }
127 break;
128 }
129 case TransformOperation::TransformOperationScale: {
130 double from_x = IsOperationIdentity(from) ? 1 : from->scale.x;
131 double from_y = IsOperationIdentity(from) ? 1 : from->scale.y;
132 double from_z = IsOperationIdentity(from) ? 1 : from->scale.z;
133 double to_x = IsOperationIdentity(to) ? 1 : to->scale.x;
134 double to_y = IsOperationIdentity(to) ? 1 : to->scale.y;
135 double to_z = IsOperationIdentity(to) ? 1 : to->scale.z;
136 result.scale3d(BlendDoubles(from_x, to_x, progress),
137 BlendDoubles(from_y, to_y, progress),
138 BlendDoubles(from_z, to_z, progress));
139 break;
140 }
141 case TransformOperation::TransformOperationSkew: {
142 double from_x = IsOperationIdentity(from) ? 0 : from->skew.x;
143 double from_y = IsOperationIdentity(from) ? 0 : from->skew.y;
144 double to_x = IsOperationIdentity(to) ? 0 : to->skew.x;
145 double to_y = IsOperationIdentity(to) ? 0 : to->skew.y;
146 result.skewX(BlendDoubles(from_x, to_x, progress));
147 result.skewY(BlendDoubles(from_y, to_y, progress));
148 break;
149 }
150 case TransformOperation::TransformOperationPerspective: {
151 double from_perspective_depth = IsOperationIdentity(from) ?
152 std::numeric_limits<double>::max() : from->perspective_depth;
153 double to_perspective_depth = IsOperationIdentity(to) ?
154 std::numeric_limits<double>::max() : to->perspective_depth;
155 result.applyPerspective(
156 BlendDoubles(from_perspective_depth, to_perspective_depth, progress));
157 break;
158 }
159 case TransformOperation::TransformOperationMatrix: {
160 WebTransformationMatrix to_matrix;
161 if (!IsOperationIdentity(to))
162 to_matrix = to->matrix;
163 WebTransformationMatrix from_matrix;
164 if (!IsOperationIdentity(from))
165 from_matrix = from->matrix;
166 result = to_matrix;
167 if (!result.blend(from_matrix, progress))
168 return false;
169 break;
170 }
171 case TransformOperation::TransformOperationIdentity:
172 // Do nothing.
173 break;
174 }
175
176 return true;
177 }
178
179 } // namespace cc
OLDNEW
« no previous file with comments | « cc/transform_operation.h ('k') | cc/transform_operations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698