X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fvaluenode_animated.cpp;h=c2d70a1425b4808d052b0818a7f23c0aae9d8648;hb=756c0d29ac1742f231e6615f9a577e574e35a4af;hp=b68149a0e615e02789a33942dfea47c67f019e58;hpb=28f28705612902c15cd0702cc891fba35bf2d2df;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/valuenode_animated.cpp b/synfig-core/trunk/src/synfig/valuenode_animated.cpp index b68149a..c2d70a1 100644 --- a/synfig-core/trunk/src/synfig/valuenode_animated.cpp +++ b/synfig-core/trunk/src/synfig/valuenode_animated.cpp @@ -1,20 +1,22 @@ /* === S Y N F I G ========================================================= */ /*! \file valuenode_animated.cpp -** \brief Template File +** \brief Implementation of the "Animated" valuenode conversion. ** -** $Id: valuenode_animated.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $ +** $Id$ ** ** \legal -** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007, 2008 Chris Moore ** -** This software and associated documentation -** are CONFIDENTIAL and PROPRIETARY property of -** the above-mentioned copyright holder. +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. ** -** You may not copy, print, publish, or in any -** other way distribute this software without -** a prior written agreement with -** the copyright holder. +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. ** \endlegal */ /* ========================================================================= */ @@ -66,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 struct is_angle_type { @@ -167,6 +170,7 @@ struct is_angle_type return true; } }; +#endif // ANGLES_USE_LINEAR_INTERPOLATION /* === G L O B A L S ======================================================= */ @@ -186,21 +190,21 @@ private: { is_angle_type 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) @@ -210,7 +214,7 @@ private: // that we support is linear. second.t1()= second.t2()=subtract_func(second.p2(),second.p1()); - + second.sync(); } @@ -228,10 +232,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 { @@ -253,23 +257,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; } @@ -279,10 +283,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; @@ -294,14 +298,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()); @@ -309,12 +313,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; @@ -323,16 +327,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) @@ -344,7 +348,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()); @@ -373,34 +377,36 @@ public: } else { + const Real& t(iter->get_tension()); // Tension + const Real& c(iter->get_continuity()); // Continuity + const Real& b(iter->get_bias()); // Bias - 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); + // The following line works where the previous line fails. + value_type Pp; Pp=curve_list.back().second.p1(); // P_{i-1} - // 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; + 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; } } else if( @@ -416,7 +422,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 @@ -425,13 +431,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); @@ -453,18 +460,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() = static_cast(curve.second.t1() * // cast to prevent warning + // (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() = static_cast(curve.second.t2() * // cast to prevent warning + // (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 @@ -481,7 +501,7 @@ public: curve_list.push_back(curve); } } - + virtual ValueBase operator()(Time t)const { if(waypoint_list_.empty()) @@ -492,7 +512,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 @@ -502,8 +522,8 @@ public: if(iter==curve_list.end()) return waypoint_list_.back().get_value(t); return iter->resolve(t); - } -}; + } +}; template @@ -539,10 +559,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; @@ -560,7 +580,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; @@ -572,7 +592,7 @@ public: virtual void on_changed() { ValueNode_Animated::on_changed(); - + if(waypoint_list_.size()<=1) return; std::sort(waypoint_list_.begin(),waypoint_list_.end()); @@ -638,10 +658,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; @@ -659,7 +679,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; @@ -671,7 +691,7 @@ public: virtual void on_changed() { ValueNode_Animated::on_changed(); - + if(waypoint_list_.size()<=1) return; std::sort(waypoint_list_.begin(),waypoint_list_.end()); @@ -703,7 +723,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); @@ -722,7 +742,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 @@ -804,7 +824,7 @@ ValueNode_Animated::new_waypoint_at_time(const Time& time)const waypoint.make_unique(); } catch(...) - { + { if(waypoint_list().empty()) { waypoint.set_value((*this)(time)); @@ -815,10 +835,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; @@ -830,7 +850,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)); @@ -838,14 +858,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) @@ -857,7 +877,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; } @@ -922,7 +942,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())); } @@ -941,7 +961,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())); */ } @@ -958,7 +978,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())); } @@ -1022,11 +1042,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: @@ -1034,7 +1054,7 @@ synfig::ValueNode_Animated::create(ValueBase::Type type) default: throw Exception::BadType(strprintf(_("%s: You cannot use a %s in an animated ValueNode"),"synfig::ValueNode_Animated::create()", - ValueBase::type_name(type).c_str()) + ValueBase::type_local_name(type).c_str()) ); break; } @@ -1074,7 +1094,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(); @@ -1091,68 +1111,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; }