From 38203fb4917049650c9bca2dd31e98fdac0e1d54 Mon Sep 17 00:00:00 2001 From: "reed@android.com" Date: Fri, 26 Feb 2010 21:45:49 +0000 Subject: [PATCH] add rotation git-svn-id: http://skia.googlecode.com/svn/trunk@513 2bbb7eff-a529-9590-31e7-b0007b416f81 --- experimental/SkMatrix44.cpp | 56 +++++++++++++++++++++++++++++++++++-- experimental/SkMatrix44.h | 24 +++++++++++++++- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/experimental/SkMatrix44.cpp b/experimental/SkMatrix44.cpp index 1b1b93b988..b2b8c30465 100644 --- a/experimental/SkMatrix44.cpp +++ b/experimental/SkMatrix44.cpp @@ -24,15 +24,27 @@ bool SkMatrix44::isIdentity() const { 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) { @@ -54,7 +66,7 @@ void SkMatrix44::setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz) { 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) { @@ -73,6 +85,44 @@ void SkMatrix44::postScale(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++) { diff --git a/experimental/SkMatrix44.h b/experimental/SkMatrix44.h index ceba83a16f..1fe46d49cf 100644 --- a/experimental/SkMatrix44.h +++ b/experimental/SkMatrix44.h @@ -20,6 +20,7 @@ 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) { @@ -34,6 +35,7 @@ static inline double SkMScalarToDouble(float x) { return static_cast(x); } + static const SkMScalar SK_MScalarPI = 3.14159265f; #endif static const SkMScalar SK_MScalar1 = 1; @@ -68,6 +70,10 @@ public: 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); @@ -85,7 +91,23 @@ public: 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); -- 2.34.1