blob: 93140b022d7aadc9ca9bb4292a9794f01b804549 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.com8260a892011-06-13 14:02:52 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
reed@google.com8260a892011-06-13 14:02:52 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.com8260a892011-06-13 14:02:52 +000011#ifndef SkMatrix44_DEFINED
12#define SkMatrix44_DEFINED
13
14#include "SkMatrix.h"
15#include "SkScalar.h"
16
reed@google.com8260a892011-06-13 14:02:52 +000017#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
bsalomon@google.com72e49b82011-10-27 21:47:03 +000049#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
reed@google.com8260a892011-06-13 14:02:52 +000063static const SkMScalar SK_MScalar1 = 1;
64
65///////////////////////////////////////////////////////////////////////////////
66
67struct 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
reed@google.com65d8bb02011-07-05 19:12:59 +0000108class SK_API SkMatrix44 {
reed@google.com8260a892011-06-13 14:02:52 +0000109public:
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
reed@google.comda9fac02011-06-13 14:46:52 +0000133 void asColMajorf(float[]) const;
134 void asColMajord(double[]) const;
135 void asRowMajorf(float[]) const;
136 void asRowMajord(double[]) const;
137
reed@google.com8260a892011-06-13 14:02:52 +0000138 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
213private:
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