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"
28 //----------------------------------------------------------------------------
29 PropertyInterpolationMgr::PropertyInterpolationMgr()
31 addInterpolatorFactory<NumericInterpolator>("numeric");
33 for( size_t i = 0; easing_functions[i].name; ++i )
36 easing_functions[i].name,
37 easing_functions[i].func
41 //----------------------------------------------------------------------------
42 void PropertyInterpolationMgr::update(double dt)
44 for( InterpolatorList::iterator it = _interpolators.begin();
45 it != _interpolators.end();
48 for(double unused_time = dt;;)
50 PropertyInterpolatorRef interp = it->second;
51 unused_time = interp->update(it->first, unused_time);
53 if( unused_time <= 0.0 )
54 // No time left for next animation
59 // Step to next animation. Note that we do not invalidate or delete
60 // the current interpolator to allow for looped animations.
61 it->second = interp->_next;
65 // No more animations so just remove it
66 it = _interpolators.erase(it);
73 //----------------------------------------------------------------------------
74 struct PropertyInterpolationMgr::PredicateIsSameProp
77 PredicateIsSameProp(SGPropertyNode* node):
80 bool operator()(const PropertyInterpolatorPair& interp) const
82 return interp.first == _node;
85 SGPropertyNode *_node;
88 //----------------------------------------------------------------------------
89 PropertyInterpolatorRef
90 PropertyInterpolationMgr::createInterpolator( const std::string& type,
91 const SGPropertyNode* target,
93 const std::string& easing )
95 InterpolatorFactoryMap::iterator interpolator_factory =
96 _interpolator_factories.find(type);
97 if( interpolator_factory == _interpolator_factories.end() )
103 "PropertyInterpolationMgr: no factory found for type '" << type << "'"
108 EasingFunctionMap::iterator easing_func = _easing_functions.find(easing);
109 if( easing_func == _easing_functions.end() )
115 "PropertyInterpolationMgr: no such easing '" << type << "'"
120 PropertyInterpolatorRef interp;
121 interp = (*interpolator_factory->second)();
122 interp->reset(target);
123 interp->_type = type;
124 interp->_duration = duration;
125 interp->_easing = easing_func->second;
130 //----------------------------------------------------------------------------
131 void PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
132 PropertyInterpolatorRef interp )
134 // Search for active interpolator on given property
135 InterpolatorList::iterator it = std::find_if
137 _interpolators.begin(),
138 _interpolators.end(),
139 PredicateIsSameProp(prop)
142 if( it != _interpolators.end() )
144 // Ensure no circular reference is left
145 it->second->_next = 0;
147 // and now safely replace old interpolator
148 // TODO maybe cache somewhere for reuse or use allocator?
152 _interpolators.push_front( std::make_pair(prop, interp) );
155 //----------------------------------------------------------------------------
156 void PropertyInterpolationMgr::addInterpolatorFactory
158 const std::string& type,
159 InterpolatorFactory factory
162 if( _interpolator_factories.find(type) != _interpolator_factories.end() )
167 "PropertyInterpolationMgr: replace existing factor for type " << type
170 _interpolator_factories[type] = factory;
173 //----------------------------------------------------------------------------
174 void PropertyInterpolationMgr::addEasingFunction( const std::string& type,
177 // TODO it's probably time for a generic factory map
178 if( _easing_functions.find(type) != _easing_functions.end() )
183 "PropertyInterpolationMgr: replace existing easing function " << type
186 _easing_functions[type] = func;
189 } // namespace simgear