[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28279] trunk/blender/source/blender/ editors/transform/transform.c: Fix problem with limit rotation constraints during transform.

Brecht Van Lommel brecht at blender.org
Mon Apr 19 11:38:36 CEST 2010


Revision: 28279
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28279
Author:   blendix
Date:     2010-04-19 11:38:36 +0200 (Mon, 19 Apr 2010)

Log Message:
-----------
Fix problem with limit rotation constraints during transform. This code
would convert from quat to matrix and back if the bone had any constraint,
but did not normalize the quat first as done in other places, giving a
sudden jump when starting transform on some bones with constraints. Two
changes:

* Normalize quaternion first.
* Only do this conversion on bones with limit rotation constraints,
  instead of all bones with any constraint.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/transform/transform.c

Modified: trunk/blender/source/blender/editors/transform/transform.c
===================================================================
--- trunk/blender/source/blender/editors/transform/transform.c	2010-04-19 07:28:23 UTC (rev 28278)
+++ trunk/blender/source/blender/editors/transform/transform.c	2010-04-19 09:38:36 UTC (rev 28279)
@@ -1921,39 +1921,50 @@
 	}
 }
 
+static void constraintob_from_transdata(bConstraintOb *cob, TransData *td)
+{
+	/* Make a temporary bConstraintOb for use by limit constraints
+	 * 	- they only care that cob->matrix is correctly set ;-)
+	 *	- current space should be local
+	 */
+	memset(cob, 0, sizeof(bConstraintOb));
+	if (td->rotOrder == ROT_MODE_QUAT) {
+		/* quats */
+		if (td->ext) {
+			/* objects and bones do normalization first too, otherwise
+			   we don't necessarily end up with a rotation matrix, and
+			   then conversion back to quat gives a different result */
+			float quat[4];
+			copy_qt_qt(quat, td->ext->quat);
+			normalize_qt(quat);
+			quat_to_mat4(cob->matrix, quat);
+		}
+		else
+			return;
+	}
+	else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+		/* axis angle */
+		if (td->ext)
+			axis_angle_to_mat4(cob->matrix, &td->ext->quat[1], td->ext->quat[0]);
+		else
+			return;
+	}
+	else {
+		/* eulers */
+		if (td->ext)
+			eulO_to_mat4(cob->matrix, td->ext->rot, td->rotOrder);
+		else
+			return;
+	}
+}
+
 static void constraintRotLim(TransInfo *t, TransData *td)
 {
 	if (td->con) {
 		bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
 		bConstraintOb cob;
 		bConstraint *con;
-
-		/* Make a temporary bConstraintOb for using these limit constraints
-		 * 	- they only care that cob->matrix is correctly set ;-)
-		 *	- current space should be local
-		 */
-		memset(&cob, 0, sizeof(bConstraintOb));
-		if (td->rotOrder == ROT_MODE_QUAT) {
-			/* quats */
-			if (td->ext)
-				quat_to_mat4( cob.matrix,td->ext->quat);
-			else
-				return;
-		}
-		else if (td->rotOrder == ROT_MODE_AXISANGLE) {
-			/* axis angle */
-			if (td->ext)
-				axis_angle_to_mat4( cob.matrix,&td->ext->quat[1], td->ext->quat[0]);
-			else
-				return;
-		}
-		else {
-			/* eulers */
-			if (td->ext)
-				eulO_to_mat4( cob.matrix,td->ext->rot, td->rotOrder);
-			else
-				return;
-		}
+		int dolimit = 0;
 		
 		/* Evaluate valid constraints */
 		for (con= td->con; con; con= con->next) {
@@ -1969,6 +1980,16 @@
 				/* only use it if it's tagged for this purpose */
 				if ((data->flag2 & LIMIT_TRANSFORM)==0)
 					continue;
+
+				/* skip incompatable spacetypes */
+				if (!ELEM(con->ownspace, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL))
+					continue;
+
+				/* only do conversion if necessary, to preserve quats and eulers */
+				if(!dolimit) {
+					constraintob_from_transdata(&cob, td);
+					dolimit= 1;
+				}
 				
 				/* do space conversions */
 				if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
@@ -1976,10 +1997,6 @@
 					copy_m4_m4(tmat, cob.matrix);
 					mul_m4_m3m4(cob.matrix, td->mtx, tmat);
 				}
-				else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
-					/* skip... incompatable spacetype */
-					continue;
-				}
 				
 				/* do constraint */
 				cti->evaluate_constraint(con, &cob, NULL);
@@ -1993,19 +2010,21 @@
 			}
 		}
 		
-		/* copy results from cob->matrix */
-		if (td->rotOrder == ROT_MODE_QUAT) {
-			/* quats */
-			mat4_to_quat( td->ext->quat,cob.matrix);
+		if(dolimit) {
+			/* copy results from cob->matrix */
+			if (td->rotOrder == ROT_MODE_QUAT) {
+				/* quats */
+				mat4_to_quat( td->ext->quat,cob.matrix);
+			}
+			else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+				/* axis angle */
+				mat4_to_axis_angle( &td->ext->quat[1], &td->ext->quat[0],cob.matrix);
+			}
+			else {
+				/* eulers */
+				mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix);
+			}
 		}
-		else if (td->rotOrder == ROT_MODE_AXISANGLE) {
-			/* axis angle */
-			mat4_to_axis_angle( &td->ext->quat[1], &td->ext->quat[0],cob.matrix);
-		}
-		else {
-			/* eulers */
-			mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix);
-		}
 	}
 }
 





More information about the Bf-blender-cvs mailing list