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 |