Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c61
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c26
-rw-r--r--source/blender/makesdna/DNA_anim_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c34
4 files changed, 117 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 4a1a0f9ac6b..dcf81c19479 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -1013,6 +1013,7 @@ FModifier *add_fmodifier (ListBase *modifiers, int type)
fcm= MEM_callocN(sizeof(FModifier), "F-Curve Modifier");
fcm->type = type;
fcm->flag = FMODIFIER_FLAG_EXPANDED;
+ fcm->influence = 1.0f;
BLI_addtail(modifiers, fcm);
/* tag modifier as "active" if no other modifiers exist in the stack yet */
@@ -1200,6 +1201,47 @@ short list_has_suitable_fmodifier (ListBase *modifiers, int mtype, short acttype
/* Evaluation API --------------------------- */
+/* helper function - calculate influence of FModifier */
+static float eval_fmodifier_influence (FModifier *fcm, float evaltime)
+{
+ float influence;
+
+ /* sanity check */
+ if (fcm == NULL)
+ return 0.0f;
+
+ /* should we use influence stored in modifier or not
+ * NOTE: this is really just a hack so that we don't need to version patch old files ;)
+ */
+ if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE)
+ influence = fcm->influence;
+ else
+ influence = 1.0f;
+
+ /* restricted range or full range? */
+ if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
+ if ((evaltime <= fcm->sfra) || (evaltime >= fcm->efra)) {
+ /* out of range */
+ return 0.0f;
+ }
+ else if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) {
+ /* blend in range */
+ float a = fcm->sfra;
+ float b = fcm->sfra + fcm->blendin;
+ return influence * (evaltime - a) / (b - a);
+ }
+ else if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) {
+ /* blend out range */
+ float a = fcm->efra;
+ float b = fcm->efra - fcm->blendout;
+ return influence * (evaltime - a) / (b - a);
+ }
+ }
+
+ /* just return the influence of the modifier */
+ return influence;
+}
+
/* evaluate time modifications imposed by some F-Curve Modifiers
* - this step acts as an optimisation to prevent the F-Curve stack being evaluated
* several times by modifiers requesting the time be modified, as the final result
@@ -1240,10 +1282,13 @@ float evaluate_time_fmodifiers (ListBase *modifiers, FCurve *fcu, float cvalue,
((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
{
/* only evaluate if there's a callback for this */
- // TODO: implement the 'influence' control feature...
if (fmi->evaluate_modifier_time) {
- if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
- evaltime= fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
+ if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0) {
+ float influence = eval_fmodifier_influence(fcm, evaltime);
+ float nval = fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
+
+ evaltime = interpf(nval, evaltime, influence);
+ }
}
}
}
@@ -1271,13 +1316,17 @@ void evaluate_value_fmodifiers (ListBase *modifiers, FCurve *fcu, float *cvalue,
continue;
/* only evaluate if there's a callback for this, and if F-Modifier can be evaluated on this frame */
- // TODO: implement the 'influence' control feature...
if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)==0 ||
((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
{
if (fmi->evaluate_modifier) {
- if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
- fmi->evaluate_modifier(fcu, fcm, cvalue, evaltime);
+ if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0) {
+ float influence = eval_fmodifier_influence(fcm, evaltime);
+ float nval = *cvalue;
+
+ fmi->evaluate_modifier(fcu, fcm, &nval, evaltime);
+ *cvalue = interpf(nval, *cvalue, influence);
+ }
}
}
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 3018fa697b8..8058454f510 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -604,7 +604,7 @@ static void draw_modifier__stepped(uiLayout *layout, ID *id, FModifier *fcm, sho
void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifiers, FModifier *fcm)
{
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- uiLayout *box, *row, *subrow;
+ uiLayout *box, *row, *subrow, *col;
uiBlock *block;
uiBut *but;
short width= 314;
@@ -700,16 +700,36 @@ void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifie
{
box = uiLayoutBox(layout);
+ /* restricted range ----------------------------------------------------- */
+ col = uiLayoutColumn(box, 1);
+
/* top row: use restricted range */
- row= uiLayoutRow(box, 0);
+ row= uiLayoutRow(col, 1);
uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
/* second row: settings */
- row = uiLayoutRow(box, 1);
+ row = uiLayoutRow(col, 1);
uiItemR(row, &ptr, "frame_start", 0, "Start", ICON_NONE);
uiItemR(row, &ptr, "frame_end", 0, "End", ICON_NONE);
+
+ /* third row: blending influence */
+ row = uiLayoutRow(col, 1);
+
+ uiItemR(row, &ptr, "blend_in", 0, "In", ICON_NONE);
+ uiItemR(row, &ptr, "blend_out", 0, "Out", ICON_NONE);
+ }
+
+ /* influence -------------------------------------------------------------- */
+ col = uiLayoutColumn(box, 1);
+
+ /* top row: use influence */
+ uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
+
+ if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
+ /* second row: influence value */
+ uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
}
}
}
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 88a3fe81825..c650d15722d 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -65,6 +65,8 @@ typedef struct FModifier {
float sfra; /* start frame of restricted frame-range */
float efra; /* end frame of restricted frame-range */
+ float blendin; /* number of frames from sfra before modifier takes full influence */
+ float blendout; /* number of frames from efra before modifier fades out */
} FModifier;
/* Types of F-Curve modifier
@@ -97,7 +99,9 @@ typedef enum eFModifier_Flags {
/* user wants modifier to be skipped */
FMODIFIER_FLAG_MUTED = (1<<3),
/* restrict range that F-Modifier can be considered over */
- FMODIFIER_FLAG_RANGERESTRICT = (1<<4)
+ FMODIFIER_FLAG_RANGERESTRICT = (1<<4),
+ /* use influence control */
+ FMODIFIER_FLAG_USEINFLUENCE = (1<<5)
} eFModifier_Flags;
/* --- */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index ba0563f554a..263978221bb 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -470,6 +470,14 @@ static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *ma
*max= MAXFRAMEF;
}
+static void rna_FModifier_blending_range(PointerRNA *ptr, float *min, float *max)
+{
+ FModifier *fcm= (FModifier*)ptr->data;
+
+ *min= 0.0f;
+ *max= fcm->efra - fcm->sfra;
+}
+
static void rna_FModifier_active_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
FModifier *fm, *fmo= (FModifier*)ptr->data;
@@ -1050,6 +1058,32 @@ static void rna_def_fmodifier(BlenderRNA *brna)
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_end_frame_range");
RNA_def_property_ui_text(prop, "End Frame", "Frame that modifier's influence ends (if Restrict Frame Range is in use)");
RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "blendin");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_blending_range");
+ RNA_def_property_ui_text(prop, "Blend In", "Number of frames from start frame for influence to take effect");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "blendout");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_blending_range");
+ RNA_def_property_ui_text(prop, "Blend Out", "Number of frames from start frame for influence to fade out");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ /* influence */
+ prop= RNA_def_property(srna, "use_influence", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_USEINFLUENCE);
+ RNA_def_property_ui_text(prop, "Use Influence", "F-Curve Modifier's effects will be tempered by a default factor");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+ RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); // XXX: depends on UI implementation
+
+ prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "influence");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Influence", "Amount of influence F-Curve Modifier will have when not fading in/out");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
}
/* *********************** */