From: dooglus Date: Sun, 30 Mar 2008 01:17:52 +0000 (+0000) Subject: When dragging a duck along a bline that it's linked to, update the tangents as well... X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=071939c9c44d0080e0843381adc19a6600f0fd69;p=synfig.git When dragging a duck along a bline that it's linked to, update the tangents as well, if they are also linked to the tangent of the bline. git-svn-id: http://svn.voria.com/code@1938 1f10aa63-cdf2-0310-b900-c93c546f37ac --- diff --git a/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.cpp b/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.cpp index 8fa0212..67c1775 100644 --- a/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.cpp +++ b/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.cpp @@ -88,14 +88,13 @@ ValueNode_BLineCalcTangent::~ValueNode_BLineCalcTangent() } ValueBase -ValueNode_BLineCalcTangent::operator()(Time t)const +ValueNode_BLineCalcTangent::operator()(Time t, Real amount)const { const std::vector bline((*bline_)(t)); handle bline_value_node(bline_); const bool looped(bline_value_node->get_loop()); int size = bline.size(), from_vertex; bool loop((*loop_)(t).get(bool())); - Real amount((*amount_)(t).get(Real())); Angle offset((*offset_)(t).get(Angle())); Real scale((*scale_)(t).get(Real())); bool fixed_length((*fixed_length_)(t).get(bool())); @@ -154,6 +153,13 @@ ValueNode_BLineCalcTangent::operator()(Time t)const } } +ValueBase +ValueNode_BLineCalcTangent::operator()(Time t)const +{ + Real amount((*amount_)(t).get(Real())); + return (*this)(t, amount); +} + String ValueNode_BLineCalcTangent::get_name()const { diff --git a/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.h b/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.h index ffe3747..a1e1806 100644 --- a/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.h +++ b/synfig-core/trunk/src/synfig/valuenode_blinecalctangent.h @@ -51,6 +51,7 @@ public: typedef etl::handle Handle; typedef etl::handle ConstHandle; + virtual ValueBase operator()(Time t, Real amount)const; virtual ValueBase operator()(Time t)const; virtual ~ValueNode_BLineCalcTangent(); diff --git a/synfig-studio/trunk/src/gtkmm/canvasview.cpp b/synfig-studio/trunk/src/gtkmm/canvasview.cpp index 1356afa..2c48158 100644 --- a/synfig-studio/trunk/src/gtkmm/canvasview.cpp +++ b/synfig-studio/trunk/src/gtkmm/canvasview.cpp @@ -2597,10 +2597,27 @@ CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDes case ValueBase::TYPE_VECTOR: if (ValueNode_BLineCalcTangent::Handle bline_tangent = ValueNode_BLineCalcTangent::Handle::cast_dynamic(value_desc.get_value_node())) { - Angle old_angle = (*bline_tangent)(get_time()).get(Vector()).angle(); + Vector old_tangent = (*bline_tangent)(get_time()).get(Vector()); + Angle old_angle = old_tangent.angle(); + Real old_length = old_tangent.mag(); Angle new_angle = value.angle(); - int offset_index = bline_tangent->get_link_index_from_name("offset"); + Real new_length = value.mag(); + int offset_index(bline_tangent->get_link_index_from_name("offset")); + int scale_index(bline_tangent->get_link_index_from_name("scale")); + int fixed_length_index(bline_tangent->get_link_index_from_name("fixed_length")); Angle old_offset((*(bline_tangent->get_link(offset_index)))(get_time()).get(Angle())); + Real scale((*(bline_tangent->get_link(scale_index)))(get_time()).get(Real())); + bool fixed_length((*(bline_tangent->get_link(fixed_length_index)))(get_time()).get(bool())); + if (fixed_length) + { + if (!(canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,scale_index), + new_length))) + return false; + } + else if (old_length != 0 && + !(canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,scale_index), + new_length * scale / old_length))) + return false; return canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,offset_index), old_offset + new_angle - old_angle); } diff --git a/synfig-studio/trunk/src/gtkmm/duckmatic.cpp b/synfig-studio/trunk/src/gtkmm/duckmatic.cpp index 5b46dda..0be4a9e 100644 --- a/synfig-studio/trunk/src/gtkmm/duckmatic.cpp +++ b/synfig-studio/trunk/src/gtkmm/duckmatic.cpp @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include @@ -505,17 +507,90 @@ DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector synfig::Vector vect(duckmatic->snap_point_to_grid(vector)-drag_offset_); int i; + Time time(duckmatic->get_time()); // drag the vertex and position ducks first - for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++) - if((*iter)->get_type() == Duck::TYPE_VERTEX || (*iter)->get_type() == Duck::TYPE_POSITION) - (*iter)->set_trans_point(positions[i]+vect); + for (i=0,iter=selected_ducks.begin(); iter!=selected_ducks.end(); ++iter,i++) + { + etl::handle duck(*iter); + if(duck->get_type() == Duck::TYPE_VERTEX || duck->get_type() == Duck::TYPE_POSITION) + { + duck->set_trans_point(positions[i]+vect); + + if (ValueNode_BLineCalcVertex::Handle bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node())) + { + synfig::Point closest_point = duck->get_point(); + synfig::Real radius = 0.0; + ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline"))); + synfig::find_closest_point( + (*bline)(time), + duck->get_point(), + radius, + bline->get_loop(), + &closest_point); + duck->set_point(closest_point); + } + } + } // then drag the others - for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++) - if((*iter)->get_type() != Duck::TYPE_VERTEX && (*iter)->get_type() != Duck::TYPE_POSITION) + for (i=0,iter=selected_ducks.begin(); iter!=selected_ducks.end(); ++iter,i++) + if ((*iter)->get_type() != Duck::TYPE_VERTEX && (*iter)->get_type() != Duck::TYPE_POSITION) (*iter)->set_trans_point(positions[i]+vect); + // then patch up the tangents for the vertices we've moved + DuckList duck_list(duckmatic->get_duck_list()); + for (iter=selected_ducks.begin(); iter!=selected_ducks.end(); ++iter) + { + etl::handle duck(*iter); + if ((duck->get_type() == Duck::TYPE_VERTEX || duck->get_type() == Duck::TYPE_POSITION) && + duck->get_value_desc().parent_is_value_node()) + { + ValueNode_BLineCalcVertex::Handle bline_vertex(ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node())); + if (bline_vertex) + { + ValueNode_Composite::Handle value_node_composite(ValueNode_Composite::Handle::cast_dynamic(duck->get_value_desc().get_parent_value_node())); + if (value_node_composite && + value_node_composite->get_type() == ValueBase::TYPE_BLINEPOINT) + { + int t1_index(value_node_composite->get_link_index_from_name("t1")); + int t2_index(value_node_composite->get_link_index_from_name("t2")); + ValueNode::Handle t1_value_node(value_node_composite->get_link(t1_index)); + ValueNode::Handle t2_value_node(value_node_composite->get_link(t2_index)); + ValueNode_BLineCalcTangent::Handle bline_tangent_1(ValueNode_BLineCalcTangent::Handle::cast_dynamic(t1_value_node)); + ValueNode_BLineCalcTangent::Handle bline_tangent_2(ValueNode_BLineCalcTangent::Handle::cast_dynamic(t2_value_node)); + + if (bline_tangent_1 || bline_tangent_2) + { + synfig::Real radius = 0.0; + ValueNode_BLine::Handle bline(ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline")))); + Real amount = synfig::find_closest_point((*bline)(time), duck->get_point(), radius, bline->get_loop()); + + // we need to update the position of the tangent ducks - but how do we find these ducks? + // this is a brute force search - but is there a better way to do it? + if (bline_tangent_1) + { + Vector tangent = (*bline_tangent_1)(time, amount).get(Vector()); + DuckList::iterator iter; + for (iter=duck_list.begin(); iter!=duck_list.end(); iter++) + if ((*iter)->get_value_desc().get_value_node() == t1_value_node) + (*iter)->set_point(tangent); + } + + if (bline_tangent_2) + { + Vector tangent = (*bline_tangent_2)(time, amount).get(Vector()); + DuckList::iterator iter; + for (iter=duck_list.begin(); iter!=duck_list.end(); iter++) + if ((*iter)->get_value_desc().get_value_node() == t2_value_node) + (*iter)->set_point(tangent); + } + } + } + } + } + } + last_translate_=vect; } diff --git a/synfig-studio/trunk/src/gtkmm/renderer_ducks.cpp b/synfig-studio/trunk/src/gtkmm/renderer_ducks.cpp index c842811..cba2fb9 100644 --- a/synfig-studio/trunk/src/gtkmm/renderer_ducks.cpp +++ b/synfig-studio/trunk/src/gtkmm/renderer_ducks.cpp @@ -37,8 +37,6 @@ #include #include "widget_color.h" #include -#include -#include #include "app.h" #include "general.h" @@ -60,46 +58,6 @@ using namespace studio; /* === M E T H O D S ======================================================= */ -bool -restrict_blinevertex_duck(etl::handle duck, WorkArea& w_area, synfig::Point *point) -{ - synfig::Point sub_trans_origin(duck->get_sub_trans_origin()); - etl::handle origin_duck = duck->get_origin_duck(); - bool origin_changed = false; - if(origin_duck) - origin_changed = restrict_blinevertex_duck(origin_duck, w_area, &sub_trans_origin); - - if( ValueNode_BLineCalcVertex::Handle bline_vertex = - ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node()) - ) - { - synfig::Point closest_point = duck->get_point(); - synfig::Real radius = 0.0; - ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline"))); - synfig::find_closest_point( - (*bline)(w_area.get_time()), - duck->get_point(), - radius, - bline->get_loop(), - &closest_point - ); - - if(closest_point != duck->get_point()) - { - *point = closest_point * duck->get_scalar() + sub_trans_origin; - return true; - } - } - - if(origin_changed) - { - *point = duck->get_point() * duck->get_scalar() + sub_trans_origin; - return true; - } - - return false; -} - Renderer_Ducks::~Renderer_Ducks() { } @@ -182,22 +140,11 @@ Renderer_Ducks::render_vfunc( // Render the beziers for(std::list >::const_iterator iter=bezier_list.begin();iter!=bezier_list.end();++iter) { - Point sub_trans_p1((*iter)->p1->get_sub_trans_point()); - Point sub_trans_p2((*iter)->p2->get_sub_trans_point()); - Point sub_trans_c1((*iter)->c1->get_sub_trans_point()); - Point sub_trans_c2((*iter)->c2->get_sub_trans_point()); - - WorkArea* w_area = get_work_area(); - restrict_blinevertex_duck((*iter)->p1, *w_area, &sub_trans_p1); - restrict_blinevertex_duck((*iter)->p2, *w_area, &sub_trans_p2); - restrict_blinevertex_duck((*iter)->c1, *w_area, &sub_trans_c1); - restrict_blinevertex_duck((*iter)->c2, *w_area, &sub_trans_c2); - Point window_start(window_startx,window_starty); - Point p1((*iter)->p1->get_transform_stack().perform(sub_trans_p1)-window_start); - Point p2((*iter)->p2->get_transform_stack().perform(sub_trans_p2)-window_start); - Point c1((*iter)->c1->get_transform_stack().perform(sub_trans_c1)-window_start); - Point c2((*iter)->c2->get_transform_stack().perform(sub_trans_c2)-window_start); + Point p1((*iter)->p1->get_trans_point()-window_start); + Point p2((*iter)->p2->get_trans_point()-window_start); + Point c1((*iter)->c1->get_trans_point()-window_start); + Point c2((*iter)->c2->get_trans_point()-window_start); p1[0]/=pw;p1[1]/=ph; p2[0]/=pw;p2[1]/=ph; c1[0]/=pw;c1[1]/=ph; @@ -264,20 +211,6 @@ Renderer_Ducks::render_vfunc( // Gdk::Rectangle area; Point sub_trans_point((*iter)->get_sub_trans_point()); Point sub_trans_origin((*iter)->get_sub_trans_origin()); - etl::handle origin_duck = (*iter)->get_origin_duck(); - - bool has_connect(false); - if((*iter)->get_tangent() || (*iter)->get_type()&Duck::TYPE_ANGLE) - { - has_connect=true; - } - if((*iter)->get_connect_duck()) - { - has_connect=true; - sub_trans_origin = (*iter)->get_connect_duck()->get_sub_trans_point(); - origin_duck = (*iter)->get_connect_duck(); - } - if (App::restrict_radius_ducks && (*iter)->is_radius()) @@ -288,17 +221,23 @@ Renderer_Ducks::render_vfunc( sub_trans_point[1] = sub_trans_origin[1]; } - WorkArea* w_area = get_work_area(); - restrict_blinevertex_duck((*iter), *w_area, &sub_trans_point); - if(origin_duck) - restrict_blinevertex_duck(origin_duck, *w_area, &sub_trans_origin); - Point point((*iter)->get_transform_stack().perform(sub_trans_point)); Point origin((*iter)->get_transform_stack().perform(sub_trans_origin)); point[0]=(point[0]-window_startx)/pw; point[1]=(point[1]-window_starty)/ph; + bool has_connect(false); + if((*iter)->get_tangent() || (*iter)->get_type()&Duck::TYPE_ANGLE) + { + has_connect=true; + } + if((*iter)->get_connect_duck()) + { + has_connect=true; + origin=(*iter)->get_connect_duck()->get_trans_point(); + } + origin[0]=(origin[0]-window_startx)/pw; origin[1]=(origin[1]-window_starty)/ph;