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/intern/anim_sys.c16
-rw-r--r--source/blender/blenkernel/intern/fcurve.c98
-rw-r--r--source/blender/blenkernel/intern/ipo.c166
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c40
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c49
-rw-r--r--source/blender/makesdna/DNA_anim_types.h32
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c28
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}};