Blame synfig-core/src/synfig/layers/layer_motionblur.cpp

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
}