|
Carlos Lopez |
a09598 |
/* === S Y N F I G ========================================================= */
|
|
Carlos Lopez |
a09598 |
/*! \file layer_motionblur.cpp
|
|
Carlos Lopez |
a09598 |
** \brief Implementation of the "Motion Blur" layer
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** $Id$
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** \legal
|
|
Carlos Lopez |
a09598 |
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
|
|
Carlos Lopez |
a09598 |
** Copyright (c) 2007, 2008 Chris Moore
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is free software; you can redistribute it and/or
|
|
Carlos Lopez |
a09598 |
** modify it under the terms of the GNU General Public License as
|
|
Carlos Lopez |
a09598 |
** published by the Free Software Foundation; either version 2 of
|
|
Carlos Lopez |
a09598 |
** the License, or (at your option) any later version.
|
|
Carlos Lopez |
a09598 |
**
|
|
Carlos Lopez |
a09598 |
** This package is distributed in the hope that it will be useful,
|
|
Carlos Lopez |
a09598 |
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Carlos Lopez |
a09598 |
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Carlos Lopez |
a09598 |
** General Public License for more details.
|
|
Carlos Lopez |
a09598 |
** \endlegal
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
/* ========================================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === H E A D E R S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#ifdef USING_PCH
|
|
Carlos Lopez |
a09598 |
# include "pch.h"
|
|
Carlos Lopez |
a09598 |
#else
|
|
Carlos Lopez |
a09598 |
#ifdef HAVE_CONFIG_H
|
|
Carlos Lopez |
a09598 |
# include <config.h></config.h>
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
#include "layer_motionblur.h"
|
|
bw |
94d8a6 |
|
|
bw |
94d8a6 |
#include <synfig general.h=""></synfig>
|
|
bw |
94d8a6 |
#include <synfig localization.h=""></synfig>
|
|
bw |
94d8a6 |
|
|
bw |
94d8a6 |
#include <synfig canvas.h=""></synfig>
|
|
Diego Barrios Romero |
dcc14d |
#include <synfig context.h=""></synfig>
|
|
Diego Barrios Romero |
dcc14d |
#include <synfig paramdesc.h=""></synfig>
|
|
Diego Barrios Romero |
dcc14d |
#include <synfig renddesc.h=""></synfig>
|
|
bw |
94d8a6 |
#include <synfig string.h=""></synfig>
|
|
Diego Barrios Romero |
dcc14d |
#include <synfig surface.h=""></synfig>
|
|
bw |
94d8a6 |
#include <synfig time.h=""></synfig>
|
|
Diego Barrios Romero |
dcc14d |
#include <synfig value.h=""></synfig>
|
|
Diego Barrios Romero |
dcc14d |
#include <synfig valuenode.h=""></synfig>
|
|
Carlos Lopez |
a09598 |
|
|
|
0ddb89 |
#include <synfig common="" rendering="" task="" taskblend.h=""></synfig>
|
|
|
0ddb89 |
|
|
Carlos Lopez |
a09598 |
#endif
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === U S I N G =========================================================== */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
using namespace synfig;
|
|
Carlos Lopez |
a09598 |
using namespace etl;
|
|
Carlos Lopez |
a09598 |
using namespace std;
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === G L O B A L S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_INIT(Layer_MotionBlur);
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_NAME(Layer_MotionBlur,"MotionBlur"); // todo: use motion_blur
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_LOCAL_NAME(Layer_MotionBlur,N_("Motion Blur"));
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_CATEGORY(Layer_MotionBlur,N_("Blurs"));
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_VERSION(Layer_MotionBlur,"0.1");
|
|
Carlos Lopez |
a09598 |
SYNFIG_LAYER_SET_CVS_ID(Layer_MotionBlur,"$Id$");
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
/* === M E M B E R S ======================================================= */
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Layer_MotionBlur::Layer_MotionBlur():
|
|
|
e222d9 |
Layer_CompositeFork (1.0,Color::BLEND_STRAIGHT),
|
|
|
b54f96 |
param_aperture (ValueBase(Time(1.0))),
|
|
Carlos Lopez |
a41560 |
param_subsamples_factor (ValueBase(Real(1.0))),
|
|
|
d89783 |
param_subsampling_type (ValueBase(int(SUBSAMPLING_HYPERBOLIC))),
|
|
Carlos Lopez |
a41560 |
param_subsample_start (ValueBase(Real(0.0))),
|
|
Carlos Lopez |
a41560 |
param_subsample_end (ValueBase(Real(1.0)))
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
e37ea8 |
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
bool
|
|
Carlos Lopez |
a09598 |
Layer_MotionBlur::set_param(const String ¶m, const ValueBase &value)
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a41560 |
IMPORT_VALUE(param_aperture);
|
|
Carlos Lopez |
a41560 |
IMPORT_VALUE(param_subsamples_factor);
|
|
Carlos Lopez |
a41560 |
IMPORT_VALUE(param_subsampling_type);
|
|
Carlos Lopez |
a41560 |
IMPORT_VALUE(param_subsample_start);
|
|
Carlos Lopez |
a41560 |
IMPORT_VALUE(param_subsample_end);
|
|
Carlos Lopez |
a09598 |
return Layer_Composite::set_param(param,value);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ValueBase
|
|
Carlos Lopez |
a09598 |
Layer_MotionBlur::get_param(const String ¶m)const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a41560 |
EXPORT_VALUE(param_aperture);
|
|
Carlos Lopez |
a41560 |
EXPORT_VALUE(param_subsamples_factor);
|
|
Carlos Lopez |
a41560 |
EXPORT_VALUE(param_subsampling_type);
|
|
Carlos Lopez |
a41560 |
EXPORT_VALUE(param_subsample_start);
|
|
Carlos Lopez |
a41560 |
EXPORT_VALUE(param_subsample_end);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
EXPORT_NAME();
|
|
Carlos Lopez |
a09598 |
EXPORT_VERSION();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
return Layer_Composite::get_param(param);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Color
|
|
Carlos Lopez |
a09598 |
Layer_MotionBlur::get_color(Context context, const Point &pos)const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
/* if(aperture)
|
|
Carlos Lopez |
a09598 |
{
|
|
|
dd97a8 |
Time time(get_time_mark());
|
|
Carlos Lopez |
a09598 |
time+=(Vector::value_type)( (signed)(RAND_MAX/2)-(signed)rand() )/(Vector::value_type)(RAND_MAX) *aperture -aperture*0.5;
|
|
Carlos Lopez |
a09598 |
context.set_time(time, pos);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
*/
|
|
Carlos Lopez |
a09598 |
return context.get_color(pos);
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
Layer::Vocab
|
|
Carlos Lopez |
a09598 |
Layer_MotionBlur::get_param_vocab()const
|
|
Carlos Lopez |
a09598 |
{
|
|
Carlos Lopez |
a09598 |
Layer::Vocab ret;
|
|
Carlos Lopez |
a09598 |
//ret=Layer_Composite::get_param_vocab();
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
a09598 |
ret.push_back(ParamDesc("aperture")
|
|
Carlos Lopez |
a09598 |
.set_local_name(_("Aperture"))
|
|
Carlos Lopez |
a09598 |
.set_description(_("Shutter Time"))
|
|
Carlos Lopez |
a09598 |
);
|
|
Carlos Lopez |
a09598 |
|
|
Carlos Lopez |
2545d8 |
ret.push_back(ParamDesc("subsamples_factor")
|
|
Carlos Lopez |
2545d8 |
.set_local_name(_("Subsamples Factor"))
|
|
Carlos Lopez |
2545d8 |
.set_description(_("Multiplies The Number Of Subsamples Rendered"))
|
|
Carlos Lopez |
2545d8 |
);
|
|
Carlos Lopez |
2545d8 |
|
|
Carlos Lopez |
2545d8 |
ret.push_back(ParamDesc("subsampling_type")
|
|
Carlos Lopez |
2545d8 |
.set_local_name(_("Subsampling Type"))
|
|
Carlos Lopez |
2545d8 |
.set_description(_("Curve Type For Weighting Subsamples"))
|
|
Carlos Lopez |
2545d8 |
.set_hint("enum")
|
|
Carlos Lopez |
2545d8 |
.add_enum_value(SUBSAMPLING_CONSTANT,"constant",_("Constant"))
|
|
Carlos Lopez |
2545d8 |
.add_enum_value(SUBSAMPLING_LINEAR,"linear",_("Linear"))
|
|
Carlos Lopez |
2545d8 |
.add_enum_value(SUBSAMPLING_HYPERBOLIC,"hyperbolic",_("Hyperbolic"))
|
|
Carlos Lopez |
2545d8 |
);
|
|
Carlos Lopez |
2545d8 |
|
|
Carlos Lopez |
2545d8 |
ret.push_back(ParamDesc("subsample_start")
|
|
Carlos Lopez |
2545d8 |
.set_local_name(_("Subsample Start Amount"))
|
|
Carlos Lopez |
2545d8 |
.set_description(_("Relative Amount Of The First Subsample, For Linear Weighting"))
|
|
Carlos Lopez |
2545d8 |
);
|
|
Carlos Lopez |
2545d8 |
|
|
Carlos Lopez |
2545d8 |
ret.push_back(ParamDesc("subsample_end")
|
|
Carlos Lopez |
2545d8 |
.set_local_name(_("Subsample End Amount"))
|
|
Carlos Lopez |
2545d8 |
.set_description(_("Relative Amount Of The Last Subsample, For Linear Weighting"))
|
|
Carlos Lopez |
2545d8 |
);
|
|
Carlos Lopez |
2545d8 |
|
|
Carlos Lopez |
a09598 |
return ret;
|
|
Carlos Lopez |
a09598 |
}
|
|
Carlos Lopez |
a09598 |
|
|
|
e222d9 |
rendering::Task::Handle
|
|
|
e222d9 |
Layer_MotionBlur::build_rendering_task_vfunc(Context context) const
|
|
|
0ddb89 |
{
|
|
|
0ddb89 |
const Real precision = 1e-8;
|
|
|
0ddb89 |
|
|
|
0ddb89 |
Time aperture = param_aperture.get(Time());
|
|
|
0ddb89 |
Real subsamples_factor = param_subsamples_factor.get(Real());
|
|
|
0ddb89 |
SubsamplingType subsampling_type = (SubsamplingType)param_subsampling_type.get(int());
|
|
|
0ddb89 |
Real subsample_start = param_subsample_start.get(Real());
|
|
|
0ddb89 |
Real subsample_end = param_subsample_end.get(Real());
|
|
|
0ddb89 |
|
|
|
0ddb89 |
int samples = (int)round(12.0 * fabs(subsamples_factor));
|
|
|
0ddb89 |
if (samples <= 1)
|
|
|
0ddb89 |
return context.build_rendering_task();
|
|
|
0ddb89 |
|
|
|
0ddb89 |
// Only in modes where subsample_start/end matters...
|
|
|
0ddb89 |
if (subsampling_type == SUBSAMPLING_LINEAR)
|
|
|
0ddb89 |
{
|
|
|
0ddb89 |
// We won't render when the scale==0, so we'll use those samples elsewhere
|
|
|
0ddb89 |
if (fabs(subsample_start) < precision) ++samples;
|
|
|
0ddb89 |
if (fabs(subsample_end) < precision) ++samples;
|
|
|
0ddb89 |
}
|
|
|
0ddb89 |
|
|
|
0ddb89 |
vector<real> scales(samples, 0.0);</real>
|
|
|
0ddb89 |
Real sum = 0.0;
|
|
|
0ddb89 |
for(int i = 0; i < samples; i++)
|
|
|
0ddb89 |
{
|
|
|
0ddb89 |
Real pos = (Real)i/(Real)(samples - 1);
|
|
|
0ddb89 |
Real ipos = 1.0 - pos;
|
|
|
0ddb89 |
Real scale = 0.0;
|
|
|
0ddb89 |
switch(subsampling_type)
|
|
|
0ddb89 |
{
|
|
|
0ddb89 |
case SUBSAMPLING_LINEAR:
|
|
|
0ddb89 |
scale = ipos*subsample_start + pos*subsample_end;
|
|
|
0ddb89 |
break;
|
|
|
0ddb89 |
case SUBSAMPLING_HYPERBOLIC:
|
|
|
0ddb89 |
scale = 1.0/(samples - i);
|
|
|
0ddb89 |
break;
|
|
|
0ddb89 |
case SUBSAMPLING_CONSTANT:
|
|
|
0ddb89 |
default:
|
|
|
0ddb89 |
scale = 1.0; // Weights don't matter for constant overall subsampling.
|
|
|
0ddb89 |
break;
|
|
|
0ddb89 |
}
|
|
|
0ddb89 |
scales[i] = scale;
|
|
|
0ddb89 |
sum += scale;
|
|
|
0ddb89 |
}
|
|
|
0ddb89 |
|
|
|
0ddb89 |
Real k = 1.0/sum;
|
|
|
ce743b |
rendering::Task::Handle task;
|
|
|
0ddb89 |
for(int i = 0; i < samples; i++)
|
|
|
0ddb89 |
{
|
|
|
0ddb89 |
if (fabs(scales[i]*k) < 1e-8)
|
|
|
0ddb89 |
continue;
|
|
|
0ddb89 |
|
|
|
0ddb89 |
Real pos = (Real)i/(Real)(samples - 1);
|
|
|
0ddb89 |
Real ipos = 1.0 - pos;
|
|
|
0ddb89 |
context.set_time(get_time_mark() - aperture*ipos);
|
|
|
0ddb89 |
|
|
|
0ddb89 |
rendering::TaskBlend::Handle task_blend(new rendering::TaskBlend());
|
|
|
0ddb89 |
task_blend->amount = scales[i]*k;
|
|
Voldracarno Draconor |
76aa1d |
task_blend->blend_method = Color::BLEND_ADD_COMPOSITE;
|
|
|
0ddb89 |
task_blend->sub_task_a() = task;
|
|
|
0ddb89 |
task_blend->sub_task_b() = context.build_rendering_task();
|
|
|
0ddb89 |
task = task_blend;
|
|
|
0ddb89 |
}
|
|
|
0ddb89 |
|
|
|
0ddb89 |
return task;
|
|
|
0ddb89 |
}
|