]> git.mxchange.org Git - simgear.git/commitdiff
Interpolation system tweaking and add helpers to SGPropertyNode to interpolate its...
authorThomas Geymayer <tomgey@gmail.com>
Sun, 17 Mar 2013 22:48:01 +0000 (23:48 +0100)
committerThomas Geymayer <tomgey@gmail.com>
Sun, 17 Mar 2013 22:48:01 +0000 (23:48 +0100)
simgear/props/PropertyInterpolationMgr.cxx
simgear/props/PropertyInterpolationMgr.hxx
simgear/props/props.cxx
simgear/props/props.hxx

index e0591e609cbbaca3fdeb5262d88e5edfa85bdb01..0ec4ad79b3796e08903856e1650f05d8fe18fb06 100644 (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;
+  }
+
+  //----------------------------------------------------------------------------
+  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,
@@ -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
index a703158f829784bfc6be81f52e05411c03b5de0f..446fad9490063200409795cfe845e86ea93cb45e 100644 (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
index f5484568f984e2449bcda499b2a4b8dac3563e31..5b778a7a97627969385f1f95f974400307ab8f91 100644 (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))
index eaf5fe1479f7937c517a0dd7c04ae10769b2c9f3..d06f4855e317f5074fc83dfef8cb84f895ff78ca 100644 (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