From b48b31570bc2b22ceb6d1ae729b7108a770fb56e Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Sep 17 2023 13:15:59 +0000 Subject: #assistants: fish eye depth grid --- diff --git a/toonz/sources/tnztools/assistants/assistantellipse.cpp b/toonz/sources/tnztools/assistants/assistantellipse.cpp index c7b5646..31a8965 100644 --- a/toonz/sources/tnztools/assistants/assistantellipse.cpp +++ b/toonz/sources/tnztools/assistants/assistantellipse.cpp @@ -16,6 +16,7 @@ TAssistantEllipse::TAssistantEllipse(TMetaObject &object): m_idRepeat("repeat"), m_idGrid("grid"), m_idPerspective("perspective"), + m_idPerspectiveDepth("perspectiveDepth"), m_center( addPoint("center", TAssistantPoint::CircleCross) ), m_a( addPoint("a", TAssistantPoint::CircleFill, TPointD(150, 0)) ), m_b( addPoint("b", TAssistantPoint::Circle, TPointD( 0, 100)) ), @@ -28,6 +29,7 @@ TAssistantEllipse::TAssistantEllipse(TMetaObject &object): addProperty( new TBoolProperty(m_idRepeat.str(), getRepeat()) ); addProperty( new TBoolProperty(m_idGrid.str(), getGrid()) ); addProperty( new TBoolProperty(m_idPerspective.str(), getPerspective()) ); + addProperty( new TBoolProperty(m_idPerspectiveDepth.str(), getPerspectiveDepth()) ); } @@ -43,6 +45,7 @@ void TAssistantEllipse::updateTranslation() const { setTranslation(m_idRepeat, tr("Repeat")); setTranslation(m_idGrid, tr("Grid")); setTranslation(m_idPerspective, tr("Perspective")); + setTranslation(m_idPerspectiveDepth, tr("Depth")); } @@ -404,6 +407,7 @@ void TAssistantEllipse::drawParallelGrid( const TPointD &grid0, const TPointD &grid1, bool perspective, + bool perspectiveDepth, bool repeat, double alpha ) { @@ -434,6 +438,38 @@ void TAssistantEllipse::drawParallelGrid( TAngleRangeSet ranges; ranges.add( TAngleRangeSet::fromDouble(0.0), TAngleRangeSet::fromDouble(M_PI) ); + if (perspectiveDepth) { + if (!( fabs(gs0) > TConsts::epsilon + && fabs(gs1) > TConsts::epsilon + && fabs(gs0) < 1 - TConsts::epsilon + && fabs(gs1) < 1 - TConsts::epsilon + && fabs(gs1 - gs0) > TConsts::epsilon )) return; + + // the formula is: x = 1/sqrt(1 + i*i) + double ig0 = sqrt(1/(gs0*gs0) - 1); + double ig1 = sqrt(1/(gs1*gs1) - 1); + double di = fabs(ig1 - ig0); + double i0 = ig0 - floor(ig0/di)*di; + if (i0 <= TConsts::epsilon) i0 += di; + + actualMinStep /= 2; + double sign = gs0 < 0 ? -1 : 1; + for(double i = i0; i+di != i; i += di) { + double x = 1/sqrt(1 + i*i); + + double curStep = fabs( di*i*x*x*x ); + double curAlpha = (curStep - actualMinStep)/actualMinStep; + if (curAlpha < 0) { if (i == i0) continue; else break; } + if (curAlpha > 1) curAlpha = 1; + + drawEllipseRanges( + ranges, + ellipseMatrix*TAffine::scale(sign, x*sign), + screenMatrixInv, + pixelSize, + alpha * curAlpha ); + } + } else if (perspective) { // draw perspective if (!( fabs(gs0) < 1 - TConsts::epsilon @@ -441,7 +477,6 @@ void TAssistantEllipse::drawParallelGrid( && fabs(gs1 - gs0) > TConsts::epsilon )) return; // the formula is: x = i/sqrt(1 + i*i) - double ig0 = gs0/sqrt(1 - gs0*gs0); double ig1 = gs1/sqrt(1 - gs1*gs1); double di = fabs(ig1 - ig0); @@ -453,7 +488,7 @@ void TAssistantEllipse::drawParallelGrid( double x = i/sqrt(1 + i*i); double curAlpha = 1; - if (fabs(i0) > TConsts::epsilon) { + if (fabs(i) > TConsts::epsilon) { double curStep = fabs( di*x*(1 - x*x)/i ); curAlpha = (curStep - actualMinStep)/actualMinStep; if (curAlpha < 0) { if (i == i0) continue; else break; } @@ -532,6 +567,7 @@ void TAssistantEllipse::draw( m_grid0.position, m_grid1.position, getPerspective(), + getPerspectiveDepth(), getRepeat(), gridAlpha ); } diff --git a/toonz/sources/tnztools/assistants/assistantellipse.h b/toonz/sources/tnztools/assistants/assistantellipse.h index dfef625..0838cf2 100644 --- a/toonz/sources/tnztools/assistants/assistantellipse.h +++ b/toonz/sources/tnztools/assistants/assistantellipse.h @@ -29,6 +29,7 @@ public: const TStringId m_idRepeat; const TStringId m_idGrid; const TStringId m_idPerspective; + const TStringId m_idPerspectiveDepth; protected: TAssistantPoint &m_center; @@ -56,6 +57,8 @@ public: { return data()[m_idGrid].getBool(); } inline bool getPerspective() const { return data()[m_idPerspective].getBool(); } + inline bool getPerspectiveDepth() const + { return data()[m_idPerspectiveDepth].getBool(); } void onDataChanged(const TVariant &value) override; @@ -108,6 +111,7 @@ public: const TPointD &grid0, const TPointD &grid1, bool perspective, + bool perspectiveDepth, bool repeat, double alpha ); diff --git a/toonz/sources/tnztools/assistants/assistantfisheye.cpp b/toonz/sources/tnztools/assistants/assistantfisheye.cpp index cdde562..d91fca4 100644 --- a/toonz/sources/tnztools/assistants/assistantfisheye.cpp +++ b/toonz/sources/tnztools/assistants/assistantfisheye.cpp @@ -23,6 +23,7 @@ class TAssistantFisheye final : public TAssistant { public: const TStringId m_idCircle; const TStringId m_idGrid; + const TStringId m_idGridDepth; protected: TAssistantPoint &m_center; @@ -30,20 +31,26 @@ protected: TAssistantPoint &m_b; TAssistantPoint &m_grid0; TAssistantPoint &m_grid1; + TAssistantPoint &m_gridD0; + TAssistantPoint &m_gridD1; public: TAssistantFisheye(TMetaObject &object): TAssistant(object), m_idCircle("circle"), m_idGrid("grid"), + m_idGridDepth("gridDepth"), m_center( addPoint("center", TAssistantPoint::CircleCross) ), m_a( addPoint("a", TAssistantPoint::CircleFill, TPointD(200, 0)) ), m_b( addPoint("b", TAssistantPoint::Circle, TPointD( 0, 200)) ), - m_grid0( addPoint("grid0", TAssistantPoint::CircleDoubleDots, TPointD( -25, 25)) ), - m_grid1( addPoint("grid1", TAssistantPoint::CircleDots, TPointD( 25, -25)) ) + m_grid0( addPoint("grid0", TAssistantPoint::CircleDoubleDots, TPointD( -25, 25)) ), + m_grid1( addPoint("grid1", TAssistantPoint::CircleDots, TPointD( 25, -25)) ), + m_gridD0( addPoint("gridD0", TAssistantPoint::CircleDoubleDots, TPointD( -70, -70)) ), + m_gridD1( addPoint("gridD1", TAssistantPoint::CircleDots, TPointD( -90, -90)) ) { addProperty( new TBoolProperty(m_idCircle.str(), getCircle()) ); addProperty( new TBoolProperty(m_idGrid.str(), getGrid()) ); + addProperty( new TBoolProperty(m_idGridDepth.str(), getGridDepth()) ); } static QString getLocalName() @@ -53,21 +60,24 @@ public: TAssistant::updateTranslation(); setTranslation(m_idCircle, tr("Circle")); setTranslation(m_idGrid, tr("Grid")); + setTranslation(m_idGridDepth, tr("Depth Grid")); } inline bool getCircle() const { return data()[m_idCircle].getBool(); } inline bool getGrid() const { return data()[m_idGrid].getBool(); } + inline bool getGridDepth() const + { return data()[m_idGridDepth].getBool(); } void onDataChanged(const TVariant &value) override { TAssistant::onDataChanged(value); - m_grid0.visible = m_grid1.visible = getGrid(); - if (getCircle() == m_b.visible) { - m_b.visible = !getCircle(); - if (!m_b.visible) - fixBAndGrid(m_center.position, m_a.position, m_b.position); - } + m_grid0.visible = m_grid1.visible = getGrid(); + m_gridD0.visible = m_gridD1.visible = getGridDepth(); + bool prevB = m_b.visible; + m_b.visible = !getCircle(); + if (prevB && !m_b.visible) + fixBAndGrid(m_center.position, m_a.position, m_b.position); } private: @@ -100,10 +110,14 @@ private: if (!(lb0 > TConsts::epsilon) || !(lb1 > TConsts::epsilon)) return; - TPointD dg0 = m_grid0.position - center; - TPointD dg1 = m_grid1.position - center; - m_grid0.position = dg0*da0/la0*da1 + dg0*db0/lb0*db1 + center; - m_grid1.position = dg1*da0/la0*da1 + dg1*db0/lb0*db1 + center; + TPointD dg0 = m_grid0.position - center; + TPointD dg1 = m_grid1.position - center; + TPointD dgD0 = m_gridD0.position - center; + TPointD dgD1 = m_gridD1.position - center; + m_grid0.position = dg0*da0/la0*da1 + dg0*db0/lb0*db1 + center; + m_grid1.position = dg1*da0/la0*da1 + dg1*db0/lb0*db1 + center; + m_gridD0.position = dgD0*da0/la0*da1 + dgD0*db0/lb0*db1 + center; + m_gridD1.position = dgD1*da0/la0*da1 + dgD1*db0/lb0*db1 + center; } @@ -119,6 +133,8 @@ public: m_b.position += d; m_grid0.position += d; m_grid1.position += d; + m_gridD0.position += d; + m_gridD1.position += d; } else if (&point == &m_a || &point == &m_b) { fixBAndGrid(prevCenter, prevA, prevB); @@ -217,6 +233,7 @@ public: m_grid1.position, true, false, + false, getDrawingGridAlpha() ); std::swap(ellipseMatrix.a11, ellipseMatrix.a12); @@ -228,6 +245,30 @@ public: m_grid1.position, true, false, + false, + getDrawingGridAlpha() ); + } + + if (getGridDepth()) { + TAssistantEllipse::drawParallelGrid( + ellipseMatrix, + m_gridD0.position, + m_gridD1.position, + false, + true, + false, + getDrawingGridAlpha() ); + + std::swap(ellipseMatrix.a11, ellipseMatrix.a12); + std::swap(ellipseMatrix.a21, ellipseMatrix.a22); + + TAssistantEllipse::drawParallelGrid( + ellipseMatrix, + m_gridD0.position, + m_gridD1.position, + false, + true, + false, getDrawingGridAlpha() ); } }