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:
Diffstat (limited to 'source/blender/blenkernel/intern/fmodifier.c')
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c94
1 files changed, 79 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 844f25e6d21..95c0aa60991 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -606,7 +604,7 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float UNUSED(cvalue),
/* calculate the 'number' of the cycle */
cycle= ((float)side * (evaltime - ofs) / cycdx);
-
+
/* calculate the time inside the cycle */
cyct= fmod(evaltime - ofs, cycdx);
@@ -631,11 +629,11 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float UNUSED(cvalue),
cycyofs = (float)ceil((evaltime - ofs) / cycdx);
cycyofs *= cycdy;
}
-
+
/* special case for cycle start/end */
if(cyct == 0.0f) {
evaltime = (side == 1 ? lastkey[0] : prevkey[0]);
-
+
if((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)cycle % 2))
evaltime = (side == 1 ? prevkey[0] : lastkey[0]);
}
@@ -1013,6 +1011,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 +1199,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
@@ -1230,11 +1270,24 @@ float evaluate_time_fmodifiers (ListBase *modifiers, FCurve *fcu, float cvalue,
for (fcm= modifiers->last; fcm; fcm= fcm->prev) {
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- /* only evaluate if there's a callback for this */
- // TODO: implement the 'influence' control feature...
- if (fmi && fmi->evaluate_modifier_time) {
- if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
- evaltime= fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
+ if (fmi == NULL)
+ continue;
+
+ /* if modifier cannot be applied on this frame (whatever scale it is on, it won't affect the results)
+ * hence we shouldn't bother seeing what it would do given the chance
+ */
+ if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)==0 ||
+ ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
+ {
+ /* only evaluate if there's a callback for this */
+ if (fmi->evaluate_modifier_time) {
+ 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);
+ }
+ }
}
}
@@ -1257,11 +1310,22 @@ void evaluate_value_fmodifiers (ListBase *modifiers, FCurve *fcu, float *cvalue,
for (fcm= modifiers->first; fcm; fcm= fcm->next) {
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- /* only evaluate if there's a callback for this */
- // TODO: implement the 'influence' control feature...
- if (fmi && fmi->evaluate_modifier) {
- if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
- fmi->evaluate_modifier(fcu, fcm, cvalue, evaltime);
+ if (fmi == NULL)
+ continue;
+
+ /* only evaluate if there's a callback for this, and if F-Modifier can be evaluated on this frame */
+ 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) {
+ float influence = eval_fmodifier_influence(fcm, evaltime);
+ float nval = *cvalue;
+
+ fmi->evaluate_modifier(fcu, fcm, &nval, evaltime);
+ *cvalue = interpf(nval, *cvalue, influence);
+ }
+ }
}
}
}