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#ifndef SkMatrix44_DEFINED 121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define SkMatrix44_DEFINED 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkMatrix.h" 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkScalar.h" 161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_MSCALAR_IS_DOUBLE 181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger typedef double SkMScalar; 191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline double SkFloatToMScalar(float x) { 201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return static_cast<double>(x); 211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline float SkMScalarToFloat(double x) { 231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return static_cast<float>(x); 241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline double SkDoubleToMScalar(double x) { 261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return x; 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline double SkMScalarToDouble(double x) { 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return x; 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const SkMScalar SK_MScalarPI = 3.141592653589793; 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger typedef float SkMScalar; 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline float SkFloatToMScalar(float x) { 351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return x; 361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline float SkMScalarToFloat(float x) { 381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return x; 391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline float SkDoubleToMScalar(double x) { 411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return static_cast<float>(x); 421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static inline double SkMScalarToDouble(float x) { 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return static_cast<double>(x); 451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger static const SkMScalar SK_MScalarPI = 3.14159265f; 471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SkMScalarToScalar SkMScalarToFloat 511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SkScalarToMScalar SkFloatToMScalar 521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #if SK_MSCALAR_IS_DOUBLE 541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // we don't have fixed <-> double macros, use double<->scalar macros 551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SkMScalarToScalar SkDoubleToScalar 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SkScalarToMScalar SkScalarToDouble 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #else 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SkMScalarToScalar SkFloatToFixed 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SkScalarToMScalar SkFixedToFloat 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #endif 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic const SkMScalar SK_MScalar1 = 1; 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstruct SkVector4 { 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar fData[4]; 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkVector4() { 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->set(0, 0, 0, 1); 721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkVector4(const SkVector4& src) { 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(fData, src.fData, sizeof(fData)); 751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[0] = x; 781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[1] = y; 791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[2] = z; 801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[3] = w; 811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkVector4& operator=(const SkVector4& src) { 841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(fData, src.fData, sizeof(fData)); 851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return *this; 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool operator==(const SkVector4& v) { 891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fData[0] == v.fData[0] && fData[1] == v.fData[1] && 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[2] == v.fData[2] && fData[3] == v.fData[3]; 911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool operator!=(const SkVector4& v) { 931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !(*this == v); 941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return fData[0] == x && fData[1] == y && 971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[2] == z && fData[3] == w; 981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { 1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[0] = x; 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[1] = y; 1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[2] = z; 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fData[3] = w; 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerclass SK_API SkMatrix44 { 1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerpublic: 1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44(); 1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44(const SkMatrix44&); 1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44(const SkMatrix44& a, const SkMatrix44& b); 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44& operator=(const SkMatrix44& src) { 1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger memcpy(this, &src, sizeof(*this)); 1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return *this; 1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool operator==(const SkMatrix44& other) const { 1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(this, &other, sizeof(*this)); 1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool operator!=(const SkMatrix44& other) const { 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !!memcmp(this, &other, sizeof(*this)); 1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44(const SkMatrix&); 1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMatrix44& operator=(const SkMatrix& src); 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger operator SkMatrix() const; 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar get(int row, int col) const; 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void set(int row, int col, const SkMScalar& value); 1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void asColMajorf(float[]) const; 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void asColMajord(double[]) const; 1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void asRowMajorf(float[]) const; 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void asRowMajord(double[]) const; 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool isIdentity() const; 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setIdentity(); 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void reset() { this->setIdentity();} 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar m10, SkMScalar m11, SkMScalar m12, 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar m20, SkMScalar m21, SkMScalar m22); 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 1511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setScale(SkMScalar scale) { 1551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setScale(scale, scale, scale); 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void preScale(SkMScalar scale) { 1581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->preScale(scale, scale, scale); 1591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void postScale(SkMScalar scale) { 1611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->postScale(scale, scale, scale); 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z, 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar degrees) { 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180); 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /** Rotate about the vector [x,y,z]. If that vector is not unit-length, 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger it will be automatically resized. 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z, 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar radians); 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /** Rotate about the vector [x,y,z]. Does not check the length of the 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger vector, assuming it is unit-length. 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z, 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar radians); 1791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void setConcat(const SkMatrix44& a, const SkMatrix44& b); 1811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void preConcat(const SkMatrix44& m) { 1821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setConcat(*this, m); 1831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void postConcat(const SkMatrix44& m) { 1851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setConcat(m, *this); 1861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) { 1891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkMatrix44(a, b); 1901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 1911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /** If this is invertible, return that in inverse and return true. If it is 1931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger not invertible, return false and ignore the inverse parameter. 1941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 1951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool invert(SkMatrix44* inverse) const; 1961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /** Apply the matrix to the src vector, returning the new vector in dst. 1981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger It is legal for src and dst to point to the same memory. 1991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 2001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void map(const SkScalar src[4], SkScalar dst[4]) const; 2011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void map(SkScalar vec[4]) const { 2021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->map(vec, vec); 2031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) { 2061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkVector4 dst; 2071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger m.map(src.fData, dst.fData); 2081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return dst; 2091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 2101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void dump() const; 2121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerprivate: 2141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* Stored in the same order as opengl: 2151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger [3][0] = tx 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger [3][1] = ty 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger [3][2] = tz 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMScalar fMat[4][4]; 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger double determinant() const; 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}; 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 225