From 1b597586609b1c4df37d5ce9726f2ab27bfd64ea Mon Sep 17 00:00:00 2001 From: dooglus Date: Wed, 26 Dec 2007 14:17:27 +0000 Subject: [PATCH] Revision 1150 changed the way angles work so that 0 degrees and 360 degrees are treated as being one whole rotation, rather than as being the same angle. However, existing .sif files expect animating a tangent from 359 degrees to 0 degrees to be a one degree turn, not 359 degrees. Until r1150, angle animation always went 'the short way'. This change bumps the canvas version number to 0.2. Canvases of version 0.2 or newer use non-wrapped angles. Loading a 0.1 canvas will convert the angles so that existing .sif files will continue to work. http://wiki.synfig.com/Image:Eyes.sif at 3s 16f is an example of a .sif file that was rendering wrongly before this change - the black shadow under the right eye shouldn't be there. git-svn-id: http://svn.voria.com/code@1227 1f10aa63-cdf2-0310-b900-c93c546f37ac --- synfig-core/trunk/src/synfig/canvas.cpp | 1 + synfig-core/trunk/src/synfig/canvas.h | 12 ++++++++ synfig-core/trunk/src/synfig/loadcanvas.cpp | 44 +++++++++++++++++++++++++++++ synfig-core/trunk/src/synfig/savecanvas.cpp | 2 +- 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/synfig-core/trunk/src/synfig/canvas.cpp b/synfig-core/trunk/src/synfig/canvas.cpp index eaa9062..b8e33a0 100644 --- a/synfig-core/trunk/src/synfig/canvas.cpp +++ b/synfig-core/trunk/src/synfig/canvas.cpp @@ -71,6 +71,7 @@ int _CanvasCounter::counter(0); Canvas::Canvas(const String &id): id_ (id), + version_ (CURRENT_CANVAS_VERSION), cur_time_ (0), is_inline_ (false), is_dirty_ (true), diff --git a/synfig-core/trunk/src/synfig/canvas.h b/synfig-core/trunk/src/synfig/canvas.h index af168f9..a62c641 100644 --- a/synfig-core/trunk/src/synfig/canvas.h +++ b/synfig-core/trunk/src/synfig/canvas.h @@ -45,6 +45,8 @@ /* === M A C R O S ========================================================= */ +#define CURRENT_CANVAS_VERSION "0.2" + /* === T Y P E D E F S ===================================================== */ /* === C L A S S E S & S T R U C T S ======================================= */ @@ -90,6 +92,10 @@ private: /*! \see set_description(), get_description() */ String description_; + //! Contains the canvas' version string + /*! \see set_version(), get_version() */ + String version_; + //! Contains the author's name /*! \see set_author(), get_author() */ String author_; @@ -290,6 +296,12 @@ public: //! Sets the name of the canvas void set_name(const String &x); + //! Gets the version string of the canvas + const String get_version()const { return version_; } + + //! Sets the version string of the canvas + void set_version(const String &x) { version_ = x; } + //! Gets the author of the canvas const String & get_author()const { return author_; } diff --git a/synfig-core/trunk/src/synfig/loadcanvas.cpp b/synfig-core/trunk/src/synfig/loadcanvas.cpp index 41406c4..c0e3f6f 100644 --- a/synfig-core/trunk/src/synfig/loadcanvas.cpp +++ b/synfig-core/trunk/src/synfig/loadcanvas.cpp @@ -1051,6 +1051,46 @@ CanvasParser::parse_animated(xmlpp::Element *element,Canvas::Handle canvas) else error_unexpected_element(child,child->get_name()); } + + // in canvas version 0.1, angles used to wrap, so to get from -179 + // degrees to 180 degrees meant a 1 degree change + // in canvas version 0.2 they don't, so that's a 359 degree change + + // when loading a version 0.1 canvas, modify constant angle + // waypoints to that they are within 180 degrees of the previous + // waypoint's value + if (type == ValueBase::TYPE_ANGLE) + { + Canvas::Handle parent = canvas; + while (!parent->is_root()) + parent = parent->parent(); + + if (parent->get_version() == "0.1") + { + bool first = true; + Real angle, prev; + WaypointList &wl = value_node->waypoint_list(); + for (WaypointList::iterator iter = wl.begin(); iter != wl.end(); iter++) + { + angle = Angle::deg(iter->get_value(iter->get_time()).get(Angle())).get(); + if (first) + first = false; + else if (iter->get_value_node()->get_name() == "constant") + if (angle - prev > 180) + { + while (angle - prev > 180) angle -= 360; + iter->set_value(Angle::deg(angle)); + } + else if (prev - angle > 180) + { + while (prev - angle > 180) angle += 360; + iter->set_value(Angle::deg(angle)); + } + prev = angle; + } + } + } + value_node->changed(); return value_node; } @@ -1855,6 +1895,9 @@ CanvasParser::parse_canvas(xmlpp::Element *element,Canvas::Handle parent,bool in canvas->set_guid(guid); } + if(element->get_attribute("version")) + canvas->set_version(element->get_attribute("version")->get_value()); + if(element->get_attribute("width")) canvas->rend_desc().set_w(atoi(element->get_attribute("width")->get_value().c_str())); @@ -2057,6 +2100,7 @@ CanvasParser::parse_canvas(xmlpp::Element *element,Canvas::Handle parent,bool in nodes.c_str())); } + canvas->set_version(CURRENT_CANVAS_VERSION); return canvas; } diff --git a/synfig-core/trunk/src/synfig/savecanvas.cpp b/synfig-core/trunk/src/synfig/savecanvas.cpp index 58d40ed..0b4468d 100644 --- a/synfig-core/trunk/src/synfig/savecanvas.cpp +++ b/synfig-core/trunk/src/synfig/savecanvas.cpp @@ -636,7 +636,7 @@ xmlpp::Element* encode_canvas(xmlpp::Element* root,Canvas::ConstHandle canvas) root->set_name("canvas"); if(canvas->is_root()) - root->set_attribute("version","0.1"); + root->set_attribute("version",canvas->get_version()); if(!canvas->get_id().empty() && !canvas->is_root() && !canvas->is_inline()) root->set_attribute("id",canvas->get_id()); -- 2.7.4