[Bf-blender-cvs] [f05f2f03360] master: Fix T51971: IK non-uniform scale regression.

Brecht Van Lommel noreply at git.blender.org
Mon Jul 17 18:55:02 CEST 2017


Commit: f05f2f0336025f00a299ec930151a155d55c6ab3
Author: Brecht Van Lommel
Date:   Wed Jul 5 23:15:12 2017 +0200
Branches: master
https://developer.blender.org/rBf05f2f0336025f00a299ec930151a155d55c6ab3

Fix T51971: IK non-uniform scale regression.

This is a different fix for the issue from D2088, preserving backwards compatibility
for IK stretching. The main problem with this patch is that this new behavior has
been there for a year, so it may break rigs created since then which rely on the new
IK stretch behavior.

Test file for various cases:
https://developer.blender.org/diffusion/BL/browse/trunk/lib/tests/animation/IK.blend

Reviewers: campbellbarton

Subscribers: maverick, pkrime

Differential Revision: https://developer.blender.org/D2743

===================================================================

M	source/blender/ikplugin/intern/iksolver_plugin.c

===================================================================

diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 6ea311b2c7b..f837789914e 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -217,9 +217,27 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3])   // nr =
 	copy_m4_m3(ikmat, ik_mat);
 
 	if (pchan->parent)
-		mul_m4_series(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat);
+		mul_m4_m4m4(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat);
 	else
-		mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, ikmat);
+		copy_m4_m4(pchan->pose_mat, pchan->chan_mat);
+
+#ifdef USE_NONUNIFORM_SCALE
+	/* apply IK mat, but as if the bones have uniform scale since the IK solver
+	 * is not aware of non-uniform scale */
+	float scale[3];
+	mat4_to_size(scale, pchan->pose_mat);
+	normalize_v3_length(pchan->pose_mat[0], scale[1]);
+	normalize_v3_length(pchan->pose_mat[2], scale[1]);
+#endif
+
+	mul_m4_m4m4(pchan->pose_mat, pchan->pose_mat, ikmat);
+
+#ifdef USE_NONUNIFORM_SCALE
+	float ik_scale[3];
+	mat3_to_size(ik_scale, ik_mat);
+	normalize_v3_length(pchan->pose_mat[0], scale[0] * ik_scale[0]);
+	normalize_v3_length(pchan->pose_mat[2], scale[2] * ik_scale[2]);
+#endif
 
 	/* calculate head */
 	copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]);
@@ -308,6 +326,10 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
 		/* change length based on bone size */
 		length = bone->length * len_v3(R_bonemat[1]);
 
+		/* basis must be pure rotation */
+		normalize_m3(R_bonemat);
+		normalize_m3(R_parmat);
+
 		/* compute rest basis and its inverse */
 		copy_m3_m3(rest_basis, bone->bone_mat);
 		transpose_m3_m3(irest_basis, bone->bone_mat);
@@ -317,11 +339,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
 		mul_m3_m3m3(full_basis, iR_parmat, R_bonemat);
 		mul_m3_m3m3(basis, irest_basis, full_basis);
 
-		/* basis must be pure rotation */
-		normalize_m3(basis);
-
 		/* transform offset into local bone space */
-		normalize_m3(iR_parmat);
 		mul_m3_v3(iR_parmat, start);
 
 		IK_SetTransform(seg, start, rest_basis, basis, length);
@@ -545,18 +563,6 @@ void iksolver_execute_tree(struct Scene *scene, Object *ob,  bPoseChannel *pchan
 			tree->pchan[a]->flag |= POSE_CHAIN;
 		}
 
-#ifdef USE_NONUNIFORM_SCALE
-		float (*pchan_scale_data)[3] = MEM_mallocN(sizeof(float[3]) * tree->totchannel, __func__);
-
-		for (a = 0; a < tree->totchannel; a++) {
-			mat4_to_size(pchan_scale_data[a], tree->pchan[a]->pose_mat);
-
-			/* make uniform at y scale since this controls the length */
-			normalize_v3_length(tree->pchan[a]->pose_mat[0], pchan_scale_data[a][1]);
-			normalize_v3_length(tree->pchan[a]->pose_mat[2], pchan_scale_data[a][1]);
-		}
-#endif
-
 		/* 5. execute the IK solver */
 		execute_posetree(scene, ob, tree);
 
@@ -571,14 +577,6 @@ void iksolver_execute_tree(struct Scene *scene, Object *ob,  bPoseChannel *pchan
 			where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
 		}
 
-#ifdef USE_NONUNIFORM_SCALE
-		for (a = 0; a < tree->totchannel; a++) {
-			normalize_v3_length(tree->pchan[a]->pose_mat[0], pchan_scale_data[a][0]);
-			normalize_v3_length(tree->pchan[a]->pose_mat[2], pchan_scale_data[a][2]);
-		}
-		MEM_freeN(pchan_scale_data);
-#endif
-
 		/* 7. and free */
 		BLI_remlink(&pchan_root->iktree, tree);
 		free_posetree(tree);




More information about the Bf-blender-cvs mailing list