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:
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h6
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/fcurve.c121
-rw-r--r--source/blender/blenkernel/intern/ipo.c49
-rw-r--r--source/blender/blenloader/intern/readfile.c18
-rw-r--r--source/blender/blenloader/intern/writefile.c12
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c6
-rw-r--r--source/blender/editors/space_outliner/outliner.c12
-rw-r--r--source/blender/makesdna/DNA_anim_types.h57
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_action.c81
11 files changed, 248 insertions, 117 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 63ecc9d548a..f973f86972d 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -6,9 +6,12 @@
#define BKE_FCURVE_H
//struct ListBase;
+
struct FCurve;
struct FModifier;
struct ChannelDriver;
+struct DriverTarget;
+
struct BezTriple;
/* ************** Keyframe Tools ***************** */
@@ -27,6 +30,9 @@ void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt);
void fcurve_free_driver(struct FCurve *fcu);
struct ChannelDriver *fcurve_copy_driver(struct ChannelDriver *driver);
+void driver_free_target(struct ChannelDriver *driver, struct DriverTarget *dtar);
+struct DriverTarget *driver_add_new_target(struct ChannelDriver *driver);
+
/* ************** F-Curve Modifiers *************** */
/* F-Curve Modifier Type-Info (fmi):
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 917fb7d1de4..088fd524b43 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -346,6 +346,7 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node
else if (driver->type == DRIVER_TYPE_ROTDIFF) {
// XXX rotational difference
}
+#if 0 // XXX old animato
else if (driver->id) {
if(GS(driver->id->name)==ID_OB) {
/* normal channel-drives-channel */
@@ -358,6 +359,7 @@ static void dag_add_driver_relation(AnimData *adt, DagForest *dag, DagNode *node
dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB, "Ipo Driver");
}
}
+#endif // XXX old animato
#if 0 // XXX old 'normal' type
else if (icu->driver->ob) {
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 2783c135cb9..5d475767369 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -558,19 +558,60 @@ short test_time_fcurve (FCurve *fcu)
/* Driver API --------------------------------- */
+/* This frees the driver target itself */
+void driver_free_target (ChannelDriver *driver, DriverTarget *dtar)
+{
+ /* sanity checks */
+ if (dtar == NULL)
+ return;
+
+ /* free target vars */
+ if (dtar->rna_path)
+ MEM_freeN(dtar->rna_path);
+
+ /* remove the target from the driver */
+ if (driver)
+ BLI_freelinkN(&driver->targets, dtar);
+ else
+ MEM_freeN(dtar);
+}
+
+/* Add a new driver target variable */
+DriverTarget *driver_add_new_target (ChannelDriver *driver)
+{
+ DriverTarget *dtar;
+
+ /* sanity checks */
+ if (driver == NULL)
+ return NULL;
+
+ /* make a new target */
+ dtar= MEM_callocN(sizeof(DriverTarget), "DriverTarget");
+ BLI_addtail(&driver->targets, dtar);
+
+ /* give the target a name */
+ strcpy(dtar->name, "a"); // XXX fimxe... this needs more work to get unique names without dots...
+
+ /* return the target */
+ return dtar;
+}
+
/* This frees the driver itself */
void fcurve_free_driver(FCurve *fcu)
{
ChannelDriver *driver;
+ DriverTarget *dtar, *dtarn;
/* sanity checks */
if ELEM(NULL, fcu, fcu->driver)
return;
driver= fcu->driver;
- /* free RNA-paths, as these were allocated when getting the path string */
- if (driver->rna_path) MEM_freeN(driver->rna_path);
- if (driver->rna_path2) MEM_freeN(driver->rna_path2);
+ /* free driver targets */
+ for (dtar= driver->targets.first; dtar; dtar= dtarn) {
+ dtarn= dtar->next;
+ driver_free_target(driver, dtar);
+ }
/* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */
MEM_freeN(driver);
@@ -581,6 +622,7 @@ void fcurve_free_driver(FCurve *fcu)
ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
{
ChannelDriver *ndriver;
+ DriverTarget *dtar;
/* sanity checks */
if (driver == NULL)
@@ -588,8 +630,16 @@ ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
/* copy all data */
ndriver= MEM_dupallocN(driver);
- ndriver->rna_path= MEM_dupallocN(ndriver->rna_path);
- ndriver->rna_path2= MEM_dupallocN(ndriver->rna_path2);
+
+ /* copy targets */
+ ndriver->targets.first= ndriver->targets.last= NULL;
+ BLI_duplicatelist(&ndriver->targets, &driver->targets);
+
+ for (dtar= ndriver->targets.first; dtar; dtar= dtar->next) {
+ /* make a copy of target's rna path if available */
+ if (dtar->rna_path)
+ dtar->rna_path = MEM_dupallocN(dtar->rna_path);
+ }
/* return the new driver */
return ndriver;
@@ -597,10 +647,8 @@ ChannelDriver *fcurve_copy_driver (ChannelDriver *driver)
/* Driver Evaluation -------------------------- */
-/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers)
- * - target: used to specify which of the two driver-targets to use
- */
-static float driver_get_driver_value (ChannelDriver *driver, short target)
+/* Helper function to obtain a value using RNA from the specified source (for evaluating drivers) */
+static float driver_get_target_value (ChannelDriver *driver, DriverTarget *dtar)
{
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
@@ -609,21 +657,15 @@ static float driver_get_driver_value (ChannelDriver *driver, short target)
int index;
float value= 0.0f;
- /* get RNA-pointer for the ID-block given in driver */
- if (target == 1) {
- /* second target */
- RNA_id_pointer_create(driver->id2, &id_ptr);
- id= driver->id2;
- path= driver->rna_path2;
- index= driver->array_index2;
- }
- else {
- /* first/main target */
- RNA_id_pointer_create(driver->id, &id_ptr);
- id= driver->id;
- path= driver->rna_path;
- index= driver->array_index;
- }
+ /* sanity check */
+ if ELEM(NULL, driver, dtar)
+ return 0.0f;
+
+ /* get RNA-pointer for the ID-block given in target */
+ RNA_id_pointer_create(dtar->id, &id_ptr);
+ id= dtar->id;
+ path= dtar->rna_path;
+ index= dtar->array_index;
/* error check for missing pointer... */
if (id == NULL) {
@@ -671,14 +713,37 @@ static float driver_get_driver_value (ChannelDriver *driver, short target)
*/
static float evaluate_driver (ChannelDriver *driver, float evaltime)
{
+ DriverTarget *dtar;
+
/* check if driver can be evaluated */
- if (driver->flag & DRIVER_FLAG_DISABLED)
+ if (driver->flag & DRIVER_FLAG_INVALID)
return 0.0f;
+ // TODO: the flags for individual targets need to be used too for more fine-grained support...
switch (driver->type) {
- case DRIVER_TYPE_CHANNEL: /* channel/setting drivers channel/setting */
- return driver_get_driver_value(driver, 0);
-
+ case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
+ {
+ /* check how many targets there are first (i.e. just one?) */
+ if (driver->targets.first == driver->targets.last) {
+ /* just one target, so just use that */
+ dtar= driver->targets.first;
+ return driver_get_target_value(driver, dtar);
+ }
+ else {
+ /* more than one target, so average the values of the targets */
+ int tot = 0;
+ float value = 0.0f;
+
+ /* loop through targets, adding (hopefully we don't get any overflow!) */
+ for (dtar= driver->targets.first; dtar; dtar=dtar->next) {
+ value += driver_get_target_value(driver, dtar);
+ tot++;
+ }
+
+ /* return the average of these */
+ return (value / (float)tot);
+ }
+ }
case DRIVER_TYPE_PYTHON: /* expression */
{
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index b9417ccb467..48ffdca3a83 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -950,6 +950,7 @@ char *get_rna_access (int blocktype, int adrcode, char actname[], char constname
static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
{
ChannelDriver *cdriver;
+ DriverTarget *dtar=NULL, *dtar2=NULL;
/* allocate memory for new driver */
cdriver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
@@ -957,6 +958,7 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
/* if 'pydriver', just copy data across */
if (idriver->type == IPO_DRIVER_TYPE_PYTHON) {
/* PyDriver only requires the expression to be copied */
+ // TODO: but the expression will be useless...
cdriver->type = DRIVER_TYPE_PYTHON;
strcpy(cdriver->expression, idriver->name); // XXX is this safe?
}
@@ -965,12 +967,15 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
if (idriver->blocktype == ID_AR) {
/* ID_PO */
if (idriver->adrcode == OB_ROT_DIFF) {
- if (G.f & G_DEBUG) printf("idriver_to_cdriver - rotdiff %p \n", idriver->ob);
/* Rotational Difference is a special type of driver now... */
cdriver->type= DRIVER_TYPE_ROTDIFF;
+ /* make 2 driver targets */
+ dtar= driver_add_new_target(cdriver);
+ dtar2= driver_add_new_target(cdriver);
+
/* driver must use bones from same armature... */
- cdriver->id= cdriver->id2= (ID *)idriver->ob;
+ dtar->id= dtar2->id= (ID *)idriver->ob;
/* paths for the two targets get the pointers to the relevant Pose-Channels
* - return pointers to Pose-Channels not rotation channels, as calculation code is picky
@@ -979,34 +984,36 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
* - we use several hacks here - blocktype == -1 specifies that no property needs to be found, and
* providing a name for 'actname' will automatically imply Pose-Channel with name 'actname'
*/
- cdriver->rna_path= get_rna_access(-1, -1, idriver->name, NULL, NULL);
- cdriver->rna_path2= get_rna_access(-1, -1, idriver->name+DRIVER_NAME_OFFS, NULL, NULL);
+ dtar->rna_path= get_rna_access(-1, -1, idriver->name, NULL, NULL);
+ dtar2->rna_path= get_rna_access(-1, -1, idriver->name+DRIVER_NAME_OFFS, NULL, NULL);
}
else {
- if (G.f & G_DEBUG) printf("idriver_to_cdriver - arm %p \n", idriver->ob);
/* 'standard' driver */
- cdriver->type= DRIVER_TYPE_CHANNEL;
- cdriver->id= (ID *)idriver->ob;
+ cdriver->type= DRIVER_TYPE_AVERAGE;
+
+ /* make 1 driver target */
+ dtar= driver_add_new_target(cdriver);
+ dtar->id= (ID *)idriver->ob;
switch (idriver->adrcode) {
case OB_LOC_X: /* x,y,z location are quite straightforward */
- cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_X, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_LOC_X, idriver->name, NULL, &dtar->array_index);
break;
case OB_LOC_Y:
- cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_Y, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_LOC_Y, idriver->name, NULL, &dtar->array_index);
break;
case OB_LOC_Z:
- cdriver->rna_path= get_rna_access(ID_PO, AC_LOC_Z, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_LOC_Z, idriver->name, NULL, &dtar->array_index);
break;
case OB_SIZE_X: /* x,y,z scaling are also quite straightforward */
- cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_X, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_X, idriver->name, NULL, &dtar->array_index);
break;
case OB_SIZE_Y:
- cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_Y, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_Y, idriver->name, NULL, &dtar->array_index);
break;
case OB_SIZE_Z:
- cdriver->rna_path= get_rna_access(ID_PO, AC_SIZE_Z, idriver->name, NULL, &cdriver->array_index);
+ dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_Z, idriver->name, NULL, &dtar->array_index);
break;
case OB_ROT_X: /* rotation - we need to be careful with this... XXX (another reason why we need eulers) */
@@ -1015,8 +1022,8 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
{
// XXX this is not yet a 1:1 map, since we'd need euler rotations to make this work nicely (unless we make some hacks)
// XXX -1 here is a special hack...
- cdriver->rna_path= get_rna_access(ID_PO, -1, idriver->name, NULL, NULL);
- cdriver->array_index= idriver->adrcode - OB_ROT_X;
+ dtar->rna_path= get_rna_access(ID_PO, -1, idriver->name, NULL, NULL);
+ dtar->array_index= idriver->adrcode - OB_ROT_X;
}
break;
}
@@ -1024,14 +1031,16 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver)
}
else {
/* ID_OB */
- if (G.f & G_DEBUG) printf("idriver_to_cdriver - ob %p \n", idriver->ob);
- cdriver->type= DRIVER_TYPE_CHANNEL;
- cdriver->id= (ID *)idriver->ob;
- cdriver->rna_path= get_rna_access(ID_OB, idriver->adrcode, NULL, NULL, &cdriver->array_index);
+ cdriver->type= DRIVER_TYPE_AVERAGE;
+
+ /* make 1 driver target */
+ dtar= driver_add_new_target(cdriver);
+
+ dtar->id= (ID *)idriver->ob;
+ dtar->rna_path= get_rna_access(ID_OB, idriver->adrcode, NULL, NULL, &dtar->array_index);
}
}
- if (G.f & G_DEBUG) printf("\tcdriver -> id = %p \n", cdriver->id);
/* free old driver */
MEM_freeN(idriver);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6508bed7437..8ea1c4a08f4 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1667,8 +1667,10 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
/* driver data */
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
- driver->id= newlibadr(fd, id->lib, driver->id);
- driver->id2= newlibadr(fd, id->lib, driver->id2);
+ DriverTarget *dtar;
+
+ for (dtar= driver->targets.first; dtar; dtar= dtar->next)
+ dtar->id= newlibadr(fd, id->lib, dtar->id);
}
/* modifiers */
@@ -1708,9 +1710,12 @@ static void direct_link_fcurves(FileData *fd, ListBase *list)
fcu->driver= newdataadr(fd, fcu->driver);
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
+ DriverTarget *dtar;
- driver->rna_path= newdataadr(fd, driver->rna_path);
- driver->rna_path2= newdataadr(fd, driver->rna_path2);
+ /* relink targets and their paths */
+ link_list(fd, &driver->targets);
+ for (dtar= driver->targets.first; dtar; dtar= dtar->next)
+ dtar->rna_path= newdataadr(fd, dtar->rna_path);
}
/* modifiers */
@@ -9193,9 +9198,10 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt)
/* drivers - assume that these F-Curves have driver data to be in this list... */
for (fcd= adt->drivers.first; fcd; fcd= fcd->next) {
ChannelDriver *driver= fcd->driver;
+ DriverTarget *dtar;
- expand_doit(fd, mainvar, driver->id);
- expand_doit(fd, mainvar, driver->id2);
+ for (dtar= driver->targets.first; dtar; dtar= dtar->next)
+ expand_doit(fd, mainvar, dtar->id);
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 076edcd59d6..10f88e4d291 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -781,13 +781,17 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
/* driver data */
if (fcu->driver) {
ChannelDriver *driver= fcu->driver;
+ DriverTarget *dtar;
writestruct(wd, DATA, "ChannelDriver", 1, driver);
- if (driver->rna_path)
- writedata(wd, DATA, strlen(driver->rna_path)+1, driver->rna_path);
- if (driver->rna_path2)
- writedata(wd, DATA, strlen(driver->rna_path2)+1, driver->rna_path2);
+ /* targets */
+ for (dtar= driver->targets.first; dtar; dtar= dtar->next) {
+ writestruct(wd, DATA, "DriverTarget", 1, dtar);
+
+ if (dtar->rna_path)
+ writedata(wd, DATA, strlen(dtar->rna_path)+1, dtar->rna_path);
+ }
}
/* Modifiers */
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index a54147f91e2..7a94614607d 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -157,6 +157,8 @@ static void do_graph_region_driver_buttons(bContext *C, void *arg, int event)
//WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
}
+#if 0
+
/* callback to copy over RNA-Paths accordingly */
static void driver_rnapath_copy_cb (bContext *C, void *driver_v, void *strbuf_v)
{
@@ -194,6 +196,8 @@ static void driver_update_flags_cb (bContext *C, void *fcu_v, void *dummy_v)
driver->flag &= ~DRIVER_FLAG_INVALID;
}
+#endif
+
static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAnimListElem *ale)
{
FCurve *fcu= (FCurve *)ale->data;
@@ -208,6 +212,7 @@ static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAn
/* to force height */
uiNewPanelHeight(block, 204);
+#if 0
/* general actions */
but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Update Dependencies", 10, 200, 180, 22, NULL, 0.0, 0.0, 0, 0, "Force updates of dependencies");
uiButSetFunc(but, driver_update_flags_cb, fcu, NULL);
@@ -267,6 +272,7 @@ static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAn
30,70,230,19, NULL, 0, 0, 0, 0, "");
}
}
+#endif
}
/* ******************* f-modifiers ******************************** */
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index a3fd16940ae..6bd1e915b2b 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -929,14 +929,18 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
TreeElement *ted= outliner_add_element(soops, &te->subtree, adt, te, TSE_DRIVER_BASE, 0);
ID *lastadded= NULL;
FCurve *fcu;
+ DriverTarget *dtar;
ted->name= "Drivers";
for (fcu= adt->drivers.first; fcu; fcu= fcu->next) {
- if (fcu->driver && fcu->driver->id) {
- if (lastadded != fcu->driver->id) {
- outliner_add_element(soops, &ted->subtree, fcu->driver->id, ted, TSE_LINKED_OB, 0);
- lastadded= fcu->driver->id;
+ if (fcu->driver && fcu->driver->targets.first) {
+ for (dtar= fcu->driver->targets.first; dtar; dtar= dtar->next) {
+ if (lastadded != dtar->id) {
+ // XXX this lastadded check is rather lame, and also fails quite badly...
+ outliner_add_element(soops, &ted->subtree, dtar->id, ted, TSE_LINKED_OB, 0);
+ lastadded= dtar->id;
+ }
}
}
}
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 0c04d046fda..e63c30faed0 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -168,6 +168,25 @@ enum {
/* Drivers -------------------------------------- */
+/* Driver Target
+ *
+ * A 'variable' for use as a target of the driver/expression.
+ * Defines a way of accessing some channel to use, that can be
+ * referred to in the expression as a variable, thus simplifying
+ * expressions and also Depsgraph building.
+ */
+typedef struct DriverTarget {
+ struct DriverTarget *next, *prev;
+
+ ID *id; /* ID-block which owns the target */
+ char *rna_path; /* target channel to use as driver value */
+ int array_index; /* if applicable, the index of the RNA-array item to use as driver */
+
+ int flags; /* flags for the validity of the target */
+
+ char name[64]; /* name of the variable */
+} DriverTarget;
+
/* Channel Driver (i.e. Drivers / Expressions) (driver)
*
* Channel Drivers are part of the dependency system, and are executed in addition to
@@ -180,34 +199,26 @@ enum {
* evaluated in. This order is set by the Depsgraph's sorting stuff.
*/
typedef struct ChannelDriver {
- /* primary target */
- ID *id; /* ID-block which owns the target */
- char *rna_path; /* target channel to use as driver value */
- int array_index; /* if applicable, the index of the RNA-array item to use as driver */
+ ListBase targets; /* targets for this driver (i.e. list of DriverTarget) */
+
+ /* python expression to execute (may call functions defined in an accessory file)
+ * which relates the target 'variables' in some way to yield a single usable value
+ */
+ char expression[256];
- /* value cache (placed here for alignment reasons) */
float curval; /* result of previous evaluation, for subtraction from result under certain circumstances */
+ float influence; /* influence of driver on result */ // XXX to be implemented... this is like the constraint influence setting
- /* secondary target (for rotational difference) */
- ID *id2; /* ID-block which owns the second target */
- char *rna_path2; /* second target channel to use as driver value */
- int array_index2; /* if applicable, the index of the RNA-array item to use as driver */
-
- /* general settings (placed here for alignment reasons) */
+ /* general settings */
int type; /* type of driver */
int flag; /* settings of driver */
-
- float influence; /* influence of driver on result */ // XXX to be implemented... this is like the constraint influence setting
-
- /* settings for Python Drivers (PyDrivers) */
- char expression[256]; /* python expression to execute (may call functions defined in an accessory file) */
} ChannelDriver;
/* driver type */
enum {
- /* channel drives channel */
- DRIVER_TYPE_CHANNEL = 0,
- /* py-expression used as driver */
+ /* target values are averaged together */
+ DRIVER_TYPE_AVERAGE = 0,
+ /* python expression/function relates targets */
DRIVER_TYPE_PYTHON,
/* rotational difference (must use rotation channels only) */
DRIVER_TYPE_ROTDIFF,
@@ -217,13 +228,11 @@ enum {
enum {
/* driver has invalid settings (internal flag) */
DRIVER_FLAG_INVALID = (1<<0),
- /* driver was disabled temporarily, so shouldn't be evaluated (set by user) */
- DRIVER_FLAG_DISABLED = (1<<1),
/* driver needs recalculation (set by depsgraph) */
- DRIVER_FLAG_RECALC = (1<<2),
+ DRIVER_FLAG_RECALC = (1<<1),
/* driver does replace value, but overrides (for layering of animation over driver) */
- // TODO: is this necessary?
- DRIVER_FLAG_LAYERING = (1<<3),
+ // TODO: this needs to be implemented at some stage or left out...
+ DRIVER_FLAG_LAYERING = (1<<2),
} eDriver_Flags;
/* F-Curves -------------------------------------- */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f6ec657b36f..b29170c435e 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -93,6 +93,7 @@ extern StructRNA RNA_DisplaceModifier;
extern StructRNA RNA_DistortedNoiseTexture;
extern StructRNA RNA_DomainFluidSettings;
extern StructRNA RNA_Driver;
+extern StructRNA RNA_DriverTarget;
extern StructRNA RNA_EdgeSplitModifier;
extern StructRNA RNA_EffectSequence;
extern StructRNA RNA_EnumProperty;
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index a73f9627121..4c8d0c88866 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Contributor(s): Blender Foundation (2008), Roland Hess
+ * Contributor(s): Blender Foundation (2008), Roland Hess, Joshua Leung
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -37,38 +37,38 @@
#ifdef RNA_RUNTIME
-static void rna_Driver_RnaPath_get(PointerRNA *ptr, char *value)
+static void rna_DriverTarget_RnaPath_get(PointerRNA *ptr, char *value)
{
- ChannelDriver *driver= (ChannelDriver *)ptr->data;
+ DriverTarget *dtar= (DriverTarget *)ptr->data;
- if (driver->rna_path)
- strcpy(value, driver->rna_path);
+ if (dtar->rna_path)
+ strcpy(value, dtar->rna_path);
else
strcpy(value, "");
}
-static int rna_Driver_RnaPath_length(PointerRNA *ptr)
+static int rna_DriverTarget_RnaPath_length(PointerRNA *ptr)
{
- ChannelDriver *driver= (ChannelDriver *)ptr->data;
+ DriverTarget *dtar= (DriverTarget *)ptr->data;
- if (driver->rna_path)
- return strlen(driver->rna_path);
+ if (dtar->rna_path)
+ return strlen(dtar->rna_path);
else
return 0;
}
-static void rna_Driver_RnaPath_set(PointerRNA *ptr, const char *value)
+static void rna_DriverTarget_RnaPath_set(PointerRNA *ptr, const char *value)
{
- ChannelDriver *driver= (ChannelDriver *)ptr->data;
+ DriverTarget *dtar= (DriverTarget *)ptr->data;
// XXX in this case we need to be very careful, as this will require some new dependencies to be added!
- if (driver->rna_path)
- MEM_freeN(driver->rna_path);
+ if (dtar->rna_path)
+ MEM_freeN(dtar->rna_path);
if (strlen(value))
- driver->rna_path= BLI_strdup(value);
+ dtar->rna_path= BLI_strdup(value);
else
- driver->rna_path= NULL;
+ dtar->rna_path= NULL;
}
@@ -108,13 +108,39 @@ static void rna_FCurve_RnaPath_set(PointerRNA *ptr, const char *value)
#else
// XXX maybe this should be in a separate file?
+void rna_def_drivertarget(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "DriverTarget", NULL);
+ RNA_def_struct_ui_text(srna, "Driver Target", "Variable from some source/target for driver relationship");
+
+ /* Variable Name */
+ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions.");
+
+ /* Target Properties */
+ prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_ui_text(prop, "Object", "Object the specific property used can be found from");
+
+ prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length", "rna_DriverTarget_RnaPath_set");
+ RNA_def_property_ui_text(prop, "RNA Path", "RNA Path (from Object) to property used");
+
+ prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
+ RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific property used (if applicable)");
+}
+
+// XXX maybe this should be in a separate file?
void rna_def_channeldriver(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem prop_type_items[] = {
- {DRIVER_TYPE_CHANNEL, "NORMAL", "Normal", ""},
+ {DRIVER_TYPE_AVERAGE, "AVERAGE", "Averaged Value", ""},
{DRIVER_TYPE_PYTHON, "SCRIPTED", "Scripted Expression", ""},
{DRIVER_TYPE_ROTDIFF, "ROTDIFF", "Rotational Difference", ""},
{0, NULL, NULL, NULL}};
@@ -131,17 +157,11 @@ void rna_def_channeldriver(BlenderRNA *brna)
prop= RNA_def_property(srna, "expression", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Expression", "Expression to use for Scripted Expression.");
- /* Pointers */
- prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "id");
- RNA_def_property_ui_text(prop, "Driver Object", "Object that controls this Driver.");
-
- prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
- RNA_def_property_string_funcs(prop, "rna_Driver_RnaPath_get", "rna_Driver_RnaPath_length", "rna_Driver_RnaPath_set");
- RNA_def_property_ui_text(prop, "Driver RNA Path", "RNA Path (from Driver Object) to property used as Driver.");
-
- prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
- RNA_def_property_ui_text(prop, "Driver RNA Array Index", "Index to the specific property used as Driver if applicable.");
+ /* Collections */
+ prop= RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "targets", NULL);
+ RNA_def_property_struct_type(prop, "DriverTarget");
+ RNA_def_property_ui_text(prop, "Target Variables", "Properties acting as targets for this driver.");
}
// XXX maybe this should be in a separate file?
@@ -171,17 +191,15 @@ void rna_def_fcurve(BlenderRNA *brna)
/* Pointers */
prop= RNA_def_property(srna, "driver", PROP_POINTER, PROP_NONE);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE); // xxx?
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Driver", "Channel Driver (only set for Driver F-Curves)");
/* Path + Array Index */
prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
- //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable
RNA_def_property_string_funcs(prop, "rna_FCurve_RnaPath_get", "rna_FCurve_RnaPath_length", "rna_FCurve_RnaPath_set");
RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property affected by F-Curve.");
prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
- //RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now editable
RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific property affected by F-Curve if applicable.");
/* Color */
@@ -196,7 +214,7 @@ void rna_def_fcurve(BlenderRNA *brna)
/* Collections */
prop= RNA_def_property(srna, "sampled_points", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "fpt", "totvert");
- RNA_def_property_struct_type(prop, "CurvePoint");
+ RNA_def_property_struct_type(prop, "CurvePoint"); // XXX FPoints not BPoints here! FPoints are much smaller!
RNA_def_property_ui_text(prop, "Sampled Points", "Sampled animation data");
prop= RNA_def_property(srna, "keyframe_points", PROP_COLLECTION, PROP_NONE);
@@ -281,6 +299,7 @@ void RNA_def_action(BlenderRNA *brna)
// should these be in their own file, or is that overkill?
rna_def_fcurve(brna);
+ rna_def_drivertarget(brna);
rna_def_channeldriver(brna);
}