diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/animation/keyframes_general.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 53d8b4d67f1..07069a69c40 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -279,28 +279,21 @@ void clean_fcurve(FCurve *fcu, float thresh) /* temp struct used for smooth_fcurve */ typedef struct tSmooth_Bezt { float *h1, *h2, *h3; /* bezt->vec[0,1,2][1] */ + float y1, y2, y3; /* averaged before/new/after y-values */ } tSmooth_Bezt; /* Use a weighted moving-means method to reduce intensity of fluctuations */ +// TODO: introduce scaling factor for weighting falloff void smooth_fcurve (FCurve *fcu) { BezTriple *bezt; int i, x, totSel = 0; - /* first loop through - count how many verts are selected, and fix up handles - * this is done for both modes - */ + /* first loop through - count how many verts are selected */ bezt= fcu->bezt; for (i=0; i < fcu->totvert; i++, bezt++) { - if (BEZSELECTED(bezt)) { - /* line point's handles up with point's vertical position */ - bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1]; - if ((bezt->h1==HD_AUTO) || (bezt->h1==HD_VECT)) bezt->h1= HD_ALIGN; - if ((bezt->h2==HD_AUTO) || (bezt->h2==HD_VECT)) bezt->h2= HD_ALIGN; - - /* add value to total */ + if (BEZSELECTED(bezt)) totSel++; - } } /* if any points were selected, allocate tSmooth_Bezt points to work on */ @@ -320,7 +313,7 @@ void smooth_fcurve (FCurve *fcu) tsb->h3 = &bezt->vec[2][1]; /* advance to the next tsb to populate */ - if (x < totSel- 1) + if (x < totSel-1) tsb++; else break; @@ -334,10 +327,10 @@ void smooth_fcurve (FCurve *fcu) * - next: w/a ratio = 1:1:2:5:3 */ - /* round 1: calculate previous and next */ + /* round 1: calculate smoothing deltas and new values */ tsb= tarray; for (i=0; i < totSel; i++, tsb++) { - /* don't touch end points (otherwise, curves slowly explode) */ + /* don't touch end points (otherwise, curves slowly explode, as we don't have enough data there) */ if (ELEM(i, 0, (totSel-1)) == 0) { const tSmooth_Bezt *tP1 = tsb - 1; const tSmooth_Bezt *tP2 = (i-2 > 0) ? (tsb - 2) : (NULL); @@ -350,21 +343,26 @@ void smooth_fcurve (FCurve *fcu) const float n1 = *tN1->h2; const float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2); - /* calculate previous and next */ - *tsb->h1= (3*p2 + 5*p1 + 2*c1 + n1 + n2) / 12; - *tsb->h3= (p2 + p1 + 2*c1 + 5*n1 + 3*n2) / 12; + /* calculate previous and next, then new position by averaging these */ + tsb->y1= (3*p2 + 5*p1 + 2*c1 + n1 + n2) / 12; + tsb->y3= (p2 + p1 + 2*c1 + 5*n1 + 3*n2) / 12; + + tsb->y2 = (tsb->y1 + tsb->y3) / 2; } } - /* round 2: calculate new values and reset handles */ + /* round 2: apply new values */ tsb= tarray; for (i=0; i < totSel; i++, tsb++) { - /* calculate new position by averaging handles */ - *tsb->h2 = (*tsb->h1 + *tsb->h3) / 2; - - /* reset handles now */ - *tsb->h1 = *tsb->h2; - *tsb->h3 = *tsb->h2; + /* don't touch end points, as their values were't touched above */ + if (ELEM(i, 0, (totSel-1)) == 0) { + /* y2 takes the average of the 2 points */ + *tsb->h2 = tsb->y2; + + /* handles are weighted between their original values and the averaged values */ + *tsb->h1 = ((*tsb->h1) * 0.7f) + (tsb->y1 * 0.3f); + *tsb->h3 = ((*tsb->h3) * 0.7f) + (tsb->y3 * 0.3f); + } } /* free memory required for tarray */ |