| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |