Home | History | Annotate | Download | only in utils
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #ifndef SkMatrix44_DEFINED
     12 #define SkMatrix44_DEFINED
     13 
     14 #include "SkMatrix.h"
     15 #include "SkScalar.h"
     16 
     17 #ifdef SK_MSCALAR_IS_DOUBLE
     18     typedef double SkMScalar;
     19     static inline double SkFloatToMScalar(float x) {
     20         return static_cast<double>(x);
     21     }
     22     static inline float SkMScalarToFloat(double x) {
     23         return static_cast<float>(x);
     24     }
     25     static inline double SkDoubleToMScalar(double x) {
     26         return x;
     27     }
     28     static inline double SkMScalarToDouble(double x) {
     29         return x;
     30     }
     31     static const SkMScalar SK_MScalarPI = 3.141592653589793;
     32 #else
     33     typedef float SkMScalar;
     34     static inline float SkFloatToMScalar(float x) {
     35         return x;
     36     }
     37     static inline float SkMScalarToFloat(float x) {
     38         return x;
     39     }
     40     static inline float SkDoubleToMScalar(double x) {
     41         return static_cast<float>(x);
     42     }
     43     static inline double SkMScalarToDouble(float x) {
     44         return static_cast<double>(x);
     45     }
     46     static const SkMScalar SK_MScalarPI = 3.14159265f;
     47 #endif
     48 
     49 #ifdef SK_SCALAR_IS_FLOAT
     50     #define SkMScalarToScalar SkMScalarToFloat
     51     #define SkScalarToMScalar SkFloatToMScalar
     52 #else
     53     #if SK_MSCALAR_IS_DOUBLE
     54         // we don't have fixed <-> double macros, use double<->scalar macros
     55         #define SkMScalarToScalar SkDoubleToScalar
     56         #define SkScalarToMScalar SkScalarToDouble
     57     #else
     58         #define SkMScalarToScalar SkFloatToFixed
     59         #define SkScalarToMScalar SkFixedToFloat
     60     #endif
     61 #endif
     62 
     63 static const SkMScalar SK_MScalar1 = 1;
     64 
     65 ///////////////////////////////////////////////////////////////////////////////
     66 
     67 struct SkVector4 {
     68     SkScalar fData[4];
     69 
     70     SkVector4() {
     71         this->set(0, 0, 0, 1);
     72     }
     73     SkVector4(const SkVector4& src) {
     74         memcpy(fData, src.fData, sizeof(fData));
     75     }
     76     SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
     77         fData[0] = x;
     78         fData[1] = y;
     79         fData[2] = z;
     80         fData[3] = w;
     81     }
     82 
     83     SkVector4& operator=(const SkVector4& src) {
     84         memcpy(fData, src.fData, sizeof(fData));
     85         return *this;
     86     }
     87 
     88     bool operator==(const SkVector4& v) {
     89         return fData[0] == v.fData[0] && fData[1] == v.fData[1] &&
     90                fData[2] == v.fData[2] && fData[3] == v.fData[3];
     91     }
     92     bool operator!=(const SkVector4& v) {
     93         return !(*this == v);
     94     }
     95     bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
     96         return fData[0] == x && fData[1] == y &&
     97                fData[2] == z && fData[3] == w;
     98     }
     99 
    100     void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
    101         fData[0] = x;
    102         fData[1] = y;
    103         fData[2] = z;
    104         fData[3] = w;
    105     }
    106 };
    107 
    108 class SK_API SkMatrix44 {
    109 public:
    110     SkMatrix44();
    111     SkMatrix44(const SkMatrix44&);
    112     SkMatrix44(const SkMatrix44& a, const SkMatrix44& b);
    113 
    114     SkMatrix44& operator=(const SkMatrix44& src) {
    115         memcpy(this, &src, sizeof(*this));
    116         return *this;
    117     }
    118 
    119     bool operator==(const SkMatrix44& other) const {
    120         return !memcmp(this, &other, sizeof(*this));
    121     }
    122     bool operator!=(const SkMatrix44& other) const {
    123         return !!memcmp(this, &other, sizeof(*this));
    124     }
    125 
    126     SkMatrix44(const SkMatrix&);
    127     SkMatrix44& operator=(const SkMatrix& src);
    128     operator SkMatrix() const;
    129 
    130     SkMScalar get(int row, int col) const;
    131     void set(int row, int col, const SkMScalar& value);
    132 
    133     void asColMajorf(float[]) const;
    134     void asColMajord(double[]) const;
    135     void asRowMajorf(float[]) const;
    136     void asRowMajord(double[]) const;
    137 
    138     bool isIdentity() const;
    139     void setIdentity();
    140     void reset() { this->setIdentity();}
    141 
    142     void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
    143                 SkMScalar m10, SkMScalar m11, SkMScalar m12,
    144                 SkMScalar m20, SkMScalar m21, SkMScalar m22);
    145 
    146     void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
    147     void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
    148     void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
    149 
    150     void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
    151     void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
    152     void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
    153 
    154     void setScale(SkMScalar scale) {
    155         this->setScale(scale, scale, scale);
    156     }
    157     void preScale(SkMScalar scale) {
    158         this->preScale(scale, scale, scale);
    159     }
    160     void postScale(SkMScalar scale) {
    161         this->postScale(scale, scale, scale);
    162     }
    163 
    164     void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
    165                                SkMScalar degrees) {
    166         this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
    167     }
    168 
    169     /** Rotate about the vector [x,y,z]. If that vector is not unit-length,
    170         it will be automatically resized.
    171      */
    172     void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
    173                         SkMScalar radians);
    174     /** Rotate about the vector [x,y,z]. Does not check the length of the
    175         vector, assuming it is unit-length.
    176      */
    177     void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
    178                             SkMScalar radians);
    179 
    180     void setConcat(const SkMatrix44& a, const SkMatrix44& b);
    181     void preConcat(const SkMatrix44& m) {
    182         this->setConcat(*this, m);
    183     }
    184     void postConcat(const SkMatrix44& m) {
    185         this->setConcat(m, *this);
    186     }
    187 
    188     friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) {
    189         return SkMatrix44(a, b);
    190     }
    191 
    192     /** If this is invertible, return that in inverse and return true. If it is
    193         not invertible, return false and ignore the inverse parameter.
    194      */
    195     bool invert(SkMatrix44* inverse) const;
    196 
    197     /** Apply the matrix to the src vector, returning the new vector in dst.
    198         It is legal for src and dst to point to the same memory.
    199      */
    200     void map(const SkScalar src[4], SkScalar dst[4]) const;
    201     void map(SkScalar vec[4]) const {
    202         this->map(vec, vec);
    203     }
    204 
    205     friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) {
    206         SkVector4 dst;
    207         m.map(src.fData, dst.fData);
    208         return dst;
    209     }
    210 
    211     void dump() const;
    212 
    213 private:
    214     /*  Stored in the same order as opengl:
    215          [3][0] = tx
    216          [3][1] = ty
    217          [3][2] = tz
    218      */
    219     SkMScalar fMat[4][4];
    220 
    221     double determinant() const;
    222 };
    223 
    224 #endif
    225