blob: b0e7148c41b33191f3e434990d74b445fa08181c [file] [log] [blame]
reed@android.com6d342a42010-02-23 20:18:17 +00001#ifndef SkMatrix44_DEFINED
2#define SkMatrix44_DEFINED
3
reed@android.comd055c1f2010-03-01 14:54:05 +00004#include "SkMatrix.h"
reed@android.com6d342a42010-02-23 20:18:17 +00005#include "SkScalar.h"
6
reed@android.comc8c49c52010-02-24 15:36:57 +00007// uncomment this to use doubles for matrix44
8#define SK_MSCALAR_IS_DOUBLE
9
10#ifdef SK_MSCALAR_IS_DOUBLE
11 typedef double SkMScalar;
12 static inline double SkFloatToMScalar(float x) {
13 return static_cast<double>(x);
14 }
15 static inline float SkMScalarToFloat(double x) {
16 return static_cast<float>(x);
17 }
18 static inline double SkDoubleToMScalar(double x) {
19 return x;
20 }
21 static inline double SkMScalarToDouble(double x) {
22 return x;
23 }
reed@android.com38203fb2010-02-26 21:45:49 +000024 static const SkMScalar SK_MScalarPI = 3.141592653589793;
reed@android.comc8c49c52010-02-24 15:36:57 +000025#else
26 typedef float SkMScalar;
27 static inline float SkFloatToMScalar(float x) {
28 return x;
29 }
30 static inline float SkMScalarToFloat(float x) {
31 return x;
32 }
33 static inline float SkDoubleToMScalar(double x) {
34 return static_cast<float>(x);
35 }
36 static inline double SkMScalarToDouble(float x) {
37 return static_cast<double>(x);
38 }
reed@android.com38203fb2010-02-26 21:45:49 +000039 static const SkMScalar SK_MScalarPI = 3.14159265f;
reed@android.comc8c49c52010-02-24 15:36:57 +000040#endif
41
reed@android.com6d342a42010-02-23 20:18:17 +000042static const SkMScalar SK_MScalar1 = 1;
reed@android.comc8c49c52010-02-24 15:36:57 +000043
44///////////////////////////////////////////////////////////////////////////////
reed@android.com6d342a42010-02-23 20:18:17 +000045
46struct SkVector4 {
47 SkScalar fData[4];
reed@android.comb5d0f7b2010-02-24 22:08:58 +000048
reed@android.com85f9e1a2010-03-01 01:10:10 +000049 SkVector4() {
50 this->set(0, 0, 0, 1);
51 }
52 SkVector4(const SkVector4& src) {
53 memcpy(fData, src.fData, sizeof(fData));
54 }
55 SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
56 fData[0] = x;
57 fData[1] = y;
58 fData[2] = z;
59 fData[3] = w;
60 }
61
62 SkVector4& operator=(const SkVector4& src) {
63 memcpy(fData, src.fData, sizeof(fData));
64 return *this;
65 }
66
67 bool operator==(const SkVector4& v) {
68 return fData[0] == v.fData[0] && fData[1] == v.fData[1] &&
69 fData[2] == v.fData[2] && fData[3] == v.fData[3];
70 }
71 bool operator!=(const SkVector4& v) {
72 return !(*this == v);
73 }
74 bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
75 return fData[0] == x && fData[1] == y &&
76 fData[2] == z && fData[3] == w;
77 }
78
reed@android.comb5d0f7b2010-02-24 22:08:58 +000079 void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
80 fData[0] = x;
81 fData[1] = y;
82 fData[2] = z;
83 fData[3] = w;
84 }
reed@android.com6d342a42010-02-23 20:18:17 +000085};
86
87class SkMatrix44 {
88public:
89 SkMatrix44();
90 SkMatrix44(const SkMatrix44&);
91 SkMatrix44(const SkMatrix44& a, const SkMatrix44& b);
92
reed@android.comd055c1f2010-03-01 14:54:05 +000093 SkMatrix44& operator=(const SkMatrix44& src) {
94 memcpy(this, &src, sizeof(*this));
95 return *this;
96 }
97
reed@android.comc8c49c52010-02-24 15:36:57 +000098 bool operator==(const SkMatrix44& other) const {
99 return !memcmp(this, &other, sizeof(*this));
100 }
101 bool operator!=(const SkMatrix44& other) const {
102 return !!memcmp(this, &other, sizeof(*this));
103 }
reed@android.comd055c1f2010-03-01 14:54:05 +0000104
105 SkMatrix44(const SkMatrix&);
106 SkMatrix44& operator=(const SkMatrix& src);
107 operator SkMatrix() const;
108
reed@android.comc8c49c52010-02-24 15:36:57 +0000109 bool isIdentity() const;
reed@android.com6d342a42010-02-23 20:18:17 +0000110 void setIdentity();
reed@android.comc8c49c52010-02-24 15:36:57 +0000111 void reset() { this->setIdentity(); }
reed@android.com6d342a42010-02-23 20:18:17 +0000112
reed@android.com38203fb2010-02-26 21:45:49 +0000113 void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
114 SkMScalar m10, SkMScalar m11, SkMScalar m12,
115 SkMScalar m20, SkMScalar m21, SkMScalar m22);
116
reed@android.com6d342a42010-02-23 20:18:17 +0000117 void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
118 void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
119 void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
120
121 void setScale(SkMScalar sx, SkMScalar sx, SkMScalar sx);
122 void preScale(SkMScalar sx, SkMScalar sx, SkMScalar sx);
123 void postScale(SkMScalar sx, SkMScalar sx, SkMScalar sx);
124
125 void setScale(SkMScalar scale) {
126 this->setScale(scale, scale, scale);
127 }
128 void preScale(SkMScalar scale) {
129 this->preScale(scale, scale, scale);
130 }
131 void postScale(SkMScalar scale) {
132 this->postScale(scale, scale, scale);
133 }
reed@android.com38203fb2010-02-26 21:45:49 +0000134
135 void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
136 SkMScalar degrees) {
137 this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
138 }
139
140 /** Rotate about the vector [x,y,z]. If that vector is not unit-length,
141 it will be automatically resized.
142 */
143 void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
144 SkMScalar radians);
145 /** Rotate about the vector [x,y,z]. Does not check the length of the
146 vector, assuming it is unit-length.
147 */
148 void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
149 SkMScalar radians);
150
reed@android.com6d342a42010-02-23 20:18:17 +0000151 void setConcat(const SkMatrix44& a, const SkMatrix44& b);
152 void preConcat(const SkMatrix44& m) {
153 this->setConcat(*this, m);
154 }
155 void postConcat(const SkMatrix44& m) {
156 this->setConcat(m, *this);
157 }
158 friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) {
159 return SkMatrix44(a, b);
160 }
161
162 /** If this is invertible, return that in inverse and return true. If it is
163 not invertible, return false and ignore the inverse parameter.
164 */
165 bool invert(SkMatrix44* inverse) const;
166
167 /** Apply the matrix to the src vector, returning the new vector in dst.
168 It is legal for src and dst to point to the same memory.
169 */
170 void map(const SkScalar src[4], SkScalar dst[4]) const;
171 void map(SkScalar vec[4]) const {
172 this->map(vec, vec);
173 }
174
175 friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) {
176 SkVector4 dst;
177 m.map(src.fData, dst.fData);
178 return dst;
179 }
180
181 void dump() const;
182
183private:
184 /* Stored in the same order as opengl:
185 [3][0] = tx
186 [3][1] = ty
187 [3][2] = tz
188 */
189 SkMScalar fMat[4][4];
190
191 double determinant() const;
192};
193
194#endif