diff --git a/toonz/sources/common/tvrender/tinbetween.cpp b/toonz/sources/common/tvrender/tinbetween.cpp index fce82be..2318b10 100644 --- a/toonz/sources/common/tvrender/tinbetween.cpp +++ b/toonz/sources/common/tvrender/tinbetween.cpp @@ -229,8 +229,8 @@ static void detectCorners(const TStroke *stroke, double minDegree, } } - const double ratioLen = 2.5; - const double ratioAngle = 0.2; + const double ratioLen = 2.5; + const double ratioAngle = 0.2; std::vector>::iterator it = corners.begin(); for (j = 1; j < (int)quadCount1; @@ -241,8 +241,9 @@ static void detectCorners(const TStroke *stroke, double minDegree, continue; } - if (j - 2 >= 0 && (corners.empty() || it == corners.begin() || - j - 1 != (*(it - 1)).first) && + if (j - 2 >= 0 && + (corners.empty() || it == corners.begin() || + j - 1 != (*(it - 1)).first) && j + 1 < (int)quadCount1 && (corners.empty() || it == corners.end() || j + 1 != (*it).first)) { speed1 = stroke->getChunk(j - 2)->getSpeed(1); @@ -255,7 +256,7 @@ static void detectCorners(const TStroke *stroke, double minDegree, if (tan1 * tan2 < 0) { angle = 180 - asin(tcrop(vectorialProduct, -1.0, 1.0)) * M_180_PI; - metaCornerLen = ratioLen * (stroke->getChunk(j - 1)->getLength() + + metaCornerLen = ratioLen * (stroke->getChunk(j - 1)->getLength() + stroke->getChunk(j)->getLength()); partialLen = 0; bool goodAngle = false; @@ -1480,8 +1481,8 @@ TVectorImageP TInbetween::Imp::tween(double t) const { len1 += step1; len2 += step2; } - point2 = subStroke2->getThickPointAtLength(totalLen2); - point2 = TThickPoint(m_transformation[i].m_inverse * + point2 = subStroke2->getThickPointAtLength(totalLen2); + point2 = TThickPoint(m_transformation[i].m_inverse * subStroke2->getThickPointAtLength(totalLen2), point2.thick); finalPoint = subStroke1->getThickPointAtLength(totalLen1) * (1 - t) + @@ -1554,3 +1555,20 @@ void TInbetween::Imp::transferColor(const TVectorImageP &destination) const { TVectorImageP TInbetween::tween(double t) const { return m_imp->tween(t); } //------------------------------------------------------------------- + +double TInbetween::interpolation(double t, enum TweenAlgorithm algorithm) { + // in tutte le interpolazioni : s(0) = 0, s(1) = 1 + switch (algorithm) { + case EaseInInterpolation: // s'(1) = 0 + return t * (2 - t); + case EaseOutInterpolation: // s'(0) = 0 + return t * t; + case EaseInOutInterpolation: // s'(0) = s'(1) = 0 + return t * t * (3 - 2 * t); + case LinearInterpolation: + default: + return t; + } +} + +//------------------------------------------------------------------- diff --git a/toonz/sources/include/tinbetween.h b/toonz/sources/include/tinbetween.h index 123ca7b..ce89e10 100644 --- a/toonz/sources/include/tinbetween.h +++ b/toonz/sources/include/tinbetween.h @@ -24,6 +24,15 @@ class DVAPI TInbetween { std::unique_ptr m_imp; public: + enum TweenAlgorithm { + LinearInterpolation, + EaseInInterpolation, + EaseOutInterpolation, + EaseInOutInterpolation + }; + + static double interpolation(double t, enum TweenAlgorithm); + TInbetween(const TVectorImageP firstImage, const TVectorImageP lastImage); virtual ~TInbetween(); diff --git a/toonz/sources/toonz/filmstripcommand.cpp b/toonz/sources/toonz/filmstripcommand.cpp index dc79cef..c768bab 100644 --- a/toonz/sources/toonz/filmstripcommand.cpp +++ b/toonz/sources/toonz/filmstripcommand.cpp @@ -2499,25 +2499,27 @@ void FilmstripCmd::inbetweenWithoutUndo( TVectorImageP img1 = sl->getFrame(fid1, false); if (!img0 || !img1) return; + enum TInbetween::TweenAlgorithm algorithm; + switch (interpolation) { + case II_Linear: + algorithm = TInbetween::LinearInterpolation; + break; + case II_EaseIn: + algorithm = TInbetween::EaseInInterpolation; + break; + case II_EaseOut: + algorithm = TInbetween::EaseOutInterpolation; + break; + case II_EaseInOut: + algorithm = TInbetween::EaseInOutInterpolation; + break; + } + TInbetween inbetween(img0, img1); int i; for (i = ia + 1; i < ib; i++) { double t = (double)(i - ia) / (double)(ib - ia); - double s = t; - // in tutte le interpolazioni : s(0) = 0, s(1) = 1 - switch (interpolation) { - case II_Linear: - break; - case II_EaseIn: - s = t * (2 - t); - break; // s'(1) = 0 - case II_EaseOut: - s = t * t; - break; // s'(0) = 0 - case II_EaseInOut: - s = t * t * (3 - 2 * t); - break; // s'(0) = s'(1) = 0 - } + double s = TInbetween::interpolation(t, algorithm); TVectorImageP vi = inbetween.tween(s); sl->setFrame(fids[i], vi);