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