1 /* === S Y N F I G ========================================================= */
2 /*! \file layer_motionblur.cpp
3 ** \brief Implementation of the "Motion Blur" layer
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
34 #include "layer_motionblur.h"
37 #include "paramdesc.h"
41 #include "valuenode.h"
46 /* === U S I N G =========================================================== */
48 using namespace synfig;
52 /* === G L O B A L S ======================================================= */
54 SYNFIG_LAYER_INIT(Layer_MotionBlur);
55 SYNFIG_LAYER_SET_NAME(Layer_MotionBlur,"MotionBlur"); // todo: use motion_blur
56 SYNFIG_LAYER_SET_LOCAL_NAME(Layer_MotionBlur,N_("Motion Blur"));
57 SYNFIG_LAYER_SET_CATEGORY(Layer_MotionBlur,N_("Blurs"));
58 SYNFIG_LAYER_SET_VERSION(Layer_MotionBlur,"0.1");
59 SYNFIG_LAYER_SET_CVS_ID(Layer_MotionBlur,"$Id$");
61 /* === M E M B E R S ======================================================= */
63 Layer_MotionBlur::Layer_MotionBlur():
64 Layer_Composite (1.0,Color::BLEND_STRAIGHT),
66 subsamples_factor (1.0),
67 subsampling_type (SUBSAMPLING_HYPERBOLIC),
68 subsample_start (0.0),
70 aperture_static (false),
71 subsamples_factor_static (false),
72 subsampling_type_static (true),
73 subsample_start_static (false),
74 subsample_end_static (false)
79 Layer_MotionBlur::set_param(const String ¶m, const ValueBase &value)
83 IMPORT(subsamples_factor);
84 IMPORT(subsampling_type);
85 IMPORT(subsample_start);
86 IMPORT(subsample_end);
87 return Layer_Composite::set_param(param,value);
91 Layer_MotionBlur::get_param(const String ¶m)const
94 EXPORT(subsamples_factor);
95 EXPORT(subsampling_type);
96 EXPORT(subsample_start);
97 EXPORT(subsample_end);
102 return Layer_Composite::get_param(param);
106 Layer_MotionBlur::set_time(Context context, Time time)const
108 context.set_time(time);
113 Layer_MotionBlur::set_time(Context context, Time time, const Point &pos)const
115 context.set_time(time,pos);
120 Layer_MotionBlur::get_color(Context context, const Point &pos)const
125 time+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) *aperture -aperture*0.5;
126 context.set_time(time, pos);
129 return context.get_color(pos);
133 Layer_MotionBlur::get_param_vocab()const
136 //ret=Layer_Composite::get_param_vocab();
138 ret.push_back(ParamDesc("aperture")
139 .set_local_name(_("Aperture"))
140 .set_description(_("Shutter Time"))
143 ret.push_back(ParamDesc("subsamples_factor")
144 .set_local_name(_("Subsamples Factor"))
145 .set_description(_("Multiplies The Number Of Subsamples Rendered"))
148 ret.push_back(ParamDesc("subsampling_type")
149 .set_local_name(_("Subsampling Type"))
150 .set_description(_("Curve Type For Weighting Subsamples"))
152 .add_enum_value(SUBSAMPLING_CONSTANT,"constant",_("Constant"))
153 .add_enum_value(SUBSAMPLING_LINEAR,"linear",_("Linear"))
154 .add_enum_value(SUBSAMPLING_HYPERBOLIC,"hyperbolic",_("Hyperbolic"))
157 ret.push_back(ParamDesc("subsample_start")
158 .set_local_name(_("Subsample Start Amount"))
159 .set_description(_("Relative Amount Of The First Subsample, For Linear Weighting"))
162 ret.push_back(ParamDesc("subsample_end")
163 .set_local_name(_("Subsample End Amount"))
164 .set_description(_("Relative Amount Of The Last Subsample, For Linear Weighting"))
171 Layer_MotionBlur::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
173 if(aperture && quality<=10)
176 SuperCallback subimagecb;
180 case 1: // Production Quality
183 case 2: // Excellent Quality
186 case 3: // Good Quality
189 case 4: // Moderate Quality
192 case 5: // Draft Quality
207 case 10: // Rough Quality
214 samples *= subsamples_factor;
216 if (samples <= 1) return context.accelerated_render(surface,quality,renddesc,cb);
218 // Only in modes where subsample_start/end matters...
219 if(subsampling_type == SUBSAMPLING_LINEAR)
221 // We won't render when the scale==0, so we'll use those samples elsewhere
222 if(subsample_start == 0) samples++;
223 if(subsample_end == 0) samples++;
228 float scale, divisor = 0;
230 surface->set_wh(renddesc.get_w(),renddesc.get_h());
233 // Render subsamples from time_cur-aperture to time_cur
234 for(i=0;i<samples;i++)
236 float pos = i/(samples-1.0);
237 float ipos = 1.0-pos;
238 switch(subsampling_type)
240 case SUBSAMPLING_LINEAR:
241 scale = ipos*subsample_start + pos*subsample_end;
243 case SUBSAMPLING_HYPERBOLIC:
244 scale = 1.0/(samples-i);
246 case SUBSAMPLING_CONSTANT:
248 scale = 1.0; // Weights don't matter for constant overall subsampling.
251 // Don't bother rendering if scale is zero
255 subimagecb=SuperCallback(cb,i*(5000/samples),(i+1)*(5000/samples),5000);
256 context.set_time(time_cur-aperture*ipos);
257 if(!context.accelerated_render(&tmp,quality,renddesc,&subimagecb))
259 for(int y=0;y<renddesc.get_h();y++)
260 for(int x=0;x<renddesc.get_w();x++)
261 (*surface)[y][x]+=tmp[y][x].premult_alpha()*scale;
263 for(int y=0;y<renddesc.get_h();y++)
264 for(int x=0;x<renddesc.get_w();x++)
265 (*surface)[y][x]=((*surface)[y][x]/divisor).demult_alpha();
268 return context.accelerated_render(surface,quality,renddesc,cb);
275 Layer_MotionBlur::set_param_static(const String ¶m, const bool x)
277 SET_STATIC(aperture, x)
278 SET_STATIC(subsamples_factor, x)
279 SET_STATIC(subsampling_type, x)
280 SET_STATIC(subsample_start, x)
281 SET_STATIC(subsample_end, x)
283 return Layer_Composite::set_param_static(param, x);
288 Layer_MotionBlur::get_param_static(const String ¶m) const
292 GET_STATIC(subsamples_factor)
293 GET_STATIC(subsampling_type)
294 GET_STATIC(subsample_start)
295 GET_STATIC(subsample_end)
297 return Layer_Composite::get_param_static(param);