[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44338] trunk/blender/source/blender/ blenkernel/intern: Armature pose evaluation: more factorization of code.

Bastien Montagne montagne29 at wanadoo.fr
Wed Feb 22 21:06:40 CET 2012


Revision: 44338
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44338
Author:   mont29
Date:     2012-02-22 20:06:33 +0000 (Wed, 22 Feb 2012)
Log Message:
-----------
Armature pose evaluation: more factorization of code.

Now constraints' space conversion code also uses generic armature_mat_(pose_to_bone/bone_to_pose). Previous own function (constraint_pchan_diff_mat) was somewhat inconsistent too with Hinge/NoScale/LocalLocation options...
As with previous similar changes, this might break some old rigs, in very specific cases (when constraint-evaluating an hinge/noscale/local_location bone in local space).

In the same part of code, removed unnecessary matrices copying, mult_m4_m4m4 can take the same matrix as input and output, nowadays...

Also found a bug-generator weakness in those armature_mat_ functions (if both input and output mat where the same, result was wrong, now systematically copying input mat, as done in LIB's matrix funcs).

Finally, factorized offset bone matrix generation into its own small function too, as it is used in two different places in armature.c (pchan_to_pose_mat itself, and restpose's where_is_armature_bone).

Note: I think all parts of blender's code related to that topic have now been tackled, but yet have to check BGE, it?\226?\128?\153s probably using that stuff too, one way or the other...

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/blenkernel/intern/constraint.c

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2012-02-22 18:57:17 UTC (rev 44337)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2012-02-22 20:06:33 UTC (rev 44338)
@@ -1129,6 +1129,24 @@
 	copy_v3_v3(outloc, nLocMat[3]);
 }
 
+/* Simple helper, computes the offset bone matrix.
+ *     offs_bone = yoffs(b-1) + root(b) + bonemat(b).
+ * Not exported, as it is only used in this file currently... */
+static void get_offset_bone_mat(Bone *bone, float offs_bone[][4])
+{
+	if (!bone->parent)
+		return;
+
+	/* Bone transform itself. */
+	copy_m4_m3(offs_bone, bone->bone_mat);
+
+	/* The bone's root offset (is in the parent's coordinate system). */
+	copy_v3_v3(offs_bone[3], bone->head);
+
+	/* Get the length translation of parent (length along y axis). */
+	offs_bone[3][1] += bone->parent->length;
+}
+
 /* Construct the matrices (rot/scale and loc) to apply the PoseChannels into the armature (object) space.
  * I.e. (roughly) the "pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b)" in the
  *     pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)
@@ -1157,17 +1175,10 @@
 	parchan = pchan->parent;
 
 	if (parchan) {
-		float offs_bone[4][4]; /* yoffs(b-1) + root(b) + bonemat(b). */
+		float offs_bone[4][4];
+		/* yoffs(b-1) + root(b) + bonemat(b). */
+		get_offset_bone_mat(bone, offs_bone);
 
-		/* Bone transform itself. */
-		copy_m4_m3(offs_bone, bone->bone_mat);
-
-		/* The bone's root offset (is in the parent's coordinate system). */
-		copy_v3_v3(offs_bone[3], bone->head);
-
-		/* Get the length translation of parent (length along y axis). */
-		offs_bone[3][1] += parbone->length;
-
 		/* Compose the rotscale matrix for this bone. */
 		if ((bone->flag & BONE_HINGE) && (bone->flag & BONE_NO_SCALE)) {
 			/* Parent rest rotation and scale. */
@@ -1297,25 +1308,31 @@
  *       pose-channel into its local space (i.e. 'visual'-keyframing) */
 void armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
 {
-	float rotscale_mat[4][4], loc_mat[4][4];
+	float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4];
 
+	/* Security, this allows to call with inmat == outmat! */
+	copy_m4_m4(inmat_, inmat);
+
 	pchan_to_pose_mat(pchan, rotscale_mat, loc_mat);
 	invert_m4(rotscale_mat);
 	invert_m4(loc_mat);
 
-	mult_m4_m4m4(outmat, rotscale_mat, inmat);
-	mul_v3_m4v3(outmat[3], loc_mat, inmat[3]);
+	mult_m4_m4m4(outmat, rotscale_mat, inmat_);
+	mul_v3_m4v3(outmat[3], loc_mat, inmat_[3]);
 }
 
 /* Convert Bone-Space Matrix to Pose-Space Matrix. */
 void armature_mat_bone_to_pose(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
 {
-	float rotscale_mat[4][4], loc_mat[4][4];
+	float rotscale_mat[4][4], loc_mat[4][4], inmat_[4][4];
 
+	/* Security, this allows to call with inmat == outmat! */
+	copy_m4_m4(inmat_, inmat);
+
 	pchan_to_pose_mat(pchan, rotscale_mat, loc_mat);
 
-	mult_m4_m4m4(outmat, rotscale_mat, inmat);
-	mul_v3_m4v3(outmat[3], loc_mat, inmat[3]);
+	mult_m4_m4m4(outmat, rotscale_mat, inmat_);
+	mul_v3_m4v3(outmat[3], loc_mat, inmat_[3]);
 }
 
 /* Convert Pose-Space Location to Bone-Space Location
@@ -1546,17 +1563,10 @@
 	}
 
 	if (prevbone) {
-		float offs_bone[4][4];  /* yoffs(b-1) + root(b) + bonemat(b) */
+		float offs_bone[4][4];
+		/* yoffs(b-1) + root(b) + bonemat(b) */
+		get_offset_bone_mat(bone, offs_bone);
 
-		/* bone transform itself */
-		copy_m4_m3(offs_bone, bone->bone_mat);
-
-		/* The bone's root offset (is in the parent's coordinate system) */
-		copy_v3_v3(offs_bone[3], bone->head);
-
-		/* Get the length translation of parent (length along y axis) */
-		offs_bone[3][1] += prevbone->length;
-
 		/* Compose the matrix for this bone  */
 		mult_m4_m4m4(bone->arm_mat, prevbone->arm_mat, offs_bone);
 	}

Modified: trunk/blender/source/blender/blenkernel/intern/constraint.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/constraint.c	2012-02-22 18:57:17 UTC (rev 44337)
+++ trunk/blender/source/blender/blenkernel/intern/constraint.c	2012-02-22 20:06:33 UTC (rev 44338)
@@ -223,6 +223,7 @@
 
 /* -------------- Space-Conversion API -------------- */
 
+#if 0 /* XXX Old code, does the same as one in armature.c, will remove it later. */
 static void constraint_pchan_diff_mat(bPoseChannel *pchan, float diff_mat[4][4])
 {
 	if (pchan->parent) {
@@ -265,15 +266,14 @@
 		copy_m4_m4(diff_mat, pchan->bone->arm_mat);
 	}
 }
+#endif
 
-
 /* This function is responsible for the correct transformations/conversions 
  * of a matrix from one space to another for constraint evaluation.
  * For now, this is only implemented for Objects and PoseChannels.
  */
 void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4], short from, short to)
 {
-	float tempmat[4][4];
 	float diff_mat[4][4];
 	float imat[4][4];
 	
@@ -290,8 +290,7 @@
 			{
 				/* world to pose */
 				invert_m4_m4(imat, ob->obmat);
-				copy_m4_m4(tempmat, mat);
-				mult_m4_m4m4(mat, imat, tempmat);
+				mult_m4_m4m4(mat, imat, mat);
 				
 				/* use pose-space as stepping stone for other spaces... */
 				if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
@@ -304,32 +303,31 @@
 			{
 				/* pose to world */
 				if (to == CONSTRAINT_SPACE_WORLD) {
-					copy_m4_m4(tempmat, mat);
-					mult_m4_m4m4(mat, ob->obmat, tempmat);
+					mult_m4_m4m4(mat, ob->obmat, mat);
 				}
 				/* pose to local */
 				else if (to == CONSTRAINT_SPACE_LOCAL) {
 					if (pchan->bone) {
+						armature_mat_pose_to_bone(pchan, mat, mat);
+#if 0  /* XXX Old code, will remove it later. */
 						constraint_pchan_diff_mat(pchan, diff_mat);
 
 						invert_m4_m4(imat, diff_mat);
+						mult_m4_m4m4(mat, imat, mat);
 
-						copy_m4_m4(tempmat, mat);
-						mult_m4_m4m4(mat, imat, tempmat);
-
 						/* override with local location */
 						if ((pchan->parent) && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) {
 							armature_mat_pose_to_bone_ex(ob, pchan, pchan->pose_mat, tempmat);
 							copy_v3_v3(mat[3], tempmat[3]);
 						}
+#endif
 					}
 				}
 				/* pose to local with parent */
 				else if (to == CONSTRAINT_SPACE_PARLOCAL) {
 					if (pchan->bone) {
 						invert_m4_m4(imat, pchan->bone->arm_mat);
-						copy_m4_m4(tempmat, mat);
-						mult_m4_m4m4(mat, imat, tempmat);
+						mult_m4_m4m4(mat, imat, mat);
 					}
 				}
 			}
@@ -339,10 +337,12 @@
 				/* local to pose - do inverse procedure that was done for pose to local */
 				if (pchan->bone) {
 					/* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
+					armature_mat_bone_to_pose(pchan, mat, mat);
+#if 0
 					constraint_pchan_diff_mat(pchan, diff_mat);
 
-					copy_m4_m4(tempmat, mat);
-					mult_m4_m4m4(mat, diff_mat, tempmat);
+					mult_m4_m4m4(mat, diff_mat, mat);
+#endif
 				}
 				
 				/* use pose-space as stepping stone for other spaces */
@@ -357,8 +357,7 @@
 				/* local + parent to pose */
 				if (pchan->bone) {					
 					copy_m4_m4(diff_mat, pchan->bone->arm_mat);
-					copy_m4_m4(tempmat, mat);
-					mult_m4_m4m4(mat, tempmat, diff_mat);
+					mult_m4_m4m4(mat, mat, diff_mat);
 				}
 				
 				/* use pose-space as stepping stone for other spaces */
@@ -378,8 +377,7 @@
 				/* 'subtract' parent's effects from owner */
 				mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
 				invert_m4_m4(imat, diff_mat);
-				copy_m4_m4(tempmat, mat);
-				mult_m4_m4m4(mat, imat, tempmat);
+				mult_m4_m4m4(mat, imat, mat);
 			}
 			else {
 				/* Local space in this case will have to be defined as local to the owner's 
@@ -390,17 +388,15 @@
 				zero_v3(diff_mat[3]);
 				
 				invert_m4_m4(imat, diff_mat);
-				copy_m4_m4(tempmat, mat);
-				mult_m4_m4m4(mat, imat, tempmat);
+				mult_m4_m4m4(mat, imat, mat);
 			}
 		}
 		else if (from==CONSTRAINT_SPACE_LOCAL && to==CONSTRAINT_SPACE_WORLD) {
 			/* check that object has a parent - otherwise this won't work */
 			if (ob->parent) {
 				/* 'add' parent's effect back to owner */
-				copy_m4_m4(tempmat, mat);
 				mult_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
-				mult_m4_m4m4(mat, diff_mat, tempmat);
+				mult_m4_m4m4(mat, diff_mat, mat);
 			}
 			else {
 				/* Local space in this case will have to be defined as local to the owner's 
@@ -410,8 +406,7 @@
 				normalize_m4(diff_mat);
 				zero_v3(diff_mat[3]);
 				
-				copy_m4_m4(tempmat, mat);
-				mult_m4_m4m4(mat, diff_mat, tempmat);
+				mult_m4_m4m4(mat, diff_mat, mat);
 			}
 		}
 	}




More information about the Bf-blender-cvs mailing list