Author: Carlos Lopez <genet...@gmail.com>
Date:   Sat Jan  7 19:56:49 2012 +0100

Use correct approaching to the problem modifying the bias of each waypoint and 
using templates to recursively call the clamped tangent calculation for real 
numbers.

---

 synfig-core/src/synfig/valuenode_animated.cpp |  242 ++++++++++++-------------
 1 files changed, 116 insertions(+), 126 deletions(-)

diff --git a/synfig-core/src/synfig/valuenode_animated.cpp 
b/synfig-core/src/synfig/valuenode_animated.cpp
index 6c4e20e..510bf03 100644
--- a/synfig-core/src/synfig/valuenode_animated.cpp
+++ b/synfig-core/src/synfig/valuenode_animated.cpp
@@ -160,6 +160,120 @@ struct is_angle_type<Angle>
 };
 #endif // ANGLES_USE_LINEAR_INTERPOLATION
 
+template<class T>
+T
+clamped_tangent(T p1, T p2, T p3, Time t1, Time t2, Time t3)
+{
+       Real bias=0.0;
+       T tangent(p3*0.0);
+       T pm=p1+(p3-p1)*(t2-t1)/(t3-t1);
+       if(p3 > p1)
+       {
+               if(p2 >= p3 || p2 <= p1)
+                       tangent = tangent*0.0;
+               else
+               {
+                       if(p2 > pm)
+                       {
+                               bias=(pm-p2)/(p3-pm);
+                       }
+                       else if (p2 < pm)
+                       {
+                               bias=(pm-p2)/(pm-p1);
+                       }
+                       else
+                               bias=0.0;
+                       tangent =( (p2-p1)*(1.0+bias)/2.0 + 
(p3-p2)*(1.0-bias)/2.0 );
+               }
+       }
+       else if (p1 > p3)
+       {
+               if(p2 >= p1 || p2 <= p3)
+                       tangent = tangent*0.0;
+               else
+               {
+                       if(p2 > pm)
+                       {
+                               bias=(pm-p2)/(pm-p1);
+                       }
+                       else if (p2 < pm)
+                       {
+                               bias=(pm-p2)/(p3-pm);
+                       }
+                       else
+                               bias=0.0;
+                       tangent =( (p2-p1)*(1.0+bias)/2.0 + 
(p3-p2)*(1.0-bias)/2.0 );
+               }
+       }
+       else
+       {
+               tangent= tangent * 0;
+       }
+       return tangent;
+};
+
+template<>
+Vector
+clamped_tangent<Vector>(Vector p1, Vector p2, Vector p3, Time t1, Time t2, 
Time t3)
+{
+       return Vector(clamped_tangent(p1[0],p2[0],p3[0],t1,t2,t3), 
clamped_tangent(p1[1],p2[1],p3[1],t1,t2,t3));
+};
+
+template<>
+Angle
+clamped_tangent<Angle>(Angle p1, Angle p2, Angle p3, Time t1, Time t2, Time t3)
+{
+       Real r1(Angle::rad(p1).get());
+       Real r2(Angle::rad(p2).get());
+       Real r3(Angle::rad(p3).get());
+       return Angle::rad(clamped_tangent(r1, r2, r3, t1, t2, t3));
+};
+
+template<>
+Time
+clamped_tangent<Time>(Time p1, Time p2, Time p3, Time t1, Time t2, Time t3)
+{
+       return Time(clamped_tangent(double(p1), double(p2), double(p3), t1, t2, 
t3));
+};
+
+template<>
+int
+clamped_tangent<int>(int p1, int p2, int p3, Time t1, Time t2, Time t3)
+{
+       return int(clamped_tangent(Real(p1), Real(p2), Real(p3), t1, t2, t3));
+};
+
+template<>
+Color
+clamped_tangent<Color>(Color p1, Color p2, Color p3, Time t1, Time t2, Time t3)
+{
+       Color ret;
+       ret.set_r(clamped_tangent(p1.get_r(), p2.get_r(), p3.get_r(), t1, t2, 
t3));
+       ret.set_g(clamped_tangent(p1.get_g(), p2.get_g(), p3.get_g(), t1, t2, 
t3));
+       ret.set_b(clamped_tangent(p1.get_b(), p2.get_b(), p3.get_b(), t1, t2, 
t3));
+       ret.set_a(clamped_tangent(p1.get_a(), p2.get_a(), p3.get_a(), t1, t2, 
t3));
+       return ret;
+};
+
+template<>
+Gradient
+clamped_tangent<Gradient>(Gradient p1, Gradient p2, Gradient p3, Time t1, Time 
t2, Time t3)
+{
+       Color c1, c2, c3;
+       Gradient::CPoint cp;
+       Gradient::const_iterator iter;
+       Gradient ret;
+       for(iter=p2.begin();iter!=p2.end();iter++)
+       {
+               cp=*iter;
+               c1=p1(cp.pos);
+               c2=cp.color;
+               c3=p3(cp.pos);
+               ret.push_back(Gradient::CPoint(cp.pos, clamped_tangent(c1, c2, 
c3, t1, t2, t3)));
+       }
+       return ret;
+};
+
 /* === G L O B A L S ======================================================= */
 
 /* === C L A S S E S ======================================================= */
@@ -405,76 +519,13 @@ public:
                                        /// ANY/CLAMPED ---- ANY/ANY and iter 
is middle waypoint
                                        if(iter_get_after == 
INTERPOLATION_CLAMPED && iter!=waypoint_list_.begin() && !is_angle())
                                        {
-                                               // 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;
-                                               synfig::info("iter after");
-                                               if(P3 > P1)
-                                               {
-                                                       synfig::info("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)
-                                                       {
-                                                               
synfig::info("P2 >= Pa");
-                                                               
t=(P2-Pa)/(P3-Pa);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                                       else if(Pa >= P2 && P2 
>= Pb)
-                                                       {
-                                                               
synfig::info("Pa >= P2 >= Pb");
-                                                               t=0.0;
-                                                       }
-                                                       else // (Pb > P2)
-                                                       {
-                                                               
synfig::info("P2 < Pb");
-                                                               
t=(Pb-P2)/(Pb-P1);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                               }
-                                               else if(P3 < P1)
-                                               {
-                                                       synfig::info("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)
-                                                       {
-                                                               
synfig::info("P2 >= Pa");
-                                                               
t=(P2-Pa)/(P1-Pa);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                                       else if(Pa >= P2 && P2 
>= Pb)
-                                                       {
-                                                               
synfig::info("Pa >= P2 >= Pb");
-                                                               t=0.0;
-                                                       }
-                                                       else // (Pb > P2)
-                                                       {
-                                                               
synfig::info("P2 < Pb");
-                                                               
t=(Pb-P2)/(Pb-P3);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                               }
-                                               else // P3 == P1
-                                                       t=0.0;
-                                               synfig::info("calculated 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)));
+                                               value_type 
vect(clamped_tangent(Pp, Pc, Pn, T1, T2, T3));
                                                curve.second.t1()=vect;
                                        }
                                        ///
@@ -528,74 +579,13 @@ public:
                                        /// 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;
-                                               synfig::info("next before");
-                                               if(P3 > P1)
-                                               {
-                                                       synfig::info("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)
-                                                       {
-                                                               
synfig::info("P2 >= Pa");
-                                                               
t=(P2-Pa)/(P3-Pa);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                                       else if(Pa >= P2 && P2 
>= Pb)
-                                                       {
-                                                               
synfig::info("Pa >= P2 >= Pb");
-                                                               t=0.0;
-                                                       }
-                                                       else // (Pb > P2)
-                                                       {
-                                                               
synfig::info("P2 < Pb");
-                                                               
t=(Pb-P2)/(Pb-P1);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                               }
-                                               else if(P3 < P1)
-                                               {
-                                                       synfig::info("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)
-                                                       {
-                                                               
synfig::info("P2 >= Pa");
-                                                               
t=(P2-Pa)/(P1-Pa);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                                       else if(Pa >= P2 && P2 
>= Pb)
-                                                       {
-                                                               
synfig::info("Pa >= P2 >= Pb");
-                                                               t=0.0;
-                                                       }
-                                                       else // (Pb > P2)
-                                                       {
-                                                               
synfig::info("P2 < Pb");
-                                                               
t=(Pb-P2)/(Pb-P3);
-                                                               if(t>1.0) t=1.0;
-                                                       }
-                                               }
-                                               else // P3 == P1
-                                                       t=0.0;
-                                               synfig::info("tangent 2 
calculated 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)));
+                                               value_type 
vect(clamped_tangent(Pp, Pc, Pn, T1, T2, T3));
                                                curve.second.t2()=vect;
                                        }
                                        // Adjust for time


------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual 
desktops for less than the cost of PCs and save 60% on VDI infrastructure 
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Synfig-devl mailing list
Synfig-devl@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synfig-devl

Reply via email to