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/anim_sys.c106
-rw-r--r--source/blender/blenkernel/nla_private.h2
2 files changed, 91 insertions, 17 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 0aadb1825ad..1037b2fd15d 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -904,16 +904,75 @@ static void nlaevalchan_buffers_accumulate (ListBase *channels, ListBase *tmp_bu
}
/* ---------------------- */
+/* F-Modifier stack joining/separation utilities - should we generalise these for BLI_listbase.h interface? */
+
+/* Temporarily join two lists of modifiers together, storing the result in a third list */
+static void nlaeval_fmodifiers_join_stacks (ListBase *result, ListBase *list1, ListBase *list2)
+{
+ FModifier *fcm1, *fcm2;
+
+ /* if list1 is invalid... */
+ if ELEM(NULL, list1, list1->first) {
+ if (list2 && list2->first) {
+ result->first= list2->first;
+ result->last= list2->last;
+ }
+ }
+ /* if list 2 is invalid... */
+ else if ELEM(NULL, list2, list2->first) {
+ result->first= list1->first;
+ result->last= list1->last;
+ }
+ else {
+ /* list1 should be added first, and list2 second, with the endpoints of these being the endpoints for result
+ * - the original lists must be left unchanged though, as we need that fact for restoring
+ */
+ result->first= list1->first;
+ result->last= list2->last;
+
+ fcm1= list1->last;
+ fcm2= list2->first;
+
+ fcm1->next= fcm2;
+ fcm2->prev= fcm1;
+ }
+}
+
+/* Split two temporary lists of modifiers */
+static void nlaeval_fmodifiers_split_stacks (ListBase *list1, ListBase *list2)
+{
+ FModifier *fcm1, *fcm2;
+
+ /* if list1/2 is invalid... just skip */
+ if ELEM(NULL, list1, list2)
+ return;
+ if ELEM(NULL, list1->first, list2->first)
+ return;
+
+ /* get endpoints */
+ fcm1= list1->last;
+ fcm2= list2->first;
+
+ /* clear their links */
+ fcm1->next= NULL;
+ fcm2->prev= NULL;
+}
+
+/* ---------------------- */
/* evaluate action-clip strip */
-static void nlastrip_evaluate_actionclip (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
+static void nlastrip_evaluate_actionclip (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
{
+ ListBase tmp_modifiers = {NULL, NULL};
NlaStrip *strip= nes->strip;
FCurve *fcu;
float evaltime;
+ /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
+ nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
+
/* evaluate strip's modifiers which modify time to evaluate the base curves at */
- evaltime= evaluate_time_fmodifiers(&strip->modifiers, NULL, 0.0f, strip->strip_time);
+ evaltime= evaluate_time_fmodifiers(&tmp_modifiers, NULL, 0.0f, strip->strip_time);
/* evaluate all the F-Curves in the action, saving the relevant pointers to data that will need to be used */
for (fcu= strip->act->curves.first; fcu; fcu= fcu->next) {
@@ -935,7 +994,7 @@ static void nlastrip_evaluate_actionclip (PointerRNA *ptr, ListBase *channels, N
/* apply strip's F-Curve Modifiers on this value
* NOTE: we apply the strip's original evaluation time not the modified one (as per standard F-Curve eval)
*/
- evaluate_value_fmodifiers(&strip->modifiers, fcu, &value, strip->strip_time);
+ evaluate_value_fmodifiers(&tmp_modifiers, fcu, &value, strip->strip_time);
/* get an NLA evaluation channel to work with, and accumulate the evaluated value with the value(s)
@@ -945,15 +1004,22 @@ static void nlastrip_evaluate_actionclip (PointerRNA *ptr, ListBase *channels, N
if (nec)
nlaevalchan_accumulate(nec, nes, newChan, value);
}
+
+ /* unlink this strip's modifiers from the parent's modifiers again */
+ nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
}
/* evaluate transition strip */
-static void nlastrip_evaluate_transition (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
+static void nlastrip_evaluate_transition (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
{
ListBase tmp_channels = {NULL, NULL};
+ ListBase tmp_modifiers = {NULL, NULL};
NlaEvalStrip tmp_nes;
NlaStrip *s1, *s2;
+ /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
+ nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &nes->strip->modifiers, modifiers);
+
/* get the two strips to operate on
* - we use the endpoints of the strips directly flanking our strip
* using these as the endpoints of the transition (destination and source)
@@ -980,25 +1046,30 @@ static void nlastrip_evaluate_transition (PointerRNA *ptr, ListBase *channels, N
tmp_nes= *nes;
/* evaluate these strips into a temp-buffer (tmp_channels) */
+ // FIXME: modifier evalation here needs some work...
/* first strip */
tmp_nes.strip_mode= NES_TIME_TRANSITION_START;
tmp_nes.strip= s1;
- nlastrip_evaluate_actionclip(ptr, &tmp_channels, &tmp_nes);
+ nlastrip_evaluate_actionclip(ptr, &tmp_channels, &tmp_modifiers, &tmp_nes);
/* second strip */
tmp_nes.strip_mode= NES_TIME_TRANSITION_END;
tmp_nes.strip= s2;
- nlastrip_evaluate_actionclip(ptr, &tmp_channels, &tmp_nes);
+ nlastrip_evaluate_actionclip(ptr, &tmp_channels, &tmp_modifiers, &tmp_nes);
/* assumulate temp-buffer and full-buffer, using the 'real' strip */
nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes);
+
+ /* unlink this strip's modifiers from the parent's modifiers again */
+ nlaeval_fmodifiers_split_stacks(&nes->strip->modifiers, modifiers);
}
/* evaluate meta-strip */
-static void nlastrip_evaluate_meta (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
+static void nlastrip_evaluate_meta (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
{
ListBase tmp_channels = {NULL, NULL};
+ ListBase tmp_modifiers = {NULL, NULL};
NlaStrip *strip= nes->strip;
NlaEvalStrip *tmp_nes;
float evaltime;
@@ -1010,6 +1081,9 @@ static void nlastrip_evaluate_meta (PointerRNA *ptr, ListBase *channels, NlaEval
*
* NOTE: keep this in sync with animsys_evaluate_nla()
*/
+
+ /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
+ nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
/* find the child-strip to evaluate */
evaltime= (nes->strip_time * (strip->end - strip->start)) + strip->start;
@@ -1020,31 +1094,31 @@ static void nlastrip_evaluate_meta (PointerRNA *ptr, ListBase *channels, NlaEval
/* evaluate child-strip into tmp_channels buffer before accumulating
* in the accumulation buffer
*/
- // TODO: need to supply overriding modifiers which will get applied over the top of these
- nlastrip_evaluate(ptr, &tmp_channels, tmp_nes);
+ nlastrip_evaluate(ptr, &tmp_channels, &tmp_modifiers, tmp_nes);
/* assumulate temp-buffer and full-buffer, using the 'real' strip */
nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes);
/* free temp eval-strip */
MEM_freeN(tmp_nes);
+
+ /* unlink this strip's modifiers from the parent's modifiers again */
+ nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
}
-
/* evaluates the given evaluation strip */
-void nlastrip_evaluate (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
+void nlastrip_evaluate (PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes)
{
/* actions to take depend on the type of strip */
- // TODO: add 'modifiers' tag to chain
switch (nes->strip->type) {
case NLASTRIP_TYPE_CLIP: /* action-clip */
- nlastrip_evaluate_actionclip(ptr, channels, nes);
+ nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes);
break;
case NLASTRIP_TYPE_TRANSITION: /* transition */
- nlastrip_evaluate_transition(ptr, channels, nes);
+ nlastrip_evaluate_transition(ptr, channels, modifiers, nes);
break;
case NLASTRIP_TYPE_META: /* meta */
- nlastrip_evaluate_meta(ptr, channels, nes);
+ nlastrip_evaluate_meta(ptr, channels, modifiers, nes);
break;
}
}
@@ -1136,7 +1210,7 @@ static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime)
/* 2. for each strip, evaluate then accumulate on top of existing channels, but don't set values yet */
for (nes= estrips.first; nes; nes= nes->next)
- nlastrip_evaluate(ptr, &echannels, nes);
+ nlastrip_evaluate(ptr, &echannels, NULL, nes);
/* 3. flush effects of accumulating channels in NLA to the actual data they affect */
nladata_flush_channels(&echannels);
diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h
index 016eaedfe4c..df7ffaa3064 100644
--- a/source/blender/blenkernel/nla_private.h
+++ b/source/blender/blenkernel/nla_private.h
@@ -79,7 +79,7 @@ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode);
/* these functions are only defined here to avoid problems with the order in which they get defined... */
NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, ListBase *strips, short index, float ctime);
-void nlastrip_evaluate(PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes);
+void nlastrip_evaluate(PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes);
void nladata_flush_channels(ListBase *channels);
#endif // NLA_PRIVATE