Interpolation system tweaking and add helpers to SGPropertyNode to interpolate its value

This commit is contained in:
Thomas Geymayer 2013-03-17 23:48:01 +01:00
parent 8898f5fe52
commit 9e9cc7859c
4 changed files with 144 additions and 9 deletions

View File

@ -41,6 +41,9 @@ namespace simgear
//----------------------------------------------------------------------------
void PropertyInterpolationMgr::update(double dt)
{
if( _rt_prop )
dt = _rt_prop->getDoubleValue();
for( InterpolatorList::iterator it = _interpolators.begin();
it != _interpolators.end();
++it )
@ -128,9 +131,12 @@ namespace simgear
}
//----------------------------------------------------------------------------
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
(
@ -139,6 +145,14 @@ namespace simgear
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
@ -150,10 +164,26 @@ namespace simgear
}
else
_interpolators.push_front( std::make_pair(prop, interp) );
return true;
}
//----------------------------------------------------------------------------
void PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
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)
);
}
//----------------------------------------------------------------------------
bool PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
const std::string& type,
const PropertyList& values,
const double_list& deltas,
@ -166,7 +196,7 @@ namespace simgear
if( !num_values )
{
SG_LOG(SG_GENERAL, SG_WARN, "interpolate: no values");
return;
return false;
}
PropertyInterpolatorRef first_interp, cur_interp;
@ -185,7 +215,7 @@ namespace simgear
cur_interp = interp;
}
interpolate(prop, first_interp);
return interpolate(prop, first_interp);
}
//----------------------------------------------------------------------------
@ -222,4 +252,10 @@ namespace simgear
_easing_functions[type] = func;
}
//----------------------------------------------------------------------------
void PropertyInterpolationMgr::setRealtimeProperty(SGPropertyNode* node)
{
_rt_prop = node;
}
} // namespace simgear

View File

@ -72,8 +72,8 @@ 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
@ -82,14 +82,20 @@ namespace simgear
* @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.
@ -111,6 +117,13 @@ namespace simgear
*/
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;
@ -124,6 +137,8 @@ namespace simgear
InterpolatorFactoryMap _interpolator_factories;
EasingFunctionMap _easing_functions;
InterpolatorList _interpolators;
SGPropertyNode_ptr _rt_prop;
};
} // namespace simgear

View File

@ -11,6 +11,7 @@
#endif
#include "props.hxx"
#include "PropertyInterpolationMgr.hxx"
#include "vectorPropTemplates.hxx"
#include <algorithm>
@ -1654,6 +1655,52 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
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))

View File

@ -31,6 +31,7 @@
#include <simgear/math/SGMathFwd.hxx>
#include <simgear/math/sg_types.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
@ -39,6 +40,9 @@
namespace simgear
{
class PropertyInterpolationMgr;
template<typename T>
std::istream& readFrom(std::istream& stream, T& result)
{
@ -1237,6 +1241,37 @@ public:
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.
*/
@ -1650,6 +1685,8 @@ protected:
template<typename Itr>
SGPropertyNode (Itr begin, Itr end, int index, SGPropertyNode * parent);
static simgear::PropertyInterpolationMgr* _interpolation_mgr;
private:
// Get the raw value