|
shun-iwasawa |
00ed45 |
#include "iwa_spingradientfx.h"
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
#include "trop.h"
|
|
shun-iwasawa |
00ed45 |
#include "tparamuiconcept.h"
|
|
shun-iwasawa |
00ed45 |
#include "tspectrumparam.h"
|
|
shun-iwasawa |
00ed45 |
#include "gradients.h"
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
#include <qpolygonf></qpolygonf>
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
#include <array></array>
|
|
shun-iwasawa |
00ed45 |
#include <algorithm></algorithm>
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
//------------------------------------------------------------
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
Iwa_SpinGradientFx::Iwa_SpinGradientFx()
|
|
shun-iwasawa |
00ed45 |
: m_center(TPointD(0.0, 0.0))
|
|
shun-iwasawa |
00ed45 |
, m_startAngle(0.0)
|
|
shun-iwasawa |
00ed45 |
, m_endAngle(0.0)
|
|
shun-iwasawa |
00ed45 |
, m_startColor(TPixel32::Black)
|
|
shun-iwasawa |
00ed45 |
, m_endColor(TPixel32::White)
|
|
shun-iwasawa |
00ed45 |
, m_curveType(new TIntEnumParam()) {
|
|
shun-iwasawa |
00ed45 |
m_center->getX()->setMeasureName("fxLength");
|
|
shun-iwasawa |
00ed45 |
m_center->getY()->setMeasureName("fxLength");
|
|
shun-iwasawa |
00ed45 |
bindParam(this, "center", m_center);
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
m_startAngle->setValueRange(-360, 720);
|
|
shun-iwasawa |
00ed45 |
m_endAngle->setValueRange(-360, 720);
|
|
shun-iwasawa |
00ed45 |
bindParam(this, "startAngle", m_startAngle);
|
|
shun-iwasawa |
00ed45 |
bindParam(this, "endAngle", m_endAngle);
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
m_curveType->addItem(EaseInOut, "Ease In-Out");
|
|
shun-iwasawa |
00ed45 |
m_curveType->addItem(Linear, "Linear");
|
|
shun-iwasawa |
00ed45 |
m_curveType->addItem(EaseIn, "Ease In");
|
|
shun-iwasawa |
00ed45 |
m_curveType->addItem(EaseOut, "Ease Out");
|
|
shun-iwasawa |
00ed45 |
m_curveType->setDefaultValue(Linear);
|
|
shun-iwasawa |
00ed45 |
m_curveType->setValue(Linear);
|
|
shun-iwasawa |
00ed45 |
bindParam(this, "curveType", m_curveType);
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
bindParam(this, "startColor", m_startColor);
|
|
shun-iwasawa |
00ed45 |
bindParam(this, "endColor", m_endColor);
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
enableComputeInFloat(true);
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
//------------------------------------------------------------
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
bool Iwa_SpinGradientFx::doGetBBox(double frame, TRectD &bBox,
|
|
shun-iwasawa |
00ed45 |
const TRenderSettings &ri) {
|
|
shun-iwasawa |
00ed45 |
bBox = TConsts::infiniteRectD;
|
|
shun-iwasawa |
00ed45 |
return true;
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
//------------------------------------------------------------
|
|
shun-iwasawa |
00ed45 |
namespace {
|
|
shun-iwasawa |
00ed45 |
template <typename pixel="" raster,="" typename=""></typename>
|
|
shun-iwasawa |
00ed45 |
void doSpinGradientT(RASTER ras, TDimensionI dim, TPointD centerPos,
|
|
shun-iwasawa |
00ed45 |
double startAngle, double endAngle,
|
|
shun-iwasawa |
00ed45 |
const TSpectrumT<pixel> &spectrum,</pixel>
|
|
shun-iwasawa |
00ed45 |
GradientCurveType type) {
|
|
shun-iwasawa |
00ed45 |
auto getFactor = [&](double angle) {
|
|
shun-iwasawa |
00ed45 |
double p = angle - startAngle;
|
|
shun-iwasawa |
00ed45 |
if (p < 0) p += 2.0 * M_PI;
|
|
shun-iwasawa |
00ed45 |
double range = endAngle - startAngle;
|
|
shun-iwasawa |
00ed45 |
if (range <= 0) range += 2.0 * M_PI;
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
double t;
|
|
shun-iwasawa |
00ed45 |
if (range >= p)
|
|
shun-iwasawa |
00ed45 |
t = p / range;
|
|
shun-iwasawa |
00ed45 |
else if (M_PI + range / 2.0 > p)
|
|
shun-iwasawa |
00ed45 |
t = 1.0;
|
|
shun-iwasawa |
00ed45 |
else
|
|
shun-iwasawa |
00ed45 |
t = 0.0;
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
double factor;
|
|
shun-iwasawa |
00ed45 |
switch (type) {
|
|
shun-iwasawa |
00ed45 |
case Linear:
|
|
shun-iwasawa |
00ed45 |
factor = t;
|
|
shun-iwasawa |
00ed45 |
break;
|
|
shun-iwasawa |
00ed45 |
case EaseIn:
|
|
shun-iwasawa |
00ed45 |
factor = t * t;
|
|
shun-iwasawa |
00ed45 |
break;
|
|
shun-iwasawa |
00ed45 |
case EaseOut:
|
|
shun-iwasawa |
00ed45 |
factor = 1.0 - (1.0 - t) * (1.0 - t);
|
|
shun-iwasawa |
00ed45 |
break;
|
|
shun-iwasawa |
00ed45 |
case EaseInOut:
|
|
shun-iwasawa |
00ed45 |
default:
|
|
shun-iwasawa |
00ed45 |
factor = (-2 * t + 3) * (t * t);
|
|
shun-iwasawa |
00ed45 |
break;
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
return factor;
|
|
shun-iwasawa |
00ed45 |
};
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
ras->lock();
|
|
shun-iwasawa |
00ed45 |
for (int j = 0; j < ras->getLy(); j++) {
|
|
shun-iwasawa |
00ed45 |
PIXEL *pix = ras->pixels(j);
|
|
shun-iwasawa |
00ed45 |
PIXEL *endPix = pix + ras->getLx();
|
|
shun-iwasawa |
00ed45 |
double dy = (double)j - centerPos.y;
|
|
shun-iwasawa |
00ed45 |
double dx = -centerPos.x;
|
|
shun-iwasawa |
00ed45 |
while (pix < endPix) {
|
|
shun-iwasawa |
00ed45 |
double angle = std::atan2(dy, dx);
|
|
shun-iwasawa |
00ed45 |
double factor = getFactor(angle);
|
|
shun-iwasawa |
00ed45 |
*pix++ = spectrum.getPremultipliedValue(factor);
|
|
shun-iwasawa |
00ed45 |
dx += 1.0;
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
ras->unlock();
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
} // namespace
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
//------------------------------------------------------------
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
void Iwa_SpinGradientFx::doCompute(TTile &tile, double frame,
|
|
shun-iwasawa |
00ed45 |
const TRenderSettings &ri) {
|
|
shun-iwasawa |
481b59 |
if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster()) &&
|
|
shun-iwasawa |
481b59 |
!((TRasterFP)tile.getRaster())) {
|
|
shun-iwasawa |
00ed45 |
throw TRopException("unsupported input pixel type");
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
// convert shape position to render region coordinate
|
|
shun-iwasawa |
00ed45 |
TAffine aff = ri.m_affine;
|
|
shun-iwasawa |
00ed45 |
TDimensionI dimOut(tile.getRaster()->getLx(), tile.getRaster()->getLy());
|
|
shun-iwasawa |
00ed45 |
TPointD dimOffset((float)dimOut.lx / 2.0f, (float)dimOut.ly / 2.0f);
|
|
shun-iwasawa |
00ed45 |
TPointD centerPos = aff * m_center->getValue(frame) -
|
|
shun-iwasawa |
00ed45 |
(tile.m_pos + tile.getRaster()->getCenterD()) + dimOffset;
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
std::vector<tspectrum::colorkey> colors = {</tspectrum::colorkey>
|
|
shun-iwasawa |
00ed45 |
TSpectrum::ColorKey(0, m_startColor->getValue(frame)),
|
|
shun-iwasawa |
00ed45 |
TSpectrum::ColorKey(1, m_endColor->getValue(frame))};
|
|
shun-iwasawa |
00ed45 |
TSpectrumParamP m_colors = TSpectrumParamP(colors);
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
auto conv2RadianAndClamp = [](double angle) {
|
|
shun-iwasawa |
00ed45 |
double ret = angle * M_PI / 180.0;
|
|
shun-iwasawa |
00ed45 |
while (ret < -M_PI) {
|
|
shun-iwasawa |
00ed45 |
ret += 2.0 * M_PI;
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
while (ret >= M_PI) {
|
|
shun-iwasawa |
00ed45 |
ret -= 2.0 * M_PI;
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
return ret;
|
|
shun-iwasawa |
00ed45 |
};
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
double startAngle = conv2RadianAndClamp(m_startAngle->getValue(frame));
|
|
shun-iwasawa |
00ed45 |
double endAngle = conv2RadianAndClamp(m_endAngle->getValue(frame));
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
tile.getRaster()->clear();
|
|
shun-iwasawa |
00ed45 |
TRaster32P outRas32 = (TRaster32P)tile.getRaster();
|
|
shun-iwasawa |
00ed45 |
TRaster64P outRas64 = (TRaster64P)tile.getRaster();
|
|
shun-iwasawa |
481b59 |
TRasterFP outRasF = (TRasterFP)tile.getRaster();
|
|
shun-iwasawa |
00ed45 |
if (outRas32)
|
|
shun-iwasawa |
00ed45 |
doSpinGradientT<traster32p, tpixel32="">(</traster32p,>
|
|
shun-iwasawa |
00ed45 |
outRas32, dimOut, centerPos, startAngle, endAngle,
|
|
shun-iwasawa |
00ed45 |
m_colors->getValue(frame), (GradientCurveType)m_curveType->getValue());
|
|
shun-iwasawa |
00ed45 |
else if (outRas64)
|
|
shun-iwasawa |
00ed45 |
doSpinGradientT<traster64p, tpixel64="">(</traster64p,>
|
|
shun-iwasawa |
00ed45 |
outRas64, dimOut, centerPos, startAngle, endAngle,
|
|
shun-iwasawa |
00ed45 |
m_colors->getValue64(frame),
|
|
shun-iwasawa |
00ed45 |
(GradientCurveType)m_curveType->getValue());
|
|
shun-iwasawa |
481b59 |
else if (outRasF)
|
|
shun-iwasawa |
481b59 |
doSpinGradientT<trasterfp, tpixelf="">(</trasterfp,>
|
|
shun-iwasawa |
481b59 |
outRasF, dimOut, centerPos, startAngle, endAngle,
|
|
shun-iwasawa |
481b59 |
m_colors->getValueF(frame), (GradientCurveType)m_curveType->getValue());
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
//------------------------------------------------------------
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
void Iwa_SpinGradientFx::getParamUIs(TParamUIConcept *&concepts, int &length) {
|
|
shun-iwasawa |
00ed45 |
concepts = new TParamUIConcept[length = 2];
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
concepts[0].m_type = TParamUIConcept::ANGLE_2;
|
|
shun-iwasawa |
00ed45 |
concepts[0].m_label = "Angle";
|
|
shun-iwasawa |
00ed45 |
concepts[0].m_params.push_back(m_startAngle);
|
|
shun-iwasawa |
00ed45 |
concepts[0].m_params.push_back(m_endAngle);
|
|
shun-iwasawa |
00ed45 |
concepts[0].m_params.push_back(m_center);
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
concepts[1].m_type = TParamUIConcept::POINT;
|
|
shun-iwasawa |
00ed45 |
concepts[1].m_label = "Center";
|
|
shun-iwasawa |
00ed45 |
concepts[1].m_params.push_back(m_center);
|
|
shun-iwasawa |
00ed45 |
}
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
//------------------------------------------------------------
|
|
shun-iwasawa |
00ed45 |
|
|
shun-iwasawa |
00ed45 |
FX_PLUGIN_IDENTIFIER(Iwa_SpinGradientFx, "iwa_SpinGradientFx");
|