[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