1 #include "iwa_lineargradientfx.h"
2
3 #include "tspectrumparam.h"
4 #include "gradients.h"
5 #include "tparamuiconcept.h"
6 #include "traster.h"
7
8 //------------------------------------------------------------
9
Iwa_LinearGradientFx()10 Iwa_LinearGradientFx::Iwa_LinearGradientFx()
11 : m_startPoint(TPointD(-50.0, 0.0))
12 , m_endPoint(TPointD(50.0, 0.0))
13 , m_startColor(TPixel32::Black)
14 , m_endColor(TPixel32::White)
15 , m_curveType(new TIntEnumParam(EaseInOut, "Ease In-Out"))
16 , m_wave_amplitude(0.0)
17 , m_wave_freq(0.0)
18 , m_wave_phase(0.0) {
19 m_startPoint->getX()->setMeasureName("fxLength");
20 m_startPoint->getY()->setMeasureName("fxLength");
21 m_endPoint->getX()->setMeasureName("fxLength");
22 m_endPoint->getY()->setMeasureName("fxLength");
23 bindParam(this, "startPoint", m_startPoint);
24 bindParam(this, "endPoint", m_endPoint);
25
26 m_curveType->addItem(Linear, "Linear");
27 m_curveType->addItem(EaseIn, "Ease In");
28 m_curveType->addItem(EaseOut, "Ease Out");
29 bindParam(this, "curveType", m_curveType);
30
31 m_wave_amplitude->setValueRange(0, std::numeric_limits<double>::max());
32 m_wave_amplitude->setMeasureName("fxLength");
33 bindParam(this, "wave_amplitude", m_wave_amplitude);
34 bindParam(this, "wave_frequency", m_wave_freq);
35 bindParam(this, "wave_phase", m_wave_phase);
36
37 bindParam(this, "startColor", m_startColor);
38 bindParam(this, "endColor", m_endColor);
39 }
40
41 //------------------------------------------------------------
42
doGetBBox(double frame,TRectD & bBox,const TRenderSettings & ri)43 bool Iwa_LinearGradientFx::doGetBBox(double frame, TRectD &bBox,
44 const TRenderSettings &ri) {
45 bBox = TConsts::infiniteRectD;
46 return true;
47 }
48
49 //------------------------------------------------------------
50
51 namespace {
52 template <typename RASTER, typename PIXEL>
doLinearGradientT(RASTER ras,TDimensionI dim,TPointD startPos,TPointD endPos,const TSpectrumT<PIXEL> & spectrum,GradientCurveType type,double w_amplitude,double w_freq,double w_phase,const TAffine & affInv)53 void doLinearGradientT(RASTER ras, TDimensionI dim, TPointD startPos,
54 TPointD endPos, const TSpectrumT<PIXEL> &spectrum,
55 GradientCurveType type, double w_amplitude,
56 double w_freq, double w_phase, const TAffine &affInv) {
57 auto getFactor = [&](double t) {
58 if (t > 1.0)
59 t = 1.0;
60 else if (t < 0.0)
61 t = 0.0;
62
63 double factor;
64 switch (type) {
65 case Linear:
66 factor = t;
67 break;
68 case EaseIn:
69 factor = t * t;
70 break;
71 case EaseOut:
72 factor = 1.0 - (1.0 - t) * (1.0 - t);
73 break;
74 case EaseInOut:
75 default:
76 factor = (-2 * t + 3) * (t * t);
77 break;
78 }
79 return factor;
80 };
81 startPos = affInv * startPos;
82 endPos = affInv * endPos;
83 TPointD seVec = endPos - startPos;
84
85 if (seVec == TPointD()) {
86 ras->fill(spectrum.getPremultipliedValue(0.0));
87 return;
88 }
89
90 TPointD posTrasf = -startPos;
91 double seVecLen2 = seVec.x * seVec.x + seVec.y * seVec.y;
92 double seVecLen = sqrt(seVecLen2);
93 double amplitude = w_amplitude / seVecLen;
94 TPointD auxVec(-seVec.y / seVecLen, seVec.x / seVecLen);
95
96 ras->lock();
97 for (int j = 0; j < ras->getLy(); j++) {
98 TPointD posAux = posTrasf;
99
100 PIXEL *pix = ras->pixels(j);
101 PIXEL *endPix = pix + ras->getLx();
102
103 while (pix < endPix) {
104 double t = (seVec.x * posAux.x + seVec.y * posAux.y) / seVecLen2;
105 if (amplitude) {
106 double distance = posAux.x * auxVec.x + posAux.y * auxVec.y;
107 t += amplitude * sin(w_freq * distance + w_phase);
108 }
109 double factor = getFactor(t);
110 *pix++ = spectrum.getPremultipliedValue(factor);
111
112 posAux.x += affInv.a11;
113 posAux.y += affInv.a21;
114 }
115 posTrasf.x += affInv.a12;
116 posTrasf.y += affInv.a22;
117 }
118 ras->unlock();
119 }
120 } // namespace
121
122 //------------------------------------------------------------
123
doCompute(TTile & tile,double frame,const TRenderSettings & ri)124 void Iwa_LinearGradientFx::doCompute(TTile &tile, double frame,
125 const TRenderSettings &ri) {
126 if (!((TRaster32P)tile.getRaster()) && !((TRaster64P)tile.getRaster())) {
127 throw TRopException("unsupported input pixel type");
128 }
129
130 // convert shape position to render region coordinate
131 TAffine aff = ri.m_affine;
132 TDimensionI dimOut(tile.getRaster()->getLx(), tile.getRaster()->getLy());
133 TPointD dimOffset((float)dimOut.lx / 2.0f, (float)dimOut.ly / 2.0f);
134 TPointD startPos = aff * m_startPoint->getValue(frame) -
135 (tile.m_pos + tile.getRaster()->getCenterD()) + dimOffset;
136 TPointD endPos = aff * m_endPoint->getValue(frame) -
137 (tile.m_pos + tile.getRaster()->getCenterD()) + dimOffset;
138
139 double w_amplitude = m_wave_amplitude->getValue(frame) / ri.m_shrinkX;
140 double w_freq = m_wave_freq->getValue(frame) * ri.m_shrinkX;
141 double w_phase = m_wave_phase->getValue(frame);
142 w_freq *= 0.01 * M_PI_180;
143
144 std::vector<TSpectrum::ColorKey> colors = {
145 TSpectrum::ColorKey(0, m_startColor->getValue(frame)),
146 TSpectrum::ColorKey(1, m_endColor->getValue(frame))};
147 TSpectrumParamP m_colors = TSpectrumParamP(colors);
148
149 tile.getRaster()->clear();
150 TRaster32P outRas32 = (TRaster32P)tile.getRaster();
151 TRaster64P outRas64 = (TRaster64P)tile.getRaster();
152 if (outRas32)
153 doLinearGradientT<TRaster32P, TPixel32>(
154 outRas32, dimOut, startPos, endPos, m_colors->getValue(frame),
155 (GradientCurveType)m_curveType->getValue(), w_amplitude, w_freq,
156 w_phase, aff.inv());
157 else if (outRas64)
158 doLinearGradientT<TRaster64P, TPixel64>(
159 outRas64, dimOut, startPos, endPos, m_colors->getValue64(frame),
160 (GradientCurveType)m_curveType->getValue(), w_amplitude, w_freq,
161 w_phase, aff.inv());
162 }
163
164 //------------------------------------------------------------
165
getParamUIs(TParamUIConcept * & concepts,int & length)166 void Iwa_LinearGradientFx::getParamUIs(TParamUIConcept *&concepts,
167 int &length) {
168 concepts = new TParamUIConcept[length = 1];
169
170 concepts[0].m_type = TParamUIConcept::LINEAR_RANGE;
171 concepts[0].m_label = "";
172 concepts[0].m_params.push_back(m_startPoint);
173 concepts[0].m_params.push_back(m_endPoint);
174 }
175
176 //------------------------------------------------------------
177
178 FX_PLUGIN_IDENTIFIER(Iwa_LinearGradientFx, "iwa_LinearGradientFx");
179