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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren>2020-07-17 18:38:09 +0300
committerSybren A. Stüvel <sybren@blender.org>2020-07-20 12:51:09 +0300
commit686ab4c9401a90b22fb17e46c992eb513fe4f693 (patch)
treec83b4da92fbd12b0c78e2ce5c3041ada23b5ef4b /source/blender/blenkernel
parent6fbfa522e66d41839449899ab53dbf20d280d5ec (diff)
T77086 Animation: Passing Dependency Graph to Drivers
Custom driver functions need access to the dependency graph that is triggering the evaluation of the driver. This patch passes the dependency graph pointer through all the animation-related calls. Instead of passing the evaluation time to functions, the code now passes an `AnimationEvalContext` pointer: ``` typedef struct AnimationEvalContext { struct Depsgraph *const depsgraph; const float eval_time; } AnimationEvalContext; ``` These structs are read-only, meaning that the code cannot change the evaluation time. Note that the `depsgraph` pointer itself is const, but it points to a non-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. There are two functions that allow creation of `AnimationEvalContext` objects: - `BKE_animsys_eval_context_construct(Depsgraph *depsgraph, float eval_time)`, which creates a new context object from scratch, and - `BKE_animsys_eval_context_construct_at(AnimationEvalContext *anim_eval_context, float eval_time)`, which can be used to create a `AnimationEvalContext` with the same depsgraph, but at a different time. This makes it possible to later add fields without changing any of the code that just want to change the eval time. This also provides a fix for T75553, although it does require a change to the custom driver function. The driver should call `custom_function(depsgraph)`, and the function should use that depsgraph instead of information from `bpy.context`. Reviewed By: brecht, sergey Differential Revision: https://developer.blender.org/D8047
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_action.h3
-rw-r--r--source/blender/blenkernel/BKE_animsys.h34
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h7
-rw-r--r--source/blender/blenkernel/BKE_fcurve_driver.h3
-rw-r--r--source/blender/blenkernel/intern/action.c12
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c163
-rw-r--r--source/blender/blenkernel/intern/constraint.c9
-rw-r--r--source/blender/blenkernel/intern/fcurve.c13
-rw-r--r--source/blender/blenkernel/intern/fcurve_driver.c14
-rw-r--r--source/blender/blenkernel/intern/object.c17
-rw-r--r--source/blender/blenkernel/intern/particle_system.c4
-rw-r--r--source/blender/blenkernel/intern/seqprefetch.c7
-rw-r--r--source/blender/blenkernel/intern/sequencer.c4
-rw-r--r--source/blender/blenkernel/nla_private.h10
14 files changed, 211 insertions, 89 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,