//----------------------------------------------------------------------------
void PropertyInterpolationMgr::update(double dt)
{
+ if( _rt_prop )
+ dt = _rt_prop->getDoubleValue();
+
for( InterpolatorList::iterator it = _interpolators.begin();
it != _interpolators.end();
++it )
}
//----------------------------------------------------------------------------
- void PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
+ bool PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
PropertyInterpolatorRef interp )
{
+ if( !prop )
+ return false;
+
// Search for active interpolator on given property
InterpolatorList::iterator it = std::find_if
(
PredicateIsSameProp(prop)
);
+ if( !interp )
+ {
+ // Without new interpolator just remove old one
+ if( it != _interpolators.end() )
+ _interpolators.erase(it);
+ return true;
+ }
+
if( it != _interpolators.end() )
{
// Ensure no circular reference is left
}
else
_interpolators.push_front( std::make_pair(prop, interp) );
+
+ return true;
+ }
+
+ //----------------------------------------------------------------------------
+ bool PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
+ const std::string& type,
+ const SGPropertyNode& target,
+ double duration,
+ const std::string& easing )
+ {
+ return interpolate
+ (
+ prop,
+ createInterpolator(type, target, duration, easing)
+ );
}
//----------------------------------------------------------------------------
- void PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
+ bool PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
const std::string& type,
const PropertyList& values,
const double_list& deltas,
if( !num_values )
{
SG_LOG(SG_GENERAL, SG_WARN, "interpolate: no values");
- return;
+ return false;
}
PropertyInterpolatorRef first_interp, cur_interp;
cur_interp = interp;
}
- interpolate(prop, first_interp);
+ return interpolate(prop, first_interp);
}
//----------------------------------------------------------------------------
_easing_functions[type] = func;
}
+ //----------------------------------------------------------------------------
+ void PropertyInterpolationMgr::setRealtimeProperty(SGPropertyNode* node)
+ {
+ _rt_prop = node;
+ }
+
} // namespace simgear
PropertyInterpolator*
createInterpolator( const std::string& type,
const SGPropertyNode& target,
- double duration = 1.0,
- const std::string& easing = "swing" );
+ double duration,
+ const std::string& easing );
/**
* Add animation of the given property from current its current value to
* @param prop Property to be interpolated
* @param interp Interpolator used for interpolation
*/
- void interpolate( SGPropertyNode* prop,
+ bool interpolate( SGPropertyNode* prop,
PropertyInterpolatorRef interp );
- void interpolate( SGPropertyNode* prop,
+ bool interpolate( SGPropertyNode* prop,
+ const std::string& type,
+ const SGPropertyNode& target,
+ double duration,
+ const std::string& easing );
+
+ bool interpolate( SGPropertyNode* prop,
const std::string& type,
const PropertyList& values,
const double_list& deltas,
- const std::string& easing = "linear" );
+ const std::string& easing );
/**
* Register factory for interpolation type.
*/
void addEasingFunction(const std::string& type, easing_func_t func);
+ /**
+ * Set property containing real time delta (not sim time)
+ *
+ * TODO better pass both deltas to all update methods...
+ */
+ void setRealtimeProperty(SGPropertyNode* node);
+
protected:
typedef std::map<std::string, InterpolatorFactory> InterpolatorFactoryMap;
InterpolatorFactoryMap _interpolator_factories;
EasingFunctionMap _easing_functions;
InterpolatorList _interpolators;
+
+ SGPropertyNode_ptr _rt_prop;
};
} // namespace simgear
#endif
#include "props.hxx"
+#include "PropertyInterpolationMgr.hxx"
#include "vectorPropTemplates.hxx"
#include <algorithm>
return result;
}
+//------------------------------------------------------------------------------
+bool SGPropertyNode::interpolate( const std::string& type,
+ const SGPropertyNode& target,
+ double duration,
+ const std::string& easing )
+{
+ if( !_interpolation_mgr )
+ {
+ SG_LOG(SG_GENERAL, SG_WARN, "No property interpolator available");
+
+ // no interpolation possible -> set to target immediately
+ setUnspecifiedValue( target.getStringValue() );
+ return false;
+ }
+
+ return _interpolation_mgr->interpolate(this, type, target, duration, easing);
+}
+
+//------------------------------------------------------------------------------
+bool SGPropertyNode::interpolate( const std::string& type,
+ const PropertyList& values,
+ const double_list& deltas,
+ const std::string& easing )
+{
+ if( !_interpolation_mgr )
+ {
+ SG_LOG(SG_GENERAL, SG_WARN, "No property interpolator available");
+
+ // no interpolation possible -> set to last value immediately
+ if( !values.empty() )
+ setUnspecifiedValue(values.back()->getStringValue());
+ return false;
+ }
+
+ return _interpolation_mgr->interpolate(this, type, values, deltas, easing);
+}
+
+//------------------------------------------------------------------------------
+void SGPropertyNode::setInterpolationMgr(simgear::PropertyInterpolationMgr* mgr)
+{
+ _interpolation_mgr = mgr;
+}
+
+simgear::PropertyInterpolationMgr* SGPropertyNode::_interpolation_mgr = 0;
+
+//------------------------------------------------------------------------------
std::ostream& SGPropertyNode::printOn(std::ostream& stream) const
{
if (!getAttribute(READ))
#include <simgear/math/SGMathFwd.hxx>
+#include <simgear/math/sg_types.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
namespace simgear
{
+
+ class PropertyInterpolationMgr;
+
template<typename T>
std::istream& readFrom(std::istream& stream, T& result)
{
return setValue(&val[0]);
}
+ /**
+ * Interpolate current value to target value within given time.
+ *
+ * @param type Type of interpolation ("numeric", "color", etc.)
+ * @param target Node containing target value
+ * @param duration Duration of interpolation (in seconds)
+ * @param easing Easing function (http://easings.net/)
+ */
+ bool interpolate( const std::string& type,
+ const SGPropertyNode& target,
+ double duration = 0.6,
+ const std::string& easing = "swing" );
+
+ /**
+ * Interpolate current value to a series of values within given durations.
+ *
+ * @param type Type of interpolation ("numeric", "color", etc.)
+ * @param values Nodes containing intermediate and target values
+ * @param duration Durations for each interpolation step (in seconds)
+ * @param easing Easing function (http://easings.net/)
+ */
+ bool interpolate( const std::string& type,
+ const simgear::PropertyList& values,
+ const double_list& deltas,
+ const std::string& easing = "swing" );
+
+ /**
+ * Set the interpolation manager used by the interpolate methods.
+ */
+ static void setInterpolationMgr(simgear::PropertyInterpolationMgr* mgr);
+
/**
* Print the value of the property to a stream.
*/
template<typename Itr>
SGPropertyNode (Itr begin, Itr end, int index, SGPropertyNode * parent);
+ static simgear::PropertyInterpolationMgr* _interpolation_mgr;
+
private:
// Get the raw value