diff options
author | Sybren A. Stüvel <sybren> | 2020-07-17 18:38:09 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-07-20 12:51:09 +0300 |
commit | 686ab4c9401a90b22fb17e46c992eb513fe4f693 (patch) | |
tree | c83b4da92fbd12b0c78e2ce5c3041ada23b5ef4b /source/blender/blenkernel/intern/fcurve.c | |
parent | 6fbfa522e66d41839449899ab53dbf20d280d5ec (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/intern/fcurve.c')
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 13 |
1 files changed, 8 insertions, 5 deletions
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; |