diff options
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 98 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 166 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 40 | ||||
-rw-r--r-- | source/blender/editors/space_sequencer/sequencer_edit.c | 49 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 32 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_fcurve.c | 28 |
7 files changed, 270 insertions, 159 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 4c63c64ccb9..8b86f6a5d1f 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -329,20 +329,20 @@ static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName, /* driver variables */ for (dvar= driver->variables.first; dvar; dvar=dvar->next) { - /* all targets (even unused ones) */ - // XXX maybe we only need to modify the used ones, since the others can be manually fixed anyways - DRIVER_TARGETS_LOOPER(dvar) + /* only change the used targets, since the others will need fixing manually anyway */ + DRIVER_TARGETS_USED_LOOPER(dvar) { /* rename RNA path */ if (dtar->rna_path) dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldName, newName, dtar->rna_path); /* also fix the bone-name (if applicable) */ - if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB)) && - (dtar->pchan_name[0]) && (strcmp(oldName, dtar->pchan_name)==0) ) - { - BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name)); - } + // XXX this has been disabled because the old/new names have padding which means this check will fail + //if ( ((dtar->id) && (GS(dtar->id->name) == ID_OB)) && + // (dtar->pchan_name[0]) && (strcmp(oldName, dtar->pchan_name)==0) ) + //{ + // BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name)); + //} } DRIVER_TARGETS_LOOPER_END } diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 9e84727fbf1..67bee90e91c 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -54,6 +54,7 @@ #include "BKE_curve.h" #include "BKE_global.h" #include "BKE_idprop.h" +#include "BKE_object.h" #include "BKE_utildefines.h" #include "RNA_access.h" @@ -922,13 +923,27 @@ static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar) /* check if object or bone */ if (pchan) { - /* bone - need to convert to worldspace */ - VECCOPY(tmp_loc, pchan->pose_head); - mul_m4_v3(ob->obmat, tmp_loc); + /* bone */ + if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) { + /* convert to worldspace */ + VECCOPY(tmp_loc, pchan->pose_head); + mul_m4_v3(ob->obmat, tmp_loc); + } + else { + /* local (use transform values directly) */ + VECCOPY(tmp_loc, pchan->loc); + } } else { - /* object, already in worldspace */ - VECCOPY(tmp_loc, ob->obmat[3]); + /* object */ + if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) { + /* worldspace */ + VECCOPY(tmp_loc, ob->obmat[3]); + } + else { + /* local (use transform values directly) */ + VECCOPY(tmp_loc, ob->loc); + } } /* copy the location to the right place */ @@ -948,6 +963,70 @@ static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar) return len_v3v3(loc1, loc2); } +/* evaluate 'transform channel' driver variable */ +static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar) +{ + DriverTarget *dtar= &dvar->targets[0]; + Object *ob= (Object *)dtar->id; + bPoseChannel *pchan; + float mat[4][4]; + short rotOrder = 0; + + /* check if this target has valid data */ + if ((ob == NULL) || (GS(dtar->id->name) != ID_OB)) { + /* invalid target, so will not have enough targets */ + driver->flag |= DRIVER_FLAG_INVALID; + return 0.0f; + } + + /* try to get posechannel */ + pchan= get_pose_channel(ob->pose, dtar->pchan_name); + + /* check if object or bone, and get transform matrix accordingly */ + if (pchan) { + /* bone */ + rotOrder= (pchan->rotmode > 0) ? pchan->rotmode : ROT_MODE_EUL; + + if (dtar->flag & DTAR_FLAG_LOCALSPACE) + copy_m4_m4(mat, pchan->chan_mat); + else + mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat); + } + else { + /* object */ + rotOrder= (ob->rotmode > 0) ? ob->rotmode : ROT_MODE_EUL; + + if (dtar->flag & DTAR_FLAG_LOCALSPACE) + object_to_mat4(ob, mat); + else + copy_m4_m4(mat, ob->obmat); + } + + /* check which transform */ + if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) { + /* not valid channel */ + return 0.0f; + } + else if (dtar->transChan >= DTAR_TRANSCHAN_SCALEX) { + /* extract scale, and choose the right axis */ + float scale[3]; + + mat4_to_size(scale, mat); + return scale[dtar->transChan - DTAR_TRANSCHAN_SCALEX]; + } + else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) { + /* extract euler rotation, and choose the right axis */ + float eul[3]; + + mat4_to_eulO(eul, rotOrder, mat); + return eul[dtar->transChan - DTAR_TRANSCHAN_ROTX]; + } + else { + /* extract location and choose right axis */ + return mat[3][dtar->transChan]; + } +} + /* ......... */ /* Table of Driver Varaiable Type Info Data */ @@ -971,7 +1050,14 @@ DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = { 2, /* number of targets used */ {"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */ {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY, DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */ - END_DVAR_TYPEDEF + END_DVAR_TYPEDEF, + + BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) + dvar_eval_transChan, /* eval callback */ + 1, /* number of targets used */ + {"Object/Bone"}, /* UI names for targets */ + {DTAR_FLAG_STRUCT_REF|DTAR_FLAG_ID_OB_ONLY} /* flags */ + END_DVAR_TYPEDEF, }; /* Get driver variable typeinfo */ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 988bd429185..feb7fc3e382 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -295,10 +295,7 @@ static char *pchan_adrcodes_to_paths (int adrcode, int *array_index) *array_index= 1; return "rotation_euler"; case AC_EUL_Z: *array_index= 2; return "rotation_euler"; - - case -1: /* special case for euler-rotations used by old drivers */ - *array_index= 0; return "rotation_euler"; - + case AC_LOC_X: *array_index= 0; return "location"; case AC_LOC_Y: @@ -944,14 +941,17 @@ static char *get_rna_access (int blocktype, int adrcode, char actname[], char co strcpy(buf, ""); /* empty string */ BLI_dynstr_append(path, buf); - /* append property to path (only if applicable) */ - if (blocktype > 0) { - /* need to add dot before property if there was anything precceding this */ - if (buf[0]) - BLI_dynstr_append(path, "."); - - /* now write name of property */ - BLI_dynstr_append(path, propname); + /* need to add dot before property if there was anything precceding this */ + if (buf[0]) + BLI_dynstr_append(path, "."); + + /* now write name of property */ + BLI_dynstr_append(path, propname); + + /* if there was no array index pointer provided, add it to the path */ + if (array_index == NULL) { + sprintf(buf, "[\"%d\"]", dummy_index); + BLI_dynstr_append(path, buf); } /* convert to normal MEM_malloc'd string */ @@ -965,6 +965,36 @@ static char *get_rna_access (int blocktype, int adrcode, char actname[], char co /* *************************************************** */ /* Conversion Utilities */ +/* Convert adrcodes to driver target transform channel types */ +static short adrcode_to_dtar_transchan (short adrcode) +{ + switch (adrcode) { + case OB_LOC_X: + return DTAR_TRANSCHAN_LOCX; + case OB_LOC_Y: + return DTAR_TRANSCHAN_LOCY; + case OB_LOC_Z: + return DTAR_TRANSCHAN_LOCZ; + + case OB_ROT_X: + return DTAR_TRANSCHAN_ROTX; + case OB_ROT_Y: + return DTAR_TRANSCHAN_ROTY; + case OB_ROT_Z: + return DTAR_TRANSCHAN_ROTZ; + + case OB_SIZE_X: + return DTAR_TRANSCHAN_SCALEX; + case OB_SIZE_Y: + return DTAR_TRANSCHAN_SCALEX; + case OB_SIZE_Z: + return DTAR_TRANSCHAN_SCALEX; + + default: + return 0; + } +} + /* Convert IpoDriver to ChannelDriver - will free the old data (i.e. the old driver) */ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver) { @@ -976,91 +1006,61 @@ 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... + // FIXME: expression will be useless due to API changes, but at least not totally lost cdriver->type = DRIVER_TYPE_PYTHON; - strcpy(cdriver->expression, idriver->name); // XXX is this safe? + if (idriver->name[0]) + BLI_strncpy(cdriver->expression, idriver->name, sizeof(cdriver->expression)); } -#if 0 // XXX needs changes for the new system else { - DriverTarget *dtar=NULL, *dtar2=NULL; + DriverVar *dvar = NULL; + DriverTarget *dtar = NULL; - /* what to store depends on the 'blocktype' (ID_OB or ID_PO - object or posechannel) */ - if (idriver->blocktype == ID_AR) { - /* ID_PO */ + /* this should be ok for all types here... */ + cdriver->type= DRIVER_TYPE_AVERAGE; + + /* what to store depends on the 'blocktype' - object or posechannel */ + if (idriver->blocktype == ID_AR) { /* PoseChannel */ if (idriver->adrcode == OB_ROT_DIFF) { - /* 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); + /* Rotational Difference requires a special type of variable */ + dvar= driver_add_new_variable(cdriver); + driver_change_variable_type(dvar, DVAR_TYPE_ROT_DIFF); - /* driver must use bones from same armature... */ - dtar->id= dtar2->id= (ID *)idriver->ob; + /* first bone target */ + dtar= &dvar->targets[0]; + dtar->id= (ID *)idriver->ob; + if (idriver->name[0]) + BLI_strncpy(dtar->pchan_name, idriver->name, 32); - /* 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 - * - old bone names were stored in same var, in idriver->name - * - * - 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' - */ - 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); + /* second bone target (name was stored in same var as the first one) */ + dtar= &dvar->targets[1]; + dtar->id= (ID *)idriver->ob; + if (idriver->name[0]) // xxx... for safety + BLI_strncpy(dtar->pchan_name, idriver->name+DRIVER_NAME_OFFS, 32); } else { - /* 'standard' driver */ - cdriver->type= DRIVER_TYPE_AVERAGE; + /* only a single variable, of type 'transform channel' */ + dvar= driver_add_new_variable(cdriver); + driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN); - /* make 1 driver target */ - dtar= driver_add_new_target(cdriver); + /* only requires a single target */ + dtar= &dvar->targets[0]; dtar->id= (ID *)idriver->ob; - - switch (idriver->adrcode) { - case OB_LOC_X: /* x,y,z location are quite straightforward */ - dtar->rna_path= get_rna_access(ID_PO, AC_LOC_X, idriver->name, NULL, &dtar->array_index); - break; - case OB_LOC_Y: - dtar->rna_path= get_rna_access(ID_PO, AC_LOC_Y, idriver->name, NULL, &dtar->array_index); - break; - case OB_LOC_Z: - 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 */ - dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_X, idriver->name, NULL, &dtar->array_index); - break; - case OB_SIZE_Y: - dtar->rna_path= get_rna_access(ID_PO, AC_SIZE_Y, idriver->name, NULL, &dtar->array_index); - break; - case OB_SIZE_Z: - 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... */ - case OB_ROT_Y: - case OB_ROT_Z: - { - /* -1 here, not rotation code, since old system didn't have eulers */ - dtar->rna_path= get_rna_access(ID_PO, -1, idriver->name, NULL, NULL); - dtar->array_index= idriver->adrcode - OB_ROT_X; - } - break; - } + if (idriver->name[0]) + BLI_strncpy(dtar->pchan_name, idriver->name, 32); + dtar->transChan= adrcode_to_dtar_transchan(idriver->adrcode); } } - else { - /* ID_OB */ - cdriver->type= DRIVER_TYPE_AVERAGE; - - /* make 1 driver target */ - dtar= driver_add_new_target(cdriver); + else { /* Object */ + /* only a single variable, of type 'transform channel' */ + dvar= driver_add_new_variable(cdriver); + driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN); + /* only requires single target */ + dtar= &dvar->targets[0]; dtar->id= (ID *)idriver->ob; - dtar->rna_path= get_rna_access(ID_OB, idriver->adrcode, NULL, NULL, &dtar->array_index); + dtar->transChan= adrcode_to_dtar_transchan(idriver->adrcode); } } -#endif // XXX fixme /* return the new one */ return cdriver; @@ -1295,11 +1295,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha DriverVar *dvar= fcu->driver->variables.first; DriverTarget *dtar= &dvar->targets[0]; - /* since drivers could only be for objects, we should just check for 'rotation' being - * in the name of the path given - * - WARNING: this will break if we encounter a bone or object explictly named in that way... - */ - if ((dtar && dtar->rna_path) && strstr(dtar->rna_path, "rotation")) { + if (ELEM3(dtar->transChan, DTAR_TRANSCHAN_ROTX, DTAR_TRANSCHAN_ROTY, DTAR_TRANSCHAN_ROTZ)) { const float fac= (float)M_PI / 180.0f; dst->vec[0][0] *= fac; diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index c42dfd0015d..c7c58689a5f 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -352,7 +352,7 @@ static void graph_panel_driverVar__rotDiff(const bContext *C, uiLayout *layout, if (dtar->id && ob1->pose) { PointerRNA tar_ptr; - RNA_pointer_create(dtar2->id, &RNA_Pose, ob1->pose, &tar_ptr); + RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr); uiItemPointerR(col, "", ICON_BONE_DATA, &dtar_ptr, "bone_target", &tar_ptr, "bones"); } @@ -367,7 +367,7 @@ static void graph_panel_driverVar__rotDiff(const bContext *C, uiLayout *layout, } } -/* settings for 'rotation difference' driver variable type */ +/* settings for 'location difference' driver variable type */ static void graph_panel_driverVar__locDiff(const bContext *C, uiLayout *layout, ID *id, DriverVar *dvar) { DriverTarget *dtar= &dvar->targets[0]; @@ -388,9 +388,11 @@ static void graph_panel_driverVar__locDiff(const bContext *C, uiLayout *layout, if (dtar->id && ob1->pose) { PointerRNA tar_ptr; - RNA_pointer_create(dtar2->id, &RNA_Pose, ob1->pose, &tar_ptr); + RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr); uiItemPointerR(col, "", ICON_BONE_DATA, &dtar_ptr, "bone_target", &tar_ptr, "bones"); } + + uiItemR(col, NULL, 0, &dtar_ptr, "use_local_space_transforms", 0); col= uiLayoutColumn(layout, 1); uiTemplateAnyID(col, (bContext *)C, &dtar2_ptr, "id", "id_type", "Ob/Bone 2:"); @@ -401,6 +403,35 @@ static void graph_panel_driverVar__locDiff(const bContext *C, uiLayout *layout, RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr); uiItemPointerR(col, "", ICON_BONE_DATA, &dtar2_ptr, "bone_target", &tar_ptr, "bones"); } + + uiItemR(col, NULL, 0, &dtar2_ptr, "use_local_space_transforms", 0); +} + +/* settings for 'transform channel' driver variable type */ +static void graph_panel_driverVar__transChan(const bContext *C, uiLayout *layout, ID *id, DriverVar *dvar) +{ + DriverTarget *dtar= &dvar->targets[0]; + Object *ob = (Object *)dtar->id; + PointerRNA dtar_ptr; + uiLayout *col, *row; + + /* initialise RNA pointer to the target */ + RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr); + + /* properties */ + col= uiLayoutColumn(layout, 1); + uiTemplateAnyID(col, (bContext *)C, &dtar_ptr, "id", "id_type", "Ob/Bone:"); + + if (dtar->id && ob->pose) { + PointerRNA tar_ptr; + + RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr); + uiItemPointerR(col, "", ICON_BONE_DATA, &dtar_ptr, "bone_target", &tar_ptr, "bones"); + } + + row= uiLayoutRow(layout, 1); + uiItemR(row, NULL, 0, &dtar_ptr, "transform_type", 0); + uiItemR(row, NULL, 0, &dtar_ptr, "use_local_space_transforms", 0); } /* driver settings for active F-Curve (only for 'Drivers' mode) */ @@ -503,6 +534,9 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) case DVAR_TYPE_LOC_DIFF: /* location difference */ graph_panel_driverVar__locDiff(C, box, ale->id, dvar); break; + case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */ + graph_panel_driverVar__transChan(C, box, ale->id, dvar); + break; } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 0f3adae8c20..bd1db4c29b6 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -382,55 +382,6 @@ Sequence *find_nearest_seq(Scene *scene, View2D *v2d, int *hand, short mval[2]) return 0; } -void update_seq_ipo_rect(Scene *scene, View2D *v2d, Sequence *seq) -{ - float start; - float end; - - if (!seq || !seq->ipo) { - return; - } - start = -5.0; - end = 105.0; - - - /* Adjust IPO window to sequence and - avoid annoying snap-back to startframe - when Lock Time is on */ - if (0) { // XXX v2d->flag & V2D_VIEWLOCK) { - if ((seq->flag & SEQ_IPO_FRAME_LOCKED) != 0) { - start = -5.0 + seq->startdisp; - end = 5.0 + seq->enddisp; - } else { - start = (float)scene->r.sfra - 0.1; - end = scene->r.efra; - } - } - - seq->ipo->cur.xmin= start; - seq->ipo->cur.xmax= end; -} - -void update_seq_icu_rects(Sequence * seq) -{ - IpoCurve *icu= NULL; - struct SeqEffectHandle sh; - - if (!seq || !seq->ipo) { - return; - } - - if(!(seq->type & SEQ_EFFECT)) { - return; - } - - sh = get_sequence_effect(seq); - - for(icu= seq->ipo->curve.first; icu; icu= icu->next) { - sh.store_icu_yrange(seq, icu->adrcode, &icu->ymin, &icu->ymax); - } -} - static int seq_is_parent(Sequence *par, Sequence *seq) { diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index f2d4471607f..dda9073aa63 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -239,11 +239,13 @@ typedef enum eFMod_Noise_Modifications { typedef struct DriverTarget { ID *id; /* ID-block which owns the target */ - char *rna_path; /* target channel to use as driver value */ - char pchan_name[32]; /* name of the posebone to use (for certain types of variable only) */ + char *rna_path; /* RNA path defining the setting to use (for DVAR_TYPE_SINGLE_PROP) */ + char pchan_name[32]; /* name of the posebone to use (for vars where DTAR_FLAG_STRUCT_REF is used) */ + short transChan; /* transform channel index (for DVAR_TYPE_TRANSFORM_CHAN)*/ + + short flag; /* flags for the validity of the target (NOTE: these get reset everytime the types change) */ int idtype; /* type of ID-block that this target can use */ - int flag; /* flags for the validity of the target (NOTE: these get reset everytime the types change) */ } DriverTarget; /* Driver Target flags */ @@ -254,12 +256,28 @@ typedef enum eDriverTarget_Flag { DTAR_FLAG_STRUCT_REF = (1<<0), /* idtype can only be 'Object' */ DTAR_FLAG_ID_OB_ONLY = (1<<1), + /* toggles localspace (where transforms are manually obtained) */ + DTAR_FLAG_LOCALSPACE = (1<<2), } eDriverTarget_Flag; +/* Transform Channels for Driver Targets */ +typedef enum eDriverTarget_TransformChannels { + DTAR_TRANSCHAN_LOCX = 0, + DTAR_TRANSCHAN_LOCY, + DTAR_TRANSCHAN_LOCZ, + DTAR_TRANSCHAN_ROTX, + DTAR_TRANSCHAN_ROTY, + DTAR_TRANSCHAN_ROTZ, + DTAR_TRANSCHAN_SCALEX, + DTAR_TRANSCHAN_SCALEY, + DTAR_TRANSCHAN_SCALEZ, + + MAX_DTAR_TRANSCHAN_TYPES +} eDriverTarget_TransformChannels; + /* --- */ /* maximum number of driver targets per variable */ -// FIXME: make this get used below (for DriverVariable defines) if DNA supports preprocessor stuff.. #define MAX_DRIVER_TARGETS 8 @@ -275,8 +293,8 @@ typedef struct DriverVar { char name[64]; /* name of the variable to use in py-expression (must be valid python identifier) */ - DriverTarget targets[8]; /* MAX_DRIVER_TARGETS - targets available for use for this type of variable */ - int num_targets; /* number of targets used by this variable */ + DriverTarget targets[MAX_DRIVER_TARGETS]; /* target slots */ + int num_targets; /* number of targets actually used by this variable */ int type; /* type of driver target (eDriverTarget_Types) */ } DriverVar; @@ -289,6 +307,8 @@ typedef enum eDriverVar_Types { DVAR_TYPE_ROT_DIFF, /* distance between objects/bones */ DVAR_TYPE_LOC_DIFF, + /* 'final' transform for object/bones */ + DVAR_TYPE_TRANSFORM_CHAN, /* maximum number of variable types * NOTE: this must always be th last item in this list, diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 10fece3391f..e55603def9d 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -687,6 +687,18 @@ static void rna_def_drivertarget(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static EnumPropertyItem prop_trans_chan_items[] = { + {DTAR_TRANSCHAN_LOCX, "LOC_X", 0, "X Location", ""}, + {DTAR_TRANSCHAN_LOCY, "LOC_Y", 0, "Y Location", ""}, + {DTAR_TRANSCHAN_LOCZ, "LOC_Z", 0, "Z Location", ""}, + {DTAR_TRANSCHAN_ROTX, "ROT_X", 0, "X Rotation", ""}, + {DTAR_TRANSCHAN_ROTY, "ROT_Y", 0, "Y Rotation", ""}, + {DTAR_TRANSCHAN_ROTZ, "ROT_Z", 0, "Z Rotation", ""}, + {DTAR_TRANSCHAN_SCALEX, "SCALE_X", 0, "X Scale", ""}, + {DTAR_TRANSCHAN_SCALEY, "SCALE_Y", 0, "Y Scale", ""}, + {DTAR_TRANSCHAN_SCALEZ, "SCALE_Z", 0, "Z Scale", ""}, + {0, NULL, 0, NULL, NULL}}; + srna= RNA_def_struct(brna, "DriverTarget", NULL); RNA_def_struct_ui_text(srna, "Driver Target", "Source of input values for driver variables."); @@ -711,13 +723,24 @@ static void rna_def_drivertarget(BlenderRNA *brna) /* Target Properties - Property to Drive */ prop= RNA_def_property(srna, "data_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, "Data Path", "RNA Path (from Object) to property used"); + RNA_def_property_ui_text(prop, "Data Path", "RNA Path (from ID-block) to property used."); RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data"); prop= RNA_def_property(srna, "bone_target", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "pchan_name"); RNA_def_property_ui_text(prop, "Bone Name", "Name of PoseBone to use as target."); RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data"); + + prop= RNA_def_property(srna, "transform_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "transChan"); + RNA_def_property_enum_items(prop, prop_trans_chan_items); + RNA_def_property_ui_text(prop, "Type", "Driver variable type."); + RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data"); + + prop= RNA_def_property(srna, "use_local_space_transforms", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", DTAR_FLAG_LOCALSPACE); + RNA_def_property_ui_text(prop, "Local Space", "Use transforms in Local Space (as opposed to the worldspace default)."); + RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data"); } static void rna_def_drivervar(BlenderRNA *brna) @@ -728,7 +751,8 @@ static void rna_def_drivervar(BlenderRNA *brna) static EnumPropertyItem prop_type_items[] = { {DVAR_TYPE_SINGLE_PROP, "SINGLE_PROP", 0, "Single Property", "Use the value from some RNA property (Default)"}, {DVAR_TYPE_ROT_DIFF, "ROTATION_DIFF", 0, "Rotational Difference", "Use the angle between two bones"}, - {DVAR_TYPE_LOC_DIFF, "LOC_DIFF", 0, "Distance", "Distance between two bones or "}, + {DVAR_TYPE_LOC_DIFF, "LOC_DIFF", 0, "Distance", "Distance between two bones or objects"}, + {DVAR_TYPE_TRANSFORM_CHAN, "TRANSFORMS", 0, "Transform Channel", "Final transformation value of object or bone"}, {0, NULL, 0, NULL, NULL}}; |