1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * This file is part of openfx-supportext <https://github.com/devernay/openfx-supportext>,
4 * Copyright (C) 2013-2018 INRIA
5 *
6 * openfx-supportext is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * openfx-supportext is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with openfx-supportext. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
18 * ***** END LICENSE BLOCK ***** */
19
20 /*
21 * OFX generic rectangle interact with 4 corner points + center point and 4 mid-points.
22 * You can use it to define any rectangle in an image resizable by the user.
23 */
24
25 #ifndef openfx_supportext_ofxsRamp_h
26 #define openfx_supportext_ofxsRamp_h
27
28 #include <cmath>
29
30 #include <ofxsInteract.h>
31 #include <ofxsImageEffect.h>
32 #include "ofxsMacros.h"
33 #include "ofxsOGLTextRenderer.h"
34
35 #define kParamRampPoint0 "rampPoint0"
36 #define kParamRampPoint0Label "Point 0"
37
38 #define kParamRampColor0 "rampColor0"
39 #define kParamRampColor0Label "Color 0"
40
41 #define kParamRampPoint1 "rampPoint1"
42 #define kParamRampPoint1Label "Point 1"
43
44 #define kParamRampColor1 "rampColor1"
45 #define kParamRampColor1Label "Color 1"
46
47 #define kParamRampType "rampType"
48 #define kParamRampTypeLabel "Ramp Type", "The type of interpolation used to generate the ramp"
49 #define kParamRampTypeOptionLinear "Linear", "Linear ramp.", "linear"
50 #define kParamRampTypeOptionPLinear "PLinear", "Perceptually linear ramp in Rec.709.", "plinear"
51 #define kParamRampTypeOptionEaseIn "Ease-in", "Catmull-Rom spline, smooth start, linear end (a.k.a. smooth0).", "easein"
52 #define kParamRampTypeOptionEaseOut "Ease-out", "Catmull-Rom spline, linear start, smooth end (a.k.a. smooth1).", "easeout"
53 #define kParamRampTypeOptionSmooth "Smooth", "Traditional smoothstep ramp.", "smooth"
54 #define kParamRampTypeOptionNone "None", "No color gradient.", "none"
55
56 #define kParamRampInteractOpen "rampInteractOpen"
57 #define kParamRampInteractOpenLabel "Show Interact", "If checked, the ramp interact is displayed over the image."
58
59 #define kParamRampInteractive "rampInteractive"
60 #define kParamRampInteractiveLabel "Interactive Update", "If checked, update the parameter values during interaction with the image viewer, else update the values when pen is released."
61
62 // old names, for the Ramp plugin only
63 #define kParamRampPoint0Old "point0"
64 #define kParamRampColor0Old "color0"
65 #define kParamRampPoint1Old "point1"
66 #define kParamRampColor1Old "color1"
67 #define kParamRampTypeOld "type"
68 #define kParamRampInteractiveOld "interactive"
69
70 namespace OFX {
71 enum RampTypeEnum
72 {
73 eRampTypeLinear = 0,
74 eRampTypePLinear,
75 eRampTypeEaseIn,
76 eRampTypeEaseOut,
77 eRampTypeSmooth,
78 eRampTypeNone
79 };
80
81 class RampInteractHelper
82 : private OFX::InteractAbstract
83 {
84 enum InteractState
85 {
86 eInteractStateIdle = 0,
87 eInteractStateDraggingPoint0,
88 eInteractStateDraggingPoint1
89 };
90
91 Double2DParam* _point0;
92 Double2DParam* _point1;
93 ChoiceParam* _type;
94 BooleanParam* _interactOpen;
95 BooleanParam* _interactive;
96 OfxPointD _point0DragPos, _point1DragPos;
97 bool _interactiveDrag;
98 OfxPointD _lastMousePos;
99 InteractState _state;
100 OFX::ImageEffect* _effect;
101 OFX::Interact* _interact;
102 Clip *_dstClip;
103
104 public:
105 RampInteractHelper(OFX::ImageEffect* effect,
106 OFX::Interact* interact,
107 bool oldParams = false)
_point0(NULL)108 : _point0(NULL)
109 , _point1(NULL)
110 , _type(NULL)
111 , _interactOpen(NULL)
112 , _interactive(NULL)
113 , _point0DragPos()
114 , _point1DragPos()
115 , _interactiveDrag(false)
116 , _lastMousePos()
117 , _state(eInteractStateIdle)
118 , _effect(effect)
119 , _interact(interact)
120 , _dstClip(NULL)
121 {
122 if (oldParams) {
123 _point0 = effect->fetchDouble2DParam(kParamRampPoint0Old);
124 _point1 = effect->fetchDouble2DParam(kParamRampPoint1Old);
125 _type = effect->fetchChoiceParam(kParamRampTypeOld);
126 _interactive = effect->fetchBooleanParam(kParamRampInteractiveOld);
127 } else {
128 _point0 = effect->fetchDouble2DParam(kParamRampPoint0);
129 _point1 = effect->fetchDouble2DParam(kParamRampPoint1);
130 _type = effect->fetchChoiceParam(kParamRampType);
131 _interactive = effect->fetchBooleanParam(kParamRampInteractive);
132 }
133 _interactOpen = _effect->fetchBooleanParam(kParamRampInteractOpen);
134 assert(_point0 && _point1 && _type && _interactOpen && _interactive);
135 assert(_effect && _interact);
136 _dstClip = _effect->fetchClip(kOfxImageEffectOutputClipName);
137 assert(_dstClip);
138 }
139
140 /** @brief virtual destructor */
~RampInteractHelper()141 virtual ~RampInteractHelper()
142 {
143 // fetched clips and params are owned and deleted by the ImageEffect and its ParamSet
144 }
145
146 /** @brief the function called to draw in the interact */
147 virtual bool draw(const DrawArgs &args) OVERRIDE;
148
149 /** @brief the function called to handle pen motion in the interact
150
151 returns true if the interact trapped the action in some sense. This will block the action being passed to
152 any other interact that may share the viewer.
153 */
154 virtual bool penMotion(const PenArgs &args) OVERRIDE;
155
156 /** @brief the function called to handle pen down events in the interact
157
158 returns true if the interact trapped the action in some sense. This will block the action being passed to
159 any other interact that may share the viewer.
160 */
161 virtual bool penDown(const PenArgs &args) OVERRIDE;
162
163 /** @brief the function called to handle pen up events in the interact
164
165 returns true if the interact trapped the action in some sense. This will block the action being passed to
166 any other interact that may share the viewer.
167 */
168 virtual bool penUp(const PenArgs &args) OVERRIDE;
169
170 /** @brief the function called to handle key down events in the interact
171
172 returns true if the interact trapped the action in some sense. This will block the action being passed to
173 any other interact that may share the viewer.
174 */
keyDown(const KeyArgs &)175 virtual bool keyDown(const KeyArgs & /*args*/) OVERRIDE { return false; };
176
177 /** @brief the function called to handle key up events in the interact
178
179 returns true if the interact trapped the action in some sense. This will block the action being passed to
180 any other interact that may share the viewer.
181 */
keyUp(const KeyArgs &)182 virtual bool keyUp(const KeyArgs & /*args*/) OVERRIDE { return false; };
183
184 /** @brief the function called to handle key down repeat events in the interact
185
186 returns true if the interact trapped the action in some sense. This will block the action being passed to
187 any other interact that may share the viewer.
188 */
keyRepeat(const KeyArgs &)189 virtual bool keyRepeat(const KeyArgs & /*args*/) OVERRIDE { return false; };
190
191 /** @brief Called when the interact is given input focus */
gainFocus(const FocusArgs &)192 virtual void gainFocus(const FocusArgs & /*args*/) OVERRIDE {};
193
194 /** @brief Called when the interact is loses input focus */
195 virtual void loseFocus(const FocusArgs &args) OVERRIDE;
196 };
197
198 typedef OverlayInteractFromHelper<RampInteractHelper> RampInteract;
199
200 class RampOverlayDescriptor
201 : public DefaultEffectOverlayDescriptor<RampOverlayDescriptor, RampInteract>
202 {
203 };
204
205 class RampInteractHelperOldParams
206 : public RampInteractHelper
207 {
208 public:
RampInteractHelperOldParams(OFX::ImageEffect * effect,OFX::Interact * interact)209 RampInteractHelperOldParams(OFX::ImageEffect* effect,
210 OFX::Interact* interact)
211 : RampInteractHelper(effect, interact, true) {}
212 };
213
214 typedef OverlayInteractFromHelper<RampInteractHelperOldParams> RampInteractOldParams;
215
216 class RampOverlayDescriptorOldParams
217 : public DefaultEffectOverlayDescriptor<RampOverlayDescriptorOldParams, RampInteractOldParams>
218 {
219 };
220
221
222 template<RampTypeEnum type>
223 double
ofxsRampFunc(double t)224 ofxsRampFunc(double t)
225 {
226 if ( (t >= 1.) || (type == eRampTypeNone) ) {
227 t = 1.;
228 } else if (t <= 0) {
229 t = 0.;
230 } else {
231 // from http://www.comp-fu.com/2012/01/nukes-smooth-ramp-functions/
232 // linear
233 //y = x
234 // plinear: perceptually linear in rec709
235 //y = pow(x, 3)
236 // smooth: traditional smoothstep
237 //y = x*x*(3 - 2*x)
238 // smooth0: Catmull-Rom spline, smooth start, linear end
239 //y = x*x*(2 - x)
240 // smooth1: Catmull-Rom spline, linear start, smooth end
241 //y = x*(1 + x*(1 - x))
242 switch (type) {
243 case eRampTypeLinear:
244 break;
245 case eRampTypePLinear:
246 // plinear: perceptually linear in rec709
247 t = t * t * t;
248 break;
249 case eRampTypeEaseIn:
250 //t *= t; // old version, end of curve is too sharp
251 // smooth0: Catmull-Rom spline, smooth start, linear end
252 t = t * t * (2 - t);
253 break;
254 case eRampTypeEaseOut:
255 //t = - t * (t - 2); // old version, start of curve is too sharp
256 // smooth1: Catmull-Rom spline, linear start, smooth end
257 t = t * ( 1 + t * (1 - t) );
258 break;
259 case eRampTypeSmooth:
260 /*
261 t *= 2.;
262 if (t < 1) {
263 t = t * t / (2.);
264 } else {
265 --t;
266 t = -0.5 * (t * (t - 2) - 1);
267 }
268 */
269 // smooth: traditional smoothstep
270 t = t * t * (3 - 2 * t);
271 break;
272 case eRampTypeNone:
273 t = 1.;
274 break;
275 default:
276 break;
277 }
278 }
279
280 return t;
281 } // ofxsRampFunc
282
283 template<RampTypeEnum type>
284 double
ofxsRampFunc(const OfxPointD & p0,double nx,double ny,const OfxPointD & p)285 ofxsRampFunc(const OfxPointD& p0,
286 double nx,
287 double ny,
288 const OfxPointD& p)
289 {
290 double t = (p.x - p0.x) * nx + (p.y - p0.y) * ny;
291
292 return ofxsRampFunc<type>(t);
293 }
294
295 inline double
ofxsRampFunc(const OfxPointD & p0,double nx,double ny,RampTypeEnum type,const OfxPointD & p)296 ofxsRampFunc(const OfxPointD& p0,
297 double nx,
298 double ny,
299 RampTypeEnum type,
300 const OfxPointD& p)
301 {
302 double t = (p.x - p0.x) * nx + (p.y - p0.y) * ny;
303
304 switch (type) {
305 case eRampTypeLinear:
306
307 return ofxsRampFunc<eRampTypeLinear>(t);
308 break;
309 case eRampTypePLinear:
310
311 return ofxsRampFunc<eRampTypePLinear>(t);
312 break;
313 case eRampTypeEaseIn:
314
315 return ofxsRampFunc<eRampTypeEaseIn>(t);
316 break;
317 case eRampTypeEaseOut:
318
319 return ofxsRampFunc<eRampTypeEaseOut>(t);
320 break;
321 case eRampTypeSmooth:
322
323 return ofxsRampFunc<eRampTypeSmooth>(t);
324 break;
325 case eRampTypeNone:
326 t = 1.;
327 break;
328 default:
329 break;
330 }
331
332 return t;
333 }
334
335 void ofxsRampDescribeParams(OFX::ImageEffectDescriptor &desc,
336 OFX::PageParamDescriptor *page,
337 OFX::GroupParamDescriptor *group,
338 RampTypeEnum defaultType,
339 bool isOpen,
340 bool oldParams);
341 } // namespace OFX
342
343 #endif /* defined(openfx_supportext_ofxsRamp_h) */
344