diff --git a/toonz/sources/common/tgeometry/tgeometry.cpp b/toonz/sources/common/tgeometry/tgeometry.cpp index d8bb6b6..5844316 100644 --- a/toonz/sources/common/tgeometry/tgeometry.cpp +++ b/toonz/sources/common/tgeometry/tgeometry.cpp @@ -235,6 +235,77 @@ TScale::TScale(const TPointD ¢er, double s) { //================================================================================================== +TPoint3D TAffine3::operator*(const TPoint3D &b) const { + return TPoint3D( + b.x*a11 + b.y*a21 + b.z*a31, + b.x*a12 + b.y*a22 + b.z*a32, + b.x*a13 + b.y*a23 + b.z*a33 ); +} + +TAffine3 TAffine3::operator*(const TAffine3 &b) const { + return TAffine3( + *this * b.rowX(), + *this * b.rowY(), + *this * b.rowZ() ); +} + +TAffine3 TAffine3::operator*=(const TAffine3 &b) + { return *this = *this * b; } + +TAffine3 TAffine3::inv() const { + TAffine3 r; + r.a11 = a22*a33 - a32*a23; + r.a12 = a32*a13 - a12*a33; + r.a13 = a12*a23 - a22*a13; + + double det = r.a11*a11 + r.a12*a21 + r.a12*a31; + det = fabs(det) > TConsts::epsilon ? 1.0/det : 0.0; + r.a11 *= det; + r.a12 *= det; + r.a13 *= det; + + r.a21 = (a31*a23 - a21*a33)*det; + r.a22 = (a11*a33 - a31*a13)*det; + r.a23 = (a21*a13 - a11*a23)*det; + r.a31 = (a21*a32 - a31*a22)*det; + r.a32 = (a31*a12 - a11*a32)*det; + r.a33 = (a11*a22 - a21*a12)*det; + return r; +} + +TAffine TAffine3::get2d() const { + return TAffine( + a11, a21, a31, + a12, a22, a32 ); +} + +TAffine3 TAffine3::translation2d(double x, double y) { + TAffine3 r; + r.rowZ().x = x; + r.rowZ().y = y; + return r; +} + +TAffine3 TAffine3::scale2d(double x, double y) { + TAffine3 r; + r.a11 = x; + r.a22 = y; + return r; +} + +TAffine3 TAffine3::rotation2d(double angle) { + TAffine3 r; + double s = sin(angle); + double c = cos(angle); + r.a11 = c; + r.a12 = s; + r.a21 = -s; + r.a22 = c; + return r; +} + +//================================================================================================== + TPoint4D TAffine4::operator*(const TPoint4D &b) const { return TPoint4D( b.x*a11 + b.y*a21 + b.z*a31 + b.w*a41, @@ -290,6 +361,13 @@ TAffine TAffine4::get2d(double z) const { a12, a22, z*a32 + a42 ); } +TAffine3 TAffine4::get2dPersp(double z) const { + return TAffine3( + TPoint3D( a11 , a12 , a14 ), + TPoint3D( a21 , a22 , a24 ), + TPoint3D( a31*z+a41 , a32*z+a42 , a34*z+a44 ) ); +} + TAffine4 TAffine4::translation(double x, double y, double z) { TAffine4 r; r.rowW().x = x; diff --git a/toonz/sources/include/tgeometry.h b/toonz/sources/include/tgeometry.h index 34b9902..67eb0f5 100644 --- a/toonz/sources/include/tgeometry.h +++ b/toonz/sources/include/tgeometry.h @@ -26,6 +26,7 @@ inline double logNormalDistribuition(double x, double x0, double w) //============================================================================= +template class TPoint3T; template class TPoint4T; /* @@ -42,6 +43,7 @@ public: inline TPointT() : x(0), y(0){}; inline TPointT(T _x, T _y) : x(_x), y(_y){}; inline TPointT(const TPointT &point) : x(point.x), y(point.y){}; + inline explicit TPointT(const TPoint3T &point); inline explicit TPointT(const TPoint4T &point); inline TPointT &operator=(const TPointT &a) { @@ -70,6 +72,23 @@ public: }; template +class TPoint3T { +public: + union { + struct { T x, y, z; }; + T a[3]; + }; + + inline TPoint3T(): + x(), y(), z() { }; + inline TPoint3T(T x, T y, T z): + x(x), y(y), z(z) { }; + inline explicit TPoint3T(const TPointT &p, T z = (T)0): + x(p.x), y(p.y), z(z) { }; + inline explicit TPoint3T(const TPoint4T &point); +}; + +template class TPoint4T { public: union { @@ -81,12 +100,19 @@ public: x(), y(), z(), w() { }; inline TPoint4T(T x, T y, T z, T w): x(x), y(y), z(z), w(w) { }; - inline explicit TPoint4T(const TPointT &p, T w = (T)1): - x(p.x), y(p.y), z(), w(w) { }; + inline explicit TPoint4T(const TPointT &p, T z = (T)0, T w = (T)1): + x(p.x), y(p.y), z(z), w(w) { }; + inline explicit TPoint4T(const TPoint3T &p, T w = (T)1): + x(p.x), y(p.y), z(p.z), w(w) { }; }; template +inline TPointT::TPointT(const TPoint3T &point) : x(point.x), y(point.y){}; +template inline TPointT::TPointT(const TPoint4T &point) : x(point.x), y(point.y){}; +template +inline TPoint3T::TPoint3T(const TPoint4T &point) : x(point.x), y(point.y), z(point.z){}; + /*! \relates TPointT * Rotate a point 90 degrees (counterclockwise). @@ -130,6 +156,7 @@ inline std::ostream &operator<<(std::ostream &out, const TPointT &p) { typedef TPointT TPoint, TPointI; typedef TPointT TPointD; +typedef TPoint3T TPoint3D; typedef TPoint4T TPoint4D; #ifdef _WIN32 @@ -1267,6 +1294,71 @@ inline std::ostream &operator<<(std::ostream &out, const TAffine &a) { //============================================================================= +//! This class performs basic manipulations of affine transformations in 2D space. +//! with ability of perspective transform +//! the matrix is transposed to TAffine and equal to OpenGL cells order + +class DVAPI TAffine3 { +public: + union { + struct { + double a11, a12, a13; + double a21, a22, a23; + double a31, a32, a33; + }; + double m[3][3]; + double a[9]; + }; + + inline TAffine3(): + a11(1.0), a12(0.0), a13(0.0), + a21(0.0), a22(1.0), a23(0.0), + a31(0.0), a32(0.0), a33(1.0) { } + + inline explicit TAffine3(const TAffine &a): + a11(a.a11), a12(a.a21), a13(0.0), + a21(a.a12), a22(a.a22), a23(0.0), + a31(a.a13), a32(a.a23), a33(1.0) { } + + inline TAffine3( + const TPoint3D &rowX, + const TPoint3D &rowY, + const TPoint3D &rowZ + ): + a11(rowX.x), a12(rowX.y), a13(rowX.z), + a21(rowY.x), a22(rowY.y), a23(rowY.z), + a31(rowZ.x), a32(rowZ.y), a33(rowZ.z) { } + + inline TPoint3D& row(int index) + { return *(TPoint3D*)(m[index]); } + inline const TPoint3D& row(int index) const + { return *(const TPoint3D*)(m[index]); } + + inline TPoint3D& rowX() { return row(0); } + inline TPoint3D& rowY() { return row(1); } + inline TPoint3D& rowZ() { return row(2); } + + inline const TPoint3D& rowX() const { return row(0); } + inline const TPoint3D& rowY() const { return row(1); } + inline const TPoint3D& rowZ() const { return row(2); } + + TPoint3D operator*(const TPoint3D &b) const; + TAffine3 operator*(const TAffine3 &b) const; + TAffine3 operator*=(const TAffine3 &b); + + TAffine3 inv() const; + + TAffine get2d() const; + + inline static TAffine3 identity() { return TAffine3(); } + static TAffine3 translation2d(double x, double y); + static TAffine3 scale2d(double x, double y); + static TAffine3 rotation2d(double angle); +}; + + +//============================================================================= + //! This class performs basic manipulations of affine transformations in 3D space. //! the matrix is transposed to TAffine and equal to OpenGL @@ -1328,6 +1420,7 @@ public: TAffine4 inv() const; TAffine get2d(double z = 0.0) const; + TAffine3 get2dPersp(double z = 0.0) const; inline static TAffine4 identity() { return TAffine4(); } static TAffine4 translation(double x, double y, double z);