Chromium Code Reviews| 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 #include "ui/gfx/transform_util.h" | 5 #include "ui/gfx/transform_util.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 | 100 |
| 101 return true; | 101 return true; |
| 102 } | 102 } |
| 103 | 103 |
| 104 // Returns false if the matrix cannot be normalized. | 104 // Returns false if the matrix cannot be normalized. |
| 105 bool Normalize(SkMatrix44& m) { | 105 bool Normalize(SkMatrix44& m) { |
| 106 if (m.get(3, 3) == 0.0) | 106 if (m.get(3, 3) == 0.0) |
| 107 // Cannot normalize. | 107 // Cannot normalize. |
| 108 return false; | 108 return false; |
| 109 | 109 |
| 110 SkMScalar scale = 1.0 / m.get(3, 3); | 110 SkMScalar scale = SK_MScalar1 / m.get(3, 3); |
| 111 for (int i = 0; i < 4; i++) | 111 for (int i = 0; i < 4; i++) |
| 112 for (int j = 0; j < 4; j++) | 112 for (int j = 0; j < 4; j++) |
| 113 m.set(i, j, m.get(i, j) * scale); | 113 m.set(i, j, m.get(i, j) * scale); |
| 114 | 114 |
| 115 return true; | 115 return true; |
| 116 } | 116 } |
| 117 | 117 |
| 118 SkMatrix44 BuildPerspectiveMatrix(const DecomposedTransform& decomp) { | 118 SkMatrix44 BuildPerspectiveMatrix(const DecomposedTransform& decomp) { |
| 119 SkMatrix44 matrix(SkMatrix44::kIdentity_Constructor); | 119 SkMatrix44 matrix(SkMatrix44::kIdentity_Constructor); |
| 120 | 120 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 133 } | 133 } |
| 134 | 134 |
| 135 SkMatrix44 BuildSnappedTranslationMatrix(DecomposedTransform decomp) { | 135 SkMatrix44 BuildSnappedTranslationMatrix(DecomposedTransform decomp) { |
| 136 decomp.translate[0] = Round(decomp.translate[0]); | 136 decomp.translate[0] = Round(decomp.translate[0]); |
| 137 decomp.translate[1] = Round(decomp.translate[1]); | 137 decomp.translate[1] = Round(decomp.translate[1]); |
| 138 decomp.translate[2] = Round(decomp.translate[2]); | 138 decomp.translate[2] = Round(decomp.translate[2]); |
| 139 return BuildTranslationMatrix(decomp); | 139 return BuildTranslationMatrix(decomp); |
| 140 } | 140 } |
| 141 | 141 |
| 142 SkMatrix44 BuildRotationMatrix(const DecomposedTransform& decomp) { | 142 SkMatrix44 BuildRotationMatrix(const DecomposedTransform& decomp) { |
| 143 double x = decomp.quaternion[0]; | 143 SkMScalar x = decomp.quaternion[0]; |
| 144 double y = decomp.quaternion[1]; | 144 SkMScalar y = decomp.quaternion[1]; |
| 145 double z = decomp.quaternion[2]; | 145 SkMScalar z = decomp.quaternion[2]; |
| 146 double w = decomp.quaternion[3]; | 146 SkMScalar w = decomp.quaternion[3]; |
| 147 SkMScalar two = SkFloatToMScalar(2.0f); | |
| 147 | 148 |
| 148 SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor); | 149 SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor); |
| 149 | 150 |
| 150 // Implicitly calls matrix.setIdentity() | 151 // Implicitly calls matrix.setIdentity() |
| 151 matrix.set3x3(1.0 - 2.0 * (y * y + z * z), | 152 matrix.set3x3(SK_MScalar1 - two * (y * y + z * z), |
|
danakj
2014/10/18 18:40:06
i think you should downcast to float after the com
Peter Kasting
2014/10/20 23:38:56
Done. It might be nice to have a test that would
danakj
2014/10/23 15:35:44
I agree, tho I'm not sure either :) +awoloszyn FYI
| |
| 152 2.0 * (x * y + z * w), | 153 two * (x * y + z * w), |
| 153 2.0 * (x * z - y * w), | 154 two * (x * z - y * w), |
| 154 2.0 * (x * y - z * w), | 155 two * (x * y - z * w), |
| 155 1.0 - 2.0 * (x * x + z * z), | 156 SK_MScalar1 - two * (x * x + z * z), |
| 156 2.0 * (y * z + x * w), | 157 two * (y * z + x * w), |
| 157 2.0 * (x * z + y * w), | 158 two * (x * z + y * w), |
| 158 2.0 * (y * z - x * w), | 159 two * (y * z - x * w), |
| 159 1.0 - 2.0 * (x * x + y * y)); | 160 SK_MScalar1 - two * (x * x + y * y)); |
| 160 return matrix; | 161 return matrix; |
| 161 } | 162 } |
| 162 | 163 |
| 163 SkMatrix44 BuildSnappedRotationMatrix(const DecomposedTransform& decomp) { | 164 SkMatrix44 BuildSnappedRotationMatrix(const DecomposedTransform& decomp) { |
| 164 // Create snapped rotation. | 165 // Create snapped rotation. |
| 165 SkMatrix44 rotation_matrix = BuildRotationMatrix(decomp); | 166 SkMatrix44 rotation_matrix = BuildRotationMatrix(decomp); |
| 166 for (int i = 0; i < 3; ++i) { | 167 for (int i = 0; i < 3; ++i) { |
| 167 for (int j = 0; j < 3; ++j) { | 168 for (int j = 0; j < 3; ++j) { |
| 168 SkMScalar value = rotation_matrix.get(i, j); | 169 SkMScalar value = rotation_matrix.get(i, j); |
| 169 // Snap values to -1, 0 or 1. | 170 // Snap values to -1, 0 or 1. |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 decomp->translate[i] = matrix.get(i, 3); | 367 decomp->translate[i] = matrix.get(i, 3); |
| 367 | 368 |
| 368 SkMScalar row[3][3]; | 369 SkMScalar row[3][3]; |
| 369 for (int i = 0; i < 3; i++) | 370 for (int i = 0; i < 3; i++) |
| 370 for (int j = 0; j < 3; ++j) | 371 for (int j = 0; j < 3; ++j) |
| 371 row[i][j] = matrix.get(j, i); | 372 row[i][j] = matrix.get(j, i); |
| 372 | 373 |
| 373 // Compute X scale factor and normalize first row. | 374 // Compute X scale factor and normalize first row. |
| 374 decomp->scale[0] = Length3(row[0]); | 375 decomp->scale[0] = Length3(row[0]); |
| 375 if (decomp->scale[0] != 0.0) | 376 if (decomp->scale[0] != 0.0) |
| 376 Scale3(row[0], 1.0 / decomp->scale[0]); | 377 Scale3(row[0], SK_MScalar1 / decomp->scale[0]); |
| 377 | 378 |
| 378 // Compute XY shear factor and make 2nd row orthogonal to 1st. | 379 // Compute XY shear factor and make 2nd row orthogonal to 1st. |
| 379 decomp->skew[0] = Dot<3>(row[0], row[1]); | 380 decomp->skew[0] = Dot<3>(row[0], row[1]); |
| 380 Combine<3>(row[1], row[1], row[0], 1.0, -decomp->skew[0]); | 381 Combine<3>(row[1], row[1], row[0], 1.0, -decomp->skew[0]); |
| 381 | 382 |
| 382 // Now, compute Y scale and normalize 2nd row. | 383 // Now, compute Y scale and normalize 2nd row. |
| 383 decomp->scale[1] = Length3(row[1]); | 384 decomp->scale[1] = Length3(row[1]); |
| 384 if (decomp->scale[1] != 0.0) | 385 if (decomp->scale[1] != 0.0) |
| 385 Scale3(row[1], 1.0 / decomp->scale[1]); | 386 Scale3(row[1], SK_MScalar1 / decomp->scale[1]); |
| 386 | 387 |
| 387 decomp->skew[0] /= decomp->scale[1]; | 388 decomp->skew[0] /= decomp->scale[1]; |
| 388 | 389 |
| 389 // Compute XZ and YZ shears, orthogonalize 3rd row | 390 // Compute XZ and YZ shears, orthogonalize 3rd row |
| 390 decomp->skew[1] = Dot<3>(row[0], row[2]); | 391 decomp->skew[1] = Dot<3>(row[0], row[2]); |
| 391 Combine<3>(row[2], row[2], row[0], 1.0, -decomp->skew[1]); | 392 Combine<3>(row[2], row[2], row[0], 1.0, -decomp->skew[1]); |
| 392 decomp->skew[2] = Dot<3>(row[1], row[2]); | 393 decomp->skew[2] = Dot<3>(row[1], row[2]); |
| 393 Combine<3>(row[2], row[2], row[1], 1.0, -decomp->skew[2]); | 394 Combine<3>(row[2], row[2], row[1], 1.0, -decomp->skew[2]); |
| 394 | 395 |
| 395 // Next, get Z scale and normalize 3rd row. | 396 // Next, get Z scale and normalize 3rd row. |
| 396 decomp->scale[2] = Length3(row[2]); | 397 decomp->scale[2] = Length3(row[2]); |
| 397 if (decomp->scale[2] != 0.0) | 398 if (decomp->scale[2] != 0.0) |
| 398 Scale3(row[2], 1.0 / decomp->scale[2]); | 399 Scale3(row[2], SK_MScalar1 / decomp->scale[2]); |
| 399 | 400 |
| 400 decomp->skew[1] /= decomp->scale[2]; | 401 decomp->skew[1] /= decomp->scale[2]; |
| 401 decomp->skew[2] /= decomp->scale[2]; | 402 decomp->skew[2] /= decomp->scale[2]; |
| 402 | 403 |
| 403 // At this point, the matrix (in rows) is orthonormal. | 404 // At this point, the matrix (in rows) is orthonormal. |
| 404 // Check for a coordinate system flip. If the determinant | 405 // Check for a coordinate system flip. If the determinant |
| 405 // is -1, then negate the matrix and the scaling factors. | 406 // is -1, then negate the matrix and the scaling factors. |
| 406 SkMScalar pdum3[3]; | 407 SkMScalar pdum3[3]; |
| 407 Cross3(pdum3, row[1], row[2]); | 408 Cross3(pdum3, row[1], row[2]); |
| 408 if (Dot<3>(row[0], pdum3) < 0) { | 409 if (Dot<3>(row[0], pdum3) < 0) { |
| 409 for (int i = 0; i < 3; i++) { | 410 for (int i = 0; i < 3; i++) { |
| 410 decomp->scale[i] *= -1.0; | 411 decomp->scale[i] *= -1.0; |
| 411 for (int j = 0; j < 3; ++j) | 412 for (int j = 0; j < 3; ++j) |
| 412 row[i][j] *= -1.0; | 413 row[i][j] *= -1.0; |
| 413 } | 414 } |
| 414 } | 415 } |
| 415 | 416 |
| 416 decomp->quaternion[0] = | 417 SkMScalar half = SkFloatToMScalar(0.5f); |
| 417 0.5 * std::sqrt(std::max(1.0 + row[0][0] - row[1][1] - row[2][2], 0.0)); | 418 double row00 = SkMScalarToDouble(row[0][0]); |
| 418 decomp->quaternion[1] = | 419 double row11 = SkMScalarToDouble(row[1][1]); |
| 419 0.5 * std::sqrt(std::max(1.0 - row[0][0] + row[1][1] - row[2][2], 0.0)); | 420 double row22 = SkMScalarToDouble(row[2][2]); |
| 420 decomp->quaternion[2] = | 421 decomp->quaternion[0] = half * |
| 421 0.5 * std::sqrt(std::max(1.0 - row[0][0] - row[1][1] + row[2][2], 0.0)); | 422 std::sqrt(SkDoubleToMScalar(std::max(1.0 + row00 - row11 - row22, 0.0))); |
|
danakj
2014/10/18 18:40:06
do the double to mscalar after taking the sqrt
Peter Kasting
2014/10/20 23:38:56
Done.
| |
| 422 decomp->quaternion[3] = | 423 decomp->quaternion[1] = half * |
| 423 0.5 * std::sqrt(std::max(1.0 + row[0][0] + row[1][1] + row[2][2], 0.0)); | 424 std::sqrt(SkDoubleToMScalar(std::max(1.0 - row00 + row11 - row22, 0.0))); |
| 425 decomp->quaternion[2] = half * | |
| 426 std::sqrt(SkDoubleToMScalar(std::max(1.0 - row00 - row11 + row22, 0.0))); | |
| 427 decomp->quaternion[3] = half * | |
| 428 std::sqrt(SkDoubleToMScalar(std::max(1.0 + row00 + row11 + row22, 0.0))); | |
| 424 | 429 |
| 425 if (row[2][1] > row[1][2]) | 430 if (row[2][1] > row[1][2]) |
| 426 decomp->quaternion[0] = -decomp->quaternion[0]; | 431 decomp->quaternion[0] = -decomp->quaternion[0]; |
| 427 if (row[0][2] > row[2][0]) | 432 if (row[0][2] > row[2][0]) |
| 428 decomp->quaternion[1] = -decomp->quaternion[1]; | 433 decomp->quaternion[1] = -decomp->quaternion[1]; |
| 429 if (row[1][0] > row[0][1]) | 434 if (row[1][0] > row[0][1]) |
| 430 decomp->quaternion[2] = -decomp->quaternion[2]; | 435 decomp->quaternion[2] = -decomp->quaternion[2]; |
| 431 | 436 |
| 432 return true; | 437 return true; |
| 433 } | 438 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 perspective[1], | 497 perspective[1], |
| 493 perspective[2], | 498 perspective[2], |
| 494 perspective[3], | 499 perspective[3], |
| 495 quaternion[0], | 500 quaternion[0], |
| 496 quaternion[1], | 501 quaternion[1], |
| 497 quaternion[2], | 502 quaternion[2], |
| 498 quaternion[3]); | 503 quaternion[3]); |
| 499 } | 504 } |
| 500 | 505 |
| 501 } // namespace ui | 506 } // namespace ui |
| OLD | NEW |