[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22943] branches/blender2.5/blender/source /blender: 2.5 - Rotation Order Tweaks for Armature Bones

Joshua Leung aligorith at gmail.com
Wed Sep 2 02:42:12 CEST 2009


Revision: 22943
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22943
Author:   aligorith
Date:     2009-09-02 02:42:12 +0200 (Wed, 02 Sep 2009)

Log Message:
-----------
2.5 - Rotation Order Tweaks for Armature Bones

* All tools where rotation order matters for armature bones have now been adjusted to use the new code

* Transform now uses the new code for bones too. However, there are some jumping issues here that I'm not too sure how to solve yet. Help fixing this is welcome.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenlib/BLI_arithb.h
    branches/blender2.5/blender/source/blender/blenlib/intern/arithb.c
    branches/blender2.5/blender/source/blender/editors/animation/keyframing.c
    branches/blender2.5/blender/source/blender/editors/armature/poseobject.c
    branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_buttons.c
    branches/blender2.5/blender/source/blender/editors/transform/transform.c
    branches/blender2.5/blender/source/blender/editors/transform/transform.h
    branches/blender2.5/blender/source/blender/editors/transform/transform_conversions.c

Modified: branches/blender2.5/blender/source/blender/blenlib/BLI_arithb.h
===================================================================
--- branches/blender2.5/blender/source/blender/blenlib/BLI_arithb.h	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/blenlib/BLI_arithb.h	2009-09-02 00:42:12 UTC (rev 22943)
@@ -193,6 +193,7 @@
 } eEulerRotationOrders;
 
 void EulOToQuat(float eul[3], short order, float quat[4]);
+void QuatToEulO(float quat[4], float eul[3], short order);
 
 void EulOToMat3(float eul[3], short order, float Mat[3][3]);
 void EulOToMat4(float eul[3], short order, float Mat[4][4]);
@@ -200,7 +201,7 @@
 void Mat3ToEulO(float Mat[3][3], float eul[3], short order);
 void Mat4ToEulO(float Mat[4][4], float eul[3], short order);
 
-void QuatToEulO(float quat[4], float eul[3], short order);
+void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order);
  
 /**
  * @section Euler conversion routines (Blender XYZ)

Modified: branches/blender2.5/blender/source/blender/blenlib/intern/arithb.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenlib/intern/arithb.c	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/blenlib/intern/arithb.c	2009-09-02 00:42:12 UTC (rev 22943)
@@ -2825,7 +2825,8 @@
  * NOTE: since we start at 1 for the values, but arrays index from 0, 
  *		 there is -1 factor involved in this process...
  */
-#define GET_ROTATIONORDER_INFO(order) (&rotOrders[(order)-1])
+// FIXME: what happens when invalid order given
+#define GET_ROTATIONORDER_INFO(order) (((order)>=1) ? &rotOrders[(order)-1] : &rotOrders[0])
 
 /* Construct quaternion from Euler angles (in radians). */
 void EulOToQuat(float e[3], short order, float q[4])
@@ -2857,6 +2858,15 @@
 	if (R->parity) q[j] = -q[j];
 }
 
+/* Convert quaternion to Euler angles (in radians). */
+void QuatToEulO(float q[4], float e[3], short order)
+{
+	float M[3][3];
+	
+	QuatToMat3(q, M);
+	Mat3ToEulO(M, e, order);
+}
+
 /* Construct 3x3 matrix from Euler angles (in radians). */
 void EulOToMat3(float e[3], short order, float M[3][3])
 {
@@ -2929,15 +2939,65 @@
 	Mat3ToEulO(m, e, order);
 }
 
-/* Convert quaternion to Euler angles (in radians). */
-void QuatToEulO(float q[4], float e[3], short order)
+/* returns two euler calculation methods, so we can pick the best */
+static void mat3_to_eulo2(float M[3][3], float *e1, float *e2, short order)
 {
-	float M[3][3];
+	RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); 
+	short i=R->i,  j=R->j, 	k=R->k;
+	double cy = sqrt(M[i][i]*M[i][i] + M[j][i]*M[j][i]);
 	
-	QuatToMat3(q, M);
-	Mat3ToEulO(M, e, order);
+	if (cy > 16*FLT_EPSILON) {
+		e1[0] = atan2(M[j][k], M[k][k]);
+		e1[1] = atan2(-M[i][k], cy);
+		e1[2] = atan2(M[i][j], M[i][i]);
+		
+		e2[0] = atan2(-M[j][k], -M[k][k]);
+		e2[1] = atan2(-M[i][k], -cy);
+		e2[2] = atan2(-M[i][j], -M[i][i]);
+	} 
+	else {
+		e1[0] = atan2(-M[k][j], M[j][j]);
+		e1[1] = atan2(-M[i][k], cy);
+		e1[2] = 0;
+		
+		VecCopyf(e2, e1);
+	}
+	
+	if (R->parity) {
+		e1[0] = -e1[0]; 
+		e1[1] = -e1[1]; 
+		e1[2] = -e1[2];
+		
+		e2[0] = -e2[0]; 
+		e2[1] = -e2[1]; 
+		e2[2] = -e2[2];
+	}
 }
 
+/* uses 2 methods to retrieve eulers, and picks the closest */
+// FIXME: this does not work well with the other rotation modes...
+void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order)
+{
+	float eul1[3], eul2[3];
+	float d1, d2;
+	
+	mat3_to_eulo2(mat, eul1, eul2, order);
+	
+	compatible_eul(eul1, oldrot);
+	compatible_eul(eul2, oldrot);
+	
+	d1= (float)fabs(eul1[0]-oldrot[0]) + (float)fabs(eul1[1]-oldrot[1]) + (float)fabs(eul1[2]-oldrot[2]);
+	d2= (float)fabs(eul2[0]-oldrot[0]) + (float)fabs(eul2[1]-oldrot[1]) + (float)fabs(eul2[2]-oldrot[2]);
+	
+	/* return best, which is just the one with lowest difference */
+	if (d1 > d2)
+		VecCopyf(eul, eul2);
+	else
+		VecCopyf(eul, eul1);
+}
+
+
+
 /* ************ EULER (old XYZ) *************** */
 
 /* XYZ order */
@@ -3102,7 +3162,7 @@
 }
 
 /* exported to transform.c */
-/* XYZ order */
+/* order independent! */
 void compatible_eul(float *eul, float *oldrot)
 {
 	float dx, dy, dz;

Modified: branches/blender2.5/blender/source/blender/editors/animation/keyframing.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/animation/keyframing.c	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/editors/animation/keyframing.c	2009-09-02 00:42:12 UTC (rev 22943)
@@ -704,7 +704,7 @@
 			float eul[3];
 			
 			/* euler-rotation test before standard rotation, as standard rotation does quats */
-			Mat4ToEul(tmat, eul);
+			Mat4ToEulO(tmat, eul, pchan->rotmode);
 			return eul[array_index];
 		}
 		else if (strstr(identifier, "rotation")) {

Modified: branches/blender2.5/blender/source/blender/editors/armature/poseobject.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/armature/poseobject.c	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/editors/armature/poseobject.c	2009-09-02 00:42:12 UTC (rev 22943)
@@ -760,6 +760,7 @@
 						break;
 					case 2: /* Local Rotation */
 						QUATCOPY(pchan->quat, pchanact->quat);
+						VECCOPY(pchan->eul, pchanact->eul);
 						break;
 					case 3: /* Local Size */
 						VECCOPY(pchan->size, pchanact->size);
@@ -808,11 +809,14 @@
 						break;
 					case 10: /* Visual Rotation */
 					{
-						float delta_mat[4][4], quat[4];
+						float delta_mat[4][4];
 						
 						armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
-						Mat4ToQuat(delta_mat, quat);
-						QUATCOPY(pchan->quat, quat);
+						
+						if (pchan->rotmode > 0) 
+							Mat4ToEulO(delta_mat, pchan->eul, pchan->rotmode);
+						else
+							Mat4ToQuat(delta_mat, pchan->quat);
 					}
 						break;
 					case 11: /* Visual Size */
@@ -990,20 +994,20 @@
 				/* check if rotation modes are compatible (i.e. do they need any conversions) */
 				if (pchan->rotmode == chan->rotmode) {
 					/* copy the type of rotation in use */
-					if (pchan->rotmode) {
+					if (pchan->rotmode > 0) {
 						VECCOPY(pchan->eul, chan->eul);
 					}
 					else {
 						QUATCOPY(pchan->quat, chan->quat);
 					}
 				}
-				else if (pchan->rotmode) {
+				else if (pchan->rotmode > 0) {
 					/* quat to euler */
-					QuatToEul(chan->quat, pchan->eul);
+					QuatToEulO(chan->quat, pchan->eul, pchan->rotmode);
 				}
 				else {
 					/* euler to quat */
-					EulToQuat(chan->eul, pchan->quat);
+					EulOToQuat(chan->eul, chan->rotmode, pchan->quat);
 				}
 				
 				/* paste flipped pose? */
@@ -1011,7 +1015,7 @@
 					pchan->loc[0]*= -1;
 					
 					/* has to be done as eulers... */
-					if (pchan->rotmode) {
+					if (pchan->rotmode > 0) {
 						pchan->eul[1] *= -1;
 						pchan->eul[2] *= -1;
 					}

Modified: branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_buttons.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_buttons.c	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_buttons.c	2009-09-02 00:42:12 UTC (rev 22943)
@@ -512,7 +512,7 @@
 	uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
 	uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
 
-	QuatToEul(pchan->quat, tfp->ob_eul);
+	QuatToEulO(pchan->quat, tfp->ob_eul, pchan->rotmode); // XXX?
 	tfp->ob_eul[0]*= 180.0/M_PI;
 	tfp->ob_eul[1]*= 180.0/M_PI;
 	tfp->ob_eul[2]*= 180.0/M_PI;
@@ -841,7 +841,7 @@
 			eul[0]= M_PI*tfp->ob_eul[0]/180.0;
 			eul[1]= M_PI*tfp->ob_eul[1]/180.0;
 			eul[2]= M_PI*tfp->ob_eul[2]/180.0;
-			EulToQuat(eul, pchan->quat);
+			EulOToQuat(eul, pchan->rotmode, pchan->quat); // xxx?
 		}
 		/* no break, pass on */
 	case B_ARMATUREPANEL2:

Modified: branches/blender2.5/blender/source/blender/editors/transform/transform.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/transform/transform.c	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/editors/transform/transform.c	2009-09-02 00:42:12 UTC (rev 22943)
@@ -2670,21 +2670,21 @@
 				/* this function works on end result */
 				protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
 			}
-			else { // TODO: need some methods for the new euler types...
+			else { 
 				float eulmat[3][3];
-
+				
 				Mat3MulMat3(totmat, mat, td->mtx);
 				Mat3MulMat3(smat, td->smtx, totmat);
-
+				
 				/* calculate the total rotatation in eulers */
 				VECCOPY(eul, td->ext->irot);
-				EulToMat3(eul, eulmat);
-
+				EulOToMat3(eul, td->rotOrder, eulmat);
+				
 				/* mat = transform, obmat = bone rotation */
 				Mat3MulMat3(fmat, smat, eulmat);
-
-				Mat3ToCompatibleEul(fmat, eul, td->ext->rot);
-
+				
+				Mat3ToCompatibleEulO(fmat, eul, td->ext->rot, td->rotOrder);
+				
 				/* and apply (to end result only) */
 				protectedRotateBits(td->protectflag, eul, td->ext->irot);
 				VECCOPY(td->ext->rot, eul);

Modified: branches/blender2.5/blender/source/blender/editors/transform/transform.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/transform/transform.h	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/editors/transform/transform.h	2009-09-02 00:42:12 UTC (rev 22943)
@@ -199,6 +199,7 @@
 	void  *extra;		 /* extra data (mirrored element pointer, in editmode mesh to EditVert) (editbone for roll fixing) (...) */
     short  flag;         /* Various flags */
 	short  protectflag;	 /* If set, copy of Object or PoseChannel protection */
+	int    rotOrder;	/* rotation order (for eulers), as defined in BLI_arithb.h */
 } TransData;
 
 typedef struct MouseInput {

Modified: branches/blender2.5/blender/source/blender/editors/transform/transform_conversions.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/transform/transform_conversions.c	2009-09-02 00:07:55 UTC (rev 22942)
+++ branches/blender2.5/blender/source/blender/editors/transform/transform_conversions.c	2009-09-02 00:42:12 UTC (rev 22943)
@@ -502,22 +502,29 @@
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list