diff --git a/stuff/config/current.txt b/stuff/config/current.txt
index 19e32cf..a6cd128 100644
--- a/stuff/config/current.txt
+++ b/stuff/config/current.txt
@@ -240,6 +240,7 @@
- "STD_linearGradientFx.wave_phase" "Phase"
- "STD_linearGradientFx.color1" "Color 1"
- "STD_linearGradientFx.color2" "Color 2"
+ - "STD_linearGradientFx.curveType" "Type"
- "STD_linearWaveFx" "Linear Wave"
- "STD_linearWaveFx.period" "Period"
@@ -267,6 +268,7 @@
- "STD_multiLinearGradientFx.wave_frequency" "Frequency"
- "STD_multiLinearGradientFx.wave_phase" "Phase"
- "STD_multiLinearGradientFx.colors" "Colors"
+ - "STD_multiLinearGradientFx.curveType" "Type"
- "STD_localBlurFx" "Local Blur"
- "STD_localBlurFx.value" "Intensity"
@@ -324,6 +326,7 @@
- "STD_radialGradientFx.innerperiod" "Inner Size"
- "STD_radialGradientFx.color1" "Color 1"
- "STD_radialGradientFx.color2" "Color 2"
+ - "STD_radialGradientFx.curveType" "Type"
- "STD_randomWaveFx" "Random Wave"
@@ -358,6 +361,7 @@
- "STD_multiRadialGradientFx.count" "Quantity"
- "STD_multiRadialGradientFx.cycle" "Cycle"
- "STD_multiRadialGradientFx.colors" "Colors"
+ - "STD_multiRadialGradientFx.curveType" "Type"
- "STD_raylitFx" "Raylit"
- "STD_raylitFx.p" "Center X"
diff --git a/stuff/profiles/layouts/fxs/STD_linearGradientFx.xml b/stuff/profiles/layouts/fxs/STD_linearGradientFx.xml
index 7eeebcb..de531e5 100644
--- a/stuff/profiles/layouts/fxs/STD_linearGradientFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_linearGradientFx.xml
@@ -4,6 +4,7 @@
color1
color2
color1 color2
+ curveType
wave_amplitude
wave_frequency
diff --git a/stuff/profiles/layouts/fxs/STD_multiLinearGradientFx.xml b/stuff/profiles/layouts/fxs/STD_multiLinearGradientFx.xml
index 988baef..8084dfc 100644
--- a/stuff/profiles/layouts/fxs/STD_multiLinearGradientFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_multiLinearGradientFx.xml
@@ -4,6 +4,7 @@
count
cycle
colors
+ curveType
wave_amplitude
wave_frequency
diff --git a/stuff/profiles/layouts/fxs/STD_multiRadialGradientFx.xml b/stuff/profiles/layouts/fxs/STD_multiRadialGradientFx.xml
index 738463a..8966e16 100644
--- a/stuff/profiles/layouts/fxs/STD_multiRadialGradientFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_multiRadialGradientFx.xml
@@ -4,6 +4,7 @@
count
cycle
colors
+ curveType
diff --git a/stuff/profiles/layouts/fxs/STD_radialGradientFx.xml b/stuff/profiles/layouts/fxs/STD_radialGradientFx.xml
index 9a9a0d5..a5eb1d2 100644
--- a/stuff/profiles/layouts/fxs/STD_radialGradientFx.xml
+++ b/stuff/profiles/layouts/fxs/STD_radialGradientFx.xml
@@ -5,6 +5,7 @@
period
color2
color1 color2
+ curveType
diff --git a/toonz/sources/stdfx/gradients.cpp b/toonz/sources/stdfx/gradients.cpp
index 6fea2e4..89d516a 100644
--- a/toonz/sources/stdfx/gradients.cpp
+++ b/toonz/sources/stdfx/gradients.cpp
@@ -13,7 +13,8 @@ namespace {
template
void doComputeRadialT(TRasterPT ras, TPointD posTrasf,
const TSpectrumT &spectrum, double period,
- double count, double cycle, const TAffine &aff) {
+ double count, double cycle, const TAffine &aff,
+ double inner = 0.0, GradientCurveType type = Linear) {
int j;
double maxRadius = period * count;
double freq = 1.0 / period;
@@ -29,8 +30,30 @@ void doComputeRadialT(TRasterPT ras, TPointD posTrasf,
t = (radius + cycle) * freq;
t -= floor(t);
}
- // double polinomfactor=(-2*t+3)*(t*t);
- *pix++ = spectrum.getPremultipliedValue(t);
+
+ if (t <= inner)
+ t = 0;
+ else
+ t = (t - inner) / (1.0 - inner);
+
+ double factor;
+ switch (type) {
+ case Linear:
+ factor = t;
+ break;
+ case EaseIn:
+ factor = t * t;
+ break;
+ case EaseOut:
+ factor = 1.0 - (1.0 - t) * (1.0 - t);
+ break;
+ case EaseInOut:
+ default:
+ factor = (-2 * t + 3) * (t * t);
+ break;
+ }
+ *pix++ = spectrum.getPremultipliedValue(factor);
+
posAux.x += aff.a11;
posAux.y += aff.a21;
}
@@ -39,19 +62,20 @@ void doComputeRadialT(TRasterPT ras, TPointD posTrasf,
}
ras->unlock();
}
-}
+} // namespace
//------------------------------------------------------------------
void multiRadial(const TRasterP &ras, TPointD posTrasf,
const TSpectrumParamP colors, double period, double count,
- double cycle, const TAffine &aff, double frame) {
+ double cycle, const TAffine &aff, double frame, double inner,
+ GradientCurveType type) {
if ((TRaster32P)ras)
doComputeRadialT(ras, posTrasf, colors->getValue(frame), period,
- count, cycle, aff);
+ count, cycle, aff, inner, type);
else if ((TRaster64P)ras)
doComputeRadialT(ras, posTrasf, colors->getValue64(frame), period,
- count, cycle, aff);
+ count, cycle, aff, inner, type);
else
throw TException("MultiRadialGradientFx: unsupported Pixel Type");
}
@@ -63,7 +87,8 @@ template
void doComputeLinearT(TRasterPT ras, TPointD posTrasf,
const TSpectrumT &spectrum, double period,
double count, double w_amplitude, double w_freq,
- double w_phase, double cycle, const TAffine &aff) {
+ double w_phase, double cycle, const TAffine &aff,
+ GradientCurveType type = EaseInOut) {
double shift = 0;
double maxRadius = period * count / 2.;
double freq = 1.0 / period;
@@ -78,16 +103,32 @@ void doComputeLinearT(TRasterPT ras, TPointD posTrasf,
T *endPix = pix + ras->getLx();
while (pix < endPix) {
if (w_amplitude) shift = w_amplitude * sin(w_freq * posAux.y + w_phase);
- double radius = posAux.x + shift;
- double t = 1;
+ double radius = posAux.x + shift;
+ double t = 1;
if (fabs(radius) < maxRadius) {
t = (radius + maxRadius + cycle) * freq;
t -= floor(t);
} else if (radius < 0)
- t = 0;
- double polinomfactor = (-2 * t + 3) * (t * t);
+ t = 0;
+
+ double factor;
+ switch (type) {
+ case Linear:
+ factor = t;
+ break;
+ case EaseIn:
+ factor = t * t;
+ break;
+ case EaseOut:
+ factor = 1.0 - (1.0 - t) * (1.0 - t);
+ break;
+ case EaseInOut:
+ default:
+ factor = (-2 * t + 3) * (t * t);
+ break;
+ }
// pos.x += 1.0;
- *pix++ = spectrum.getPremultipliedValue(polinomfactor);
+ *pix++ = spectrum.getPremultipliedValue(factor);
posAux.x += aff.a11;
posAux.y += aff.a21;
}
@@ -96,19 +137,19 @@ void doComputeLinearT(TRasterPT ras, TPointD posTrasf,
}
ras->unlock();
}
-}
+} // namespace
//------------------------------------------------------------------
void multiLinear(const TRasterP &ras, TPointD posTrasf,
const TSpectrumParamP colors, double period, double count,
double amplitude, double freq, double phase, double cycle,
- const TAffine &aff, double frame) {
+ const TAffine &aff, double frame, GradientCurveType type) {
if ((TRaster32P)ras)
doComputeLinearT(ras, posTrasf, colors->getValue(frame), period,
- count, amplitude, freq, phase, cycle, aff);
+ count, amplitude, freq, phase, cycle, aff, type);
else if ((TRaster64P)ras)
doComputeLinearT(ras, posTrasf, colors->getValue64(frame), period,
- count, amplitude, freq, phase, cycle, aff);
+ count, amplitude, freq, phase, cycle, aff, type);
else
throw TException("MultiLinearGradientFx: unsupported Pixel Type");
}
diff --git a/toonz/sources/stdfx/gradients.h b/toonz/sources/stdfx/gradients.h
index 411512d..2650374 100644
--- a/toonz/sources/stdfx/gradients.h
+++ b/toonz/sources/stdfx/gradients.h
@@ -15,17 +15,21 @@ struct MultiRAdialParams {
double m_gridStep;
};
+enum GradientCurveType { EaseInOut = 0, Linear, EaseIn, EaseOut };
+
/*---------------------------------------------------------------------------*/
//! Deals with raster tiles and invokes multiradial functions
void multiRadial(const TRasterP &ras, TPointD posTrasf,
const TSpectrumParamP colors, double period, double count,
- double cycle, const TAffine &aff, double frame);
+ double cycle, const TAffine &aff, double frame,
+ double inner = 0.0, GradientCurveType type = Linear);
void multiLinear(const TRasterP &ras, TPointD posTrasf,
const TSpectrumParamP colors, double period, double count,
double amplitude, double freq, double phase, double cycle,
- const TAffine &aff, double frame);
+ const TAffine &aff, double frame,
+ GradientCurveType type = EaseInOut);
#endif
diff --git a/toonz/sources/stdfx/stdfx.cpp b/toonz/sources/stdfx/stdfx.cpp
index cd8499b..2f11f6c 100644
--- a/toonz/sources/stdfx/stdfx.cpp
+++ b/toonz/sources/stdfx/stdfx.cpp
@@ -174,6 +174,8 @@ class MultiLinearGradientFx final : public TStandardZeraryFx {
TDoubleParamP m_wave_phase;
TSpectrumParamP m_colors;
+ TIntEnumParamP m_curveType;
+
public:
MultiLinearGradientFx()
: m_period(100) // args, "Period")
@@ -182,8 +184,12 @@ public:
, m_wave_amplitude(0.0) // args, "Cycle")
, m_wave_freq(0.0) // args, "Cycle")
, m_wave_phase(0.0) // args, "Cycle")
- // , m_colors (0) //args, "Colors")
- {
+ // , m_colors (0) //args, "Colors")
+ , m_curveType(new TIntEnumParam(EaseInOut, "Ease In-Out")) {
+ m_curveType->addItem(Linear, "Linear");
+ m_curveType->addItem(EaseIn, "Ease In");
+ m_curveType->addItem(EaseOut, "Ease Out");
+
std::vector colors = {
TSpectrum::ColorKey(0, TPixel32::White),
TSpectrum::ColorKey(0.33, TPixel32::Yellow),
@@ -198,6 +204,8 @@ public:
bindParam(this, "wave_frequency", m_wave_freq);
bindParam(this, "wave_phase", m_wave_phase);
bindParam(this, "colors", m_colors);
+ bindParam(this, "curveType", m_curveType);
+
m_period->setValueRange(0, (std::numeric_limits::max)());
m_cycle->setValueRange(0, (std::numeric_limits::max)());
m_wave_amplitude->setValueRange(0, (std::numeric_limits::max)());
@@ -238,6 +246,8 @@ class LinearGradientFx final : public TStandardZeraryFx {
TPixelParamP m_color1;
TPixelParamP m_color2;
+ TIntEnumParamP m_curveType;
+
public:
LinearGradientFx()
: m_period(100) // args, "Period")
@@ -246,14 +256,20 @@ public:
, m_wave_phase(0.0) // args, "Cycle")
, m_color1(TPixel32::Black)
, m_color2(TPixel32::White)
- // , m_colors (0) //args, "Colors")
- {
+ // , m_colors (0) //args, "Colors")
+ , m_curveType(new TIntEnumParam(EaseInOut, "Ease In-Out")) {
+ m_curveType->addItem(Linear, "Linear");
+ m_curveType->addItem(EaseIn, "Ease In");
+ m_curveType->addItem(EaseOut, "Ease Out");
+
bindParam(this, "period", m_period);
bindParam(this, "wave_amplitude", m_wave_amplitude);
bindParam(this, "wave_frequency", m_wave_freq);
bindParam(this, "wave_phase", m_wave_phase);
bindParam(this, "color1", m_color1);
bindParam(this, "color2", m_color2);
+ bindParam(this, "curveType", m_curveType);
+
m_period->setValueRange(0, std::numeric_limits::max());
m_wave_amplitude->setValueRange(0, std::numeric_limits::max());
m_period->setMeasureName("fxLength");
@@ -346,7 +362,8 @@ void LinearGradientFx::doCompute(TTile &tile, double frame,
TAffine aff = ri.m_affine.inv();
TPointD posTrasf = aff * tile.m_pos;
multiLinear(tile.getRaster(), posTrasf, m_colors, period, count, w_amplitude,
- w_freq, w_phase, cycle, aff, frame);
+ w_freq, w_phase, cycle, aff, frame,
+ (GradientCurveType)m_curveType->getValue());
/*
if (TRaster32P ras32 = tile.getRaster())
doComputeT(
@@ -380,7 +397,8 @@ void MultiLinearGradientFx::doCompute(TTile &tile, double frame,
TAffine aff = ri.m_affine.inv();
TPointD posTrasf = aff * tile.m_pos;
multiLinear(tile.getRaster(), posTrasf, m_colors, period, count, w_amplitude,
- w_freq, w_phase, cycle, aff, frame);
+ w_freq, w_phase, cycle, aff, frame,
+ (GradientCurveType)m_curveType->getValue());
/*
if (TRaster32P ras32 = tile.getRaster())
doComputeT(
@@ -406,20 +424,30 @@ class RadialGradientFx final : public TStandardZeraryFx {
TPixelParamP m_color1;
TPixelParamP m_color2;
+ TIntEnumParamP m_curveType;
+
public:
RadialGradientFx()
: m_period(100.0)
, m_innerperiod(0.0) // args, "Period")
, m_color1(TPixel32::White)
, m_color2(TPixel32::Transparent)
- // , m_colors (0) //args, "Colors")
- {
+ // , m_colors (0) //args, "Colors")
+ , m_curveType(new TIntEnumParam()) {
+ m_curveType->addItem(EaseInOut, "Ease In-Out");
+ m_curveType->addItem(Linear, "Linear");
+ m_curveType->addItem(EaseIn, "Ease In");
+ m_curveType->addItem(EaseOut, "Ease Out");
+ m_curveType->setDefaultValue(Linear);
+ m_curveType->setValue(Linear);
+
m_period->setMeasureName("fxLength");
m_innerperiod->setMeasureName("fxLength");
bindParam(this, "period", m_period);
bindParam(this, "innerperiod", m_innerperiod);
bindParam(this, "color1", m_color1);
bindParam(this, "color2", m_color2);
+ bindParam(this, "curveType", m_curveType);
m_period->setValueRange(0.0, std::numeric_limits::max());
m_innerperiod->setValueRange(0.0, std::numeric_limits::max());
}
@@ -458,13 +486,22 @@ class MultiRadialGradientFx final : public TStandardZeraryFx {
TDoubleParamP m_cycle;
TSpectrumParamP m_colors;
+ TIntEnumParamP m_curveType;
+
public:
MultiRadialGradientFx()
: m_period(100) // args, "Period")
, m_count(2) // args, "Count")
, m_cycle(0.0) // args, "Count")
- // , m_colors (0) //args, "Colors")
- {
+ // , m_colors (0) //args, "Colors")
+ , m_curveType(new TIntEnumParam()) {
+ m_curveType->addItem(EaseInOut, "Ease In-Out");
+ m_curveType->addItem(Linear, "Linear");
+ m_curveType->addItem(EaseIn, "Ease In");
+ m_curveType->addItem(EaseOut, "Ease Out");
+ m_curveType->setDefaultValue(Linear);
+ m_curveType->setValue(Linear);
+
m_period->setMeasureName("fxLength");
std::vector colors = {
TSpectrum::ColorKey(0, TPixel32::White),
@@ -477,6 +514,7 @@ public:
bindParam(this, "count", m_count);
bindParam(this, "cycle", m_cycle);
bindParam(this, "colors", m_colors);
+ bindParam(this, "curveType", m_curveType);
m_period->setValueRange(0, (std::numeric_limits::max)());
m_cycle->setValueRange(0, (std::numeric_limits::max)());
m_count->setValueRange(0, (std::numeric_limits::max)());
@@ -517,7 +555,7 @@ void MultiRadialGradientFx::doCompute(TTile &tile, double frame,
TAffine aff = ri.m_affine.inv();
TPointD posTrasf = aff * tile.m_pos;
multiRadial(tile.getRaster(), posTrasf, m_colors, period, count, cycle, aff,
- frame);
+ frame, 0.0, (GradientCurveType)m_curveType->getValue());
}
//==================================================================
@@ -536,13 +574,12 @@ void RadialGradientFx::doCompute(TTile &tile, double frame,
inner = 1 - TConsts::epsilon;
std::vector colors = {
TSpectrum::ColorKey(0, m_color1->getValue(frame)),
- TSpectrum::ColorKey(inner, m_color1->getValue(frame)),
TSpectrum::ColorKey(1, m_color2->getValue(frame))};
TSpectrumParamP m_colors = TSpectrumParamP(colors);
TAffine aff = ri.m_affine.inv();
TPointD posTrasf = aff * tile.m_pos;
multiRadial(tile.getRaster(), posTrasf, m_colors, period, count, cycle, aff,
- frame);
+ frame, inner, (GradientCurveType)m_curveType->getValue());
}
//------------------------------------------------------------------