diff options
Diffstat (limited to 'source/blender/blenkernel/intern/anim_sys.c')
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 163 |
1 files changed, 113 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 09d6ba4ff44..ea5a4bd99d1 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -538,7 +538,7 @@ static void animsys_write_orig_anim_rna(PointerRNA *ptr, */ static void animsys_evaluate_fcurves(PointerRNA *ptr, ListBase *list, - float ctime, + const AnimationEvalContext *anim_eval_context, bool flush_to_original) { /* Calculate then execute each curve. */ @@ -557,7 +557,7 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr, } PathResolvedRNA anim_rna; if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) { - const float curval = calculate_fcurve(&anim_rna, fcu, ctime); + const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context); BKE_animsys_write_rna_setting(&anim_rna, curval); if (flush_to_original) { animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval); @@ -569,8 +569,26 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr, /* ***************************************** */ /* Driver Evaluation */ +AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, + float eval_time) +{ + AnimationEvalContext ctx = { + .depsgraph = depsgraph, + .eval_time = eval_time, + }; + return ctx; +} + +AnimationEvalContext BKE_animsys_eval_context_construct_at( + const AnimationEvalContext *anim_eval_context, float eval_time) +{ + return BKE_animsys_eval_context_construct(anim_eval_context->depsgraph, eval_time); +} + /* Evaluate Drivers */ -static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime) +static void animsys_evaluate_drivers(PointerRNA *ptr, + AnimData *adt, + const AnimationEvalContext *anim_eval_context) { FCurve *fcu; @@ -591,7 +609,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime * before adding new to only be done when drivers only changed. */ PathResolvedRNA anim_rna; if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) { - const float curval = calculate_fcurve(&anim_rna, fcu, ctime); + const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context); ok = BKE_animsys_write_rna_setting(&anim_rna, curval); } @@ -647,7 +665,10 @@ static void action_idcode_patch_check(ID *id, bAction *act) /* ----------------------------------------- */ /* Evaluate Action Group */ -void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *agrp, float ctime) +void animsys_evaluate_action_group(PointerRNA *ptr, + bAction *act, + bActionGroup *agrp, + const AnimationEvalContext *anim_eval_context) { FCurve *fcu; @@ -669,7 +690,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup * if ((fcu->flag & (FCURVE_MUTED | FCURVE_DISABLED)) == 0 && !BKE_fcurve_is_empty(fcu)) { PathResolvedRNA anim_rna; if (BKE_animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) { - const float curval = calculate_fcurve(&anim_rna, fcu, ctime); + const float curval = calculate_fcurve(&anim_rna, fcu, anim_eval_context); BKE_animsys_write_rna_setting(&anim_rna, curval); } } @@ -679,7 +700,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup * /* Evaluate Action (F-Curve Bag) */ static void animsys_evaluate_action_ex(PointerRNA *ptr, bAction *act, - float ctime, + const AnimationEvalContext *anim_eval_context, const bool flush_to_original) { /* check if mapper is appropriate for use here (we set to NULL if it's inappropriate) */ @@ -690,15 +711,15 @@ static void animsys_evaluate_action_ex(PointerRNA *ptr, action_idcode_patch_check(ptr->owner_id, act); /* calculate then execute each curve */ - animsys_evaluate_fcurves(ptr, &act->curves, ctime, flush_to_original); + animsys_evaluate_fcurves(ptr, &act->curves, anim_eval_context, flush_to_original); } void animsys_evaluate_action(PointerRNA *ptr, bAction *act, - float ctime, + const AnimationEvalContext *anim_eval_context, const bool flush_to_original) { - animsys_evaluate_action_ex(ptr, act, ctime, flush_to_original); + animsys_evaluate_action_ex(ptr, act, anim_eval_context, flush_to_original); } /* ***************************************** */ @@ -726,7 +747,9 @@ static float nlastrip_get_influence(NlaStrip *strip, float cframe) } /* evaluate the evaluation time and influence for the strip, storing the results in the strip */ -static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool flush_to_original) +static void nlastrip_evaluate_controls(NlaStrip *strip, + const AnimationEvalContext *anim_eval_context, + const bool flush_to_original) { /* now strip's evaluate F-Curves for these settings (if applicable) */ if (strip->fcurves.first) { @@ -736,7 +759,7 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr); /* execute these settings as per normal */ - animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, ctime, flush_to_original); + animsys_evaluate_fcurves(&strip_ptr, &strip->fcurves, anim_eval_context, flush_to_original); } /* analytically generate values for influence and time (if applicable) @@ -744,17 +767,18 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool * in case the override has been turned off. */ if ((strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) == 0) { - strip->influence = nlastrip_get_influence(strip, ctime); + strip->influence = nlastrip_get_influence(strip, anim_eval_context->eval_time); } /* Bypass evaluation time computation if time mapping is disabled. */ if ((strip->flag & NLASTRIP_FLAG_NO_TIME_MAP) != 0) { - strip->strip_time = ctime; + strip->strip_time = anim_eval_context->eval_time; return; } if ((strip->flag & NLASTRIP_FLAG_USR_TIME) == 0) { - strip->strip_time = nlastrip_get_frame(strip, ctime, NLATIME_CONVERT_EVAL); + strip->strip_time = nlastrip_get_frame( + strip, anim_eval_context->eval_time, NLATIME_CONVERT_EVAL); } /* if user can control the evaluation time (using F-Curves), consider the option which allows @@ -768,12 +792,16 @@ static void nlastrip_evaluate_controls(NlaStrip *strip, float ctime, const bool } /* gets the strip active at the current time for a list of strips for evaluation purposes */ -NlaEvalStrip *nlastrips_ctime_get_strip( - ListBase *list, ListBase *strips, short index, float ctime, const bool flush_to_original) +NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, + ListBase *strips, + short index, + const AnimationEvalContext *anim_eval_context, + const bool flush_to_original) { NlaStrip *strip, *estrip = NULL; NlaEvalStrip *nes; short side = 0; + float ctime = anim_eval_context->eval_time; /* loop over strips, checking if they fall within the range */ for (strip = strips->first; strip; strip = strip->next) { @@ -852,7 +880,9 @@ NlaEvalStrip *nlastrips_ctime_get_strip( */ /* TODO: this sounds a bit hacky having a few isolated F-Curves * stuck on some data it operates on... */ - nlastrip_evaluate_controls(estrip, ctime, flush_to_original); + AnimationEvalContext clamped_eval_context = BKE_animsys_eval_context_construct_at( + anim_eval_context, ctime); + nlastrip_evaluate_controls(estrip, &clamped_eval_context, flush_to_original); if (estrip->influence <= 0.0f) { return NULL; } @@ -874,8 +904,12 @@ NlaEvalStrip *nlastrips_ctime_get_strip( } /* evaluate controls for the relevant extents of the bordering strips... */ - nlastrip_evaluate_controls(estrip->prev, estrip->start, flush_to_original); - nlastrip_evaluate_controls(estrip->next, estrip->end, flush_to_original); + AnimationEvalContext start_eval_context = BKE_animsys_eval_context_construct_at( + anim_eval_context, estrip->start); + AnimationEvalContext end_eval_context = BKE_animsys_eval_context_construct_at( + anim_eval_context, estrip->end); + nlastrip_evaluate_controls(estrip->prev, &start_eval_context, flush_to_original); + nlastrip_evaluate_controls(estrip->next, &end_eval_context, flush_to_original); break; } @@ -1795,6 +1829,7 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, + const AnimationEvalContext *anim_eval_context, const bool flush_to_original) { ListBase tmp_modifiers = {NULL, NULL}; @@ -1836,13 +1871,15 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr, tmp_nes.strip_mode = NES_TIME_TRANSITION_START; tmp_nes.strip = s1; nlaeval_snapshot_init(&snapshot1, channels, snapshot); - nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, flush_to_original); + nlastrip_evaluate( + ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, anim_eval_context, flush_to_original); /* second strip */ tmp_nes.strip_mode = NES_TIME_TRANSITION_END; tmp_nes.strip = s2; nlaeval_snapshot_init(&snapshot2, channels, snapshot); - nlastrip_evaluate(ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, flush_to_original); + nlastrip_evaluate( + ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_context, flush_to_original); /* accumulate temp-buffer and full-buffer, using the 'real' strip */ nlaeval_snapshot_mix_and_free(channels, snapshot, &snapshot1, &snapshot2, nes->strip_time); @@ -1857,6 +1894,7 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, + const AnimationEvalContext *anim_eval_context, const bool flush_to_original) { ListBase tmp_modifiers = {NULL, NULL}; @@ -1877,13 +1915,16 @@ static void nlastrip_evaluate_meta(PointerRNA *ptr, /* find the child-strip to evaluate */ evaltime = (nes->strip_time * (strip->end - strip->start)) + strip->start; - tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, evaltime, flush_to_original); + AnimationEvalContext child_context = BKE_animsys_eval_context_construct_at(anim_eval_context, + evaltime); + tmp_nes = nlastrips_ctime_get_strip(NULL, &strip->strips, -1, &child_context, flush_to_original); /* directly evaluate child strip into accumulation buffer... * - there's no need to use a temporary buffer (as it causes issues [T40082]) */ if (tmp_nes) { - nlastrip_evaluate(ptr, channels, &tmp_modifiers, tmp_nes, snapshot, flush_to_original); + nlastrip_evaluate( + ptr, channels, &tmp_modifiers, tmp_nes, snapshot, &child_context, flush_to_original); /* free temp eval-strip */ MEM_freeN(tmp_nes); @@ -1899,6 +1940,7 @@ void nlastrip_evaluate(PointerRNA *ptr, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, + const AnimationEvalContext *anim_eval_context, const bool flush_to_original) { NlaStrip *strip = nes->strip; @@ -1921,10 +1963,12 @@ void nlastrip_evaluate(PointerRNA *ptr, nlastrip_evaluate_actionclip(ptr, channels, modifiers, nes, snapshot); break; case NLASTRIP_TYPE_TRANSITION: /* transition */ - nlastrip_evaluate_transition(ptr, channels, modifiers, nes, snapshot, flush_to_original); + nlastrip_evaluate_transition( + ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original); break; case NLASTRIP_TYPE_META: /* meta */ - nlastrip_evaluate_meta(ptr, channels, modifiers, nes, snapshot, flush_to_original); + nlastrip_evaluate_meta( + ptr, channels, modifiers, nes, snapshot, anim_eval_context, flush_to_original); break; default: /* do nothing */ @@ -2072,7 +2116,7 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels, static bool animsys_evaluate_nla(NlaEvalData *echannels, PointerRNA *ptr, AnimData *adt, - float ctime, + const AnimationEvalContext *anim_eval_context, const bool flush_to_original, NlaKeyframingContext *r_context) { @@ -2120,7 +2164,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels, } /* otherwise, get strip to evaluate for this channel */ - nes = nlastrips_ctime_get_strip(&estrips, &nlt->strips, track_index, ctime, flush_to_original); + nes = nlastrips_ctime_get_strip( + &estrips, &nlt->strips, track_index, anim_eval_context, flush_to_original); if (nes) { nes->track = nlt; } @@ -2186,7 +2231,8 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels, /* add this to our list of evaluation strips */ if (r_context == NULL) { - nlastrips_ctime_get_strip(&estrips, &dummy_trackslist, -1, ctime, flush_to_original); + nlastrips_ctime_get_strip( + &estrips, &dummy_trackslist, -1, anim_eval_context, flush_to_original); } /* If computing the context for keyframing, store data there instead of the list. */ else { @@ -2196,7 +2242,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels, NLASTRIP_EXTEND_HOLD; r_context->eval_strip = nes = nlastrips_ctime_get_strip( - NULL, &dummy_trackslist, -1, ctime, flush_to_original); + NULL, &dummy_trackslist, -1, anim_eval_context, flush_to_original); /* These setting combinations require no data from strips below, so exit immediately. */ if ((nes == NULL) || @@ -2221,7 +2267,13 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels, /* 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, NULL, nes, &echannels->eval_snapshot, flush_to_original); + nlastrip_evaluate(ptr, + echannels, + NULL, + nes, + &echannels->eval_snapshot, + anim_eval_context, + flush_to_original); } /* 3. free temporary evaluation data that's not used elsewhere */ @@ -2235,7 +2287,7 @@ static bool animsys_evaluate_nla(NlaEvalData *echannels, */ static void animsys_calculate_nla(PointerRNA *ptr, AnimData *adt, - float ctime, + const AnimationEvalContext *anim_eval_context, const bool flush_to_original) { NlaEvalData echannels; @@ -2243,7 +2295,7 @@ static void animsys_calculate_nla(PointerRNA *ptr, nlaeval_init(&echannels); /* evaluate the NLA stack, obtaining a set of values to flush */ - if (animsys_evaluate_nla(&echannels, ptr, adt, ctime, flush_to_original, NULL)) { + if (animsys_evaluate_nla(&echannels, ptr, adt, anim_eval_context, flush_to_original, NULL)) { /* reset any channels touched by currently inactive actions to default value */ animsys_evaluate_nla_domain(ptr, &echannels, adt); @@ -2257,7 +2309,7 @@ static void animsys_calculate_nla(PointerRNA *ptr, CLOG_WARN(&LOG, "NLA Eval: Stopgap for active action on NLA Stack - no strips case"); } - animsys_evaluate_action(ptr, adt->action, ctime, flush_to_original); + animsys_evaluate_action(ptr, adt->action, anim_eval_context, flush_to_original); } /* free temp data */ @@ -2275,11 +2327,12 @@ static void animsys_calculate_nla(PointerRNA *ptr, * \param ptr: RNA pointer to the Object with the animation. * \return Keyframing context, or NULL if not necessary. */ -NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache, - struct PointerRNA *ptr, - struct AnimData *adt, - float ctime, - const bool flush_to_original) +NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context( + struct ListBase *cache, + struct PointerRNA *ptr, + struct AnimData *adt, + const AnimationEvalContext *anim_eval_context, + const bool flush_to_original) { /* No remapping needed if NLA is off or no action. */ if ((adt == NULL) || (adt->action == NULL) || (adt->nla_tracks.first == NULL) || @@ -2302,7 +2355,7 @@ NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *ca ctx->adt = adt; nlaeval_init(&ctx->nla_channels); - animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, ctime, flush_to_original, ctx); + animsys_evaluate_nla(&ctx->nla_channels, ptr, adt, anim_eval_context, flush_to_original, ctx); BLI_assert(ELEM(ctx->strip.act, NULL, adt->action)); BLI_addtail(cache, ctx); @@ -2492,8 +2545,11 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt) * and that the flags for which parts of the anim-data settings need to be recalculated * have been set already by the depsgraph. Now, we use the recalc */ -void BKE_animsys_evaluate_animdata( - ID *id, AnimData *adt, float ctime, eAnimData_Recalc recalc, const bool flush_to_original) +void BKE_animsys_evaluate_animdata(ID *id, + AnimData *adt, + const AnimationEvalContext *anim_eval_context, + eAnimData_Recalc recalc, + const bool flush_to_original) { PointerRNA id_ptr; @@ -2516,11 +2572,11 @@ void BKE_animsys_evaluate_animdata( /* evaluate NLA-stack * - active action is evaluated as part of the NLA stack as the last item */ - animsys_calculate_nla(&id_ptr, adt, ctime, flush_to_original); + animsys_calculate_nla(&id_ptr, adt, anim_eval_context, flush_to_original); } /* evaluate Active Action only */ else if (adt->action) { - animsys_evaluate_action_ex(&id_ptr, adt->action, ctime, flush_to_original); + animsys_evaluate_action_ex(&id_ptr, adt->action, anim_eval_context, flush_to_original); } } @@ -2530,7 +2586,7 @@ void BKE_animsys_evaluate_animdata( * - Drivers should be in the appropriate order to be evaluated without problems... */ if (recalc & ADT_RECALC_DRIVERS) { - animsys_evaluate_drivers(&id_ptr, adt, ctime); + animsys_evaluate_drivers(&id_ptr, adt, anim_eval_context); } /* always execute 'overrides' @@ -2558,6 +2614,8 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float } const bool flush_to_original = DEG_is_active(depsgraph); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + ctime); /* macros for less typing * - only evaluate animation data for id if it has users (and not just fake ones) @@ -2568,7 +2626,7 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float for (id = first; id; id = id->next) { \ if (ID_REAL_USERS(id) > 0) { \ AnimData *adt = BKE_animdata_from_id(id); \ - BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \ + BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \ } \ } \ (void)0 @@ -2587,9 +2645,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, float if (ntp->nodetree) { \ AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \ BKE_animsys_evaluate_animdata( \ - &ntp->nodetree->id, adt2, ctime, ADT_RECALC_ANIM, flush_to_original); \ + &ntp->nodetree->id, adt2, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); \ } \ - BKE_animsys_evaluate_animdata(id, adt, ctime, aflag, flush_to_original); \ + BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, aflag, flush_to_original); \ } \ } \ (void)0 @@ -2706,7 +2764,10 @@ void BKE_animsys_eval_animdata(Depsgraph *depsgraph, ID *id) * which should get handled as part of the dependency graph instead. */ DEG_debug_print_eval_time(depsgraph, __func__, id->name, id, ctime); const bool flush_to_original = DEG_is_active(depsgraph); - BKE_animsys_evaluate_animdata(id, adt, ctime, ADT_RECALC_ANIM, flush_to_original); + + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + ctime); + BKE_animsys_evaluate_animdata(id, adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); } void BKE_animsys_update_driver_array(ID *id) @@ -2768,7 +2829,9 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCu if (BKE_animsys_store_rna_setting(&id_ptr, fcu->rna_path, fcu->array_index, &anim_rna)) { /* Evaluate driver, and write results to COW-domain destination */ const float ctime = DEG_get_ctime(depsgraph); - const float curval = calculate_fcurve(&anim_rna, fcu, ctime); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + depsgraph, ctime); + const float curval = calculate_fcurve(&anim_rna, fcu, &anim_eval_context); ok = BKE_animsys_write_rna_setting(&anim_rna, curval); /* Flush results & status codes to original data for UI (T59984) */ |