1 // Subsystem that manages interpolation of properties.
3 // Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Library General Public
7 // License as published by the Free Software Foundation; either
8 // version 2 of the License, or (at your option) any later version.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Library General Public License for more details.
15 // You should have received a copy of the GNU Library General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "PropertyInterpolationMgr.hxx"
20 #include "PropertyInterpolator.hxx"
22 #ifndef SIMGEAR_HEADLESS
23 # include <simgear/scene/util/ColorInterpolator.hxx>
26 #include <simgear/props/props.hxx>
27 #include <simgear_config.h>
34 //----------------------------------------------------------------------------
35 PropertyInterpolationMgr::PropertyInterpolationMgr()
37 addInterpolatorFactory<NumericInterpolator>("numeric");
38 #ifndef SIMGEAR_HEADLESS
39 addInterpolatorFactory<ColorInterpolator>("color");
42 for( size_t i = 0; easing_functions[i].name; ++i )
45 easing_functions[i].name,
46 easing_functions[i].func
50 //----------------------------------------------------------------------------
51 void PropertyInterpolationMgr::update(double dt)
53 for( InterpolatorList::iterator it = _interpolators.begin();
54 it != _interpolators.end();
57 for(double unused_time = dt;;)
59 PropertyInterpolatorRef interp = it->second;
60 unused_time = interp->update(it->first, unused_time);
62 if( unused_time <= 0.0 )
63 // No time left for next animation
68 // Step to next animation. Note that we do not invalidate or delete
69 // the current interpolator to allow for looped animations.
70 it->second = interp->_next;
74 // No more animations so just remove it
75 it = _interpolators.erase(it);
82 //----------------------------------------------------------------------------
83 struct PropertyInterpolationMgr::PredicateIsSameProp
86 PredicateIsSameProp(SGPropertyNode* node):
89 bool operator()(const PropertyInterpolatorPair& interp) const
91 return interp.first == _node;
94 SGPropertyNode *_node;
97 //----------------------------------------------------------------------------
98 PropertyInterpolatorRef
99 PropertyInterpolationMgr::createInterpolator( const std::string& type,
100 const SGPropertyNode* target,
102 const std::string& easing )
104 InterpolatorFactoryMap::iterator interpolator_factory =
105 _interpolator_factories.find(type);
106 if( interpolator_factory == _interpolator_factories.end() )
112 "PropertyInterpolationMgr: no factory found for type '" << type << "'"
117 EasingFunctionMap::iterator easing_func = _easing_functions.find(easing);
118 if( easing_func == _easing_functions.end() )
124 "PropertyInterpolationMgr: no such easing '" << type << "'"
129 PropertyInterpolatorRef interp;
130 interp = (*interpolator_factory->second)(target);
131 interp->_type = type;
132 interp->_duration = duration;
133 interp->_easing = easing_func->second;
138 //----------------------------------------------------------------------------
139 void PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
140 PropertyInterpolatorRef interp )
142 // Search for active interpolator on given property
143 InterpolatorList::iterator it = std::find_if
145 _interpolators.begin(),
146 _interpolators.end(),
147 PredicateIsSameProp(prop)
150 if( it != _interpolators.end() )
152 // Ensure no circular reference is left
153 it->second->_next = 0;
155 // and now safely replace old interpolator
156 // TODO maybe cache somewhere for reuse or use allocator?
160 _interpolators.push_front( std::make_pair(prop, interp) );
163 //----------------------------------------------------------------------------
164 void PropertyInterpolationMgr::addInterpolatorFactory
166 const std::string& type,
167 InterpolatorFactory factory
170 if( _interpolator_factories.find(type) != _interpolator_factories.end() )
175 "PropertyInterpolationMgr: replace existing factor for type " << type
178 _interpolator_factories[type] = factory;
181 //----------------------------------------------------------------------------
182 void PropertyInterpolationMgr::addEasingFunction( const std::string& type,
185 // TODO it's probably time for a generic factory map
186 if( _easing_functions.find(type) != _easing_functions.end() )
191 "PropertyInterpolationMgr: replace existing easing function " << type
194 _easing_functions[type] = func;
197 } // namespace simgear