OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkMatrix44.h" | 8 #include "SkMatrix44.h" |
9 | 9 |
10 static inline bool eq4(const SkMScalar* SK_RESTRICT a, | 10 static inline bool eq4(const SkMScalar* SK_RESTRICT a, |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 173 } |
174 | 174 |
175 /////////////////////////////////////////////////////////////////////////////// | 175 /////////////////////////////////////////////////////////////////////////////// |
176 | 176 |
177 const SkMatrix44& SkMatrix44::I() { | 177 const SkMatrix44& SkMatrix44::I() { |
178 static const SkMatrix44 gIdentity44(kIdentity_Constructor); | 178 static const SkMatrix44 gIdentity44(kIdentity_Constructor); |
179 return gIdentity44; | 179 return gIdentity44; |
180 } | 180 } |
181 | 181 |
182 void SkMatrix44::setIdentity() { | 182 void SkMatrix44::setIdentity() { |
183 sk_bzero(fMat, sizeof(fMat)); | 183 fMat[0][0] = 1; |
184 fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = 1; | 184 fMat[0][1] = 0; |
| 185 fMat[0][2] = 0; |
| 186 fMat[0][3] = 0; |
| 187 fMat[1][0] = 0; |
| 188 fMat[1][1] = 1; |
| 189 fMat[1][2] = 0; |
| 190 fMat[1][3] = 0; |
| 191 fMat[2][0] = 0; |
| 192 fMat[2][1] = 0; |
| 193 fMat[2][2] = 1; |
| 194 fMat[2][3] = 0; |
| 195 fMat[3][0] = 0; |
| 196 fMat[3][1] = 0; |
| 197 fMat[3][2] = 0; |
| 198 fMat[3][3] = 1; |
185 this->setTypeMask(kIdentity_Mask); | 199 this->setTypeMask(kIdentity_Mask); |
186 } | 200 } |
187 | 201 |
188 void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, | 202 void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, |
189 SkMScalar m10, SkMScalar m11, SkMScalar m12, | 203 SkMScalar m10, SkMScalar m11, SkMScalar m12, |
190 SkMScalar m20, SkMScalar m21, SkMScalar m22) { | 204 SkMScalar m20, SkMScalar m21, SkMScalar m22) { |
191 fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0; | 205 fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0; |
192 fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0; | 206 fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0; |
193 fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0; | 207 fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0; |
194 fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1; | 208 fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 double b09 = a21 * a32 - a22 * a31; | 459 double b09 = a21 * a32 - a22 * a31; |
446 double b10 = a21 * a33 - a23 * a31; | 460 double b10 = a21 * a33 - a23 * a31; |
447 double b11 = a22 * a33 - a23 * a32; | 461 double b11 = a22 * a33 - a23 * a32; |
448 | 462 |
449 // Calculate the determinant | 463 // Calculate the determinant |
450 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06
; | 464 return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06
; |
451 } | 465 } |
452 | 466 |
453 /////////////////////////////////////////////////////////////////////////////// | 467 /////////////////////////////////////////////////////////////////////////////// |
454 | 468 |
455 // just picked a small value. not sure how to pick the "right" one | |
456 #define TOO_SMALL_FOR_DETERMINANT (1.e-8) | |
457 | |
458 static inline double dabs(double x) { | 469 static inline double dabs(double x) { |
459 if (x < 0) { | 470 if (x < 0) { |
460 x = -x; | 471 x = -x; |
461 } | 472 } |
462 return x; | 473 return x; |
463 } | 474 } |
464 | 475 |
465 bool SkMatrix44::invert(SkMatrix44* inverse) const { | 476 bool SkMatrix44::invert(SkMatrix44* inverse) const { |
466 if (this->isIdentity()) { | 477 if (this->isIdentity()) { |
467 if (inverse) { | 478 if (inverse) { |
468 *inverse = *this; | 479 inverse->setIdentity(); |
469 return true; | 480 return true; |
470 } | 481 } |
471 } | 482 } |
472 if (this->isTranslate()) { | 483 if (this->isTranslate()) { |
473 if (inverse) { | 484 if (inverse) { |
474 inverse->setTranslate(-fMat[3][0], -fMat[3][1], -fMat[3][2]); | 485 inverse->setTranslate(-fMat[3][0], -fMat[3][1], -fMat[3][2]); |
475 } | 486 } |
476 return true; | 487 return true; |
477 } | 488 } |
478 if (this->isScaleTranslate()) { | 489 if (this->isScaleTranslate()) { |
479 if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) { | 490 if (0 == fMat[0][0] * fMat[1][1] * fMat[2][2]) { |
480 return false; | 491 return false; |
481 } | 492 } |
482 if (inverse) { | |
483 sk_bzero(inverse->fMat, sizeof(inverse->fMat)); | |
484 | 493 |
485 double invXScale = 1 / fMat[0][0]; | 494 double a00 = fMat[0][0]; |
486 double invYScale = 1 / fMat[1][1]; | 495 double a11 = fMat[1][1]; |
487 double invZScale = 1 / fMat[2][2]; | 496 double a22 = fMat[2][2]; |
| 497 double a30 = fMat[3][0]; |
| 498 double a31 = fMat[3][1]; |
| 499 double a32 = fMat[3][2]; |
488 | 500 |
489 inverse->fMat[3][0] = -fMat[3][0] * invXScale; | 501 double b00 = a00 * a11; |
490 inverse->fMat[3][1] = -fMat[3][1] * invYScale; | 502 double b07 = -a22 * a30; |
491 inverse->fMat[3][2] = -fMat[3][2] * invZScale; | 503 double b09 = -a22 * a31; |
| 504 double b11 = a22; |
492 | 505 |
493 inverse->fMat[0][0] = invXScale; | 506 // Calculate the determinant |
494 inverse->fMat[1][1] = invYScale; | 507 double det = b00 * b11; |
495 inverse->fMat[2][2] = invZScale; | |
496 inverse->fMat[3][3] = 1; | |
497 | 508 |
498 inverse->setTypeMask(this->getType()); | 509 double invdet = 1.0 / det; |
| 510 // If det is zero, we want to return false. However, we also want to ret
urn false |
| 511 // if 1/det overflows to infinity (i.e. det is denormalized). Both of th
ese are |
| 512 // handled by checking that 1/det is finite. |
| 513 if (!sk_float_isfinite(invdet)) { |
| 514 return false; |
499 } | 515 } |
| 516 if (NULL == inverse) { |
| 517 return true; |
| 518 } |
| 519 |
| 520 b00 *= invdet; |
| 521 b07 *= invdet; |
| 522 b09 *= invdet; |
| 523 b11 *= invdet; |
| 524 |
| 525 inverse->fMat[0][0] = SkDoubleToMScalar(a11 * b11); |
| 526 inverse->fMat[0][1] = 0; |
| 527 inverse->fMat[0][2] = 0; |
| 528 inverse->fMat[0][3] = 0; |
| 529 inverse->fMat[1][0] = 0; |
| 530 inverse->fMat[1][1] = SkDoubleToMScalar(a00 * b11); |
| 531 inverse->fMat[1][2] = 0; |
| 532 inverse->fMat[1][3] = 0; |
| 533 inverse->fMat[2][0] = 0; |
| 534 inverse->fMat[2][1] = 0; |
| 535 inverse->fMat[2][2] = SkDoubleToMScalar(b00); |
| 536 inverse->fMat[2][3] = 0; |
| 537 inverse->fMat[3][0] = SkDoubleToMScalar(a11 * b07); |
| 538 inverse->fMat[3][1] = SkDoubleToMScalar(a00 * b09); |
| 539 inverse->fMat[3][2] = SkDoubleToMScalar(-a32 * b00); |
| 540 inverse->fMat[3][3] = 1; |
| 541 |
| 542 inverse->setTypeMask(this->getType()); |
500 return true; | 543 return true; |
501 } | 544 } |
502 | 545 |
503 double a00 = fMat[0][0]; | 546 double a00 = fMat[0][0]; |
504 double a01 = fMat[0][1]; | 547 double a01 = fMat[0][1]; |
505 double a02 = fMat[0][2]; | 548 double a02 = fMat[0][2]; |
506 double a03 = fMat[0][3]; | 549 double a03 = fMat[0][3]; |
507 double a10 = fMat[1][0]; | 550 double a10 = fMat[1][0]; |
508 double a11 = fMat[1][1]; | 551 double a11 = fMat[1][1]; |
509 double a12 = fMat[1][2]; | 552 double a12 = fMat[1][2]; |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
876 fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3], | 919 fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3], |
877 fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]); | 920 fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]); |
878 #endif | 921 #endif |
879 } | 922 } |
880 | 923 |
881 /////////////////////////////////////////////////////////////////////////////// | 924 /////////////////////////////////////////////////////////////////////////////// |
882 | 925 |
883 // TODO: make this support src' perspective elements | 926 // TODO: make this support src' perspective elements |
884 // | 927 // |
885 static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) { | 928 static void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) { |
886 sk_bzero(dst, 16 * sizeof(SkMScalar)); | |
887 dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]); | 929 dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]); |
888 dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]); | 930 dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]); |
| 931 dst[2][0] = 0; |
889 dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]); | 932 dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]); |
890 dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]); | 933 dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]); |
891 dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]); | 934 dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]); |
| 935 dst[2][1] = 0; |
892 dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]); | 936 dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]); |
893 dst[2][2] = dst[3][3] = 1; | 937 dst[0][2] = 0; |
| 938 dst[1][2] = 0; |
| 939 dst[2][2] = 1; |
| 940 dst[3][2] = 0; |
| 941 dst[0][3] = 0; |
| 942 dst[1][3] = 0; |
| 943 dst[2][3] = 0; |
| 944 dst[3][3] = 1; |
894 } | 945 } |
895 | 946 |
896 SkMatrix44::SkMatrix44(const SkMatrix& src) { | 947 SkMatrix44::SkMatrix44(const SkMatrix& src) { |
897 initFromMatrix(fMat, src); | 948 initFromMatrix(fMat, src); |
898 } | 949 } |
899 | 950 |
900 SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) { | 951 SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) { |
901 initFromMatrix(fMat, src); | 952 initFromMatrix(fMat, src); |
902 | 953 |
903 if (src.isIdentity()) { | 954 if (src.isIdentity()) { |
(...skipping 13 matching lines...) Expand all Loading... |
917 dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]); | 968 dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]); |
918 dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]); | 969 dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]); |
919 dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]); | 970 dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]); |
920 | 971 |
921 dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]); | 972 dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]); |
922 dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]); | 973 dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]); |
923 dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]); | 974 dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]); |
924 | 975 |
925 return dst; | 976 return dst; |
926 } | 977 } |
OLD | NEW |