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

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

Issue 11411270: Improve implementation of gfx::Transform::IsBackFaceVisible (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed reviewer feedback 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 matrix_.getDouble(3, 1) || 263 matrix_.getDouble(3, 1) ||
264 matrix_.getDouble(3, 2) || 264 matrix_.getDouble(3, 2) ||
265 (matrix_.getDouble(3, 3) != 1); 265 (matrix_.getDouble(3, 3) != 1);
266 } 266 }
267 267
268 bool Transform::IsInvertible() const { 268 bool Transform::IsInvertible() const {
269 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant; 269 return std::abs(matrix_.determinant()) > kTooSmallForDeterminant;
270 } 270 }
271 271
272 bool Transform::IsBackFaceVisible() const { 272 bool Transform::IsBackFaceVisible() const {
273 // Compute whether a layer with a forward-facing normal of (0, 0, 1) would 273 // Compute whether a layer with a forward-facing normal of (0, 0, 1, 0)
274 // have its back face visible after applying the transform. 274 // would have its back face visible after applying the transform.
275 // 275 //
276 // This is done by transforming the normal and seeing if the resulting z 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 277 // value is positive or negative. However, note that transforming a normal
278 // actually requires using the inverse-transpose of the original transform. 278 // actually requires using the inverse-transpose of the original transform.
279 //
280 // We can avoid inverting and transposing the matrix since we know we want
281 // to transform only the specific normal vector (0, 0, 1, 0). In this case,
282 // we only need the 3rd row, 3rd column of the inverse-transpose. We can
283 // calculate only the 3rd row 3rd column element of the inverse, skipping
284 // everything else.
285 //
286 // For more information, refer to:
287 // http://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution
288 //
279 289
280 // TODO (shawnsingh) make this perform more efficiently - we do not 290 double determinant = matrix_.determinant();
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 291
286 // Assume the transform does not apply if it's not invertible, so it's 292 // If matrix was not invertible, then just assume back face is not visible.
287 // front face remains visible. 293 if (std::abs(determinant) <= kTooSmallForDeterminant)
288 if (!invertible)
289 return false; 294 return false;
290 295
291 return inverse.getDouble(2, 2) < 0; 296 double cofactor33 =
297 matrix_.getDouble(0,0) * matrix_.getDouble(1,1) * matrix_.getDouble(3,3) +
sky 2012/11/29 23:58:35 It should be 4 space indented and spaces after the
298 matrix_.getDouble(0,1) * matrix_.getDouble(1,3) * matrix_.getDouble(3,0) +
299 matrix_.getDouble(0,3) * matrix_.getDouble(1,0) * matrix_.getDouble(3,1) -
300 matrix_.getDouble(0,0) * matrix_.getDouble(1,3) * matrix_.getDouble(3,1) -
301 matrix_.getDouble(0,1) * matrix_.getDouble(1,0) * matrix_.getDouble(3,3) -
302 matrix_.getDouble(0,3) * matrix_.getDouble(1,1) * matrix_.getDouble(3,0);
303
304 // Technically the transformed z component is cofactor33 / determinant. But
305 // we can avoid the costly division because we only care about the resulting
306 // +/- sign; we can check this equivalently by multiplication.
307 return cofactor33 * determinant < 0;
292 } 308 }
293 309
294 bool Transform::GetInverse(Transform* transform) const { 310 bool Transform::GetInverse(Transform* transform) const {
295 return matrix_.invert(&transform->matrix_); 311 return matrix_.invert(&transform->matrix_);
296 } 312 }
297 313
298 void Transform::Transpose() { 314 void Transform::Transpose() {
299 matrix_.transpose(); 315 matrix_.transpose();
300 } 316 }
301 317
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 SkDoubleToMScalar(0), 420 SkDoubleToMScalar(0),
405 SkDoubleToMScalar(1) 421 SkDoubleToMScalar(1)
406 }; 422 };
407 423
408 xform.mapMScalars(p); 424 xform.mapMScalars(p);
409 425
410 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1])); 426 point.SetPoint(ToRoundedInt(p[0]), ToRoundedInt(p[1]));
411 } 427 }
412 428
413 } // namespace gfx 429 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698