[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12470] trunk/blender/source/blender: New driver option for the poor suffering riggers:
Ton Roosendaal
ton at blender.org
Sun Nov 4 18:14:39 CET 2007
Revision: 12470
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12470
Author: ton
Date: 2007-11-04 18:14:39 +0100 (Sun, 04 Nov 2007)
Log Message:
-----------
New driver option for the poor suffering riggers:
"Rotation Difference"
This option, for Bones, allows the angle between two Bones to be
the driver for another Ipo channel. This angle now is hardcoded
based on the Bone-space orientation (without parenting rotation).
Thanks to nathan for poking and test!
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/intern/ipo.c
trunk/blender/source/blender/makesdna/DNA_curve_types.h
trunk/blender/source/blender/makesdna/DNA_ipo_types.h
trunk/blender/source/blender/src/drawipo.c
Modified: trunk/blender/source/blender/blenkernel/intern/ipo.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/ipo.c 2007-11-04 15:23:26 UTC (rev 12469)
+++ trunk/blender/source/blender/blenkernel/intern/ipo.c 2007-11-04 17:14:39 UTC (rev 12470)
@@ -751,6 +751,46 @@
}
}
+#define TFM_WITHOUT_BONE 1
+
+static void posechannel_get_local_transform(bPoseChannel *pchan, float *quat, float *eul, float *size, int flag)
+{
+ float pose_mat[3][3];
+ float diff_mat[3][3], ipar_mat[3][3];
+
+ /* we need the local transform = current transform - (parent transform + bone transform) */
+
+ Mat3CpyMat4(pose_mat, pchan->pose_mat);
+
+ if (pchan->parent) {
+
+ if(flag & TFM_WITHOUT_BONE) {
+ float par_mat[3][3];
+ Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
+ Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat);
+ }
+ else
+ Mat3CpyMat4(diff_mat, pchan->parent->pose_mat);
+
+ Mat3Inv(ipar_mat, diff_mat);
+ }
+ else {
+ if(flag & TFM_WITHOUT_BONE)
+ Mat3Inv(ipar_mat, pchan->bone->bone_mat);
+ else
+ Mat3One(ipar_mat);
+ }
+
+ Mat3MulMat3(diff_mat, ipar_mat, pose_mat);
+
+ if(quat)
+ Mat3ToQuat(diff_mat, quat);
+ if(eul)
+ Mat3ToEul(diff_mat, eul);
+ if(size)
+ Mat3ToSize(diff_mat, size);
+}
+
/* has to return a float value */
static float eval_driver(IpoDriver *driver, float ipotime)
{
@@ -802,48 +842,49 @@
else { /* ID_AR */
bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name);
if(pchan && pchan->bone) {
- float pose_mat[3][3];
- float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3];
- float eul[3], size[3];
- /* we need the local transform = current transform - (parent transform + bone transform) */
-
- Mat3CpyMat4(pose_mat, pchan->pose_mat);
-
- if (pchan->parent) {
- Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
- Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat);
-
- Mat3Inv(ipar_mat, diff_mat);
+ /* rotation difference is not a simple driver (i.e. value drives value), but the angle between 2 bones is driving stuff... which is useful */
+ if(driver->adrcode==OB_ROT_DIFF) {
+ bPoseChannel *pchan2= get_pose_channel(ob->pose, driver->name+DRIVER_NAME_OFFS);
+ if(pchan2 && pchan2->bone) {
+ float q1[4], q2[4], quat[4], angle;
+
+ posechannel_get_local_transform(pchan , q1, NULL, NULL, 0);
+ posechannel_get_local_transform(pchan2, q2, NULL, NULL, 0);
+
+ QuatInv(q1);
+ QuatMul(quat, q1, q2);
+ angle = 2.0f * (saacos(quat[0]));
+ angle= ABS(angle);
+
+ return angle>M_PI?2.0f*M_PI-angle:angle;
+ }
}
else {
- Mat3Inv(ipar_mat, pchan->bone->bone_mat);
- }
-
- Mat3MulMat3(diff_mat, ipar_mat, pose_mat);
-
- Mat3ToEul(diff_mat, eul);
- Mat3ToSize(diff_mat, size);
+ float eul[3], size[3];
+
+ posechannel_get_local_transform(pchan, NULL, eul, size, TFM_WITHOUT_BONE);
- switch(driver->adrcode) {
- case OB_LOC_X:
- return pchan->loc[0];
- case OB_LOC_Y:
- return pchan->loc[1];
- case OB_LOC_Z:
- return pchan->loc[2];
- case OB_ROT_X:
- return eul[0]/(M_PI_2/9.0);
- case OB_ROT_Y:
- return eul[1]/(M_PI_2/9.0);
- case OB_ROT_Z:
- return eul[2]/(M_PI_2/9.0);
- case OB_SIZE_X:
- return size[0];
- case OB_SIZE_Y:
- return size[1];
- case OB_SIZE_Z:
- return size[2];
+ switch(driver->adrcode) {
+ case OB_LOC_X:
+ return pchan->loc[0];
+ case OB_LOC_Y:
+ return pchan->loc[1];
+ case OB_LOC_Z:
+ return pchan->loc[2];
+ case OB_ROT_X:
+ return eul[0]/(M_PI_2/9.0);
+ case OB_ROT_Y:
+ return eul[1]/(M_PI_2/9.0);
+ case OB_ROT_Z:
+ return eul[2]/(M_PI_2/9.0);
+ case OB_SIZE_X:
+ return size[0];
+ case OB_SIZE_Y:
+ return size[1];
+ case OB_SIZE_Z:
+ return size[2];
+ }
}
}
}
Modified: trunk/blender/source/blender/makesdna/DNA_curve_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_curve_types.h 2007-11-04 15:23:26 UTC (rev 12469)
+++ trunk/blender/source/blender/makesdna/DNA_curve_types.h 2007-11-04 17:14:39 UTC (rev 12470)
@@ -193,9 +193,12 @@
typedef struct IpoDriver {
struct Object *ob;
short blocktype, adrcode, type, flag;
- char name[128]; /* bone or constraint(?), or python expression here */
+ char name[128]; /* bone or constraint(?), or python expression here */
} IpoDriver;
+/* temp? we store more bone names in 1 driver... */
+#define DRIVER_NAME_OFFS 32
+
typedef struct IpoCurve {
struct IpoCurve *next, *prev;
Modified: trunk/blender/source/blender/makesdna/DNA_ipo_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_ipo_types.h 2007-11-04 15:23:26 UTC (rev 12469)
+++ trunk/blender/source/blender/makesdna/DNA_ipo_types.h 2007-11-04 17:14:39 UTC (rev 12470)
@@ -108,6 +108,8 @@
#define OB_PD_RDAMP 28
#define OB_PD_PERM 29
+/* exception: driver channel, for bone driver only */
+#define OB_ROT_DIFF 100
/* ******************** */
Modified: trunk/blender/source/blender/src/drawipo.c
===================================================================
--- trunk/blender/source/blender/src/drawipo.c 2007-11-04 15:23:26 UTC (rev 12469)
+++ trunk/blender/source/blender/src/drawipo.c 2007-11-04 17:14:39 UTC (rev 12470)
@@ -2031,6 +2031,7 @@
tmp+= sprintf(tmp, "|Scale X %%x%d", OB_SIZE_X);
tmp+= sprintf(tmp, "|Scale Y %%x%d", OB_SIZE_Y);
tmp+= sprintf(tmp, "|Scale Z %%x%d", OB_SIZE_Z);
+ tmp+= sprintf(tmp, "|Rotation Differance %%x%d", OB_ROT_DIFF);
return (string);
}
@@ -2081,6 +2082,10 @@
if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR) {
icon = ICON_POSE_DEHLT;
uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,220,150,20, driver->name, 0, 31, 0, 0, "Bone name");
+
+ if(driver->adrcode==OB_ROT_DIFF)
+ uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,200,150,20, driver->name+DRIVER_NAME_OFFS, 0, 31, 0, 0, "Bone name for angular reference");
+
}
else driver->blocktype= ID_OB; /* safety when switching object button */
More information about the Bf-blender-cvs
mailing list