]> git.mxchange.org Git - simgear.git/commitdiff
Tweak interpolator and allow passing list of interpolation steps
authorThomas Geymayer <tomgey@gmail.com>
Sat, 16 Mar 2013 15:36:20 +0000 (16:36 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Sat, 16 Mar 2013 15:36:20 +0000 (16:36 +0100)
simgear/props/PropertyInterpolationMgr.cxx
simgear/props/PropertyInterpolationMgr.hxx
simgear/props/PropertyInterpolator.cxx
simgear/props/PropertyInterpolator.hxx
simgear/scene/util/ColorInterpolator.cxx
simgear/scene/util/ColorInterpolator.hxx
simgear/scene/util/parse_color_test.cxx

index 60ff32244597712f7340ee9ec1d8235535737591..e0591e609cbbaca3fdeb5262d88e5edfa85bdb01 100644 (file)
@@ -48,7 +48,7 @@ namespace simgear
       for(double unused_time = dt;;)
       {
         PropertyInterpolatorRef interp = it->second;
-        unused_time = interp->update(it->first, unused_time);
+        unused_time = interp->update(*it->first, unused_time);
 
         if( unused_time <= 0.0 )
           // No time left for next animation
@@ -86,9 +86,9 @@ namespace simgear
   };
 
   //----------------------------------------------------------------------------
-  PropertyInterpolatorRef
+  PropertyInterpolator*
   PropertyInterpolationMgr::createInterpolator( const std::string& type,
-                                                const SGPropertyNode* target,
+                                                const SGPropertyNode& target,
                                                 double duration,
                                                 const std::string& easing )
   {
@@ -117,7 +117,7 @@ namespace simgear
       return 0;
     }
 
-    PropertyInterpolatorRef interp;
+    PropertyInterpolator* interp;
     interp = (*interpolator_factory->second)();
     interp->reset(target);
     interp->_type = type;
@@ -152,6 +152,42 @@ namespace simgear
       _interpolators.push_front( std::make_pair(prop, interp) );
   }
 
+  //----------------------------------------------------------------------------
+  void PropertyInterpolationMgr::interpolate( SGPropertyNode* prop,
+                                              const std::string& type,
+                                              const PropertyList& values,
+                                              const double_list& deltas,
+                                              const std::string& easing )
+  {
+    if( values.size() != deltas.size() )
+      SG_LOG(SG_GENERAL, SG_WARN, "interpolate: sizes do not match");
+
+    size_t num_values = std::min(values.size(), deltas.size());
+    if( !num_values )
+    {
+      SG_LOG(SG_GENERAL, SG_WARN, "interpolate: no values");
+      return;
+    }
+
+    PropertyInterpolatorRef first_interp, cur_interp;
+    for(size_t i = 0; i < num_values; ++i)
+    {
+      assert(values[i]);
+
+      PropertyInterpolator* interp =
+        createInterpolator(type, *values[i], deltas[i], easing);
+
+      if( !first_interp )
+        first_interp = interp;
+      else
+        cur_interp->_next = interp;
+
+      cur_interp = interp;
+    }
+
+    interpolate(prop, first_interp);
+  }
+
   //----------------------------------------------------------------------------
   void PropertyInterpolationMgr::addInterpolatorFactory
   (
index 96e942c1fee99ef5a9264da627cef239a5ab5b2a..a703158f829784bfc6be81f52e05411c03b5de0f 100644 (file)
@@ -21,7 +21,9 @@
 
 #include "PropertyInterpolator.hxx"
 
+#include <simgear/math/sg_types.hxx>
 #include <simgear/misc/make_new.hxx>
+#include <simgear/props/props.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 
 #include <list>
@@ -67,9 +69,9 @@ namespace simgear
        * @param duration    Duration if the animation (in seconds)
        * @param easing      Type of easing ("linear", "swing", etc.)
        */
-      PropertyInterpolatorRef
+      PropertyInterpolator*
       createInterpolator( const std::string& type,
-                          const SGPropertyNode* target,
+                          const SGPropertyNode& target,
                           double duration = 1.0,
                           const std::string& easing = "swing" );
 
@@ -83,6 +85,12 @@ namespace simgear
       void interpolate( SGPropertyNode* prop,
                         PropertyInterpolatorRef interp );
 
+      void interpolate( SGPropertyNode* prop,
+                        const std::string& type,
+                        const PropertyList& values,
+                        const double_list& deltas,
+                        const std::string& easing = "linear" );
+
       /**
        * Register factory for interpolation type.
        */
index 79b830caf6ebdc2fbc1e635d2f9e5bdd3224be63..dd010641ab23ed19086db08939bc8d8f549e31c3 100644 (file)
@@ -32,7 +32,7 @@ namespace simgear
   }
 
   //----------------------------------------------------------------------------
-  void PropertyInterpolator::reset(const SGPropertyNode* target)
+  void PropertyInterpolator::reset(const SGPropertyNode& target)
   {
     _cur_t = 0;
     setTarget(target);
@@ -45,7 +45,7 @@ namespace simgear
   }
 
   //----------------------------------------------------------------------------
-  double PropertyInterpolator::update(SGPropertyNode* prop, double dt)
+  double PropertyInterpolator::update(SGPropertyNode& prop, double dt)
   {
     if( _cur_t == 0 )
       init(prop);
@@ -74,31 +74,31 @@ namespace simgear
   }
 
   //----------------------------------------------------------------------------
-  void NumericInterpolator::setTarget(const SGPropertyNode* target)
+  void NumericInterpolator::setTarget(const SGPropertyNode& target)
   {
-    _end = target->getDoubleValue();
+    _end = target.getDoubleValue();
   }
 
   //----------------------------------------------------------------------------
-  void NumericInterpolator::init(const SGPropertyNode* prop)
+  void NumericInterpolator::init(const SGPropertyNode& prop)
   {
     // If unable to get start value, immediately change to target value
-    double value_start = prop->getType() == props::NONE
+    double value_start = prop.getType() == props::NONE
                        ? _end
-                       : prop->getDoubleValue();
+                       : prop.getDoubleValue();
 
     _diff = _end - value_start;
   }
 
   //----------------------------------------------------------------------------
-  void NumericInterpolator::write(SGPropertyNode* prop, double t)
+  void NumericInterpolator::write(SGPropertyNode& prop, double t)
   {
     double cur = _end - (1 - t) * _diff;
 
-    if( prop->getType() == props::INT || prop->getType() == props::LONG )
-      prop->setLongValue( static_cast<long>(std::floor(cur + 0.5)) );
+    if( prop.getType() == props::INT || prop.getType() == props::LONG )
+      prop.setLongValue( static_cast<long>(std::floor(cur + 0.5)) );
     else
-      prop->setDoubleValue(cur);
+      prop.setDoubleValue(cur);
   }
 
 } // namespace simgear
index a89b3e2d992947c725b68f0e9b464ec7d5b0f027..b3bd6f8c4631c42f64e94666ae6034af1c64e232 100644 (file)
@@ -47,7 +47,7 @@ namespace simgear
        * Resets animation timer to zero and prepares for interpolation to new
        * target value.
        */
-      void reset(const SGPropertyNode* target);
+      void reset(const SGPropertyNode& target);
 
       /**
        * Set easing function to be used for interpolation.
@@ -63,7 +63,7 @@ namespace simgear
        *         else time is negative indicating the remaining time until
        *         finished)
        */
-      double update(SGPropertyNode* prop, double dt);
+      double update(SGPropertyNode& prop, double dt);
 
       const std::string& getType() const    { return _type; }
 
@@ -78,9 +78,9 @@ namespace simgear
 
       PropertyInterpolator();
 
-      virtual void setTarget(const SGPropertyNode* target) = 0;
-      virtual void init(const SGPropertyNode* prop) = 0;
-      virtual void write(SGPropertyNode* prop, double t) = 0;
+      virtual void setTarget(const SGPropertyNode& target) = 0;
+      virtual void init(const SGPropertyNode& prop) = 0;
+      virtual void write(SGPropertyNode& prop, double t) = 0;
   };
 
   class NumericInterpolator:
@@ -90,9 +90,9 @@ namespace simgear
       double _end,
              _diff;
 
-      virtual void setTarget(const SGPropertyNode* target);
-      virtual void init(const SGPropertyNode* prop);
-      virtual void write(SGPropertyNode* prop, double t);
+      virtual void setTarget(const SGPropertyNode& target);
+      virtual void init(const SGPropertyNode& prop);
+      virtual void write(SGPropertyNode& prop, double t);
   };
 
 } // namespace simgear
index 6abe2e112567ab68bc2b710180ec38f758bc473c..fd2edbfc297c6edce5cccb8d6cf10afce95c3da7 100644 (file)
@@ -25,9 +25,9 @@ namespace simgear
 {
 
   //----------------------------------------------------------------------------
-  void ColorInterpolator::setTarget(const SGPropertyNode* target)
+  void ColorInterpolator::setTarget(const SGPropertyNode& target)
   {
-    if( !parseColor(target->getStringValue(), _color_end) )
+    if( !parseColor(target.getStringValue(), _color_end) )
       SG_LOG
       (
         SG_GENERAL, SG_WARN, "ColorInterpolator: failed to parse end color."
@@ -35,10 +35,10 @@ namespace simgear
   }
 
   //----------------------------------------------------------------------------
-  void ColorInterpolator::init(const SGPropertyNode* prop)
+  void ColorInterpolator::init(const SGPropertyNode& prop)
   {
     osg::Vec4 color_start;
-    if( !parseColor(prop->getStringValue(), color_start) )
+    if( !parseColor(prop.getStringValue(), color_start) )
       // If unable to get current color, immediately change to target color
       color_start = _color_end;
 
@@ -46,7 +46,7 @@ namespace simgear
   }
 
   //----------------------------------------------------------------------------
-  void ColorInterpolator::write(SGPropertyNode* prop, double t)
+  void ColorInterpolator::write(SGPropertyNode& prop, double t)
   {
     osg::Vec4 color_cur = _color_end - _color_diff * (1 - t);
     bool has_alpha = color_cur.a() < 0.999;
@@ -68,7 +68,7 @@ namespace simgear
 
     strm << ')';
 
-    prop->setStringValue(strm.str());
+    prop.setStringValue(strm.str());
   }
 
 } // namespace simgear
index 0fad5659e5043f7648cce2edb41d5ced23efde47..568ffa04ee92c8321feed722fc10fa3ef91b43bd 100644 (file)
@@ -37,9 +37,9 @@ namespace simgear
       osg::Vec4 _color_end,
                 _color_diff;
 
-      virtual void setTarget(const SGPropertyNode* target);
-      virtual void init(const SGPropertyNode* prop);
-      virtual void write(SGPropertyNode* prop, double t);
+      virtual void setTarget(const SGPropertyNode& target);
+      virtual void init(const SGPropertyNode& prop);
+      virtual void write(SGPropertyNode& prop, double t);
 
 
   };
index e82884a787bbb8b4180e70566f3751f4cbe3921b..36ec882f44ed128aadb0f46122a98529e050eb68 100644 (file)
@@ -42,29 +42,29 @@ int main (int ac, char ** av)
   color_arg.setStringValue("#000000");
 
   simgear::PropertyInterpolator* interp = new simgear::ColorInterpolator;
-  interp->reset(&color_arg);
+  interp->reset(color_arg);
 
-  interp->update(&color_node, 0.5); // with no color it should immediately set to the target
+  interp->update(color_node, 0.5); // with no color it should immediately set to the target
   VERIFY_NODE_STR(color_node, "rgb(0,0,0)");
 
   color_arg.setStringValue("rgba(255,0,0,0.5)");
-  interp->reset(&color_arg);
+  interp->reset(color_arg);
 
-  interp->update(&color_node, 0.5);
+  interp->update(color_node, 0.5);
   VERIFY_NODE_STR(color_node, "rgba(127,0,0,0.75)");
 
-  interp->update(&color_node, 0.5);
+  interp->update(color_node, 0.5);
   VERIFY_NODE_STR(color_node, "rgba(255,0,0,0.5)");
 
   // Animation has already completed and therefore should be reset and start a
   // new animation starting with the current value of the animation. As this
   // is already the same as the target value, nothing should change.
-  interp->update(&color_node, 0.5);
+  interp->update(color_node, 0.5);
   VERIFY_NODE_STR(color_node, "rgba(255,0,0,0.5)");
 
   color_arg.setStringValue("#00ff00");
-  interp->reset(&color_arg);
-  interp->update(&color_node, 1.0);
+  interp->reset(color_arg);
+  interp->update(color_node, 1.0);
   VERIFY_NODE_STR(color_node, "rgb(0,255,0)");
 
   std::cout << "all tests passed successfully!" << std::endl;