[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23700] trunk/blender/source/blender: Rotation Modes Bugfix:

Joshua Leung aligorith at gmail.com
Thu Oct 8 02:57:01 CEST 2009


Revision: 23700
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23700
Author:   aligorith
Date:     2009-10-08 02:57:00 +0200 (Thu, 08 Oct 2009)

Log Message:
-----------
Rotation Modes Bugfix:

Animating rotations using different rotation modes should now work more often than before. 

Previously, quaternion and axis-angle values were stored in the same variable in DNA, but that was causing problems with other animation curves overwriting the values and causing the rotations to not work as expected. 

There are still some issues, but I'll track those down later tonight

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_armature.h
    trunk/blender/source/blender/blenkernel/intern/action.c
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/editors/animation/keyframes_general.c
    trunk/blender/source/blender/editors/armature/editarmature.c
    trunk/blender/source/blender/editors/armature/poseobject.c
    trunk/blender/source/blender/editors/object/object_transform.c
    trunk/blender/source/blender/editors/space_view3d/view3d_buttons.c
    trunk/blender/source/blender/editors/transform/transform_conversions.c
    trunk/blender/source/blender/makesdna/DNA_action_types.h
    trunk/blender/source/blender/makesdna/DNA_object_types.h
    trunk/blender/source/blender/makesrna/intern/rna_object.c
    trunk/blender/source/blender/makesrna/intern/rna_pose.c

Modified: trunk/blender/source/blender/blenkernel/BKE_armature.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_armature.h	2009-10-07 22:05:30 UTC (rev 23699)
+++ trunk/blender/source/blender/blenkernel/BKE_armature.h	2009-10-08 00:57:00 UTC (rev 23700)
@@ -104,7 +104,7 @@
 void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
 
 /* Rotation Mode Conversions - Used for PoseChannels + Objects... */
-void BKE_rotMode_change_values(float quat[4], float eul[3], short oldMode, short newMode);
+void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode);
 
 /* B-Bone support */
 typedef struct Mat4 {

Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c	2009-10-07 22:05:30 UTC (rev 23699)
+++ trunk/blender/source/blender/blenkernel/intern/action.c	2009-10-08 00:57:00 UTC (rev 23700)
@@ -446,7 +446,7 @@
 	
 	strncpy(chan->name, name, 31);
 	/* init vars to prevent math errors */
-	chan->quat[0] = 1.0f;
+	chan->quat[0] = chan->rotAxis[1]= 1.0f;
 	chan->size[0] = chan->size[1] = chan->size[2] = 1.0f;
 	
 	chan->limitmin[0]= chan->limitmin[1]= chan->limitmin[2]= -180.0f;
@@ -607,6 +607,8 @@
 	VECCOPY(pchan->loc, chan->loc);
 	VECCOPY(pchan->size, chan->size);
 	VECCOPY(pchan->eul, chan->eul);
+	VECCOPY(pchan->rotAxis, chan->rotAxis);
+	pchan->rotAngle= chan->rotAngle;
 	QUATCOPY(pchan->quat, chan->quat);
 	pchan->rotmode= chan->rotmode;
 	Mat4CpyMat4(pchan->chan_mat, (float(*)[4])chan->chan_mat);
@@ -975,14 +977,16 @@
 	memset(pose->stride_offset, 0, sizeof(pose->stride_offset));
 	memset(pose->cyclic_offset, 0, sizeof(pose->cyclic_offset));
 	
-	for (pchan=pose->chanbase.first; pchan; pchan= pchan->next){
+	for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) {
 		for (i=0; i<3; i++) {
 			pchan->loc[i]= 0.0f;
 			pchan->quat[i+1]= 0.0f;
 			pchan->eul[i]= 0.0f;
 			pchan->size[i]= 1.0f;
+			pchan->rotAxis[i]= 0.0f;
 		}
-		pchan->quat[0]= 1.0f;
+		pchan->quat[0]= pchan->rotAxis[1]= 1.0f;
+		pchan->rotAngle= 0.0f;
 		
 		pchan->flag &= ~(POSE_LOC|POSE_ROT|POSE_SIZE);
 	}

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2009-10-07 22:05:30 UTC (rev 23699)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2009-10-08 00:57:00 UTC (rev 23700)
@@ -1285,16 +1285,14 @@
 /* Called from RNA when rotation mode changes 
  *	- the result should be that the rotations given in the provided pointers have had conversions 
  *	  applied (as appropriate), such that the rotation of the element hasn't 'visually' changed 
- *
- *	- as in SDNA data, quat is used to store quaternions AND axis-angle rotations...
  */
-void BKE_rotMode_change_values (float quat[4], float eul[3], short oldMode, short newMode)
+void BKE_rotMode_change_values (float quat[4], float eul[3], float *axis, float angle[3], short oldMode, short newMode)
 {
 	/* check if any change - if so, need to convert data */
 	if (newMode > 0) { /* to euler */
 		if (oldMode == ROT_MODE_AXISANGLE) {
 			/* axis-angle to euler */
-			AxisAngleToEulO(&quat[1], quat[0], eul, newMode);
+			AxisAngleToEulO(axis, *angle, eul, newMode);
 		}
 		else if (oldMode == ROT_MODE_QUAT) {
 			/* quat to euler */
@@ -1305,11 +1303,7 @@
 	else if (newMode == ROT_MODE_QUAT) { /* to quat */
 		if (oldMode == ROT_MODE_AXISANGLE) {
 			/* axis angle to quat */
-			float q[4];
-			
-			/* copy to temp var first, since quats and axis-angle are stored in same place */
-			QuatCopy(q, quat);
-			AxisAngleToQuat(q, &quat[1], quat[0]);
+			AxisAngleToQuat(quat, axis, *angle);
 		}
 		else if (oldMode > 0) {
 			/* euler to quat */
@@ -1317,24 +1311,20 @@
 		}
 		/* else { no conversion needed } */
 	}
-	else { /* to axis-angle */
+	else if (newMode == ROT_MODE_AXISANGLE) { /* to axis-angle */
 		if (oldMode > 0) {
 			/* euler to axis angle */
 			EulOToAxisAngle(eul, oldMode, &quat[1], &quat[0]);
 		}
 		else if (oldMode == ROT_MODE_QUAT) {
 			/* quat to axis angle */
-			float q[4];
-			
-			/* copy to temp var first, since quats and axis-angle are stored in same place */
-			QuatCopy(q, quat);
-			QuatToAxisAngle(q, &quat[1], &quat[0]);
+			QuatToAxisAngle(quat, axis, angle);
 		}
 		
 		/* when converting to axis-angle, we need a special exception for the case when there is no axis */
-		if (IS_EQ(quat[1], quat[2]) && IS_EQ(quat[2], quat[3])) {
+		if (IS_EQ(axis[0], axis[1]) && IS_EQ(axis[1], axis[2])) {
 			/* for now, rotate around y-axis then (so that it simply becomes the roll) */
-			quat[2]= 1.0f;
+			axis[1]= 1.0f;
 		}
 	}
 }
@@ -1651,8 +1641,8 @@
 		EulOToMat3(chan->eul, chan->rotmode, rmat);
 	}
 	else if (chan->rotmode == ROT_MODE_AXISANGLE) {
-		/* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
-		AxisAngleToMat3(&chan->quat[1], chan->quat[0], rmat);
+		/* axis-angle - not really that great for 3D-changing orientations */
+		AxisAngleToMat3(chan->rotAxis, chan->rotAngle, rmat);
 	}
 	else {
 		/* quats are normalised before use to eliminate scaling issues */

Modified: trunk/blender/source/blender/blenkernel/intern/object.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/object.c	2009-10-07 22:05:30 UTC (rev 23699)
+++ trunk/blender/source/blender/blenkernel/intern/object.c	2009-10-08 00:57:00 UTC (rev 23700)
@@ -1041,6 +1041,8 @@
 	 * but rotations default to quaternions 
 	 */
 	ob->rotmode= ROT_MODE_EUL;
+	/* axis-angle must not have a 0,0,0 axis, so set y-axis as default... */
+	ob->rotAxis[1]= ob->drotAxis[1]= 1.0f;
 
 	base= scene_add_base(scene, ob);
 	scene_select_base(scene, base);
@@ -1602,9 +1604,9 @@
 		EulOToMat3(ob->drot, ob->rotmode, dmat);
 	}
 	else if (ob->rotmode == ROT_MODE_AXISANGLE) {
-		/* axis-angle - stored in quaternion data, but not really that great for 3D-changing orientations */
-		AxisAngleToMat3(&ob->quat[1], ob->quat[0], rmat);
-		AxisAngleToMat3(&ob->dquat[1], ob->dquat[0], dmat);
+		/* axis-angle -  not really that great for 3D-changing orientations */
+		AxisAngleToMat3(ob->rotAxis, ob->rotAngle, rmat);
+		AxisAngleToMat3(ob->drotAxis, ob->drotAngle, dmat);
 	}
 	else {
 		/* quats are normalised before use to eliminate scaling issues */

Modified: trunk/blender/source/blender/editors/animation/keyframes_general.c
===================================================================
--- trunk/blender/source/blender/editors/animation/keyframes_general.c	2009-10-07 22:05:30 UTC (rev 23699)
+++ trunk/blender/source/blender/editors/animation/keyframes_general.c	2009-10-08 00:57:00 UTC (rev 23700)
@@ -581,6 +581,7 @@
 		for (aci= animcopybuf.first; aci; aci= aci->next) {
 			/* check that paths exist */
 			if (aci->rna_path && fcu->rna_path) {
+				// FIXME: this breaks for bone names!
 				if (strcmp(aci->rna_path, fcu->rna_path) == 0) {
 					/* should be a match unless there's more than one of these */
 					if ((no_name) || (aci->array_index == fcu->array_index)) 

Modified: trunk/blender/source/blender/editors/armature/editarmature.c
===================================================================
--- trunk/blender/source/blender/editors/armature/editarmature.c	2009-10-07 22:05:30 UTC (rev 23699)
+++ trunk/blender/source/blender/editors/armature/editarmature.c	2009-10-08 00:57:00 UTC (rev 23700)
@@ -4875,14 +4875,39 @@
 			/* check if convert to eulers for locking... */
 			if (pchan->protectflag & OB_LOCK_ROT4D) {
 				/* perform clamping on a component by component basis */
-				if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
-					pchan->quat[0]= (pchan->rotmode == ROT_MODE_AXISANGLE) ? 0.0f : 1.0f;
-				if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
-					pchan->quat[1]= 0.0f;
-				if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
-					pchan->quat[2]= 0.0f;
-				if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
-					pchan->quat[3]= 0.0f;
+				if (pchan->rotmode == ROT_MODE_AXISANGLE) {
+					if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
+						pchan->rotAngle= 0.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
+						pchan->rotAxis[0]= 0.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
+						pchan->rotAxis[1]= 0.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
+						pchan->rotAxis[2]= 0.0f;
+						
+					/* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
+					if (IS_EQ(pchan->rotAxis[0], pchan->rotAxis[1]) && IS_EQ(pchan->rotAxis[1], pchan->rotAxis[2]))
+						pchan->rotAxis[1] = 1.0f;
+				}
+				else if (pchan->rotmode == ROT_MODE_QUAT) {
+					if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
+						pchan->quat[0]= 1.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
+						pchan->quat[1]= 0.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
+						pchan->quat[2]= 0.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
+						pchan->quat[3]= 0.0f;
+				}
+				else {
+					/* the flag may have been set for the other modes, so just ignore the extra flag... */
+					if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
+						pchan->eul[0]= 0.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
+						pchan->eul[1]= 0.0f;
+					if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
+						pchan->eul[2]= 0.0f;
+				}
 			}
 			else {
 				/* perform clamping using euler form (3-components) */
@@ -4893,7 +4918,7 @@
 					QuatToEul(pchan->quat, oldeul);
 				}
 				else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
-					AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT);
+					AxisAngleToEulO(pchan->rotAxis, pchan->rotAngle, oldeul, EULER_ORDER_DEFAULT);
 				}
 				else {
 					VECCOPY(oldeul, pchan->eul);
@@ -4916,7 +4941,7 @@
 					}
 				}
 				else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
-					AxisAngleToEulO(&pchan->quat[1], pchan->quat[0], oldeul, EULER_ORDER_DEFAULT);
+					EulOToAxisAngle(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, &pchan->rotAngle);
 				}
 				else {
 					VECCOPY(pchan->eul, eul);
@@ -4930,8 +4955,8 @@
 			}
 			else if (pchan->rotmode == ROT_MODE_AXISANGLE) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list