Author: Carlos Lopez <genet...@gmail.com>
Date:   Tue Jan  3 19:44:24 2012 +0100

Add code to interpret the clamped interpolation method

---

 synfig-core/src/synfig/valuenode_animated.cpp |  172 ++++++++++++++++++++++--
 1 files changed, 157 insertions(+), 15 deletions(-)

diff --git a/synfig-core/src/synfig/valuenode_animated.cpp 
b/synfig-core/src/synfig/valuenode_animated.cpp
index 82e4633..f1f5804 100644
--- a/synfig-core/src/synfig/valuenode_animated.cpp
+++ b/synfig-core/src/synfig/valuenode_animated.cpp
@@ -131,6 +131,15 @@ struct magnitude<Color> : public 
std::unary_function<float, Color>
        }
 };
 
+template <>
+struct magnitude<Gradient> : public std::unary_function<float, Gradient>
+{
+       float operator()(const Gradient &a)const
+       {
+               return a.mag();
+       }
+};
+
 template <class T>
 struct is_angle_type
 {
@@ -373,18 +382,87 @@ public:
                                                }
                                        }
                                        else
+                                       {
                                                ///
-                                               /// ANY/LINEAR ------- ANY/ANY
+                                               /// ANY/LINEAR ----- ANY/ANY
                                                ///            or
-                                               /// ANY/EASE -------- ANY/ANY
+                                               /// ANY/EASE ------- ANY/ANY
                                                ///            or
                                                /// ANY/TCB -------- ANY/ANY 
and iter is first.
+                                               ///            or
+                                               /// ANY/CLAMPED ---- ANT/ANY 
and iter is first
                                            if(
                                                
iter_get_after==INTERPOLATION_LINEAR || iter_get_after==INTERPOLATION_HALT ||
-                                               
(iter_get_after==INTERPOLATION_TCB && iter==waypoint_list_.begin()))
+                                               
(iter_get_after==INTERPOLATION_TCB && iter==waypoint_list_.begin()) ||
+                                               
(iter_get_after==INTERPOLATION_CLAMPED && iter==waypoint_list_.begin())
+                                               )
+                                               {
+                                                       /// t1 = p2 - p1
+                                                       
curve.second.t1()=subtract_func(curve.second.p2(),curve.second.p1());
+                                               }
+                                       }
+                                       /// iter             next
+                                       /// ANY/CLAMPED ---- ANY/ANY and iter 
is middle waypoint
+                                       if(iter_get_after == 
INTERPOLATION_CLAMPED && iter!=waypoint_list_.begin() && !is_angle())
                                        {
-                                               /// t1 = p2 - p1
-                                               
curve.second.t1()=subtract_func(curve.second.p2(),curve.second.p1());
+                                               // Default TCB values
+                                               Real t(0.0);          // Tension
+                                               const Real& c(0.0);   // 
Continuity
+                                               const Real& b(0.0);   // Bias
+                                               value_type Pp; 
Pp=curve_list.back().second.p1(); // P_{i-1}
+                                               const value_type& 
Pc(curve.second.p1());         // P_i
+                                               const value_type& 
Pn(curve.second.p2());         // P_{i+1}
+                                               Real P1(magnitude_func(Pp));
+                                               Real P2(magnitude_func(Pc));
+                                               Real P3(magnitude_func(Pn));
+                                               Time 
T1(curve_list.back().first.p1());
+                                               Time T2(iter->get_time());
+                                               Time T3(next->get_time());
+                                               Real Pa;
+                                               Real Pb;
+                                               if(P3 > P1)
+                                               {
+                                                       
Pa=P3-(P3-P1)*1.3*(T3-T2)*(T3-T2)/((T3-T1)*(T3-T1));
+                                                       
Pb=P1+(P3-P1)*0.7*(T2-T1)*(T2-T1)/((T3-T1)*(T3-T1));
+                                                       if(P2 >= Pa)
+                                                       {
+                                                               
t=(P2-Pa)/(P3-Pa);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                                       else if(Pa >= P2 && P2 
>= Pb)
+                                                               t=0.0;
+                                                       else // (Pb > P2)
+                                                       {
+                                                               
t=(Pb-P2)/(Pb-P1);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                               }
+                                               else if(P3 < P1)
+                                               {
+                                                       
Pa=P1-(P1-P3)*0.7*(T2-T1)*(T2-T1)/((T3-T1)*(T3-T1));
+                                                       
Pb=P3+(P1-P3)*1.3*(T3-T2)*(T3-T2)/((T3-T1)*(T3-T1));
+                                                       if(P2 >= Pa)
+                                                       {
+                                                               
t=(P2-Pa)/(P1-Pa);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                                       else if(Pa >= P2 && P2 
>= Pb)
+                                                               t=0.0;
+                                                       else // (Pb > P2)
+                                                       {
+                                                               
t=(Pb-P2)/(Pb-P3);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                               }
+                                               else // P3 == P1
+                                                       t=0.0;
+                                               synfig::info("iter ->t=%f", t);
+                                               // TCB tangent calculation
+                                               value_type 
vect(static_cast<value_type>
+                                                                               
(subtract_func(Pc,Pp) *
+                                                                               
           (((1.0-t) * (1.0+c) * (1.0+b)) / 2.0) +
+                                                                               
 (Pn-Pc) * (((1.0-t) * (1.0-c) * (1.0-b)) / 2.0)));
+                                               curve.second.t1()=vect;
                                        }
                                        ///
                                        /// TCB/!TCB and list not empty
@@ -398,17 +476,17 @@ public:
                                                
curve_list.back().second.t2()=curve.second.t1();
                                                curve_list.back().second.sync();
                                        }
-                                       /// iter          next          
after-next
+                                       /// iter          next          
after_next
                                        /// ANY/ANY ------TCB/ANY ----- ANY/ANY
                                        ///
                                        if(next_get_before==INTERPOLATION_TCB 
&& after_next!=waypoint_list_.end()  && !is_angle())
                                        {
-                                               const Real 
&t(next->get_tension());             // Tension
-                                               const Real 
&c(next->get_continuity());  // Continuity
-                                               const Real 
&b(next->get_bias());                        // Bias
-                                               const value_type 
&Pp(curve.second.p1());        // P_{i-1}
-                                               const value_type 
&Pc(curve.second.p2());        // P_i
-                                               value_type Pn; 
Pn=after_next->get_value().get(T());     // P_{i+1}
+                                               const Real 
&t(next->get_tension());       // Tension
+                                               const Real 
&c(next->get_continuity());    // Continuity
+                                               const Real 
&b(next->get_bias());          // Bias
+                                               const value_type 
&Pp(curve.second.p1());  // P_{i-1}
+                                               const value_type 
&Pc(curve.second.p2());  // P_i
+                                               value_type Pn; 
Pn=after_next->get_value().get(T()); // P_{i+1}
 
                                                /// TCB calculation
                                                value_type 
vect(static_cast<value_type>(subtract_func(Pc,Pp) * 
(((1.0-t)*(1.0-c)*(1.0+b))/2.0) +
@@ -421,15 +499,79 @@ public:
                                                ///           or
                                                /// ANY/ANY ----- EASE/ANY
                                                ///           or
-                                               /// ANY/ANY -----TCB/ANY ---- 
END
+                                               /// ANY/ANY ----- TCB/ANY ---- 
END
+                                               ///           or
+                                               /// ANY/ANY ----- CLAMPED/ANY 
----END
                                            if(
                                                
next_get_before==INTERPOLATION_LINEAR || next_get_before==INTERPOLATION_HALT ||
-                                               
(next_get_before==INTERPOLATION_TCB && after_next==waypoint_list_.end()))
+                                               
(next_get_before==INTERPOLATION_TCB && after_next==waypoint_list_.end()) ||
+                                               
(next_get_before==INTERPOLATION_CLAMPED && after_next==waypoint_list_.end())
+                                               )
                                        {
                                                /// t2 = p2 - p1
                                                
curve.second.t2()=subtract_func(curve.second.p2(),curve.second.p1());
                                        }
-
+                                       /// iter             next         
after_next
+                                       /// ANY/ANY ---- CLAMPED/ANY      
ANY/ANY
+                                       if(next_get_before == 
INTERPOLATION_CLAMPED && after_next!=waypoint_list_.end()  && !is_angle())
+                                       {
+                                               Real t(0.0);         // Tension
+                                               const Real &c(0.0);  // 
Continuity
+                                               const Real &b(0.0);  // Bias
+                                               const value_type 
&Pp(curve.second.p1());            // P_{i-1}
+                                               const value_type 
&Pc(curve.second.p2());            // P_i
+                                               value_type Pn; 
Pn=after_next->get_value().get(T()); // P_{i+1}
+                                               Real P1(magnitude_func(Pp));
+                                               Real P2(magnitude_func(Pc));
+                                               Real P3(magnitude_func(Pn));
+                                               Time T1(iter->get_time());
+                                               Time T2(next->get_time());
+                                               Time T3(after_next->get_time());
+                                               Real Pa;
+                                               Real Pb;
+                                               if(P3 > P1)
+                                               {
+                                                       
Pa=P3-(P3-P1)*1.3*(T3-T2)*(T3-T2)/((T3-T1)*(T3-T1));
+                                                       
Pb=P1+(P3-P1)*0.7*(T2-T1)*(T2-T1)/((T3-T1)*(T3-T1));
+                                                       if(P2 >= Pa)
+                                                       {
+                                                               
t=(P2-Pa)/(P3-Pa);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                                       else if(Pa >= P2 && P2 
>= Pb)
+                                                               t=0.0;
+                                                       else // (Pb > P2)
+                                                       {
+                                                               
t=(Pb-P2)/(Pb-P1);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                               }
+                                               else if(P3 < P1)
+                                               {
+                                                       
Pa=P1-(P1-P3)*0.7*(T2-T1)*(T2-T1)/((T3-T1)*(T3-T1));
+                                                       
Pb=P3+(P1-P3)*1.3*(T3-T2)*(T3-T2)/((T3-T1)*(T3-T1));
+                                                       if(P2 >= Pa)
+                                                       {
+                                                               
t=(P2-Pa)/(P1-Pa);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                                       else if(Pa >= P2 && P2 
>= Pb)
+                                                               t=0.0;
+                                                       else // (Pb > P2)
+                                                       {
+                                                               
t=(Pb-P2)/(Pb-P3);
+                                                               if(t>1.0) t=1.0;
+                                                       }
+                                               }
+                                               else // P3 == P1
+                                                       t=0.0;
+                                               synfig::info("next ->t=%f", t);
+                                               
synfig::info("----------------");
+                                               /// TCB calculation
+                                               value_type 
vect(static_cast<value_type>(subtract_func(Pc,Pp) * 
(((1.0-t)*(1.0-c)*(1.0+b))/2.0) +
+                                                                               
                                                                         
(Pn-Pc) * (((1.0-t)*(1.0+c)*(1.0-b))/2.0)));
+                                               curve.second.t2()=vect;
+                                       }
                                        // Adjust for time
                                        const float timeadjust(0.5);
                                        /// iter           next


------------------------------------------------------------------------------
Write once. Port to many.
Get the SDK and tools to simplify cross-platform app development. Create 
new or port existing apps to sell to consumers worldwide. Explore the 
Intel AppUpSM program developer opportunity. appdeveloper.intel.com/join
http://p.sf.net/sfu/intel-appdev
_______________________________________________
Synfig-devl mailing list
Synfig-devl@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synfig-devl

Reply via email to