[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12483] trunk/blender/source/blender/ blenkernel/intern/armature.c:

Brecht Van Lommel brechtvanlommel at pandora.be
Mon Nov 5 19:44:42 CET 2007


Revision: 12483
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12483
Author:   blendix
Date:     2007-11-05 19:44:42 +0100 (Mon, 05 Nov 2007)

Log Message:
-----------

Bugfix:
B-bones didn't work well with non-uniform scaling applied to them.
The code to solve this is not too pretty, but don't know how to do
it simpler, and at least it makes that stretchy spine work.

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

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2007-11-05 17:38:07 UTC (rev 12482)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2007-11-05 18:44:42 UTC (rev 12483)
@@ -411,12 +411,31 @@
 	Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
 	bPoseChannel *next, *prev;
 	Bone *bone= pchan->bone;
-	float h1[3], h2[3], length, hlength1, hlength2, roll1=0.0f, roll2;
-	float mat3[3][3], imat[4][4];
+	float h1[3], h2[3], scale[3], length, hlength1, hlength2, roll1=0.0f, roll2;
+	float mat3[3][3], imat[4][4], posemat[4][4], scalemat[4][4], iscalemat[4][4];
 	float data[MAX_BBONE_SUBDIV+1][4], *fp;
-	int a;
+	int a, doscale= 0;
+
+	length= bone->length;
+
+	if(!rest) {
+		/* check if we need to take non-uniform bone scaling into account */
+		scale[0]= VecLength(pchan->pose_mat[0]);
+		scale[1]= VecLength(pchan->pose_mat[1]);
+		scale[2]= VecLength(pchan->pose_mat[2]);
+
+		if(fabs(scale[0] - scale[1]) > 1e-6f || fabs(scale[1] - scale[2]) > 1e-6f) {
+			Mat4One(scalemat);
+			scalemat[0][0]= scale[0];
+			scalemat[1][1]= scale[1];
+			scalemat[2][2]= scale[2];
+			Mat4Invert(iscalemat, scalemat);
+
+			length *= scale[1];
+			doscale = 1;
+		}
+	}
 	
-	length= bone->length;
 	hlength1= bone->ease1*length*0.390464f;		// 0.5*sqrt(2)*kappa, the handle length for near-perfect circles
 	hlength2= bone->ease2*length*0.390464f;
 	
@@ -432,8 +451,14 @@
 		first point = (0,0,0)
 		last point =  (0, length, 0) */
 	
-	if(rest)
+	if(rest) {
 		Mat4Invert(imat, pchan->bone->arm_mat);
+	}
+	else if(doscale) {
+		Mat4CpyMat4(posemat, pchan->pose_mat);
+		Mat4Ortho(posemat);
+		Mat4Invert(imat, posemat);
+	}
 	else
 		Mat4Invert(imat, pchan->pose_mat);
 	
@@ -527,8 +552,15 @@
 	for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) {
 		VecSubf(h1, fp+4, fp);
 		vec_roll_to_mat3(h1, fp[3], mat3);		// fp[3] is roll
+
 		Mat4CpyMat3(result_array[a].mat, mat3);
 		VECCOPY(result_array[a].mat[3], fp);
+
+		if(doscale) {
+			/* correct for scaling when this matrix is used in scaled space */
+			Mat4MulSerie(result_array[a].mat, iscalemat, result_array[a].mat,
+				scalemat, NULL, NULL, NULL, NULL, NULL);
+		}
 	}
 	
 	return result_array;





More information about the Bf-blender-cvs mailing list