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 #include <simgear_config.h>
24 #ifndef SIMGEAR_HEADLESS
25 # include <simgear/scene/util/ColorInterpolator.hxx>
28 #include <simgear/props/props.hxx>
35 //----------------------------------------------------------------------------
36 PropertyInterpolationMgr::PropertyInterpolationMgr()
38 addInterpolatorFactory<NumericInterpolator>("numeric");
39 #ifndef SIMGEAR_HEADLESS
40 addInterpolatorFactory<ColorInterpolator>("color");
43 for( size_t i = 0; easing_functions[i].name; ++i )
46 easing_functions[i].name,
47 easing_functions[i].func
51 //----------------------------------------------------------------------------
52 void PropertyInterpolationMgr::update(double dt)
54 for( InterpolatorList::iterator it = _interpolators.begin();
55 it != _interpolators.end();
58 for(double unused_time = dt;;)
60 PropertyInterpolatorRef interp = it->second;
61 unused_time = interp->update(it->first, unused_time);
63 if( unused_time <= 0.0 )
64 // No time left for next animation
69 // Step to next animation. Note that we do not invalidate or delete
70 // the current interpolator to allow for looped animations.
71 it->second = interp->_next;
75 // No more animations so just remove it
76 it = _interpolators.erase(it);
83 //----------------------------------------------------------------------------
84 struct PropertyInterpolationMgr::PredicateIsSameProp
87 PredicateIsSameProp(SGPropertyNode* node):
90 bool operator()(const PropertyInterpolatorPair& interp) const
92 return interp.first == _node;
95 SGPropertyNode *_node;
98 //----------------------------------------------------------------------------
99 PropertyInterpolatorRef
100 PropertyInterpolationMgr::createInterpolator( const std::string& type,
101 const SGPropertyNode* target,
103 const std::string& easing )
105 InterpolatorFactoryMap::iterator interpolator_factory =
106 _interpolator_factories.find(type);
107 if( interpolator_factory == _interpolator_factories.end() )
113 "PropertyInterpolationMgr: no factory found for type '" << type << "'"
118 EasingFunctionMap::iterator easing_func = _easing_functions.find(easing);
119 if( easing_func == _easing_functions.end() )
125 "PropertyInterpolationMgr: no such easing '" << type << "'"
130 PropertyInterpolatorRef interp;
131 interp = (*interpolator_factory->second)(target);
132 interp->_type = type;
133 interp->_duration = duration;
134 interp->_easing = easing_func->second;
139 //----------------------------------------------------------------------------
140 void PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
141 PropertyInterpolatorRef interp )
143 // Search for active interpolator on given property
144 InterpolatorList::iterator it = std::find_if
146 _interpolators.begin(),
147 _interpolators.end(),
148 PredicateIsSameProp(prop)
151 if( it != _interpolators.end() )
153 // Ensure no circular reference is left
154 it->second->_next = 0;
156 // and now safely replace old interpolator
157 // TODO maybe cache somewhere for reuse or use allocator?
161 _interpolators.push_front( std::make_pair(prop, interp) );
164 //----------------------------------------------------------------------------
165 void PropertyInterpolationMgr::addInterpolatorFactory
167 const std::string& type,
168 InterpolatorFactory factory
171 if( _interpolator_factories.find(type) != _interpolator_factories.end() )
176 "PropertyInterpolationMgr: replace existing factor for type " << type
179 _interpolator_factories[type] = factory;
182 //----------------------------------------------------------------------------
183 void PropertyInterpolationMgr::addEasingFunction( const std::string& type,
186 // TODO it's probably time for a generic factory map
187 if( _easing_functions.find(type) != _easing_functions.end() )
192 "PropertyInterpolationMgr: replace existing easing function " << type
195 _easing_functions[type] = func;
198 } // namespace simgear