diff options
-rw-r--r-- | source/blender/blenkernel/BKE_fcurve.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 121 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 49 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 18 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 12 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 6 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner.c | 12 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 57 | ||||
-rw-r--r-- | source/blender/makesrna/RNA_access.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_action.c | 81 |
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); } |