11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkMatrix44.h" 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 131cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMatrix44::SkMatrix44() { 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setIdentity(); 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 171cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMatrix44::SkMatrix44(const SkMatrix44& src) { 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(this, &src, sizeof(src)); 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 211cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMatrix44::SkMatrix44(const SkMatrix44& a, const SkMatrix44& b) { 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setConcat(a, b); 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 251cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMScalar SkMatrix44::get(int row, int col) const { 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(row <= 3 && row >= 0); 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(col <= 3 && col >= 0); 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fMat[col][row]; 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::set(int row, int col, const SkMScalar& value) { 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(row <= 3 && row >= 0); 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(col <= 3 && col >= 0); 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[col][row] = value; 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::asColMajorf(float dst[]) const { 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMScalar* src = &fMat[0][0]; 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_MSCALAR_IS_DOUBLE 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 16; ++i) { 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkMScalarToFloat(src[i]); 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(dst, src, 16 * sizeof(float)); 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::asColMajord(double dst[]) const { 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMScalar* src = &fMat[0][0]; 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_MSCALAR_IS_DOUBLE 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(dst, src, 16 * sizeof(double)); 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 16; ++i) { 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[i] = SkMScalarToDouble(src[i]); 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::asRowMajorf(float dst[]) const { 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMScalar* src = &fMat[0][0]; 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; ++i) { 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[0] = SkMScalarToFloat(src[0]); 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[4] = SkMScalarToFloat(src[1]); 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[8] = SkMScalarToFloat(src[2]); 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[12] = SkMScalarToFloat(src[3]); 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src += 4; 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst += 1; 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::asRowMajord(double dst[]) const { 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMScalar* src = &fMat[0][0]; 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; ++i) { 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[0] = SkMScalarToDouble(src[0]); 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[4] = SkMScalarToDouble(src[1]); 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[8] = SkMScalarToDouble(src[2]); 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[12] = SkMScalarToDouble(src[3]); 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger src += 4; 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst += 1; 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkMatrix44::isIdentity() const { 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const SkMScalar sIdentityMat[4][4] = { 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 1, 0, 0, 0 }, 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 0, 1, 0, 0 }, 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 0, 0, 1, 0 }, 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 0, 0, 0, 1 }, 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger }; 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(fMat, sIdentityMat, sizeof(fMat)); 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::setIdentity() { 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sk_bzero(fMat, sizeof(fMat)); 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = 1; 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar m10, SkMScalar m11, SkMScalar m12, 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar m20, SkMScalar m21, SkMScalar m22) { 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sk_bzero(fMat, sizeof(fMat)); 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0; 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0; 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0; 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1; 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::setTranslate(SkMScalar tx, SkMScalar ty, SkMScalar tz) { 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setIdentity(); 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][0] = tx; 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][1] = ty; 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][2] = tz; 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][3] = 1; 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) { 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44 mat; 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger mat.setTranslate(dx, dy, dz); 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->preConcat(mat); 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) { 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][0] += dx; 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][1] += dy; 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][2] += dz; 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sk_bzero(fMat, sizeof(fMat)); 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][0] = sx; 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[1][1] = sy; 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[2][2] = sz; 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][3] = 1; 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44 tmp; 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp.setScale(sx, sy, sz); 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->preConcat(tmp); 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; i++) { 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[i][0] *= sx; 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[i][1] *= sy; 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[i][2] *= sz; 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z, 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar radians) { 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double len2 = x * x + y * y + z * z; 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (len2 != 1) { 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (len2 == 0) { 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setIdentity(); 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return; 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double scale = 1 / sqrt(len2); 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x = SkDoubleToMScalar(x * scale); 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger y = SkDoubleToMScalar(y * scale); 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger z = SkDoubleToMScalar(z * scale); 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setRotateAboutUnit(x, y, z, radians); 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z, 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar radians) { 1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double c = cos(radians); 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double s = sin(radians); 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double C = 1 - c; 1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double xs = x * s; 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double ys = y * s; 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double zs = z * s; 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double xC = x * C; 1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double yC = y * C; 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double zC = z * C; 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double xyC = x * yC; 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double yzC = y * zC; 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double zxC = z * xC; 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if you're looking at wikipedia, remember that we're column major. 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->set3x3(SkDoubleToMScalar(x * xC + c), // scale x 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(xyC + zs), // skew x 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(zxC - ys), // trans x 1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(xyC - zs), // skew y 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(y * yC + c), // scale y 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(yzC + xs), // trans y 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(zxC + ys), // persp x 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(yzC - xs), // persp y 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDoubleToMScalar(z * zC + c)); // persp 2 2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::setConcat(const SkMatrix44& a, const SkMatrix44& b) { 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar result[4][4]; 2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; i++) { 2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int j = 0; j < 4; j++) { 2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double value = 0; 2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int k = 0; k < 4; k++) { 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger value += SkMScalarToDouble(a.fMat[k][i]) * b.fMat[j][k]; 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger result[j][i] = SkDoubleToMScalar(value); 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(fMat, result, sizeof(result)); 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline SkMScalar det2x2(double m00, double m01, double m10, double m11) { 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkDoubleToMScalar(m00 * m11 - m10 * m01); 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline double det3x3(double m00, double m01, double m02, 2301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m10, double m11, double m12, 2311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m20, double m21, double m22) { 2321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return m00 * det2x2(m11, m12, m21, m22) - 2331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m10 * det2x2(m01, m02, m21, m22) + 2341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m20 * det2x2(m01, m02, m11, m12); 2351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/** We always perform the calculation in doubles, to avoid prematurely losing 2381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger precision along the way. This relies on the compiler automatically 2391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger promoting our SkMScalar values to double (if needed). 2401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 2411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerdouble SkMatrix44::determinant() const { 2421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fMat[0][0] * det3x3(fMat[1][1], fMat[1][2], fMat[1][3], 2431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[2][1], fMat[2][2], fMat[2][3], 2441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][1], fMat[3][2], fMat[3][3]) - 2451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[1][0] * det3x3(fMat[0][1], fMat[0][2], fMat[0][3], 2461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[2][1], fMat[2][2], fMat[2][3], 2471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][1], fMat[3][2], fMat[3][3]) + 2481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[2][0] * det3x3(fMat[0][1], fMat[0][2], fMat[0][3], 2491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[1][1], fMat[1][2], fMat[1][3], 2501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][1], fMat[3][2], fMat[3][3]) - 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][0] * det3x3(fMat[0][1], fMat[0][2], fMat[0][3], 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[1][1], fMat[1][2], fMat[1][3], 2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[2][1], fMat[2][2], fMat[2][3]); 2541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// just picked a small value. not sure how to pick the "right" one 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define TOO_SMALL_FOR_DETERMINANT (1.e-8) 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic inline double dabs(double x) { 2621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (x < 0) { 2631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x = -x; 2641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return x; 2661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkMatrix44::invert(SkMatrix44* inverse) const { 2691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double det = this->determinant(); 2701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (dabs(det) < TOO_SMALL_FOR_DETERMINANT) { 2711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 2721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (NULL == inverse) { 2741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 2751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we explicitly promote to doubles to keep the intermediate values in 2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // higher precision (assuming SkMScalar isn't already a double) 2791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m00 = fMat[0][0]; 2801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m01 = fMat[0][1]; 2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m02 = fMat[0][2]; 2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m03 = fMat[0][3]; 2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m10 = fMat[1][0]; 2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m11 = fMat[1][1]; 2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m12 = fMat[1][2]; 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m13 = fMat[1][3]; 2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m20 = fMat[2][0]; 2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m21 = fMat[2][1]; 2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m22 = fMat[2][2]; 2901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m23 = fMat[2][3]; 2911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m30 = fMat[3][0]; 2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m31 = fMat[3][1]; 2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m32 = fMat[3][2]; 2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double m33 = fMat[3][3]; 2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double tmp[4][4]; 2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[0][0] = m12*m23*m31 - m13*m22*m31 + m13*m21*m32 - m11*m23*m32 - m12*m21*m33 + m11*m22*m33; 2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[0][1] = m03*m22*m31 - m02*m23*m31 - m03*m21*m32 + m01*m23*m32 + m02*m21*m33 - m01*m22*m33; 3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[0][2] = m02*m13*m31 - m03*m12*m31 + m03*m11*m32 - m01*m13*m32 - m02*m11*m33 + m01*m12*m33; 3011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[0][3] = m03*m12*m21 - m02*m13*m21 - m03*m11*m22 + m01*m13*m22 + m02*m11*m23 - m01*m12*m23; 3021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[1][0] = m13*m22*m30 - m12*m23*m30 - m13*m20*m32 + m10*m23*m32 + m12*m20*m33 - m10*m22*m33; 3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[1][1] = m02*m23*m30 - m03*m22*m30 + m03*m20*m32 - m00*m23*m32 - m02*m20*m33 + m00*m22*m33; 3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[1][2] = m03*m12*m30 - m02*m13*m30 - m03*m10*m32 + m00*m13*m32 + m02*m10*m33 - m00*m12*m33; 3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[1][3] = m02*m13*m20 - m03*m12*m20 + m03*m10*m22 - m00*m13*m22 - m02*m10*m23 + m00*m12*m23; 3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[2][0] = m11*m23*m30 - m13*m21*m30 + m13*m20*m31 - m10*m23*m31 - m11*m20*m33 + m10*m21*m33; 3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[2][1] = m03*m21*m30 - m01*m23*m30 - m03*m20*m31 + m00*m23*m31 + m01*m20*m33 - m00*m21*m33; 3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[2][2] = m01*m13*m30 - m03*m11*m30 + m03*m10*m31 - m00*m13*m31 - m01*m10*m33 + m00*m11*m33; 3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[2][3] = m03*m11*m20 - m01*m13*m20 - m03*m10*m21 + m00*m13*m21 + m01*m10*m23 - m00*m11*m23; 3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[3][0] = m12*m21*m30 - m11*m22*m30 - m12*m20*m31 + m10*m22*m31 + m11*m20*m32 - m10*m21*m32; 3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[3][1] = m01*m22*m30 - m02*m21*m30 + m02*m20*m31 - m00*m22*m31 - m01*m20*m32 + m00*m21*m32; 3121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[3][2] = m02*m11*m30 - m01*m12*m30 - m02*m10*m31 + m00*m12*m31 + m01*m10*m32 - m00*m11*m32; 3131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger tmp[3][3] = m01*m12*m20 - m02*m11*m20 + m02*m10*m21 - m00*m12*m21 - m01*m10*m22 + m00*m11*m22; 3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double invDet = 1.0 / det; 3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; i++) { 3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int j = 0; j < 4; j++) { 3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger inverse->fMat[i][j] = SkDoubleToMScalar(tmp[i][j] * invDet); 3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::map(const SkScalar src[4], SkScalar dst[4]) const { 3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar result[4]; 3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int i = 0; i < 4; i++) { 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar value = 0; 3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger for (int j = 0; j < 4; j++) { 3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger value += fMat[j][i] * src[j]; 3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger result[i] = SkMScalarToScalar(value); 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(dst, result, sizeof(result)); 3361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkMatrix44::dump() const { 3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const char* format = 3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger "[%g %g %g %g][%g %g %g %g][%g %g %g %g][%g %g %g %g]\n"; 3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 0 3441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf(format, 3451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][0], fMat[1][0], fMat[2][0], fMat[3][0], 3461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][1], fMat[1][1], fMat[2][1], fMat[3][1], 3471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][2], fMat[1][2], fMat[2][2], fMat[3][2], 3481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][3], fMat[1][3], fMat[2][3], fMat[3][3]); 3491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 3501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf(format, 3511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[0][0], fMat[0][1], fMat[0][2], fMat[0][3], 3521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[1][0], fMat[1][1], fMat[1][2], fMat[1][3], 3531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[2][0], fMat[2][1], fMat[2][2], fMat[2][3], 3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fMat[3][0], fMat[3][1], fMat[3][2], fMat[3][3]); 3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void initFromMatrix(SkMScalar dst[4][4], const SkMatrix& src) { 3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger sk_bzero(dst, 16 * sizeof(SkMScalar)); 3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[0][0] = SkScalarToMScalar(src[SkMatrix::kMScaleX]); 3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[1][0] = SkScalarToMScalar(src[SkMatrix::kMSkewX]); 3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[3][0] = SkScalarToMScalar(src[SkMatrix::kMTransX]); 3651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[0][1] = SkScalarToMScalar(src[SkMatrix::kMSkewY]); 3661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[1][1] = SkScalarToMScalar(src[SkMatrix::kMScaleY]); 3671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[3][1] = SkScalarToMScalar(src[SkMatrix::kMTransY]); 3681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[2][2] = dst[3][3] = 1; 3691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3711cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMatrix44::SkMatrix44(const SkMatrix& src) { 3721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger initFromMatrix(fMat, src); 3731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3751cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMatrix44& SkMatrix44::operator=(const SkMatrix& src) { 3761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger initFromMatrix(fMat, src); 3771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return *this; 3781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3801cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkMatrix44::operator SkMatrix() const { 3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix dst; 3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst.reset(); // setup our perspective correctly for identity 3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]); 3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]); 3861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]); 3871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[SkMatrix::kMSkewY] = SkMScalarToScalar(fMat[0][1]); 3891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[SkMatrix::kMScaleY] = SkMScalarToScalar(fMat[1][1]); 3901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger dst[SkMatrix::kMTransY] = SkMScalarToScalar(fMat[3][1]); 3911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return dst; 3931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 394