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