X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fvaluenode_animated.cpp;h=d354f979500479ed04749eb2e6efe63b8bcc6f0e;hb=37600b4b217caa5e316984ec0b035c5e8f9698af;hp=e965418feda7b274166dd59c42a0c34bc3bfb042;hpb=e8a065f2385c219c511b57dac52786120bfa097d;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/valuenode_animated.cpp b/synfig-core/trunk/src/synfig/valuenode_animated.cpp index e965418..d354f97 100644 --- a/synfig-core/trunk/src/synfig/valuenode_animated.cpp +++ b/synfig-core/trunk/src/synfig/valuenode_animated.cpp @@ -2,10 +2,11 @@ /*! \file valuenode_animated.cpp ** \brief Template File ** -** $Id: valuenode_animated.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $ +** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007 Chris Moore ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as @@ -67,11 +68,11 @@ template inline I binary_find(I begin, I end, const T& value) { I iter(begin+(end-begin)/2); - + while(end-begin>1 && !(*iter==value)) { ((*iter is_angle; subtractor subtract_func; - + mutable hermite first; mutable hermite second; WaypointList::iterator start; WaypointList::iterator end; - + value_type resolve(const Time &t)const { bool start_static(start->is_static()); bool end_static(end->is_static()); - + if(!start_static || !end_static) { //if(!start_static) - second.p1()=start->get_value(t).get(value_type()); + second.p1()=start->get_value(t).get(value_type()); if(start->get_after()==INTERPOLATION_CONSTANT || end->get_before()==INTERPOLATION_CONSTANT) return second.p1(); //if(!end_static) @@ -211,7 +212,7 @@ private: // that we support is linear. second.t1()= second.t2()=subtract_func(second.p2(),second.p1()); - + second.sync(); } @@ -229,10 +230,10 @@ private: > curve_list_type; curve_list_type curve_list; - + // Bounds of this curve Time r,s; - + public: ValueNode* clone(const GUID& deriv_guid)const { @@ -254,23 +255,23 @@ public: // Make sure we are getting data of the correct type //if(data.type!=type) // return waypoint_list_type::iterator(); - + try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { }; Waypoint waypoint(value,t); waypoint.set_parent_value_node(this); - + waypoint_list_.push_back(waypoint); WaypointList::iterator ret=waypoint_list_.end(); --ret; - + if(is_angle()) { ret->set_before(INTERPOLATION_LINEAR); ret->set_after(INTERPOLATION_LINEAR); } - + changed(); - + return ret; } @@ -280,10 +281,10 @@ public: //if(data.type!=type) // return waypoint_list_type::iterator(); try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { }; - + Waypoint waypoint(value_node,t); waypoint.set_parent_value_node(this); - + waypoint_list_.push_back(waypoint); WaypointList::iterator ret=waypoint_list_.end(); --ret; @@ -295,14 +296,14 @@ public: } changed(); - + return ret; } - + virtual void on_changed() { ValueNode_Animated::on_changed(); - + if(waypoint_list_.size()<=1) return; std::sort(waypoint_list_.begin(),waypoint_list_.end()); @@ -310,12 +311,12 @@ public: r=waypoint_list_.front().get_time(); s=waypoint_list_.back().get_time(); - + curve_list.clear(); - + WaypointList::iterator prev,iter,next=waypoint_list_.begin(); int i=0; - + for(iter=next++;iter!=waypoint_list_.end() && next!=waypoint_list_.end();prev=iter,iter=next++,i++) { typename curve_list_type::value_type curve; @@ -324,16 +325,16 @@ public: curve.start=iter; curve.end=next; - + // Set up the positions curve.first.set_rs(iter->get_time(), next->get_time()); curve.second.set_rs(iter->get_time(), next->get_time()); - + Waypoint::Interpolation iter_get_after(iter->get_after()); Waypoint::Interpolation next_get_after(next->get_after()); Waypoint::Interpolation iter_get_before(iter->get_before()); Waypoint::Interpolation next_get_before(next->get_before()); - + if(is_angle()) { if(iter_get_after==INTERPOLATION_TCB) @@ -345,7 +346,7 @@ public: if(next_get_before==INTERPOLATION_TCB) next_get_before=INTERPOLATION_LINEAR; } - + if(iter->is_static() && next->is_static()) { curve.second.p1()=iter->get_value().get(T()); @@ -378,29 +379,29 @@ public: const Real& t(iter->get_tension()); // Tension const Real& c(iter->get_continuity()); // Continuity const Real& b(iter->get_bias()); // Bias - + // The folloing line works where the previous line fails. 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} - + // TCB value_type vect(static_cast(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))); - + // Tension Only //value_type vect=(value_type)((Pn-Pp)*(1.0-t)); - + // Linear //value_type vect=(value_type)(Pn-Pc); // Debugging stuff //synfig::info("%d:t1: %s",i,tangent_info(Pp,Pn,vect).c_str()); - + // Adjust for time //vect=value_type(vect*(curve.second.get_dt()*2.0)/(curve.second.get_dt()+curve_list.back().second.get_dt())); //vect=value_type(vect*(curve.second.get_dt())/(curve_list.back().second.get_dt())); - + curve.second.t1()=vect; } } @@ -417,7 +418,7 @@ public: curve_list.back().second.sync(); } - + if(next_get_before==INTERPOLATION_TCB && after_next!=waypoint_list_.end() && !is_angle()) { const Real &t(next->get_tension()); // Tension @@ -426,13 +427,14 @@ public: 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 - value_type vect(static_cast(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(static_cast(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))); // Tension Only //value_type vect((value_type)((Pn-Pp)*(1.0-t))); - + // Linear //value_type vect=(value_type)(Pc-Pp); @@ -454,18 +456,31 @@ public: // Adjust for time const float timeadjust(0.5); - - if(!curve_list.empty()) - curve.second.t1()*=(curve.second.get_dt()*(timeadjust+1))/(curve.second.get_dt()*timeadjust+curve_list.back().second.get_dt()); - if(after_next!=waypoint_list_.end()) - curve.second.t2()*=(curve.second.get_dt()*(timeadjust+1))/(curve.second.get_dt()*timeadjust+(after_next->get_time()-next->get_time())); if(iter_get_after==INTERPOLATION_HALT) curve.second.t1()*=0; - + // if this isn't the first curve + else if(iter_get_after != INTERPOLATION_LINEAR && !curve_list.empty()) + // adjust it for the curve that came before it + curve.second.t1() *= + // (time span of this curve) * 1.5 + // ----------------------------------------------------------------- + // ((time span of this curve) * 0.5) + (time span of previous curve) + (curve.second.get_dt()*(timeadjust+1)) / + (curve.second.get_dt()*timeadjust + curve_list.back().second.get_dt()); + if(next_get_before==INTERPOLATION_HALT) - curve.second.t2()*=0; - } + curve.second.t2()*=0; + // if this isn't the last curve + else if(next_get_before != INTERPOLATION_LINEAR && after_next!=waypoint_list_.end()) + // adjust it for the curve that came after it + curve.second.t2() *= + // (time span of this curve) * 1.5 + // ------------------------------------------------------------- + // ((time span of this curve) * 0.5) + (time span of next curve) + (curve.second.get_dt()*(timeadjust+1)) / + (curve.second.get_dt()*timeadjust+(after_next->get_time()-next->get_time())); + } // not CONSTANT } // Set up the time to the default stuff @@ -482,7 +497,7 @@ public: curve_list.push_back(curve); } } - + virtual ValueBase operator()(Time t)const { if(waypoint_list_.empty()) @@ -493,7 +508,7 @@ public: return waypoint_list_.front().get_value(t); if(t>=s) return waypoint_list_.back().get_value(t); - + typename curve_list_type::const_iterator iter; // This next line will set iter to the @@ -503,8 +518,8 @@ public: if(iter==curve_list.end()) return waypoint_list_.back().get_value(t); return iter->resolve(t); - } -}; + } +}; template @@ -540,10 +555,10 @@ public: //if(data.type!=type) // return waypoint_list_type::iterator(); try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { }; - + Waypoint waypoint(value,t); waypoint.set_parent_value_node(this); - + waypoint_list_.push_back(waypoint); WaypointList::iterator ret=waypoint_list_.end(); --ret; @@ -561,7 +576,7 @@ public: Waypoint waypoint(value_node,t); waypoint.set_parent_value_node(this); - + waypoint_list_.push_back(waypoint); WaypointList::iterator ret=waypoint_list_.end(); --ret; @@ -573,7 +588,7 @@ public: virtual void on_changed() { ValueNode_Animated::on_changed(); - + if(waypoint_list_.size()<=1) return; std::sort(waypoint_list_.begin(),waypoint_list_.end()); @@ -639,10 +654,10 @@ public: // return waypoint_list_type::iterator(); try { find(t); throw Exception::BadTime(_("A waypoint already exists at this point in time")); } catch(Exception::NotFound) { }; - + Waypoint waypoint(value,t); waypoint.set_parent_value_node(this); - + waypoint_list_.push_back(waypoint); WaypointList::iterator ret=waypoint_list_.end(); --ret; @@ -660,7 +675,7 @@ public: Waypoint waypoint(value_node,t); waypoint.set_parent_value_node(this); - + waypoint_list_.push_back(waypoint); WaypointList::iterator ret=waypoint_list_.end(); --ret; @@ -672,7 +687,7 @@ public: virtual void on_changed() { ValueNode_Animated::on_changed(); - + if(waypoint_list_.size()<=1) return; std::sort(waypoint_list_.begin(),waypoint_list_.end()); @@ -704,7 +719,7 @@ public: if(iter->get_time()==t) return iter->get_value(t); - + if(next!=waypoint_list_.end()) return iter->get_value(t).get(bool()) || next->get_value(t).get(bool()); return iter->get_value(t); @@ -723,7 +738,7 @@ ValueNode_Animated::find(const Time& begin,const Time& end,std::vectorset_time(old_2_new(selected.back()->get_time())); selected.pop_back(); } - - + + while(!selected.empty()) { selected.back()->set_time(old_2_new(selected.back()->get_time())); selected.pop_back(); } - + changed(); } #undef old_2_new @@ -805,7 +820,7 @@ ValueNode_Animated::new_waypoint_at_time(const Time& time)const waypoint.make_unique(); } catch(...) - { + { if(waypoint_list().empty()) { waypoint.set_value((*this)(time)); @@ -816,10 +831,10 @@ ValueNode_Animated::new_waypoint_at_time(const Time& time)const WaypointList::const_iterator next; bool has_prev(false), has_next(false); - + try { prev=find_prev(time); has_prev=true; } catch(...) { } try { next=find_next(time); has_next=true; } catch(...) { } - + /* WaypointList::const_iterator closest; @@ -831,7 +846,7 @@ ValueNode_Animated::new_waypoint_at_time(const Time& time)const closest=prev; else closest=next; - + for(iter=waypoint_list().begin();iter!=waypoint_list().end();++iter) { const Real dist(abs(iter->get_time()-time)); @@ -839,14 +854,14 @@ ValueNode_Animated::new_waypoint_at_time(const Time& time)const closest=iter; } */ - + if(has_prev && !prev->is_static()) waypoint.set_value_node(prev->get_value_node()); if(has_next && !next->is_static()) waypoint.set_value_node(next->get_value_node()); else waypoint.set_value((*this)(time)); - + /*if(has_prev) waypoint.set_after(prev->get_before()); if(has_next) @@ -858,7 +873,7 @@ ValueNode_Animated::new_waypoint_at_time(const Time& time)const waypoint.set_parent_value_node(const_cast(this)); // synfig::info("waypoint.get_after()=set to %d",waypoint.get_after()); // synfig::info("waypoint.get_before()=set to %d",waypoint.get_before()); - + return waypoint; } @@ -923,7 +938,7 @@ ValueNode_Animated::find_next(const Time &x) if(iter!=waypoint_list().end() && iter->get_time().is_more_than(x)) return iter; } - + throw Exception::NotFound(strprintf("ValueNode_Animated::find_next(): Can't find Waypoint after %s",x.get_string().c_str())); } @@ -942,7 +957,7 @@ ValueNode_Animated::find_next(const Time &x)const if(iter!=waypoint_list().end() && iter->get_time()-Time::epsilon()>x) return iter; } - + throw Exception::NotFound(strprintf("ValueNode_Animated::find_next(): Can't find Waypoint after %s",x.get_string().c_str())); */ } @@ -959,7 +974,7 @@ ValueNode_Animated::find_prev(const Time &x) if(iter!=waypoint_list().begin() && (--iter)->get_time().is_less_than(x)) return iter; } - + throw Exception::NotFound(strprintf("ValueNode_Animated::find_prev(): Can't find Waypoint after %s",x.get_string().c_str())); } @@ -1023,11 +1038,11 @@ synfig::ValueNode_Animated::create(ValueBase::Type type) return ValueNode_Animated::Handle(new _Hermite); case ValueBase::TYPE_COLOR: return ValueNode_Animated::Handle(new _Hermite); - + case ValueBase::TYPE_STRING: return ValueNode_Animated::Handle(new _Constant); case ValueBase::TYPE_GRADIENT: - return ValueNode_Animated::Handle(new _Constant); + return ValueNode_Animated::Handle(new _Hermite); case ValueBase::TYPE_BOOL: return ValueNode_Animated::Handle(new _AnimBool); case ValueBase::TYPE_CANVAS: @@ -1075,7 +1090,7 @@ ValueNode_Animated::get_local_name()const void ValueNode_Animated::get_times_vfunc(Node::time_set &set) const { //add all the way point times to the value node... - + WaypointList::const_iterator i = waypoint_list().begin(), end = waypoint_list().end(); @@ -1092,68 +1107,68 @@ void ValueNode_Animated::get_times_vfunc(Node::time_set &set) const struct timecmp { Time t; - + timecmp(const Time &c) :t(c) {} - + bool operator()(const Waypoint &rhs) const { return t.is_equal(rhs.get_time()); } }; - + ValueNode_Animated::findresult ValueNode_Animated::find_uid(const UniqueID &x) { findresult f; f.second = false; - + //search for it... and set the bool part of the return value to true if we found it! f.first = std::find(waypoint_list_.begin(), waypoint_list_.end(), x); if(f.first != waypoint_list_.end()) f.second = true; - + return f; } - + ValueNode_Animated::const_findresult ValueNode_Animated::find_uid(const UniqueID &x)const { const_findresult f; f.second = false; - + //search for it... and set the bool part of the return value to true if we found it! f.first = std::find(waypoint_list_.begin(), waypoint_list_.end(), x); if(f.first != waypoint_list_.end()) f.second = true; - + return f; } - - ValueNode_Animated::findresult + + ValueNode_Animated::findresult ValueNode_Animated::find_time(const Time &x) { findresult f; f.second = false; - + //search for it... and set the bool part of the return value to true if we found it! f.first = std::find_if(waypoint_list_.begin(), waypoint_list_.end(), timecmp(x)); if(f.first != waypoint_list_.end()) f.second = true; - + return f; } - + ValueNode_Animated::const_findresult ValueNode_Animated::find_time(const Time &x)const { const_findresult f; f.second = false; - + //search for it... and set the bool part of the return value to true if we found it! f.first = std::find_if(waypoint_list_.begin(), waypoint_list_.end(), timecmp(x)); if(f.first != waypoint_list_.end()) f.second = true; - + return f; }