diff options
Diffstat (limited to 'include/utils/SkMatrix44.h')
-rw-r--r-- | include/utils/SkMatrix44.h | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/include/utils/SkMatrix44.h b/include/utils/SkMatrix44.h new file mode 100644 index 0000000..93140b0 --- /dev/null +++ b/include/utils/SkMatrix44.h @@ -0,0 +1,224 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + + +#ifndef SkMatrix44_DEFINED +#define SkMatrix44_DEFINED + +#include "SkMatrix.h" +#include "SkScalar.h" + +#ifdef SK_MSCALAR_IS_DOUBLE + typedef double SkMScalar; + static inline double SkFloatToMScalar(float x) { + return static_cast<double>(x); + } + static inline float SkMScalarToFloat(double x) { + return static_cast<float>(x); + } + static inline double SkDoubleToMScalar(double x) { + return x; + } + static inline double SkMScalarToDouble(double x) { + return x; + } + static const SkMScalar SK_MScalarPI = 3.141592653589793; +#else + typedef float SkMScalar; + static inline float SkFloatToMScalar(float x) { + return x; + } + static inline float SkMScalarToFloat(float x) { + return x; + } + static inline float SkDoubleToMScalar(double x) { + return static_cast<float>(x); + } + static inline double SkMScalarToDouble(float x) { + return static_cast<double>(x); + } + static const SkMScalar SK_MScalarPI = 3.14159265f; +#endif + +#ifdef SK_SCALAR_IS_FLOAT + #define SkMScalarToScalar SkMScalarToFloat + #define SkScalarToMScalar SkFloatToMScalar +#else + #if SK_MSCALAR_IS_DOUBLE + // we don't have fixed <-> double macros, use double<->scalar macros + #define SkMScalarToScalar SkDoubleToScalar + #define SkScalarToMScalar SkScalarToDouble + #else + #define SkMScalarToScalar SkFloatToFixed + #define SkScalarToMScalar SkFixedToFloat + #endif +#endif + +static const SkMScalar SK_MScalar1 = 1; + +/////////////////////////////////////////////////////////////////////////////// + +struct SkVector4 { + SkScalar fData[4]; + + SkVector4() { + this->set(0, 0, 0, 1); + } + SkVector4(const SkVector4& src) { + memcpy(fData, src.fData, sizeof(fData)); + } + SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { + fData[0] = x; + fData[1] = y; + fData[2] = z; + fData[3] = w; + } + + SkVector4& operator=(const SkVector4& src) { + memcpy(fData, src.fData, sizeof(fData)); + return *this; + } + + bool operator==(const SkVector4& v) { + return fData[0] == v.fData[0] && fData[1] == v.fData[1] && + fData[2] == v.fData[2] && fData[3] == v.fData[3]; + } + bool operator!=(const SkVector4& v) { + return !(*this == v); + } + bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { + return fData[0] == x && fData[1] == y && + fData[2] == z && fData[3] == w; + } + + void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) { + fData[0] = x; + fData[1] = y; + fData[2] = z; + fData[3] = w; + } +}; + +class SK_API SkMatrix44 { +public: + SkMatrix44(); + SkMatrix44(const SkMatrix44&); + SkMatrix44(const SkMatrix44& a, const SkMatrix44& b); + + SkMatrix44& operator=(const SkMatrix44& src) { + memcpy(this, &src, sizeof(*this)); + return *this; + } + + bool operator==(const SkMatrix44& other) const { + return !memcmp(this, &other, sizeof(*this)); + } + bool operator!=(const SkMatrix44& other) const { + return !!memcmp(this, &other, sizeof(*this)); + } + + SkMatrix44(const SkMatrix&); + SkMatrix44& operator=(const SkMatrix& src); + operator SkMatrix() const; + + SkMScalar get(int row, int col) const; + void set(int row, int col, const SkMScalar& value); + + void asColMajorf(float[]) const; + void asColMajord(double[]) const; + void asRowMajorf(float[]) const; + void asRowMajord(double[]) const; + + bool isIdentity() const; + void setIdentity(); + void reset() { this->setIdentity();} + + void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02, + SkMScalar m10, SkMScalar m11, SkMScalar m12, + SkMScalar m20, SkMScalar m21, SkMScalar m22); + + void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); + void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); + void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz); + + void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); + void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); + void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz); + + void setScale(SkMScalar scale) { + this->setScale(scale, scale, scale); + } + void preScale(SkMScalar scale) { + this->preScale(scale, scale, scale); + } + void postScale(SkMScalar scale) { + this->postScale(scale, scale, scale); + } + + void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z, + SkMScalar degrees) { + this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180); + } + + /** Rotate about the vector [x,y,z]. If that vector is not unit-length, + it will be automatically resized. + */ + void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z, + SkMScalar radians); + /** Rotate about the vector [x,y,z]. Does not check the length of the + vector, assuming it is unit-length. + */ + void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z, + SkMScalar radians); + + void setConcat(const SkMatrix44& a, const SkMatrix44& b); + void preConcat(const SkMatrix44& m) { + this->setConcat(*this, m); + } + void postConcat(const SkMatrix44& m) { + this->setConcat(m, *this); + } + + friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) { + return SkMatrix44(a, b); + } + + /** If this is invertible, return that in inverse and return true. If it is + not invertible, return false and ignore the inverse parameter. + */ + bool invert(SkMatrix44* inverse) const; + + /** Apply the matrix to the src vector, returning the new vector in dst. + It is legal for src and dst to point to the same memory. + */ + void map(const SkScalar src[4], SkScalar dst[4]) const; + void map(SkScalar vec[4]) const { + this->map(vec, vec); + } + + friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) { + SkVector4 dst; + m.map(src.fData, dst.fData); + return dst; + } + + void dump() const; + +private: + /* Stored in the same order as opengl: + [3][0] = tx + [3][1] = ty + [3][2] = tz + */ + SkMScalar fMat[4][4]; + + double determinant() const; +}; + +#endif |