Graph Editor: F-Curves which can only take integral values are now drawn stair-stepped using the sampling code.
This commit is contained in:
@@ -94,13 +94,15 @@ FModifierTypeInfo *get_fmodifier_typeinfo(int type);
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
struct FModifier *fcurve_active_modifier(struct FCurve *fcu);
|
||||
struct FModifier *fcurve_add_modifier(struct FCurve *fcu, int type);
|
||||
void fcurve_copy_modifiers(ListBase *dst, ListBase *src);
|
||||
void fcurve_remove_modifier(struct FCurve *fcu, struct FModifier *fcm);
|
||||
void fcurve_free_modifiers(struct FCurve *fcu);
|
||||
void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
|
||||
|
||||
struct FModifier *fcurve_find_active_modifier(struct FCurve *fcu);
|
||||
void fcurve_set_active_modifier(struct FCurve *fcu, struct FModifier *fcm);
|
||||
|
||||
/* ************** F-Curves API ******************** */
|
||||
|
||||
/* -------- Data Managemnt -------- */
|
||||
|
||||
@@ -1892,7 +1892,7 @@ void fcurve_bake_modifiers (FCurve *fcu, int start, int end)
|
||||
}
|
||||
|
||||
/* Find the active F-Curve Modifier */
|
||||
FModifier *fcurve_active_modifier (FCurve *fcu)
|
||||
FModifier *fcurve_find_active_modifier (FCurve *fcu)
|
||||
{
|
||||
FModifier *fcm;
|
||||
|
||||
@@ -1910,6 +1910,24 @@ FModifier *fcurve_active_modifier (FCurve *fcu)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the active F-Curve Modifier */
|
||||
void fcurve_set_active_modifier (FCurve *fcu, FModifier *fcm)
|
||||
{
|
||||
FModifier *fm;
|
||||
|
||||
/* sanity checks */
|
||||
if ELEM(NULL, fcu, fcu->modifiers.first)
|
||||
return NULL;
|
||||
|
||||
/* deactivate all, and set current one active */
|
||||
for (fm= fcu->modifiers.first; fm; fm= fm->next)
|
||||
fm->flag &= ~FMODIFIER_FLAG_ACTIVE;
|
||||
|
||||
/* make given modifier active */
|
||||
if (fcm)
|
||||
fcm->flag |= FMODIFIER_FLAG_ACTIVE;
|
||||
}
|
||||
|
||||
/* ***************************** F-Curve - Evaluation ********************************* */
|
||||
|
||||
/* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
|
||||
@@ -1946,6 +1964,12 @@ float evaluate_fcurve (FCurve *fcu, float evaltime)
|
||||
}
|
||||
}
|
||||
|
||||
/* if curve can only have integral values, perform truncation (i.e. drop the decimal part)
|
||||
* here so that the curve can be sampled correctly
|
||||
*/
|
||||
if (fcu->flag & FCURVE_INT_VALUES)
|
||||
cvalue= (float)((int)cvalue);
|
||||
|
||||
/* return evaluated value */
|
||||
return cvalue;
|
||||
}
|
||||
|
||||
@@ -252,6 +252,17 @@ static void validate_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
|
||||
fmi->verify_data(fcm);
|
||||
}
|
||||
|
||||
/* callback to set the active modifier */
|
||||
static void activate_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
|
||||
{
|
||||
FCurve *fcu= (FCurve *)fcu_v;
|
||||
FModifier *fcm= (FModifier *)fcm_v;
|
||||
|
||||
/* call API function to set the active modifier for active F-Curve */
|
||||
fcurve_set_active_modifier(fcu, fcm);
|
||||
}
|
||||
|
||||
|
||||
/* callback to remove the given modifier */
|
||||
static void delete_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
|
||||
{
|
||||
@@ -492,12 +503,13 @@ static void graph_panel_modifier_draw(uiBlock *block, FCurve *fcu, FModifier *fc
|
||||
|
||||
/* name */
|
||||
if (fmi)
|
||||
uiDefBut(block, LABEL, 1, fmi->name, 10+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type");
|
||||
but= uiDefBut(block, LABEL, 1, fmi->name, 10+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
|
||||
else
|
||||
uiDefBut(block, LABEL, 1, "<Unknown Modifier>", 10+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type");
|
||||
but= uiDefBut(block, LABEL, 1, "<Unknown Modifier>", 10+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
|
||||
uiButSetFunc(but, activate_fmodifier_cb, fcu, fcm);
|
||||
|
||||
/* delete button */
|
||||
but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 10+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer");
|
||||
but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 10+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete F-Curve Modifier.");
|
||||
uiButSetFunc(but, delete_fmodifier_cb, fcu, fcm);
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
|
||||
@@ -546,7 +546,7 @@ static void draw_fcurve_curve_bezts (FCurve *fcu, View2D *v2d, View2DGrid *grid)
|
||||
v1[0]= v2d->cur.xmin;
|
||||
|
||||
/* y-value depends on the interpolation */
|
||||
if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo==BEZT_IPO_CONST) || (fcu->totvert==1)) {
|
||||
if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (prevbezt->ipo==BEZT_IPO_CONST) || (fcu->totvert==1)) {
|
||||
/* just extend across the first keyframe's value */
|
||||
v1[1]= prevbezt->vec[1][1];
|
||||
}
|
||||
@@ -575,7 +575,7 @@ static void draw_fcurve_curve_bezts (FCurve *fcu, View2D *v2d, View2DGrid *grid)
|
||||
|
||||
/* draw curve between first and last keyframe (if there are enough to do so) */
|
||||
while (b--) {
|
||||
if ((fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo==BEZT_IPO_CONST)) {
|
||||
if (prevbezt->ipo==BEZT_IPO_CONST) {
|
||||
/* Constant-Interpolation: draw segment between previous keyframe and next, but holding same value */
|
||||
v1[0]= prevbezt->vec[1][0];
|
||||
v1[1]= prevbezt->vec[1][1];
|
||||
@@ -710,7 +710,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
|
||||
*/
|
||||
for (ale=anim_data.first; ale; ale=ale->next) {
|
||||
FCurve *fcu= (FCurve *)ale->key_data;
|
||||
FModifier *fcm= fcurve_active_modifier(fcu);
|
||||
FModifier *fcm= fcurve_find_active_modifier(fcu);
|
||||
//Object *nob= ANIM_nla_mapping_get(ac, ale);
|
||||
|
||||
/* map keyframes for drawing if scaled F-Curve */
|
||||
@@ -746,8 +746,10 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
/* draw F-Curve */
|
||||
if (fcu->modifiers.first) {
|
||||
/* draw a curve affected by modifiers by sampling its points */
|
||||
if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
|
||||
/* draw a curve affected by modifiers or only allowed to have integer values
|
||||
* by sampling it at various small-intervals over the visible region
|
||||
*/
|
||||
draw_fcurve_curve(fcu, sipo, &ar->v2d, grid);
|
||||
}
|
||||
else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
|
||||
|
||||
@@ -1438,6 +1438,7 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
|
||||
bAnimContext ac;
|
||||
bAnimListElem *ale;
|
||||
FCurve *fcu;
|
||||
FModifier *fcm;
|
||||
short type;
|
||||
|
||||
/* get editor data */
|
||||
@@ -1454,13 +1455,17 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
|
||||
if (fcu == NULL)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
|
||||
/* get type of modifier to add */
|
||||
type= RNA_enum_get(op->ptr, "type");
|
||||
|
||||
/* add F-Modifier of specified type to active F-Curve */
|
||||
fcurve_add_modifier(fcu, type);
|
||||
|
||||
/* add F-Modifier of specified type to active F-Curve, and make it the active one */
|
||||
fcm= fcurve_add_modifier(fcu, type);
|
||||
if (fcm)
|
||||
fcurve_set_active_modifier(fcu, fcm);
|
||||
else {
|
||||
BKE_report(op->reports, RPT_ERROR, "Modifier couldn't be added. See console for details.");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* validate keyframes after editing */
|
||||
ANIM_editkeyframes_refresh(&ac);
|
||||
|
||||
@@ -613,6 +613,7 @@ static short findnearest_fcurve_vert (bAnimContext *ac, int mval[2], FCurve **fc
|
||||
}
|
||||
|
||||
/* handles - only do them if they're visible */
|
||||
// XXX also need to check for int-values only?
|
||||
if ((sipo->flag & SIPO_NOHANDLES)==0) {
|
||||
/* first handle only visible if previous segment had handles */
|
||||
if ( (!prevbezt && (bezt1->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) )
|
||||
|
||||
@@ -347,6 +347,7 @@ typedef struct TransInfo {
|
||||
#define TD_BEZTRIPLE (1 << 12) /* if this is a bez triple, we need to restore the handles, if this is set transdata->misc.hdata needs freeing */
|
||||
#define TD_NO_LOC (1 << 13) /* when this is set, don't apply translation changes to this element */
|
||||
#define TD_NOTIMESNAP (1 << 14) /* for Graph Editor autosnap, indicates that point should not undergo autosnapping */
|
||||
#define TD_INTVALUES (1 << 15) /* for Graph Editor - curves that can only have int-values need their keyframes tagged with this */
|
||||
|
||||
/* transsnap->status */
|
||||
#define SNAP_ON 1
|
||||
|
||||
@@ -3047,7 +3047,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
|
||||
/* Helper function for createTransGraphEditData, which is reponsible for associating
|
||||
* source data with transform data
|
||||
*/
|
||||
static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, float *loc, float *cent, short selected, short ishandle)
|
||||
static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, float *loc, float *cent, short selected, short ishandle, short intvals)
|
||||
{
|
||||
/* New location from td gets dumped onto the old-location of td2d, which then
|
||||
* gets copied to the actual data at td2d->loc2d (bezt->vec[n])
|
||||
@@ -3094,6 +3094,8 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, fl
|
||||
|
||||
if (ishandle)
|
||||
td->flag |= TD_NOTIMESNAP;
|
||||
if (intvals)
|
||||
td->flag |= TD_INTVALUES;
|
||||
|
||||
Mat3One(td->mtx);
|
||||
Mat3One(td->smtx);
|
||||
@@ -3204,6 +3206,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
Object *nob= NULL; //ANIM_nla_mapping_get(&ac, ale); // XXX we don't handle NLA mapping here yet
|
||||
FCurve *fcu= (FCurve *)ale->key_data;
|
||||
short intvals= (fcu->flag & FCURVE_INT_VALUES);
|
||||
|
||||
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */
|
||||
bezt= fcu->bezt;
|
||||
@@ -3218,7 +3221,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
if ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) {
|
||||
if (bezt->f1 & SELECT) {
|
||||
hdata = initTransDataCurveHandes(td, bezt);
|
||||
bezt_to_transdata(td++, td2d++, nob, bezt->vec[0], bezt->vec[1], 1, 1);
|
||||
bezt_to_transdata(td++, td2d++, nob, bezt->vec[0], bezt->vec[1], 1, 1, intvals);
|
||||
}
|
||||
else
|
||||
h1= 0;
|
||||
@@ -3227,7 +3230,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
if (bezt->f3 & SELECT) {
|
||||
if (hdata==NULL)
|
||||
hdata = initTransDataCurveHandes(td, bezt);
|
||||
bezt_to_transdata(td++, td2d++, nob, bezt->vec[2], bezt->vec[1], 1, 1);
|
||||
bezt_to_transdata(td++, td2d++, nob, bezt->vec[2], bezt->vec[1], 1, 1, intvals);
|
||||
}
|
||||
else
|
||||
h2= 0;
|
||||
@@ -3243,7 +3246,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
hdata = initTransDataCurveHandes(td, bezt);
|
||||
}
|
||||
|
||||
bezt_to_transdata(td++, td2d++, nob, bezt->vec[1], bezt->vec[1], 1, 0);
|
||||
bezt_to_transdata(td++, td2d++, nob, bezt->vec[1], bezt->vec[1], 1, 0, intvals);
|
||||
}
|
||||
|
||||
/* special hack (must be done after initTransDataCurveHandes(), as that stores handle settings to restore...):
|
||||
@@ -3489,7 +3492,11 @@ void flushTransGraphData(TransInfo *t)
|
||||
//else
|
||||
td2d->loc2d[0]= td2d->loc[0];
|
||||
|
||||
td2d->loc2d[1]= td2d->loc[1];
|
||||
/* if int-values only, truncate to integers */
|
||||
if (td->flag & TD_INTVALUES)
|
||||
td2d->loc2d[1]= (float)((int)td2d->loc[1]);
|
||||
else
|
||||
td2d->loc2d[1]= td2d->loc[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user