tahoma2d/toonz/sources/stdfx/gradients.cpp

156 lines
4.6 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
#include "trop.h"
#include "traster.h"
#include "tspectrumparam.h"
#include "gradients.h"
2016-03-19 06:57:51 +13:00
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
namespace {
2016-03-19 06:57:51 +13:00
template <class T>
2016-06-15 18:43:10 +12:00
void doComputeRadialT(TRasterPT<T> ras, TPointD posTrasf,
const TSpectrumT<T> &spectrum, double period,
2019-08-29 14:25:57 +12:00
double count, double cycle, const TAffine &aff,
double inner = 0.0, GradientCurveType type = Linear) {
2016-06-15 18:43:10 +12:00
int j;
double maxRadius = period * count;
double freq = 1.0 / period;
ras->lock();
for (j = 0; j < ras->getLy(); j++) {
TPointD posAux = posTrasf;
T *pix = ras->pixels(j);
T *endPix = pix + ras->getLx();
while (pix < endPix) {
double radius = norm(posAux);
double t = 1;
if (radius < maxRadius) {
t = (radius + cycle) * freq;
t -= floor(t);
}
2019-08-29 14:25:57 +12:00
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);
2016-06-15 18:43:10 +12:00
posAux.x += aff.a11;
posAux.y += aff.a21;
}
posTrasf.x += aff.a12;
posTrasf.y += aff.a22;
}
ras->unlock();
2016-03-19 06:57:51 +13:00
}
2019-08-29 14:25:57 +12:00
} // namespace
2016-03-19 06:57:51 +13:00
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void multiRadial(const TRasterP &ras, TPointD posTrasf,
const TSpectrumParamP colors, double period, double count,
2019-08-29 14:25:57 +12:00
double cycle, const TAffine &aff, double frame, double inner,
GradientCurveType type) {
2016-06-15 18:43:10 +12:00
if ((TRaster32P)ras)
doComputeRadialT<TPixel32>(ras, posTrasf, colors->getValue(frame), period,
2019-08-29 14:25:57 +12:00
count, cycle, aff, inner, type);
2016-06-15 18:43:10 +12:00
else if ((TRaster64P)ras)
doComputeRadialT<TPixel64>(ras, posTrasf, colors->getValue64(frame), period,
2019-08-29 14:25:57 +12:00
count, cycle, aff, inner, type);
2016-06-15 18:43:10 +12:00
else
throw TException("MultiRadialGradientFx: unsupported Pixel Type");
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
namespace {
2016-03-19 06:57:51 +13:00
template <class T>
2016-06-15 18:43:10 +12:00
void doComputeLinearT(TRasterPT<T> ras, TPointD posTrasf,
const TSpectrumT<T> &spectrum, double period,
double count, double w_amplitude, double w_freq,
2019-08-29 14:25:57 +12:00
double w_phase, double cycle, const TAffine &aff,
GradientCurveType type = EaseInOut) {
2016-06-15 18:43:10 +12:00
double shift = 0;
double maxRadius = period * count / 2.;
double freq = 1.0 / period;
int j;
ras->lock();
for (j = 0; j < ras->getLy(); j++) {
TPointD posAux = posTrasf;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// TPointD pos = tile.m_pos;
// pos.y += j;
T *pix = ras->pixels(j);
T *endPix = pix + ras->getLx();
while (pix < endPix) {
if (w_amplitude) shift = w_amplitude * sin(w_freq * posAux.y + w_phase);
2019-08-29 14:25:57 +12:00
double radius = posAux.x + shift;
double t = 1;
2016-06-15 18:43:10 +12:00
if (fabs(radius) < maxRadius) {
t = (radius + maxRadius + cycle) * freq;
t -= floor(t);
} else if (radius < 0)
2019-08-29 14:25:57 +12:00
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;
}
2016-06-15 18:43:10 +12:00
// pos.x += 1.0;
2019-08-29 14:25:57 +12:00
*pix++ = spectrum.getPremultipliedValue(factor);
2016-06-15 18:43:10 +12:00
posAux.x += aff.a11;
posAux.y += aff.a21;
}
posTrasf.x += aff.a12;
posTrasf.y += aff.a22;
}
ras->unlock();
2016-03-19 06:57:51 +13:00
}
2019-08-29 14:25:57 +12:00
} // namespace
2016-03-19 06:57:51 +13:00
//------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void multiLinear(const TRasterP &ras, TPointD posTrasf,
const TSpectrumParamP colors, double period, double count,
double amplitude, double freq, double phase, double cycle,
2019-08-29 14:25:57 +12:00
const TAffine &aff, double frame, GradientCurveType type) {
2016-06-15 18:43:10 +12:00
if ((TRaster32P)ras)
doComputeLinearT<TPixel32>(ras, posTrasf, colors->getValue(frame), period,
2019-08-29 14:25:57 +12:00
count, amplitude, freq, phase, cycle, aff, type);
2016-06-15 18:43:10 +12:00
else if ((TRaster64P)ras)
doComputeLinearT<TPixel64>(ras, posTrasf, colors->getValue64(frame), period,
2019-08-29 14:25:57 +12:00
count, amplitude, freq, phase, cycle, aff, type);
2016-06-15 18:43:10 +12:00
else
throw TException("MultiLinearGradientFx: unsupported Pixel Type");
2016-03-19 06:57:51 +13:00
}