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

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

Issue 11418197: Move temporary MathUtil wrappers to permanent home in gfx::Transform (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: patch for landing Created 8 years 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 | « ui/gfx/transform.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // MSVC++ requires this to be set before any other includes to get M_PI. 5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES 6 #define _USE_MATH_DEFINES
7 7
8 #include "ui/gfx/transform.h" 8 #include "ui/gfx/transform.h"
9 9
10 #include <cmath> 10 #include <cmath>
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 } 42 }
43 43
44 bool Transform::operator!=(const Transform& rhs) const { 44 bool Transform::operator!=(const Transform& rhs) const {
45 return !(*this == rhs); 45 return !(*this == rhs);
46 } 46 }
47 47
48 void Transform::MakeIdentity() { 48 void Transform::MakeIdentity() {
49 matrix_.setIdentity(); 49 matrix_.setIdentity();
50 } 50 }
51 51
52 void Transform::Rotate(double degree) { 52 void Transform::RotateAboutXAxis(double degrees) {
53 double radians = degrees * M_PI / 180;
54 double cosTheta = std::cos(radians);
55 double sinTheta = std::sin(radians);
53 if (matrix_.isIdentity()) { 56 if (matrix_.isIdentity()) {
54 matrix_.setRotateDegreesAbout(SkDoubleToMScalar(0), 57 matrix_.set3x3(1, 0, 0,
55 SkDoubleToMScalar(0), 58 0, cosTheta, sinTheta,
56 SkDoubleToMScalar(1), 59 0, -sinTheta, cosTheta);
57 SkDoubleToMScalar(degree));
58 } else { 60 } else {
59 SkMatrix44 rot; 61 SkMatrix44 rot;
60 rot.setRotateDegreesAbout(SkDoubleToMScalar(0), 62 rot.set3x3(1, 0, 0,
61 SkDoubleToMScalar(0), 63 0, cosTheta, sinTheta,
62 SkDoubleToMScalar(1), 64 0, -sinTheta, cosTheta);
63 SkDoubleToMScalar(degree));
64 matrix_.preConcat(rot); 65 matrix_.preConcat(rot);
65 } 66 }
66 } 67 }
67 68
68 void Transform::RotateAbout(const Vector3dF& axis, double degree) { 69 void Transform::RotateAboutYAxis(double degrees) {
70 double radians = degrees * M_PI / 180;
71 double cosTheta = std::cos(radians);
72 double sinTheta = std::sin(radians);
73 if (matrix_.isIdentity()) {
74 // Note carefully the placement of the -sinTheta for rotation about
75 // y-axis is different than rotation about x-axis or z-axis.
76 matrix_.set3x3(cosTheta, 0, -sinTheta,
77 0, 1, 0,
78 sinTheta, 0, cosTheta);
79 } else {
80 SkMatrix44 rot;
81 rot.set3x3(cosTheta, 0, -sinTheta,
82 0, 1, 0,
83 sinTheta, 0, cosTheta);
84 matrix_.preConcat(rot);
85 }
86 }
87
88 void Transform::RotateAboutZAxis(double degrees) {
89 double radians = degrees * M_PI / 180;
90 double cosTheta = std::cos(radians);
91 double sinTheta = std::sin(radians);
92 if (matrix_.isIdentity()) {
93 matrix_.set3x3(cosTheta, sinTheta, 0,
94 -sinTheta, cosTheta, 0,
95 0, 0, 1);
96 } else {
97 SkMatrix44 rot;
98 rot.set3x3(cosTheta, sinTheta, 0,
99 -sinTheta, cosTheta, 0,
100 0, 0, 1);
101 matrix_.preConcat(rot);
102 }
103 }
104
105 void Transform::RotateAbout(const Vector3dF& axis, double degrees) {
69 if (matrix_.isIdentity()) { 106 if (matrix_.isIdentity()) {
70 matrix_.setRotateDegreesAbout(SkDoubleToMScalar(axis.x()), 107 matrix_.setRotateDegreesAbout(SkDoubleToMScalar(axis.x()),
71 SkDoubleToMScalar(axis.y()), 108 SkDoubleToMScalar(axis.y()),
72 SkDoubleToMScalar(axis.z()), 109 SkDoubleToMScalar(axis.z()),
73 SkDoubleToMScalar(degree)); 110 SkDoubleToMScalar(degrees));
74 } else { 111 } else {
75 SkMatrix44 rot; 112 SkMatrix44 rot;
76 rot.setRotateDegreesAbout(SkDoubleToMScalar(axis.x()), 113 rot.setRotateDegreesAbout(SkDoubleToMScalar(axis.x()),
77 SkDoubleToMScalar(axis.y()), 114 SkDoubleToMScalar(axis.y()),
78 SkDoubleToMScalar(axis.z()), 115 SkDoubleToMScalar(axis.z()),
79 SkDoubleToMScalar(degree)); 116 SkDoubleToMScalar(degrees));
80 matrix_.preConcat(rot); 117 matrix_.preConcat(rot);
81 } 118 }
82 } 119 }
83 120
84 void Transform::Scale(double x, double y) { 121 void Transform::Scale(double x, double y) {
85 if (matrix_.isIdentity()) { 122 if (matrix_.isIdentity()) {
86 matrix_.setScale(SkDoubleToMScalar(x), 123 matrix_.setScale(SkDoubleToMScalar(x),
87 SkDoubleToMScalar(y), 124 SkDoubleToMScalar(y),
88 SkDoubleToMScalar(1)); 125 SkDoubleToMScalar(1));
89 } else { 126 } else {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 void Transform::ConcatTransform(const Transform& transform) { 215 void Transform::ConcatTransform(const Transform& transform) {
179 if (!transform.matrix_.isIdentity()) { 216 if (!transform.matrix_.isIdentity()) {
180 matrix_.postConcat(transform.matrix_); 217 matrix_.postConcat(transform.matrix_);
181 } 218 }
182 } 219 }
183 220
184 bool Transform::IsIdentity() const { 221 bool Transform::IsIdentity() const {
185 return matrix_.isIdentity(); 222 return matrix_.isIdentity();
186 } 223 }
187 224
225 bool Transform::IsIdentityOrTranslation() const {
226 bool has_no_perspective = !matrix_.getDouble(3, 0) &&
227 !matrix_.getDouble(3, 1) &&
228 !matrix_.getDouble(3, 2) &&
229 (matrix_.getDouble(3, 3) == 1);
230
231 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) &&
232 !matrix_.getDouble(0, 2) &&
233 !matrix_.getDouble(1, 0) &&
234 !matrix_.getDouble(1, 2) &&
235 !matrix_.getDouble(2, 0) &&
236 !matrix_.getDouble(2, 1);
237
238 bool has_no_scale = matrix_.getDouble(0, 0) == 1 &&
239 matrix_.getDouble(1, 1) == 1 &&
240 matrix_.getDouble(2, 2) == 1;
241
242 return has_no_perspective && has_no_rotation_or_skew && has_no_scale;
243 }
244
245 bool Transform::IsScaleOrTranslation() const {
246 bool has_no_perspective = !matrix_.getDouble(3, 0) &&
247 !matrix_.getDouble(3, 1) &&
248 !matrix_.getDouble(3, 2) &&
249 (matrix_.getDouble(3, 3) == 1);
250
251 bool has_no_rotation_or_skew = !matrix_.getDouble(0, 1) &&
252 !matrix_.getDouble(0, 2) &&
253 !matrix_.getDouble(1, 0) &&
254 !matrix_.getDouble(1, 2) &&
255 !matrix_.getDouble(2, 0) &&
256 !matrix_.getDouble(2, 1);
257
258 return has_no_perspective && has_no_rotation_or_skew;
259 }
260
261 bool Transform::HasPerspective() const {
262 return matrix_.getDouble(3, 0) ||
263 matrix_.getDouble(3, 1) ||
264 matrix_.getDouble(3, 2) ||
265 (matrix_.getDouble(3, 3) != 1);
266 }
267
188 bool Transform::IsInvertible() const { 268 bool Transform::IsInvertible() const {
189 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant; 269 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant;
190 } 270 }
191 271
272 bool Transform::IsBackFaceVisible() const {
273 // Compute whether a layer with a forward-facing normal of (0, 0, 1) would
274 // have its back face visible after applying the transform.
275 //
276 // This is done by transforming the normal and seeing if the resulting z
277 // value is positive or negative. However, note that transforming a normal
278 // actually requires using the inverse-transpose of the original transform.
279
280 // TODO (shawnsingh) make this perform more efficiently - we do not
281 // actually need to instantiate/invert/transpose any matrices, exploiting the
282 // fact that we only need to transform (0, 0, 1, 0).
283 SkMatrix44 inverse;
284 bool invertible = matrix_.invert(&inverse);
285
286 // Assume the transform does not apply if it's not invertible, so it's
287 // front face remains visible.
288 if (!invertible)
289 return false;
290
291 return inverse.getDouble(2, 2) < 0;
292 }
293
192 bool Transform::GetInverse(Transform* transform) const { 294 bool Transform::GetInverse(Transform* transform) const {
193 return matrix_.invert(&transform->matrix_); 295 return matrix_.invert(&transform->matrix_);
194 } 296 }
195 297
196 void Transform::Transpose() { 298 void Transform::Transpose() {
197 matrix_.transpose(); 299 matrix_.transpose();
198 } 300 }
199 301
200 void Transform::TransformPoint(Point& point) const { 302 void Transform::TransformPoint(Point& point) const {
201 TransformPointInternal(matrix_, point); 303 TransformPointInternal(matrix_, point);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 SkDoubleToMScalar(0), 404 SkDoubleToMScalar(0),
303 SkDoubleToMScalar(1) 405 SkDoubleToMScalar(1)
304 }; 406 };
305 407
306 xform.mapMScalars(p); 408 xform.mapMScalars(p);
307 409
308 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1])); 410 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1]));
309 } 411 }
310 412
311 } // namespace gfx 413 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/transform.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698