Interpolation system tweaking and add helpers to SGPropertyNode to interpolate its value
This commit is contained in:
parent
8898f5fe52
commit
9e9cc7859c
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user