void SkMatrix44::setIdentity() {
sk_bzero(fMat, sizeof(fMat));
- fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = SK_MScalar1;
+ fMat[0][0] = fMat[1][1] = fMat[2][2] = fMat[3][3] = 1;
}
+void SkMatrix44::set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
+ SkMScalar m10, SkMScalar m11, SkMScalar m12,
+ SkMScalar m20, SkMScalar m21, SkMScalar m22) {
+ sk_bzero(fMat, sizeof(fMat));
+ fMat[0][0] = m00; fMat[0][1] = m01; fMat[0][2] = m02; fMat[0][3] = 0;
+ fMat[1][0] = m10; fMat[1][1] = m11; fMat[1][2] = m12; fMat[1][3] = 0;
+ fMat[2][0] = m20; fMat[2][1] = m21; fMat[2][2] = m22; fMat[2][3] = 0;
+ fMat[3][0] = 0; fMat[3][1] = 0; fMat[3][2] = 0; fMat[3][3] = 1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
void SkMatrix44::setTranslate(SkMScalar tx, SkMScalar ty, SkMScalar tz) {
this->setIdentity();
fMat[3][0] = tx;
fMat[3][1] = ty;
fMat[3][2] = tz;
- fMat[3][3] = SK_MScalar1;
+ fMat[3][3] = 1;
}
void SkMatrix44::preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
fMat[0][0] = sx;
fMat[1][1] = sy;
fMat[2][2] = sz;
- fMat[3][3] = SK_MScalar1;
+ fMat[3][3] = 1;
}
void SkMatrix44::preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) {
///////////////////////////////////////////////////////////////////////////////
+void SkMatrix44::setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar radians) {
+ double len2 = x * x + y * y + z * z;
+ if (len2 != 1) {
+ if (len2 == 0) {
+ this->setIdentity();
+ return;
+ }
+ double scale = 1 / sqrt(len2);
+ x *= scale;
+ y *= scale;
+ z *= scale;
+ }
+ this->setRotateAboutUnit(x, y, z, radians);
+}
+
+void SkMatrix44::setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar radians) {
+ double c = cos(radians);
+ double s = sin(radians);
+ double C = 1 - c;
+ double xs = x * s;
+ double ys = y * s;
+ double zs = z * s;
+ double xC = x * C;
+ double yC = y * C;
+ double zC = z * C;
+ double xyC = x * yC;
+ double yzC = y * zC;
+ double zxC = z * xC;
+
+ this->set3x3(x * xC + c, xyC - zs, zxC + ys,
+ xyC + zs, y * yC + c, yzC - xs,
+ zxC - ys, yzC + xs, z * zC + c);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
void SkMatrix44::setConcat(const SkMatrix44& a, const SkMatrix44& b) {
SkMScalar result[4][4];
for (int i = 0; i < 4; i++) {
static inline double SkMScalarToDouble(double x) {
return x;
}
+ static const SkMScalar SK_MScalarPI = 3.141592653589793;
#else
typedef float SkMScalar;
static inline float SkFloatToMScalar(float x) {
static inline double SkMScalarToDouble(float x) {
return static_cast<double>(x);
}
+ static const SkMScalar SK_MScalarPI = 3.14159265f;
#endif
static const SkMScalar SK_MScalar1 = 1;
void setIdentity();
void reset() { this->setIdentity(); }
+ void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
+ SkMScalar m10, SkMScalar m11, SkMScalar m12,
+ SkMScalar m20, SkMScalar m21, SkMScalar m22);
+
void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
void postScale(SkMScalar scale) {
this->postScale(scale, scale, scale);
}
-
+
+ void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar degrees) {
+ this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
+ }
+
+ /** Rotate about the vector [x,y,z]. If that vector is not unit-length,
+ it will be automatically resized.
+ */
+ void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar radians);
+ /** Rotate about the vector [x,y,z]. Does not check the length of the
+ vector, assuming it is unit-length.
+ */
+ void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
+ SkMScalar radians);
+
void setConcat(const SkMatrix44& a, const SkMatrix44& b);
void preConcat(const SkMatrix44& m) {
this->setConcat(*this, m);