X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ffloatauto.C;h=8e3e63682af1a56e43d3d474bb3f8076d9909041;hp=c63a3754c84cfdc7186143177781ebfcfed7f47a;hb=HEAD;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd diff --git a/cinelerra-5.1/cinelerra/floatauto.C b/cinelerra-5.1/cinelerra/floatauto.C index c63a3754..8e3e6368 100644 --- a/cinelerra-5.1/cinelerra/floatauto.C +++ b/cinelerra-5.1/cinelerra/floatauto.C @@ -2,21 +2,21 @@ /* * CINELERRA * Copyright (C) 2008 Adam Williams - * + * * This program 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. - * + * * This program 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. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * */ #include "autos.h" @@ -40,13 +40,13 @@ FloatAuto::FloatAuto(EDL *edl, FloatAutos *autos) control_out_position = 0; pos_valid = -1; //"dirty" curve_mode = FREE; -// note: in most cases the curve_mode value is set +// note: in most cases the curve_mode value is set // by the method interpolate_from() rsp. copy_from() } FloatAuto::~FloatAuto() { - // as we are going away, the neighbouring float auto nodes + // as we are going away, the neighbouring float auto nodes // need to re-adjust their ctrl point positions and curves if (next) ((FloatAuto*)next)->curve_dirty(); @@ -74,9 +74,21 @@ int FloatAuto::identical(FloatAuto *src) // curve_mode is ignored, no recalculations } -/* Note: the following is essentially display-code and has been moved to: +// exactly equals +int FloatAuto::equals(FloatAuto *that) +{ + return this->value == that->value && + this->control_in_value == that->control_in_value && + this->control_out_value == that->control_out_value && + this->control_in_position == that->control_in_position && + this->control_out_position == that->control_out_position && + this->curve_mode == that->curve_mode; +} + + +/* Note: the following is essentially display-code and has been moved to: * TrackCanvas::value_to_percentage(float auto_value, int autogrouptype) - * + * float FloatAuto::value_to_percentage() { } @@ -103,7 +115,7 @@ void FloatAuto::copy_from(FloatAuto *that) this->control_in_position = that->control_in_position; this->control_out_position = that->control_out_position; this->curve_mode = that->curve_mode; -// note: literate copy, no recalculations +// note: literate copy, no recalculations } inline @@ -112,7 +124,7 @@ void FloatAuto::handle_automatic_curve_after_copy() // of the left neighbour used as a template for interpolation. // Rather, we (re)set to automatically smoothed curves. Note // auto generated nodes (while tweaking values) indeed are -// inserted by using this "interpolation" approach, thus making +// inserted by using this "interpolation" approach, thus making // this defaulting to auto-smooth curves very important. { if(curve_mode == FREE || curve_mode == TFREE) @@ -127,7 +139,7 @@ int FloatAuto::interpolate_from(Auto *a1, Auto *a2, int64_t pos, Auto *templ) // between the positions of a1 and a2. If a1 or a2 are omitted, they default // to this->previous and this->next. If this FloatAuto has automatic curves, // this may trigger re-adjusting of this and its neighbours in this->autos. -// Note while a1 and a2 need not be members of this->autos, automatic +// Note while a1 and a2 need not be members of this->autos, automatic // readjustments are always done to the neighbours in this->autos. // If the template is given, it will be used to fill out this // objects fields prior to interpolating. @@ -142,9 +154,11 @@ int FloatAuto::interpolate_from(Auto *a1, Auto *a2, int64_t pos, Auto *templ) // set this->value using bézier interpolation if possible FloatAuto *left = (FloatAuto*)a1; FloatAuto *right = (FloatAuto*)a2; - float new_value = FloatAutos::calculate_bezier(left, right, pos); + if( pos != position ) { // this may trigger smoothing + this->adjust_to_new_coordinates(pos, + FloatAutos::calculate_bezier(left, right, pos)); + } float new_slope = FloatAutos::calculate_bezier_derivation(left, right, pos); - this->adjust_to_new_coordinates(pos, new_value); // this may trigger smoothing this->set_control_in_value(new_slope * control_in_position); this->set_control_out_value(new_slope * control_out_position); return 1; //return true: interpolated indeed... @@ -177,11 +191,11 @@ void FloatAuto::toggle_curve_mode() void FloatAuto::set_value(float newvalue) { - this->value=newvalue; + this->value=newvalue; this->adjust_curves(); if(previous) ((FloatAuto*)previous)->adjust_curves(); if(next) ((FloatAuto*)next)->adjust_curves(); -} +} void FloatAuto::set_control_in_value(float newvalue) { @@ -216,7 +230,7 @@ inline float weighted_mean(float v1, float v2, float w1, float w2){ void FloatAuto::adjust_curves() -// recalculates curves if current mode +// recalculates curves if current mode // implies automatic adjustment of curves { if(!autos) return; @@ -226,7 +240,7 @@ void FloatAuto::adjust_curves() // but this could cause the curve to overshot extremal automation nodes. // (e.g when setting a fade node at zero, the curve could go negative) // we can interpret the slope of chord as a weighted mean value, where - // the length of the interval is used as weight; we just use other + // the length of the interval is used as weight; we just use other // weights: intervall length /and/ reciprocal of slope. So, if the // connection to one of the neighbours has very low slope this will // dominate the calculated curve slope at this automation node. @@ -236,7 +250,7 @@ void FloatAuto::adjust_curves() float s, dxl, dxr, sl, sr; calculate_slope((FloatAuto*) previous, this, sl, dxl); calculate_slope(this, (FloatAuto*) next, sr, dxr); - + if(0 < sgn(sl) * sgn(sr)) { float wl = fabs(dxl) * (fabs(1.0/sl) + 1); @@ -244,11 +258,11 @@ void FloatAuto::adjust_curves() s = weighted_mean(sl, sr, wl, wr); } else s = 0; // fixed hoizontal curve - + control_in_value = s * control_in_position; control_out_value = s * control_out_position; } - + else if(curve_mode == LINEAR) { float g, dx; if(previous) @@ -261,14 +275,14 @@ void FloatAuto::adjust_curves() calculate_slope(this, (FloatAuto*)next, g, dx); control_out_value = g * dx / 3; } } - + else if(curve_mode == TFREE && control_in_position && control_out_position) { float gl = control_in_value / control_in_position; float gr = control_out_value / control_out_position; float wl = fabs(control_in_value); float wr = fabs(control_out_value); float g = weighted_mean(gl, gr, wl, wr); - + control_in_value = g * control_in_position; control_out_value = g * control_out_position; } @@ -291,33 +305,33 @@ void FloatAuto::adjust_ctrl_positions(FloatAuto *prev, FloatAuto *next) // next neighbours. The reason is: for this special // distance the bézier function yields x(t) = t, i.e. // we can use the y(t) as if it was a simple function y(x). - -// This adjustment is done only on demand and involves + +// This adjustment is done only on demand and involves // updating neighbours and adjust_curves() as well. -{ +{ if(!prev && !next) { // use current siblings prev = (FloatAuto*)this->previous; next = (FloatAuto*)this->next; - } - + } + if(prev) { set_ctrl_positions(prev, this); prev->adjust_curves(); } else // disable curve on left side control_in_position = 0; - - if(next) + + if(next) { set_ctrl_positions(this, next); next->adjust_curves(); } else // disable right curve control_out_position = 0; - + this->adjust_curves(); pos_valid = position; -// curves up-to-date +// curves up-to-date } @@ -352,7 +366,7 @@ void FloatAuto::adjust_to_new_coordinates(int64_t position, float value) int FloatAuto::value_to_str(char *string, float value) { int j = 0, i = 0; - if(value > 0) + if(value > 0) sprintf(string, "+%.2f", value); else sprintf(string, "%.2f", value); @@ -364,17 +378,17 @@ int FloatAuto::value_to_str(char *string, float value) string[1] = 0; } else - if(value < 1 && value > -1) + if(value < 1 && value > -1) { j = 1; string[j] = string[0]; } - else + else { j = 0; string[3] = 0; } - + while(string[j] != 0) string[i++] = string[j++]; string[i] = 0; @@ -404,7 +418,7 @@ void FloatAuto::load(FileXML *file) control_in_value = file->tag.get_property("CONTROL_IN_VALUE", control_in_value); control_out_value = file->tag.get_property("CONTROL_OUT_VALUE", control_out_value); curve_mode = (t_mode)file->tag.get_property("TANGENT_MODE", (int)FREE); - + // Compatibility to old session data format: // Versions previous to the bezier auto patch (Jun 2006) applied a factor 2 // to the y-coordinates of ctrl points while calculating the bezier function.