2020-05-01 12:43:12 +02:00
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
* \ingroup bke
|
|
|
|
*/
|
|
|
|
|
2020-05-08 18:16:39 +02:00
|
|
|
#include "DNA_curve_types.h"
|
|
|
|
|
2020-05-01 12:43:12 +02:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
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
2020-07-17 17:38:09 +02:00
|
|
|
struct AnimationEvalContext;
|
2020-05-01 12:43:12 +02:00
|
|
|
struct ChannelDriver;
|
|
|
|
struct DriverTarget;
|
|
|
|
struct DriverVar;
|
|
|
|
struct FCurve;
|
|
|
|
struct PathResolvedRNA;
|
|
|
|
struct PointerRNA;
|
|
|
|
struct PropertyRNA;
|
|
|
|
|
|
|
|
/* ************** F-Curve Drivers ***************** */
|
|
|
|
|
|
|
|
/* With these iterators for convenience, the variables "tarIndex" and "dtar" can be
|
|
|
|
* accessed directly from the code using them, but it is not recommended that their
|
|
|
|
* values be changed to point at other slots...
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* convenience looper over ALL driver targets for a given variable (even the unused ones) */
|
|
|
|
#define DRIVER_TARGETS_LOOPER_BEGIN(dvar) \
|
|
|
|
{ \
|
|
|
|
DriverTarget *dtar = &dvar->targets[0]; \
|
|
|
|
int tarIndex = 0; \
|
|
|
|
for (; tarIndex < MAX_DRIVER_TARGETS; tarIndex++, dtar++)
|
|
|
|
|
|
|
|
/* convenience looper over USED driver targets only */
|
|
|
|
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar) \
|
|
|
|
{ \
|
|
|
|
DriverTarget *dtar = &dvar->targets[0]; \
|
|
|
|
int tarIndex = 0; \
|
|
|
|
for (; tarIndex < dvar->num_targets; tarIndex++, dtar++)
|
|
|
|
|
|
|
|
/* tidy up for driver targets loopers */
|
|
|
|
#define DRIVER_TARGETS_LOOPER_END \
|
|
|
|
} \
|
|
|
|
((void)0)
|
|
|
|
|
|
|
|
/* ---------------------- */
|
|
|
|
|
|
|
|
void fcurve_free_driver(struct FCurve *fcu);
|
|
|
|
struct ChannelDriver *fcurve_copy_driver(const struct ChannelDriver *driver);
|
|
|
|
|
|
|
|
void driver_variables_copy(struct ListBase *dst_vars, const struct ListBase *src_vars);
|
|
|
|
|
|
|
|
void BKE_driver_target_matrix_to_rot_channels(
|
|
|
|
float mat[4][4], int auto_order, int rotation_mode, int channel, bool angles, float r_buf[4]);
|
|
|
|
|
|
|
|
void driver_free_variable(struct ListBase *variables, struct DriverVar *dvar);
|
|
|
|
void driver_free_variable_ex(struct ChannelDriver *driver, struct DriverVar *dvar);
|
|
|
|
|
|
|
|
void driver_change_variable_type(struct DriverVar *dvar, int type);
|
|
|
|
void driver_variable_name_validate(struct DriverVar *dvar);
|
|
|
|
struct DriverVar *driver_add_new_variable(struct ChannelDriver *driver);
|
|
|
|
|
|
|
|
float driver_get_variable_value(struct ChannelDriver *driver, struct DriverVar *dvar);
|
|
|
|
bool driver_get_variable_property(struct ChannelDriver *driver,
|
|
|
|
struct DriverTarget *dtar,
|
|
|
|
struct PointerRNA *r_ptr,
|
|
|
|
struct PropertyRNA **r_prop,
|
|
|
|
int *r_index);
|
|
|
|
|
|
|
|
bool BKE_driver_has_simple_expression(struct ChannelDriver *driver);
|
|
|
|
bool BKE_driver_expression_depends_on_time(struct ChannelDriver *driver);
|
|
|
|
void BKE_driver_invalidate_expression(struct ChannelDriver *driver,
|
|
|
|
bool expr_changed,
|
|
|
|
bool varname_changed);
|
|
|
|
|
|
|
|
float evaluate_driver(struct PathResolvedRNA *anim_rna,
|
|
|
|
struct ChannelDriver *driver,
|
|
|
|
struct ChannelDriver *driver_orig,
|
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
2020-07-17 17:38:09 +02:00
|
|
|
const struct AnimationEvalContext *anim_eval_context);
|
2020-05-01 12:43:12 +02:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|