diff options
Diffstat (limited to 'source/blender')
36 files changed, 503 insertions, 183 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 104582be932..43071c2966d 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -32,6 +32,7 @@ extern "C" { #endif /* The following structures are defined in DNA_action_types.h, and DNA_anim_types.h */ +struct AnimationEvalContext; struct FCurve; struct Main; struct Object; @@ -202,7 +203,7 @@ void what_does_obaction(struct Object *ob, struct bPose *pose, struct bAction *act, char groupname[], - float cframe); + const struct AnimationEvalContext *anim_eval_context); /* for proxy */ void BKE_pose_copy_pchan_result(struct bPoseChannel *pchanto, diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 4a2ad28f90f..2b7162418f8 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -48,6 +48,23 @@ struct bAction; struct bActionGroup; struct bContext; +/* Container for data required to do FCurve and Driver evaluation. */ +typedef struct AnimationEvalContext { + /* For drivers, so that they have access to the dependency graph and the current view layer. See + * T77086. */ + struct Depsgraph *const depsgraph; + + /* FCurves and Drivers can be evaluated at a different time than the current scene time, for + * example when evaluating NLA strips. This means that, even though the current time is stored in + * the dependency graph, we need an explicit evaluation time. */ + const float eval_time; +} AnimationEvalContext; + +AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, + float eval_time); +AnimationEvalContext BKE_animsys_eval_context_construct_at( + const AnimationEvalContext *anim_eval_context, float eval_time); + /* ************************************* */ /* KeyingSets API */ @@ -172,11 +189,12 @@ void BKE_fcurves_id_cb(struct ID *id, ID_FCurve_Edit_Callback func, void *user_d typedef struct NlaKeyframingContext NlaKeyframingContext; -struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(struct ListBase *cache, - struct PointerRNA *ptr, - struct AnimData *adt, - float ctime, - const bool flush_to_original); +struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context( + struct ListBase *cache, + struct PointerRNA *ptr, + struct AnimData *adt, + const struct AnimationEvalContext *anim_eval_context, + const bool flush_to_original); bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context, struct PointerRNA *prop_ptr, struct PropertyRNA *prop, @@ -209,7 +227,7 @@ bool BKE_animsys_write_rna_setting(struct PathResolvedRNA *anim_rna, const float /* Evaluation loop for evaluating animation data */ void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, - float ctime, + const struct AnimationEvalContext *anim_eval_context, eAnimData_Recalc recalc, const bool flush_to_original); @@ -229,14 +247,14 @@ void BKE_animsys_evaluate_all_animation(struct Main *main, /* Evaluate Action (F-Curve Bag) */ void animsys_evaluate_action(struct PointerRNA *ptr, struct bAction *act, - float ctime, + const struct AnimationEvalContext *anim_eval_context, const bool flush_to_original); /* Evaluate Action Group */ void animsys_evaluate_action_group(struct PointerRNA *ptr, struct bAction *act, struct bActionGroup *agrp, - float ctime); + const struct AnimationEvalContext *anim_eval_context); /* ************************************* */ diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index ddd0cc286ab..b846e2e5b7b 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -36,6 +36,7 @@ struct FCurve; struct FModifier; struct AnimData; +struct AnimationEvalContext; struct BezTriple; struct LibraryForeachIDData; struct PathResolvedRNA; @@ -281,10 +282,12 @@ float evaluate_fcurve_only_curve(struct FCurve *fcu, float evaltime); float evaluate_fcurve_driver(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, struct ChannelDriver *driver_orig, - float evaltime); + const struct AnimationEvalContext *anim_eval_context); bool BKE_fcurve_is_empty(struct FCurve *fcu); /* evaluate fcurve and store value */ -float calculate_fcurve(struct PathResolvedRNA *anim_rna, struct FCurve *fcu, float evaltime); +float calculate_fcurve(struct PathResolvedRNA *anim_rna, + struct FCurve *fcu, + const struct AnimationEvalContext *anim_eval_context); /* ************* F-Curve Samples API ******************** */ diff --git a/source/blender/blenkernel/BKE_fcurve_driver.h b/source/blender/blenkernel/BKE_fcurve_driver.h index 563ed408ed7..6803485f843 100644 --- a/source/blender/blenkernel/BKE_fcurve_driver.h +++ b/source/blender/blenkernel/BKE_fcurve_driver.h @@ -30,6 +30,7 @@ extern "C" { #endif +struct AnimationEvalContext; struct ChannelDriver; struct DriverTarget; struct DriverVar; @@ -97,7 +98,7 @@ void BKE_driver_invalidate_expression(struct ChannelDriver *driver, float evaluate_driver(struct PathResolvedRNA *anim_rna, struct ChannelDriver *driver, struct ChannelDriver *driver_orig, - const float evaltime); + const struct AnimationEvalContext *anim_eval_context); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index b35d2183408..0ee2fcb1963 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -1612,8 +1612,12 @@ void BKE_pose_tag_recalc(Main *bmain, bPose *pose) /* For the calculation of the effects of an Action at the given frame on an object * This is currently only used for the Action Constraint */ -void what_does_obaction( - Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe) +void what_does_obaction(Object *ob, + Object *workob, + bPose *pose, + bAction *act, + char groupname[], + const AnimationEvalContext *anim_eval_context) { bActionGroup *agrp = BKE_action_group_find_name(act, groupname); @@ -1669,7 +1673,7 @@ void what_does_obaction( RNA_id_pointer_create(&workob->id, &id_ptr); /* execute action for this group only */ - animsys_evaluate_action_group(&id_ptr, act, agrp, cframe); + animsys_evaluate_action_group(&id_ptr, act, agrp, anim_eval_context); } else { AnimData adt = {NULL}; @@ -1680,6 +1684,6 @@ void what_does_obaction( adt.action = act; /* execute effects of Action on to workob (or it's PoseChannels) */ - BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM, false); + BKE_animsys_evaluate_animdata(&workob->id, &adt, anim_eval_context, ADT_RECALC_ANIM, false); } } 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) */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 06c28776840..2ef32895db9 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -53,6 +53,7 @@ #include "BKE_action.h" #include "BKE_anim_path.h" +#include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_bvhutils.h" #include "BKE_cachefile.h" @@ -2625,7 +2626,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy) } } -static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph), +static void actcon_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, @@ -2679,6 +2680,8 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph), s = (vec[axis] - data->min) / (data->max - data->min); CLAMP(s, 0, 1); t = (s * (data->end - data->start)) + data->start; + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + t); if (G.debug & G_DEBUG) { printf("do Action Constraint %s - Ob %s Pchan %s\n", @@ -2693,7 +2696,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph), /* evaluate using workob */ /* FIXME: we don't have any consistent standards on limiting effects on object... */ - what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, t); + what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, &anim_eval_context); BKE_object_to_mat4(&workob, ct->matrix); } else if (cob->type == CONSTRAINT_OBTYPE_BONE) { @@ -2710,7 +2713,7 @@ static void actcon_get_tarmat(struct Depsgraph *UNUSED(depsgraph), tchan->rotmode = pchan->rotmode; /* evaluate action using workob (it will only set the PoseChannel in question) */ - what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, t); + what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, &anim_eval_context); /* convert animation to matrices for use here */ BKE_pchan_calc_mat(tchan); diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 746aff1697c..acbbf50701a 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1872,17 +1872,18 @@ float evaluate_fcurve_only_curve(FCurve *fcu, float evaltime) float evaluate_fcurve_driver(PathResolvedRNA *anim_rna, FCurve *fcu, ChannelDriver *driver_orig, - float evaltime) + const AnimationEvalContext *anim_eval_context) { BLI_assert(fcu->driver != NULL); float cvalue = 0.0f; + float evaltime = anim_eval_context->eval_time; /* If there is a driver (only if this F-Curve is acting as 'driver'), * evaluate it to find value to use as "evaltime" since drivers essentially act as alternative * input (i.e. in place of 'time') for F-Curves. */ if (fcu->driver) { /* evaltime now serves as input for the curve */ - evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, evaltime); + evaltime = evaluate_driver(anim_rna, fcu->driver, driver_orig, anim_eval_context); /* only do a default 1-1 mapping if it's unlikely that anything else will set a value... */ if (fcu->totvert == 0) { @@ -1924,7 +1925,9 @@ bool BKE_fcurve_is_empty(FCurve *fcu) } /* Calculate the value of the given F-Curve at the given frame, and set its curval */ -float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime) +float calculate_fcurve(PathResolvedRNA *anim_rna, + FCurve *fcu, + const AnimationEvalContext *anim_eval_context) { /* only calculate + set curval (overriding the existing value) if curve has * any data which warrants this... @@ -1936,10 +1939,10 @@ float calculate_fcurve(PathResolvedRNA *anim_rna, FCurve *fcu, float evaltime) /* calculate and set curval (evaluates driver too if necessary) */ float curval; if (fcu->driver) { - curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, evaltime); + curval = evaluate_fcurve_driver(anim_rna, fcu, fcu->driver, anim_eval_context); } else { - curval = evaluate_fcurve(fcu, evaltime); + curval = evaluate_fcurve(fcu, anim_eval_context->eval_time); } fcu->curval = curval; /* debug display only, not thread safe! */ return curval; diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c index a0625918a62..10d804f437e 100644 --- a/source/blender/blenkernel/intern/fcurve_driver.c +++ b/source/blender/blenkernel/intern/fcurve_driver.c @@ -43,6 +43,7 @@ #include "BLT_translation.h" #include "BKE_action.h" +#include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_fcurve_driver.h" @@ -1232,24 +1233,25 @@ static void evaluate_driver_min_max(ChannelDriver *driver) static void evaluate_driver_python(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, - const float evaltime) + const AnimationEvalContext *anim_eval_context) { /* check for empty or invalid expression */ if ((driver_orig->expression[0] == '\0') || (driver_orig->flag & DRIVER_FLAG_INVALID)) { driver->curval = 0.0f; } - else if (!driver_try_evaluate_simple_expr(driver, driver_orig, &driver->curval, evaltime)) { + else if (!driver_try_evaluate_simple_expr( + driver, driver_orig, &driver->curval, anim_eval_context->eval_time)) { #ifdef WITH_PYTHON /* this evaluates the expression using Python, and returns its result: * - on errors it reports, then returns 0.0f */ BLI_mutex_lock(&python_driver_lock); - driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, evaltime); + driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, anim_eval_context); BLI_mutex_unlock(&python_driver_lock); #else /* WITH_PYTHON*/ - UNUSED_VARS(anim_rna, evaltime); + UNUSED_VARS(anim_rna, anim_eval_context); #endif /* WITH_PYTHON*/ } } @@ -1262,7 +1264,7 @@ static void evaluate_driver_python(PathResolvedRNA *anim_rna, float evaluate_driver(PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, - const float evaltime) + const AnimationEvalContext *anim_eval_context) { /* check if driver can be evaluated */ if (driver_orig->flag & DRIVER_FLAG_INVALID) { @@ -1279,7 +1281,7 @@ float evaluate_driver(PathResolvedRNA *anim_rna, evaluate_driver_min_max(driver); break; case DRIVER_TYPE_PYTHON: /* expression */ - evaluate_driver_python(anim_rna, driver, driver_orig, evaltime); + evaluate_driver_python(anim_rna, driver, driver_orig, anim_eval_context); break; default: /* special 'hack' - just use stored value diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index d48ea33cc65..a344d2a163f 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2746,7 +2746,10 @@ void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *o { /* Execute drivers and animation. */ const bool flush_to_original = DEG_is_active(depsgraph); - BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_ALL, flush_to_original); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + ctime); + BKE_animsys_evaluate_animdata( + &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ALL, flush_to_original); object_where_is_calc_ex(depsgraph, scene, ob, ctime, NULL, NULL); } @@ -4643,9 +4646,13 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, /* was originally ID_RECALC_ALL - TODO - which flags are really needed??? */ /* TODO(sergey): What about animation? */ + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + frame); + ob->id.recalc |= ID_RECALC_ALL; if (update_mesh) { - BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM, flush_to_original); + BKE_animsys_evaluate_animdata( + &ob->id, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); /* ignore cache clear during subframe updates * to not mess up cache validity */ object_cacheIgnoreClear(ob, 1); @@ -4659,12 +4666,14 @@ bool BKE_object_modifier_update_subframe(Depsgraph *depsgraph, /* for curve following objects, parented curve has to be updated too */ if (ob->type == OB_CURVE) { Curve *cu = ob->data; - BKE_animsys_evaluate_animdata(&cu->id, cu->adt, frame, ADT_RECALC_ANIM, flush_to_original); + BKE_animsys_evaluate_animdata( + &cu->id, cu->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); } /* and armatures... */ if (ob->type == OB_ARMATURE) { bArmature *arm = ob->data; - BKE_animsys_evaluate_animdata(&arm->id, arm->adt, frame, ADT_RECALC_ANIM, flush_to_original); + BKE_animsys_evaluate_animdata( + &arm->id, arm->adt, &anim_eval_context, ADT_RECALC_ANIM, flush_to_original); BKE_pose_where_is(depsgraph, scene, ob); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index bf9aea81181..bec9cbbad79 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4854,8 +4854,10 @@ void particle_system_update(struct Depsgraph *depsgraph, for (i = 0; i <= part->hair_step; i++) { hcfra = 100.0f * (float)i / (float)psys->part->hair_step; if ((part->flag & PART_HAIR_REGROW) == 0) { + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + depsgraph, hcfra); BKE_animsys_evaluate_animdata( - &part_local->id, part_local->adt, hcfra, ADT_RECALC_ANIM, false); + &part_local->id, part_local->adt, &anim_eval_context, ADT_RECALC_ANIM, false); } system_step(&sim, hcfra, use_render_params); psys->cfra = hcfra; diff --git a/source/blender/blenkernel/intern/seqprefetch.c b/source/blender/blenkernel/intern/seqprefetch.c index 30a371b5b28..ff3829bdebb 100644 --- a/source/blender/blenkernel/intern/seqprefetch.c +++ b/source/blender/blenkernel/intern/seqprefetch.c @@ -183,6 +183,10 @@ static float seq_prefetch_cfra(PrefetchJob *pfjob) { return pfjob->cfra + pfjob->num_frames_prefetched; } +static AnimationEvalContext seq_prefetch_anim_eval_context(PrefetchJob *pfjob) +{ + return BKE_animsys_eval_context_construct(pfjob->depsgraph, seq_prefetch_cfra(pfjob)); +} void BKE_sequencer_prefetch_get_time_range(Scene *scene, int *start, int *end) { @@ -435,8 +439,9 @@ static void *seq_prefetch_frames(void *job) seq_prefetch_update_depsgraph(pfjob); AnimData *adt = BKE_animdata_from_id(&pfjob->context_cpy.scene->id); + AnimationEvalContext anim_eval_context = seq_prefetch_anim_eval_context(pfjob); BKE_animsys_evaluate_animdata( - &pfjob->context_cpy.scene->id, adt, seq_prefetch_cfra(pfjob), ADT_RECALC_ALL, false); + &pfjob->context_cpy.scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false); /* This is quite hacky solution: * We need cross-reference original scene with copy for cache. diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 6921a13e2c2..31ae71622f7 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3361,7 +3361,9 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr /* anim-data */ adt = BKE_animdata_from_id(&mask->id); - BKE_animsys_evaluate_animdata(&mask_temp->id, adt, mask->sfra + nr, ADT_RECALC_ANIM, false); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + context->depsgraph, mask->sfra + nr); + BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false); maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__); diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h index c72747a8c51..67e9afdf7fa 100644 --- a/source/blender/blenkernel/nla_private.h +++ b/source/blender/blenkernel/nla_private.h @@ -32,6 +32,8 @@ extern "C" { #endif +struct AnimationEvalContext; + /* --------------- NLA Evaluation DataTypes ----------------------- */ /* used for list of strips to accumulate at current time */ @@ -168,13 +170,17 @@ 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, const bool flush_to_original); +NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, + ListBase *strips, + short index, + const struct AnimationEvalContext *anim_eval_context, + const bool flush_to_original); void nlastrip_evaluate(PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, + const struct AnimationEvalContext *anim_eval_context, const bool flush_to_original); void nladata_flush_channels(PointerRNA *ptr, NlaEvalData *channels, diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 79c465c1f33..53401e0c05a 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4708,6 +4708,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi ReportList *reports = CTX_wm_reports(C); Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); ToolSettings *ts = scene->toolsettings; ListBase nla_cache = {NULL, NULL}; PointerRNA id_ptr, ptr; @@ -4720,8 +4721,10 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi RNA_id_pointer_create(id, &id_ptr); /* Get NLA context for value remapping */ + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + (float)CFRA); NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context( - &nla_cache, &id_ptr, adt, (float)CFRA, false); + &nla_cache, &id_ptr, adt, &anim_eval_context, false); /* get current frame and apply NLA-mapping to it (if applicable) */ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); @@ -4738,7 +4741,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi /* insert a keyframe for this F-Curve */ done = insert_keyframe_direct( - reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag); + reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, nla_context, flag); if (done) { if (adt->action != NULL) { @@ -4762,23 +4765,26 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi ReportList *reports = CTX_wm_reports(C); Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); ToolSettings *ts = scene->toolsettings; ListBase nla_cache = {NULL, NULL}; PointerRNA id_ptr, ptr; PropertyRNA *prop; eInsertKeyFlags flag = 0; bool done = false; - float cfra; /* Get RNA pointer */ RNA_id_pointer_create((ID *)key, &id_ptr); /* Get NLA context for value remapping */ + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + (float)CFRA); NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context( - &nla_cache, &id_ptr, key->adt, (float)CFRA, false); + &nla_cache, &id_ptr, key->adt, &anim_eval_context, false); /* get current frame and apply NLA-mapping to it (if applicable) */ - cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP); + const float remapped_frame = BKE_nla_tweakedit_remap( + key->adt, anim_eval_context.eval_time, NLATIME_CONVERT_UNMAP); /* get flags for keyframing */ flag = ANIM_get_keyframing_flags(scene, true); @@ -4791,13 +4797,21 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi FCurve *fcu = ED_action_fcurve_ensure(bmain, act, NULL, &ptr, rna_path, 0); /* set the special 'replace' flag if on a keyframe */ - if (fcurve_frame_has_keyframe(fcu, cfra, 0)) { + if (fcurve_frame_has_keyframe(fcu, remapped_frame, 0)) { flag |= INSERTKEY_REPLACE; } /* insert a keyframe for this F-Curve */ - done = insert_keyframe_direct( - reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag); + const AnimationEvalContext remapped_anim_eval_context = BKE_animsys_eval_context_construct_at( + &anim_eval_context, remapped_frame); + done = insert_keyframe_direct(reports, + ptr, + prop, + fcu, + &remapped_anim_eval_context, + ts->keyframe_type, + nla_context, + flag); if (done) { WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); @@ -4848,7 +4862,11 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C, } /* insert a keyframe for this F-Curve */ - done = insert_keyframe_direct(reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, flag); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + cfra); + done = insert_keyframe_direct( + reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, flag); if (done) { WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index bbb673caa71..50733afe6fb 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -419,6 +419,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) ac->markers = ED_context_get_markers(C); } ac->view_layer = CTX_data_view_layer(C); + ac->depsgraph = CTX_data_depsgraph_pointer(C); ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL; ac->area = area; ac->region = region; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 9cb41e06aa0..8c2f4216aa9 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1113,7 +1113,7 @@ static bool insert_keyframe_value(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, FCurve *fcu, - float cfra, + const AnimationEvalContext *anim_eval_context, float curval, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag) @@ -1130,13 +1130,15 @@ static bool insert_keyframe_value(ReportList *reports, return false; } + float cfra = anim_eval_context->eval_time; + /* adjust frame on which to add keyframe */ if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) { PathResolvedRNA anim_rna; if (RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) { /* for making it easier to add corrective drivers... */ - cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, cfra); + cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, anim_eval_context); } else { cfra = 0.0f; @@ -1202,7 +1204,7 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, - float cfra, + const AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, struct NlaKeyframingContext *nla_context, eInsertKeyFlags flag) @@ -1274,7 +1276,7 @@ bool insert_keyframe_direct(ReportList *reports, MEM_freeN(values); } - return insert_keyframe_value(reports, &ptr, prop, fcu, cfra, curval, keytype, flag); + return insert_keyframe_value(reports, &ptr, prop, fcu, anim_eval_context, curval, keytype, flag); } /* Find or create the FCurve based on the given path, and insert the specified value into it. */ @@ -1286,7 +1288,7 @@ static bool insert_keyframe_fcurve_value(Main *bmain, const char group[], const char rna_path[], int array_index, - float cfra, + const AnimationEvalContext *anim_eval_context, float curval, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag) @@ -1320,12 +1322,35 @@ static bool insert_keyframe_fcurve_value(Main *bmain, update_autoflags_fcurve_direct(fcu, prop); /* insert keyframe */ - return insert_keyframe_value(reports, ptr, prop, fcu, cfra, curval, keytype, flag); + return insert_keyframe_value( + reports, ptr, prop, fcu, anim_eval_context, curval, keytype, flag); } return false; } +static AnimationEvalContext nla_time_remap(const AnimationEvalContext *anim_eval_context, + PointerRNA *id_ptr, + AnimData *adt, + bAction *act, + ListBase *nla_cache, + NlaKeyframingContext **r_nla_context) +{ + if (adt && adt->action == act) { + /* Get NLA context for value remapping. */ + *r_nla_context = BKE_animsys_get_nla_keyframing_context( + nla_cache, id_ptr, adt, anim_eval_context, false); + + /* Apply NLA-mapping to frame. */ + const float remapped_frame = BKE_nla_tweakedit_remap( + adt, anim_eval_context->eval_time, NLATIME_CONVERT_UNMAP); + return BKE_animsys_eval_context_construct_at(anim_eval_context, remapped_frame); + } + + *r_nla_context = NULL; + return *anim_eval_context; +} + /** * Main Keyframing API call * @@ -1346,7 +1371,7 @@ int insert_keyframe(Main *bmain, const char group[], const char rna_path[], int array_index, - float cfra, + const AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, ListBase *nla_cache, eInsertKeyFlags flag) @@ -1393,15 +1418,8 @@ int insert_keyframe(Main *bmain, /* apply NLA-mapping to frame to use (if applicable) */ adt = BKE_animdata_from_id(id); - - if (adt && adt->action == act) { - /* Get NLA context for value remapping. */ - nla_context = BKE_animsys_get_nla_keyframing_context( - nla_cache ? nla_cache : &tmp_nla_cache, &id_ptr, adt, cfra, false); - - /* Apply NLA-mapping to frame. */ - cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); - } + const AnimationEvalContext remapped_context = nla_time_remap( + anim_eval_context, &id_ptr, adt, act, nla_cache ? nla_cache : &tmp_nla_cache, &nla_context); /* Obtain values to insert. */ float value_buffer[RNA_MAX_ARRAY_LENGTH]; @@ -1435,7 +1453,7 @@ int insert_keyframe(Main *bmain, group, rna_path, array_index, - cfra, + &remapped_context, values[array_index], keytype, flag)) { @@ -1458,7 +1476,7 @@ int insert_keyframe(Main *bmain, group, rna_path, array_index, - cfra, + &remapped_context, values[array_index], keytype, flag); @@ -1477,7 +1495,7 @@ int insert_keyframe(Main *bmain, group, rna_path, array_index, - cfra, + &remapped_context, values[array_index], keytype, flag); @@ -1495,7 +1513,7 @@ int insert_keyframe(Main *bmain, group, rna_path, array_index, - cfra, + &remapped_context, values[array_index], keytype, flag); @@ -2375,7 +2393,8 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) PropertyRNA *prop = NULL; char *path; uiBut *but; - float cfra = (float)CFRA; + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + CTX_data_depsgraph_pointer(C), (float)CFRA); bool changed = false; int index; const bool all = RNA_boolean_get(op->ptr, "all"); @@ -2401,7 +2420,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) if (fcu) { changed = insert_keyframe_direct( - op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0); + op->reports, ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, 0); } else { BKE_report(op->reports, @@ -2417,8 +2436,14 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) fcu = BKE_fcurve_find_by_rna_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special); if (fcu && driven) { - changed = insert_keyframe_direct( - op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER); + changed = insert_keyframe_direct(op->reports, + ptr, + prop, + fcu, + &anim_eval_context, + ts->keyframe_type, + NULL, + INSERTKEY_DRIVER); } } else { @@ -2461,7 +2486,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) group, path, index, - cfra, + &anim_eval_context, ts->keyframe_type, NULL, flag) != 0); @@ -2769,7 +2794,10 @@ bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter) } /* Returns whether the current value of a given property differs from the interpolated value. */ -bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float frame) +bool fcurve_is_changed(PointerRNA ptr, + PropertyRNA *prop, + FCurve *fcu, + const AnimationEvalContext *anim_eval_context) { PathResolvedRNA anim_rna; anim_rna.ptr = ptr; @@ -2780,7 +2808,7 @@ bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float fra int count, index = fcu->array_index; float *values = setting_get_rna_values(&ptr, prop, buffer, RNA_MAX_ARRAY_LENGTH, &count); - float fcurve_val = calculate_fcurve(&anim_rna, fcu, frame); + float fcurve_val = calculate_fcurve(&anim_rna, fcu, anim_eval_context); float cur_val = (index >= 0 && index < count) ? values[index] : 0.0f; if (values != buffer) { @@ -2987,6 +3015,9 @@ bool ED_autokeyframe_property( bContext *C, Scene *scene, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, float cfra) { Main *bmain = CTX_data_main(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + cfra); ID *id; bAction *action; FCurve *fcu; @@ -3007,7 +3038,8 @@ bool ED_autokeyframe_property( ReportList *reports = CTX_wm_reports(C); ToolSettings *ts = scene->toolsettings; - changed = insert_keyframe_direct(reports, *ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0); + changed = insert_keyframe_direct( + reports, *ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, 0); WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } } @@ -3020,7 +3052,7 @@ bool ED_autokeyframe_property( ToolSettings *ts = scene->toolsettings; changed = insert_keyframe_direct( - reports, *ptr, prop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER); + reports, *ptr, prop, fcu, &anim_eval_context, ts->keyframe_type, NULL, INSERTKEY_DRIVER); WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } } @@ -3044,7 +3076,7 @@ bool ED_autokeyframe_property( ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, rnaindex, - cfra, + &anim_eval_context, ts->keyframe_type, NULL, flag) != 0; diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 5e4b39d9d81..876740b889a 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -1120,6 +1120,9 @@ int ANIM_apply_keyingset( /* for each possible index, perform operation * - assume that arraylen is greater than index */ + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + cfra); for (; i < arraylen; i++) { /* action to take depends on mode */ if (mode == MODIFYKEY_MODE_INSERT) { @@ -1130,7 +1133,7 @@ int ANIM_apply_keyingset( groupname, ksp->rna_path, i, - cfra, + &anim_eval_context, keytype, &nla_cache, kflag2); diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 6ce9ed06f1a..c9d0478270a 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -1023,7 +1023,8 @@ static void poselib_backup_free_data(tPoseLib_PreviewData *pld) * - gets the string to print in the header * - this code is based on the code for extract_pose_from_action in blenkernel/action.c */ -static void poselib_apply_pose(tPoseLib_PreviewData *pld) +static void poselib_apply_pose(tPoseLib_PreviewData *pld, + const AnimationEvalContext *anim_eval_context) { PointerRNA *ptr = &pld->rna_ptr; bArmature *arm = pld->arm; @@ -1049,6 +1050,8 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld) group_ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE); ked.f1 = ((float)frame) - 0.5f; ked.f2 = ((float)frame) + 0.5f; + AnimationEvalContext anim_context_at_frame = BKE_animsys_eval_context_construct_at( + anim_eval_context, frame); /* start applying - only those channels which have a key at this point in time! */ for (agrp = act->groups.first; agrp; agrp = agrp->next) { @@ -1075,7 +1078,7 @@ static void poselib_apply_pose(tPoseLib_PreviewData *pld) } if (ok) { - animsys_evaluate_action_group(ptr, act, agrp, (float)frame); + animsys_evaluate_action_group(ptr, act, agrp, &anim_context_at_frame); } } } @@ -1150,7 +1153,11 @@ static void poselib_preview_apply(bContext *C, wmOperator *op) /* pose should be the right one to draw (unless we're temporarily not showing it) */ if ((pld->flag & PL_PREVIEW_SHOWORIGINAL) == 0) { RNA_int_set(op->ptr, "pose_index", BLI_findindex(&pld->act->markers, pld->marker)); - poselib_apply_pose(pld); + struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + depsgraph, 0.0f /* poselib_apply_pose() determines its own evaluation time. */); + poselib_apply_pose(pld, &anim_eval_context); } else { RNA_int_set(op->ptr, "pose_index", -2); /* -2 means don't apply any pose */ diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index 1d2bf152777..615d59c3154 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -1219,7 +1219,9 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); - float cframe = (float)CFRA; + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + (float)CFRA); const bool only_select = RNA_boolean_get(op->ptr, "only_selected"); FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) { @@ -1240,7 +1242,8 @@ static int pose_clear_user_transforms_exec(bContext *C, wmOperator *op) workob.adt = ob->adt; workob.pose = dummyPose; - BKE_animsys_evaluate_animdata(&workob.id, workob.adt, cframe, ADT_RECALC_ANIM, false); + BKE_animsys_evaluate_animdata( + &workob.id, workob.adt, &anim_eval_context, ADT_RECALC_ANIM, false); /* copy back values, but on selected bones only */ for (pchan = dummyPose->chanbase.first; pchan; pchan = pchan->next) { diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index e111ce44bc4..52e9a437830 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -48,6 +48,7 @@ #include "DNA_space_types.h" #include "DNA_view3d_types.h" +#include "BKE_animsys.h" #include "BKE_collection.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -399,6 +400,7 @@ static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd, static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, + Depsgraph *depsgraph, FCurve *fcu, Curve *cu, tGpTimingData *gtd, @@ -453,8 +455,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports, if ((cfra - last_valid_time) < MIN_TIME_DELTA) { cfra = last_valid_time + MIN_TIME_DELTA; } - insert_keyframe_direct( - reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + depsgraph, cfra); + insert_keyframe_direct(reports, + ptr, + prop, + fcu, + &anim_eval_context, + BEZT_KEYTYPE_KEYFRAME, + NULL, + INSERTKEY_FAST); last_valid_time = cfra; } else if (G.debug & G_DEBUG) { @@ -466,8 +476,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports, if ((cfra - last_valid_time) < MIN_TIME_DELTA) { cfra = last_valid_time + MIN_TIME_DELTA; } - insert_keyframe_direct( - reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + cfra); + insert_keyframe_direct(reports, + ptr, + prop, + fcu, + &anim_eval_context, + BEZT_KEYTYPE_KEYFRAME, + NULL, + INSERTKEY_FAST); last_valid_time = cfra; } else { @@ -475,8 +493,16 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports, * and also far enough from (not yet added!) end_stroke keyframe! */ if ((cfra - last_valid_time) > MIN_TIME_DELTA && (end_stroke_time - cfra) > MIN_TIME_DELTA) { - insert_keyframe_direct( - reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_BREAKDOWN, NULL, INSERTKEY_FAST); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + depsgraph, cfra); + insert_keyframe_direct(reports, + ptr, + prop, + fcu, + &anim_eval_context, + BEZT_KEYTYPE_BREAKDOWN, + NULL, + INSERTKEY_FAST); last_valid_time = cfra; } else if (G.debug & G_DEBUG) { @@ -496,6 +522,7 @@ static void gpencil_stroke_path_animation(bContext *C, { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); bAction *act; FCurve *fcu; PointerRNA ptr; @@ -537,8 +564,16 @@ static void gpencil_stroke_path_animation(bContext *C, cu->ctime = 0.0f; cfra = (float)gtd->start_frame; - insert_keyframe_direct( - reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST); + AnimationEvalContext anim_eval_context_start = BKE_animsys_eval_context_construct(depsgraph, + cfra); + insert_keyframe_direct(reports, + ptr, + prop, + fcu, + &anim_eval_context_start, + BEZT_KEYTYPE_KEYFRAME, + NULL, + INSERTKEY_FAST); cu->ctime = cu->pathlen; if (gtd->realtime) { @@ -547,8 +582,16 @@ static void gpencil_stroke_path_animation(bContext *C, else { cfra = (float)gtd->end_frame; } - insert_keyframe_direct( - reports, ptr, prop, fcu, cfra, BEZT_KEYTYPE_KEYFRAME, NULL, INSERTKEY_FAST); + AnimationEvalContext anim_eval_context_end = BKE_animsys_eval_context_construct(depsgraph, + cfra); + insert_keyframe_direct(reports, + ptr, + prop, + fcu, + &anim_eval_context_end, + BEZT_KEYTYPE_KEYFRAME, + NULL, + INSERTKEY_FAST); } else { /* Use actual recorded timing! */ @@ -575,7 +618,7 @@ static void gpencil_stroke_path_animation(bContext *C, } gpencil_stroke_path_animation_add_keyframes( - reports, ptr, prop, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time); + reports, ptr, prop, depsgraph, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time); BLI_rng_free(rng); } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index bffa11a32f2..9d9f2925c23 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -95,6 +95,8 @@ typedef struct bAnimContext { struct Scene *scene; /** active scene layer */ struct ViewLayer *view_layer; + /** active dependency graph */ + struct Depsgraph *depsgraph; /** active object */ struct Object *obact; /** active set of markers */ diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 5635ef2800a..3fe6407aae7 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -38,6 +38,7 @@ struct Scene; struct KeyingSet; +struct AnimationEvalContext; struct BezTriple; struct FCurve; struct bAction; @@ -118,7 +119,7 @@ bool insert_keyframe_direct(struct ReportList *reports, struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, - float cfra, + const struct AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, struct NlaKeyframingContext *nla, eInsertKeyFlags flag); @@ -136,7 +137,7 @@ int insert_keyframe(struct Main *bmain, const char group[], const char rna_path[], int array_index, - float cfra, + const struct AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, struct ListBase *nla_cache, eInsertKeyFlags flag); @@ -458,7 +459,7 @@ bool fcurve_frame_has_keyframe(struct FCurve *fcu, float frame, short filter); bool fcurve_is_changed(struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, - float frame); + const struct AnimationEvalContext *anim_eval_context); /** * Main Keyframe Checking API call: diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 28b86674fdd..106145005bd 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -44,6 +44,7 @@ #include "BLI_utildefines.h" +#include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_idprop.h" #include "BKE_main.h" @@ -1733,6 +1734,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x wmWindow *window = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); ARegion *region = CTX_wm_region(C); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); uiBut *but; BLI_assert(block->active); @@ -1761,7 +1763,9 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x } } - ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + depsgraph, (scene) ? scene->r.cfra : 0.0f); + ui_but_anim_flag(but, &anim_eval_context); ui_but_override_flag(CTX_data_main(C), but); if (UI_but_is_decorator(but)) { ui_but_anim_decorate_update_from_flag(but); diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 5bf2147aff5..8d12a1dd1ad 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -33,6 +33,7 @@ #include "BLI_string_utf8.h" #include "BLI_utildefines.h" +#include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_fcurve.h" #include "BKE_fcurve_driver.h" @@ -65,7 +66,7 @@ static FCurve *ui_but_get_fcurve( but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special); } -void ui_but_anim_flag(uiBut *but, float cfra) +void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context) { AnimData *adt; bAction *act; @@ -95,6 +96,7 @@ void ui_but_anim_flag(uiBut *but, float cfra) * we need to correct the frame number to "look inside" the * remapped action */ + float cfra = anim_eval_context->eval_time; if (adt) { cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); } @@ -105,7 +107,9 @@ void ui_but_anim_flag(uiBut *but, float cfra) /* XXX: this feature is totally broken and useless with NLA */ if (adt == NULL || adt->nla_tracks.first == NULL) { - if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, cfra)) { + const AnimationEvalContext remapped_context = BKE_animsys_eval_context_construct_at( + anim_eval_context, cfra); + if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, &remapped_context)) { but->drawflag |= UI_BUT_ANIMATED_CHANGED; } } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 43c91f1d2eb..988d19e30d3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -47,6 +47,7 @@ #include "PIL_time.h" +#include "BKE_animsys.h" #include "BKE_blender_undo.h" #include "BKE_brush.h" #include "BKE_colorband.h" @@ -8408,6 +8409,9 @@ void UI_context_update_anim_flag(const bContext *C) { Scene *scene = CTX_data_scene(C); ARegion *region = CTX_wm_region(C); + struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + depsgraph, (scene) ? scene->r.cfra : 0.0f); uiBlock *block; uiBut *but, *activebut; @@ -8417,7 +8421,7 @@ void UI_context_update_anim_flag(const bContext *C) for (block = region->uiblocks.first; block; block = block->next) { for (but = block->buttons.first; but; but = but->next) { - ui_but_anim_flag(but, (scene) ? scene->r.cfra : 0.0f); + ui_but_anim_flag(but, &anim_eval_context); ui_but_override_flag(CTX_data_main(C), but); if (UI_but_is_decorator(but)) { ui_but_anim_decorate_update_from_flag(but); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index a7cbfc23399..249134c6abf 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -32,6 +32,7 @@ #include "UI_interface.h" #include "UI_resources.h" +struct AnimationEvalContext; struct ARegion; struct ID; struct ImBuf; @@ -938,7 +939,7 @@ int ui_but_align_opposite_to_area_align_get(const struct ARegion *region) ATTR_W void ui_block_align_calc(uiBlock *block, const struct ARegion *region); /* interface_anim.c */ -void ui_but_anim_flag(uiBut *but, float cfra); +void ui_but_anim_flag(uiBut *but, const struct AnimationEvalContext *anim_eval_context); void ui_but_anim_copy_driver(struct bContext *C); void ui_but_anim_paste_driver(struct bContext *C); bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 6f254ea9400..4470269ec23 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -2796,12 +2796,16 @@ static int ocean_bake_exec(bContext *C, wmOperator *op) cfra = scene->r.cfra; /* precalculate time variable before baking */ + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); for (f = omd->bakestart; f <= omd->bakeend; f++) { /* For now only simple animation of time value is supported, nothing else. * No drivers or other modifier parameters. */ /* TODO(sergey): This operates on an original data, so no flush is needed. However, baking * usually should happen on an evaluated objects, so this seems to be deeper issue here. */ - BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, f, ADT_RECALC_ANIM, false); + + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + f); + BKE_animsys_evaluate_animdata((ID *)ob, ob->adt, &anim_eval_context, ADT_RECALC_ANIM, false); och->time[i] = omd->time; i++; diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 185066b49ce..af8e0e9d9de 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -724,9 +724,10 @@ static void insert_action_keys(bAnimContext *ac, short mode) flag = ANIM_get_keyframing_flags(scene, true); /* insert keyframes */ + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(ac->depsgraph, + (float)CFRA); for (ale = anim_data.first; ale; ale = ale->next) { FCurve *fcu = (FCurve *)ale->key_data; - float cfra = (float)CFRA; /* Read value from property the F-Curve represents, or from the curve only? * - ale->id != NULL: @@ -745,7 +746,7 @@ static void insert_action_keys(bAnimContext *ac, short mode) ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, - cfra, + &anim_eval_context, ts->keyframe_type, &nla_cache, flag); @@ -754,8 +755,9 @@ static void insert_action_keys(bAnimContext *ac, short mode) AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* adjust current frame for NLA-scaling */ + float cfra = anim_eval_context.eval_time; if (adt) { - cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP); + cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); } const float curval = evaluate_fcurve(fcu, cfra); diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 1925a3847d6..68fdef54a53 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -681,9 +681,10 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) } } else { + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + ac->depsgraph, (float)CFRA); for (ale = anim_data.first; ale; ale = ale->next) { FCurve *fcu = (FCurve *)ale->key_data; - float cfra = (float)CFRA; /* Read value from property the F-Curve represents, or from the curve only? * @@ -705,7 +706,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, - cfra, + &anim_eval_context, ts->keyframe_type, &nla_cache, flag); @@ -714,6 +715,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode) AnimData *adt = ANIM_nla_mapping_get(ac, ale); /* adjust current frame for NLA-mapping */ + float cfra = (float)CFRA; if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS)) { cfra = sipo->cursorTime; } diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index f721ed0b866..9885c8fc3a6 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -115,7 +115,9 @@ static void autokeyframe_pose( ToolSettings *ts = scene->toolsettings; KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); ListBase nla_cache = {NULL, NULL}; - float cfra = (float)CFRA; + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + (float)CFRA); eInsertKeyFlags flag = 0; /* flag is initialized from UserPref keyframing settings @@ -146,7 +148,8 @@ static void autokeyframe_pose( /* only insert into active keyingset? */ if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) { /* run the active Keying Set on the current datasource */ - ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } /* only insert into available channels? */ else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) { @@ -169,7 +172,7 @@ static void autokeyframe_pose( ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, - cfra, + &anim_eval_context, ts->keyframe_type, &nla_cache, flag); @@ -220,21 +223,25 @@ static void autokeyframe_pose( if (do_loc) { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } if (do_rot) { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } if (do_scale) { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } } /* insert keyframe in all (transform) channels */ else { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } /* free temp info */ diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 92ed477eb25..2e92b4e5c09 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -794,7 +794,9 @@ static void autokeyframe_object( ToolSettings *ts = scene->toolsettings; KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene); ListBase dsources = {NULL, NULL}; - float cfra = (float)CFRA; // xxx this will do for now + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + (float)CFRA); eInsertKeyFlags flag = 0; /* Get flags used for inserting keyframes. */ @@ -808,7 +810,8 @@ static void autokeyframe_object( * NOTE: we assume here that the active Keying Set * does not need to have its iterator overridden. */ - ANIM_apply_keyingset(C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL)) { AnimData *adt = ob->adt; @@ -824,7 +827,7 @@ static void autokeyframe_object( (fcu->grp ? fcu->grp->name : NULL), fcu->rna_path, fcu->array_index, - cfra, + &anim_eval_context, ts->keyframe_type, &nla_cache, flag); @@ -872,21 +875,25 @@ static void autokeyframe_object( /* insert keyframes for the affected sets of channels using the builtin KeyingSets found */ if (do_loc) { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } if (do_rot) { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } if (do_scale) { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_SCALING_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } } /* insert keyframe in all (transform) channels */ else { KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); + ANIM_apply_keyingset( + C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, anim_eval_context.eval_time); } /* free temp info */ diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index 18d4c7da534..5c6e0b0a308 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -21,6 +21,7 @@ #ifndef __BPY_EXTERN_H__ #define __BPY_EXTERN_H__ +struct AnimationEvalContext; struct ChannelDriver; /* DNA_anim_types.h */ struct ID; /* DNA_ID.h */ struct ListBase; /* DNA_listBase.h */ @@ -117,7 +118,7 @@ void BPY_driver_reset(void); float BPY_driver_exec(struct PathResolvedRNA *anim_rna, struct ChannelDriver *driver, struct ChannelDriver *driver_orig, - const float evaltime); + const struct AnimationEvalContext *anim_eval_context); void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */ void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr); diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 9b191ee5698..3d83eb90da6 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -33,19 +33,22 @@ #include "BLI_math_base.h" #include "BLI_string.h" +#include "BKE_animsys.h" #include "BKE_fcurve_driver.h" #include "BKE_global.h" +#include "RNA_access.h" +#include "RNA_types.h" + #include "bpy_rna_driver.h" /* for pyrna_driver_get_variable_value */ #include "bpy_intern_string.h" #include "bpy_driver.h" +#include "bpy_rna.h" #include "BPY_extern.h" -extern void BPY_update_rna_module(void); - #define USE_RNA_AS_PYOBJECT #define USE_BYTECODE_WHITELIST @@ -377,6 +380,37 @@ static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *d #endif /* USE_BYTECODE_WHITELIST */ +static PyObject *bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph) +{ + /* This should never happen, but it's probably better to have None in Python + * than a NULL-wrapping Depsgraph py struct. */ + BLI_assert(depsgraph != NULL); + if (depsgraph == NULL) { + Py_RETURN_NONE; + } + + struct PointerRNA depsgraph_ptr; + RNA_pointer_create(NULL, &RNA_Depsgraph, depsgraph, &depsgraph_ptr); + return pyrna_struct_CreatePyObject(&depsgraph_ptr); +} + +/* Adds a variable 'depsgraph' to the driver variables. This can then be used to obtain evaluated + * datablocks, and the current view layer and scene. See T75553. */ +static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars, + struct Depsgraph *depsgraph) +{ + PyObject *py_depsgraph = bpy_pydriver_depsgraph_as_pyobject(depsgraph); + const char *depsgraph_variable_name = "depsgraph"; + + if (PyDict_SetItemString(driver_vars, depsgraph_variable_name, py_depsgraph) == -1) { + fprintf(stderr, + "\tBPY_driver_eval() - couldn't add variable '%s' to namespace\n", + depsgraph_variable_name); + PyErr_Print(); + PyErr_Clear(); + } +} + /* This evals py driver expressions, 'expr' is a Python expression that * should evaluate to a float number, which is returned. * @@ -396,7 +430,7 @@ static bool bpy_driver_secure_bytecode_validate(PyObject *expr_code, PyObject *d float BPY_driver_exec(struct PathResolvedRNA *anim_rna, ChannelDriver *driver, ChannelDriver *driver_orig, - const float evaltime) + const AnimationEvalContext *anim_eval_context) { PyObject *driver_vars = NULL; PyObject *retval = NULL; @@ -456,7 +490,7 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, } /* update global namespace */ - bpy_pydriver_namespace_update_frame(evaltime); + bpy_pydriver_namespace_update_frame(anim_eval_context->eval_time); if (driver_orig->flag & DRIVER_FLAG_USE_SELF) { bpy_pydriver_namespace_update_self(anim_rna); @@ -589,6 +623,8 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna, } #endif /* USE_BYTECODE_WHITELIST */ + bpy_pydriver_namespace_add_depsgraph(driver_vars, anim_eval_context->depsgraph); + #if 0 /* slow, with this can avoid all Py_CompileString above. */ /* execute expression to get a value */ retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 1c84e95672f..8aba2ae8598 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -36,6 +36,7 @@ #include "ED_keyframing.h" #include "BKE_anim_data.h" +#include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_fcurve.h" #include "BKE_global.h" @@ -332,7 +333,20 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb &options) == -1) { return NULL; } - else if (self->ptr.type == &RNA_NlaStrip) { + + /* This assumes that keyframes are only added on original data & using the active depsgraph. If + * it turns out to be necessary for some reason to insert keyframes on evaluated objects, we can + * revisit this and add an explicit `depsgraph` keyword argument to the function call. + * + * It is unlikely that driver code (which is the reason this depsgraph pointer is obtained) will + * be executed from this function call, as this only happens when `options` has + * `INSERTKEY_DRIVER`, which is not exposed to Python. */ + bContext *C = BPy_GetContext(); + struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, + cfra); + + if (self->ptr.type == &RNA_NlaStrip) { /* Handle special properties for NLA Strips, whose F-Curves are stored on the * strips themselves. These are stored separately or else the properties will * not have any effect. @@ -355,8 +369,8 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb if (prop) { NlaStrip *strip = ptr.data; FCurve *fcu = BKE_fcurve_find(&strip->fcurves, RNA_property_identifier(prop), index); - - result = insert_keyframe_direct(&reports, ptr, prop, fcu, cfra, keytype, NULL, options); + result = insert_keyframe_direct( + &reports, ptr, prop, fcu, &anim_eval_context, keytype, NULL, options); } else { BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full); @@ -384,7 +398,7 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb group_name, path_full, index, - cfra, + &anim_eval_context, keytype, NULL, options) != 0); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index b335862abe0..ade80898131 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2493,7 +2493,9 @@ void RE_RenderAnim(Render *re, { float ctime = BKE_scene_frame_get(scene); AnimData *adt = BKE_animdata_from_id(&scene->id); - BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, ADT_RECALC_ALL, false); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + re->pipeline_depsgraph, ctime); + BKE_animsys_evaluate_animdata(&scene->id, adt, &anim_eval_context, ADT_RECALC_ALL, false); } render_update_depsgraph(re); |