| 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 |