[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [32713] trunk/blender/source/blender: move matrix decomposition out of object.c into BLI_math_matrix function: mat4_to_loc_rot_size(), use this now for pchan_apply_mat4() to support negative scale, visual keying now uses compatible eulers.

Campbell Barton ideasman42 at gmail.com
Tue Oct 26 14:48:07 CEST 2010


Revision: 32713
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32713
Author:   campbellbarton
Date:     2010-10-26 14:48:07 +0200 (Tue, 26 Oct 2010)

Log Message:
-----------
move matrix decomposition out of object.c into BLI_math_matrix function: mat4_to_loc_rot_size(), use this now for pchan_apply_mat4() to support negative scale, visual keying now uses compatible eulers.
also added access to this in python's mathutils.Matrix()
 loc, quat, scale = matrix.decompose()

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_armature.h
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/blenkernel/intern/object.c
    trunk/blender/source/blender/blenlib/BLI_math_matrix.h
    trunk/blender/source/blender/blenlib/intern/math_matrix.c
    trunk/blender/source/blender/editors/armature/editarmature.c
    trunk/blender/source/blender/makesrna/intern/rna_pose.c
    trunk/blender/source/blender/python/generic/mathutils_matrix.c

Modified: trunk/blender/source/blender/blenkernel/BKE_armature.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_armature.h	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/blenkernel/BKE_armature.h	2010-10-26 12:48:07 UTC (rev 32713)
@@ -105,7 +105,8 @@
 void armature_loc_pose_to_bone(struct bPoseChannel *pchan, float *inloc, float *outloc);
 void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]);
 
-void pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4]);
+void pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[][3], short use_compat);
+void pchan_apply_mat4(struct bPoseChannel *pchan, float mat[][4], short use_comat);
 void pchan_to_mat4(struct bPoseChannel *pchan, float chan_mat[4][4]);
 
 /* Rotation Mode Conversions - Used for PoseChannels + Objects... */

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2010-10-26 12:48:07 UTC (rev 32713)
@@ -1177,32 +1177,30 @@
 	VECCOPY(outloc, nLocMat[3]);
 }
 
+/* same as object_mat3_to_rot() */
+void pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat)
+{
+	switch(pchan->rotmode) {
+	case ROT_MODE_QUAT:
+		mat3_to_quat(pchan->quat, mat);
+		break;
+	case ROT_MODE_AXISANGLE:
+		mat3_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, mat);
+		break;
+	default: /* euler */
+		if(use_compat)	mat3_to_compatible_eulO(pchan->eul, pchan->eul, pchan->rotmode, mat);
+		else			mat3_to_eulO(pchan->eul, pchan->rotmode, mat);
+	}
+}
 
 /* Apply a 4x4 matrix to the pose bone,
  * similar to object_apply_mat4()
  */
-void pchan_apply_mat4(bPoseChannel *pchan, float mat[][4])
+void pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat)
 {
-	/* location */
-	copy_v3_v3(pchan->loc, mat[3]);
-
-	/* scale */
-	mat4_to_size(pchan->size, mat);
-
-	/* rotation */
-	if (pchan->rotmode == ROT_MODE_AXISANGLE) {
-		float tmp_quat[4];
-
-		/* need to convert to quat first (in temp var)... */
-		mat4_to_quat(tmp_quat, mat);
-		quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, tmp_quat);
-	}
-	else if (pchan->rotmode == ROT_MODE_QUAT) {
-		mat4_to_quat(pchan->quat, mat);
-	}
-	else {
-		mat4_to_eulO(pchan->eul, pchan->rotmode, mat);
-	}
+	float rot[3][3];
+	mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
+	pchan_mat3_to_rot(pchan, rot, use_compat);
 }
 
 /* Remove rest-position effects from pose-transform for obtaining

Modified: trunk/blender/source/blender/blenkernel/intern/object.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/object.c	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/blenkernel/intern/object.c	2010-10-26 12:48:07 UTC (rev 32713)
@@ -1680,54 +1680,25 @@
 
 void object_mat3_to_rot(Object *ob, float mat[][3], short use_compat)
 {
-	if (ob->rotmode == ROT_MODE_QUAT)
+	switch(ob->rotmode) {
+	case ROT_MODE_QUAT:
 		mat3_to_quat(ob->quat, mat);
-	else if (ob->rotmode == ROT_MODE_AXISANGLE)
+		break;
+	case ROT_MODE_AXISANGLE:
 		mat3_to_axis_angle(ob->rotAxis, &ob->rotAngle, mat);
-	else {
-		if(use_compat) {
-			float eul[3];
-			VECCOPY(eul, ob->rot);
-			mat3_to_compatible_eulO(ob->rot, eul, ob->rotmode, mat);
-		}
-		else
-			mat3_to_eulO(ob->rot, ob->rotmode, mat);
+		break;
+	default: /* euler */
+		if(use_compat)	mat3_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, mat);
+		else			mat3_to_eulO(ob->rot, ob->rotmode, mat);
 	}
 }
 
 /* see pchan_apply_mat4() for the equivalent 'pchan' function */
 void object_apply_mat4(Object *ob, float mat[][4], short use_compat)
 {
-	float mat3[3][3];    /* obmat -> 3x3 */
-	float mat3_n[3][3];  /* obmat -> normalized, 3x3 */
-	float imat3_n[3][3]; /* obmat -> normalized & inverted, 3x3 */
-
-	/* location */
-	copy_v3_v3(ob->loc, mat[3]);
-
-	/* rotation & scale are linked, we need to create the mat's
-	 * for these together since they are related. */
-	copy_m3_m4(mat3, mat);
-	/* so scale doesnt interfear with rotation [#24291] */
-	/* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
-	normalize_m3_m3(mat3_n, (const float(*)[3])mat3);
-	if(is_negative_m3(mat3_n)) {
-		negate_v3(mat3_n[0]);
-		negate_v3(mat3_n[1]);
-		negate_v3(mat3_n[2]);
-	}
-
-	/* rotation */
-	object_mat3_to_rot(ob, mat3_n, use_compat);
-
-	/* scale */
-	/* note: mat4_to_size(ob->size, mat) fails for negative scale */
-	invert_m3_m3(imat3_n, mat3_n);
-	mul_m3_m3m3(mat3, imat3_n, mat3);
-
-	ob->size[0]= mat3[0][0];
-	ob->size[1]= mat3[1][1];
-	ob->size[2]= mat3[2][2];
+	float rot[3][3];
+	mat4_to_loc_rot_size(ob->loc, rot, ob->size, mat);
+	object_mat3_to_rot(ob, rot, use_compat);
 }
 
 void object_to_mat3(Object *ob, float mat[][3])	/* no parent */

Modified: trunk/blender/source/blender/blenlib/BLI_math_matrix.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_math_matrix.h	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/blenlib/BLI_math_matrix.h	2010-10-26 12:48:07 UTC (rev 32713)
@@ -144,6 +144,8 @@
 void translate_m4(float mat[4][4], float tx, float ty, float tz);
 void rotate_m4(float mat[4][4], const char axis, const float angle);
 
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4]);
+
 void loc_eul_size_to_mat4(float R[4][4],
 	const float loc[3], const float eul[3], const float size[3]);
 void loc_eulO_size_to_mat4(float R[4][4],

Modified: trunk/blender/source/blender/blenlib/intern/math_matrix.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_matrix.c	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/blenlib/intern/math_matrix.c	2010-10-26 12:48:07 UTC (rev 32713)
@@ -952,6 +952,48 @@
 	return mat3_to_scale(tmat);
 }
 
+void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[][4])
+{
+	float mat3[3][3];    /* wmat -> 3x3 */
+	float mat3_n[3][3];  /* wmat -> normalized, 3x3 */
+	float imat3_n[3][3]; /* wmat -> normalized & inverted, 3x3 */
+	short is_neg;
+	/* location */
+	copy_v3_v3(loc, wmat[3]);
+
+	/* rotation & scale are linked, we need to create the mat's
+	 * for these together since they are related. */
+	copy_m3_m4(mat3, wmat);
+	/* so scale doesnt interfear with rotation [#24291] */
+	/* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */
+	is_neg= is_negative_m3(mat3);
+	normalize_m3_m3(mat3_n, (const float(*)[3])mat3);
+	if(is_neg) {
+		negate_v3(mat3_n[0]);
+		negate_v3(mat3_n[1]);
+		negate_v3(mat3_n[2]);
+	}
+
+	/* rotation */
+	/* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */
+	copy_m3_m3(rot, mat3_n);
+
+	/* scale */
+	/* note: mat4_to_size(ob->size, mat) fails for negative scale */
+	invert_m3_m3(imat3_n, mat3_n);
+	mul_m3_m3m3(mat3, imat3_n, mat3);
+
+	size[0]= mat3[0][0];
+	size[1]= mat3[1][1];
+	size[2]= mat3[2][2];
+
+	/* with a negative matrix, all scaled will be negative
+	 * flipping isnt needed but nicer to result in a positive scale */
+	if(is_neg) {
+		negate_v3(size);
+	}
+}
+
 void scale_m3_fl(float m[][3], float scale)
 {
 	m[0][0]= m[1][1]= m[2][2]= scale;

Modified: trunk/blender/source/blender/editors/armature/editarmature.c
===================================================================
--- trunk/blender/source/blender/editors/armature/editarmature.c	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/editors/armature/editarmature.c	2010-10-26 12:48:07 UTC (rev 32713)
@@ -681,7 +681,7 @@
 		invert_m4_m4(imat, pchan->pose_mat);
 		mul_m4_m4m4(delta_mat, mat, imat);
 
-		pchan_apply_mat4(pchan, delta_mat);
+		pchan_apply_mat4(pchan, delta_mat, TRUE);
 
 		where_is_pose_bone(scene, ob, pchan, CFRA, 1);
 	}

Modified: trunk/blender/source/blender/makesrna/intern/rna_pose.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_pose.c	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/makesrna/intern/rna_pose.c	2010-10-26 12:48:07 UTC (rev 32713)
@@ -550,7 +550,7 @@
 static void rna_PoseChannel_matrix_local_set(PointerRNA *ptr, const float *values)
 {
 	bPoseChannel *pchan= (bPoseChannel*)ptr->data;
-	pchan_apply_mat4(pchan, (float (*)[4])values);
+	pchan_apply_mat4(pchan, (float (*)[4])values, FALSE); /* no compat for pradictable result */
 }
 
 #else

Modified: trunk/blender/source/blender/python/generic/mathutils_matrix.c
===================================================================
--- trunk/blender/source/blender/python/generic/mathutils_matrix.c	2010-10-26 07:14:31 UTC (rev 32712)
+++ trunk/blender/source/blender/python/generic/mathutils_matrix.c	2010-10-26 12:48:07 UTC (rev 32713)
@@ -942,6 +942,7 @@
 	scale[2]= tmat[2][2];
 	return newVectorObject(scale, 3, Py_NEW, NULL);
 }
+
 /*---------------------------Matrix.invert() ---------------------*/
 static char Matrix_Invert_doc[] =
 ".. method:: invert()\n"
@@ -1009,7 +1010,42 @@
 	return (PyObject *)self;
 }
 
+/*---------------------------Matrix.decompose() ---------------------*/
+static char Matrix_decompose_doc[] =
+".. method:: decompose()\n"
+"\n"
+"   Return the location, rotaion and scale components of this matrix.\n"
+"\n"
+"   :return: loc, rot, scale triple.\n"
+"   :rtype: (:class:`Vector`, :class:`Quaternion`, :class:`Vector`)";
+static PyObject *Matrix_decompose(MatrixObject * self)
+{
+	PyObject *ret;
+	float loc[3];
+	float rot[3][3];
+	float quat[4];
+	float size[3];
 
+	if(self->colSize != 4 || self->rowSize != 4) {
+		PyErr_SetString(PyExc_AttributeError, "Matrix.decompose(): inappropriate matrix size - expects 4x4 matrix\n");
+		return NULL;
+	}
+
+	if(!BaseMath_ReadCallback(self))
+		return NULL;
+
+	mat4_to_loc_rot_size(loc, rot, size, (float (*)[4])self->contigPtr);
+	mat3_to_quat(quat, rot);
+
+	ret= PyTuple_New(3);
+	PyTuple_SET_ITEM(ret, 0, newVectorObject(loc, 3, Py_NEW, NULL));
+	PyTuple_SET_ITEM(ret, 1, newQuaternionObject(quat, Py_NEW, NULL));
+	PyTuple_SET_ITEM(ret, 2, newVectorObject(size, 3, Py_NEW, NULL));
+
+	return ret;
+}
+
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list