1
0
Fork 0

property-interpolate: support using rate instead of time.

- property-interpolate now supports specifying the
   interpolation time by passing rate instead of the actual time,
   similar to max-rate-of-change in the noise-spike filter.
This commit is contained in:
Thomas Geymayer 2012-09-06 14:05:57 +02:00
parent 1dbc2c83e5
commit 0554d987e8

View file

@ -923,14 +923,18 @@ do_property_randomize (const SGPropertyNode * arg)
/** /**
* Built-in command: interpolate a property value over time * Built-in command: interpolate a property value over time
* *
* property: the name of the property value to interpolate. * property: the name of the property value to interpolate.
* value[0..n] any number of constant values to interpolate * value[0..n] any number of constant values to interpolate
* time[0..n] time between each value, number of time elements must * time/rate[0..n] time between each value, number of time elements must
* match those of value elements * match those of value elements. Instead of time also rate can
* be used which automatically calculates the time to change
* the property value at the given speed.
* -or- * -or-
* property[1..n] any number of target values taken from named properties * property[1..n] any number of target values taken from named properties
* time[0..n] time between each value, number of time elements must * time/rate[0..n] time between each value, number of time elements must
* match those of property elements minus one * match those of value elements. Instead of time also rate can
* be used which automatically calculates the time to change
* the property value at the given speed.
*/ */
static bool static bool
do_property_interpolate (const SGPropertyNode * arg) do_property_interpolate (const SGPropertyNode * arg)
@ -939,13 +943,22 @@ do_property_interpolate (const SGPropertyNode * arg)
simgear::PropertyList valueNodes = arg->getChildren( "value" ); simgear::PropertyList valueNodes = arg->getChildren( "value" );
simgear::PropertyList timeNodes = arg->getChildren( "time" ); simgear::PropertyList timeNodes = arg->getChildren( "time" );
simgear::PropertyList rateNodes = arg->getChildren( "rate" );
if( !timeNodes.empty() && !rateNodes.empty() )
// mustn't specify time and rate
return false;
simgear::PropertyList::size_type num_times = timeNodes.empty()
? rateNodes.size()
: timeNodes.size();
boost::scoped_array<double> value; boost::scoped_array<double> value;
boost::scoped_array<double> time; boost::scoped_array<double> time;
if( valueNodes.size() > 0 ) { if( valueNodes.size() > 0 ) {
// must match // must match
if( timeNodes.size() != valueNodes.size() ) if( num_times != valueNodes.size() )
return false; return false;
value.reset( new double[valueNodes.size()] ); value.reset( new double[valueNodes.size()] );
@ -955,7 +968,7 @@ do_property_interpolate (const SGPropertyNode * arg)
} else { } else {
valueNodes = arg->getChildren("property"); valueNodes = arg->getChildren("property");
// must have one more property node // must have one more property node
if( valueNodes.size() - 1 != timeNodes.size() ) if( valueNodes.size() - 1 != num_times )
return false; return false;
value.reset( new double[valueNodes.size()-1] ); value.reset( new double[valueNodes.size()-1] );
@ -965,14 +978,22 @@ do_property_interpolate (const SGPropertyNode * arg)
} }
time.reset( new double[timeNodes.size()] ); time.reset( new double[num_times] );
for( simgear::PropertyList::size_type n = 0; n < timeNodes.size(); n++ ) { if( !timeNodes.empty() ) {
time[n] = timeNodes[n]->getDoubleValue(); for( simgear::PropertyList::size_type n = 0; n < num_times; n++ ) {
time[n] = timeNodes[n]->getDoubleValue();
}
} else {
for( simgear::PropertyList::size_type n = 0; n < num_times; n++ ) {
double delta = value[n]
- (n > 0 ? value[n - 1] : prop->getDoubleValue());
time[n] = fabs(delta / rateNodes[n]->getDoubleValue());
}
} }
((SGInterpolator*)globals->get_subsystem_mgr() ((SGInterpolator*)globals->get_subsystem_mgr()
->get_group(SGSubsystemMgr::INIT)->get_subsystem("interpolator")) ->get_group(SGSubsystemMgr::INIT)->get_subsystem("interpolator"))
->interpolate(prop, timeNodes.size(), value.get(), time.get() ); ->interpolate(prop, num_times, value.get(), time.get() );
return true; return true;
} }