blob: af632d755b4944c901bb702c1484990c0b48d15a [file] [log] [blame]
reed@google.com8260a892011-06-13 14:02:52 +00001/*
2 Copyright 2011 Google Inc.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#ifndef SkMatrix44_DEFINED
19#define SkMatrix44_DEFINED
20
21#include "SkMatrix.h"
22#include "SkScalar.h"
23
24// uncomment this to use doubles for matrix44
25#define SK_MSCALAR_IS_DOUBLE
26
27#ifdef SK_MSCALAR_IS_DOUBLE
28 typedef double SkMScalar;
29 static inline double SkFloatToMScalar(float x) {
30 return static_cast<double>(x);
31 }
32 static inline float SkMScalarToFloat(double x) {
33 return static_cast<float>(x);
34 }
35 static inline double SkDoubleToMScalar(double x) {
36 return x;
37 }
38 static inline double SkMScalarToDouble(double x) {
39 return x;
40 }
41 static const SkMScalar SK_MScalarPI = 3.141592653589793;
42#else
43 typedef float SkMScalar;
44 static inline float SkFloatToMScalar(float x) {
45 return x;
46 }
47 static inline float SkMScalarToFloat(float x) {
48 return x;
49 }
50 static inline float SkDoubleToMScalar(double x) {
51 return static_cast<float>(x);
52 }
53 static inline double SkMScalarToDouble(float x) {
54 return static_cast<double>(x);
55 }
56 static const SkMScalar SK_MScalarPI = 3.14159265f;
57#endif
58
59static const SkMScalar SK_MScalar1 = 1;
60
61///////////////////////////////////////////////////////////////////////////////
62
63struct SkVector4 {
64 SkScalar fData[4];
65
66 SkVector4() {
67 this->set(0, 0, 0, 1);
68 }
69 SkVector4(const SkVector4& src) {
70 memcpy(fData, src.fData, sizeof(fData));
71 }
72 SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
73 fData[0] = x;
74 fData[1] = y;
75 fData[2] = z;
76 fData[3] = w;
77 }
78
79 SkVector4& operator=(const SkVector4& src) {
80 memcpy(fData, src.fData, sizeof(fData));
81 return *this;
82 }
83
84 bool operator==(const SkVector4& v) {
85 return fData[0] == v.fData[0] && fData[1] == v.fData[1] &&
86 fData[2] == v.fData[2] && fData[3] == v.fData[3];
87 }
88 bool operator!=(const SkVector4& v) {
89 return !(*this == v);
90 }
91 bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
92 return fData[0] == x && fData[1] == y &&
93 fData[2] == z && fData[3] == w;
94 }
95
96 void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
97 fData[0] = x;
98 fData[1] = y;
99 fData[2] = z;
100 fData[3] = w;
101 }
102};
103
104class SkMatrix44 {
105public:
106 SkMatrix44();
107 SkMatrix44(const SkMatrix44&);
108 SkMatrix44(const SkMatrix44& a, const SkMatrix44& b);
109
110 SkMatrix44& operator=(const SkMatrix44& src) {
111 memcpy(this, &src, sizeof(*this));
112 return *this;
113 }
114
115 bool operator==(const SkMatrix44& other) const {
116 return !memcmp(this, &other, sizeof(*this));
117 }
118 bool operator!=(const SkMatrix44& other) const {
119 return !!memcmp(this, &other, sizeof(*this));
120 }
121
122 SkMatrix44(const SkMatrix&);
123 SkMatrix44& operator=(const SkMatrix& src);
124 operator SkMatrix() const;
125
126 SkMScalar get(int row, int col) const;
127 void set(int row, int col, const SkMScalar& value);
128
129 bool isIdentity() const;
130 void setIdentity();
131 void reset() { this->setIdentity();}
132
133 void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
134 SkMScalar m10, SkMScalar m11, SkMScalar m12,
135 SkMScalar m20, SkMScalar m21, SkMScalar m22);
136
137 void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
138 void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
139 void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
140
141 void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
142 void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
143 void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
144
145 void setScale(SkMScalar scale) {
146 this->setScale(scale, scale, scale);
147 }
148 void preScale(SkMScalar scale) {
149 this->preScale(scale, scale, scale);
150 }
151 void postScale(SkMScalar scale) {
152 this->postScale(scale, scale, scale);
153 }
154
155 void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
156 SkMScalar degrees) {
157 this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
158 }
159
160 /** Rotate about the vector [x,y,z]. If that vector is not unit-length,
161 it will be automatically resized.
162 */
163 void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
164 SkMScalar radians);
165 /** Rotate about the vector [x,y,z]. Does not check the length of the
166 vector, assuming it is unit-length.
167 */
168 void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
169 SkMScalar radians);
170
171 void setConcat(const SkMatrix44& a, const SkMatrix44& b);
172 void preConcat(const SkMatrix44& m) {
173 this->setConcat(*this, m);
174 }
175 void postConcat(const SkMatrix44& m) {
176 this->setConcat(m, *this);
177 }
178
179 friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) {
180 return SkMatrix44(a, b);
181 }
182
183 /** If this is invertible, return that in inverse and return true. If it is
184 not invertible, return false and ignore the inverse parameter.
185 */
186 bool invert(SkMatrix44* inverse) const;
187
188 /** Apply the matrix to the src vector, returning the new vector in dst.
189 It is legal for src and dst to point to the same memory.
190 */
191 void map(const SkScalar src[4], SkScalar dst[4]) const;
192 void map(SkScalar vec[4]) const {
193 this->map(vec, vec);
194 }
195
196 friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) {
197 SkVector4 dst;
198 m.map(src.fData, dst.fData);
199 return dst;
200 }
201
202 void dump() const;
203
204private:
205 /* Stored in the same order as opengl:
206 [3][0] = tx
207 [3][1] = ty
208 [3][2] = tz
209 */
210 SkMScalar fMat[4][4];
211
212 double determinant() const;
213};
214
215#endif