[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23577] trunk/blender/source/blender/ blenkernel/intern: Use curve twist for the CurveDeform modifier and bones ( anything that uses curve_deform_verts() and curve_deform_vector()).

Campbell Barton ideasman42 at gmail.com
Thu Oct 1 01:31:10 CEST 2009


Revision: 23577
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23577
Author:   campbellbarton
Date:     2009-10-01 01:31:10 +0200 (Thu, 01 Oct 2009)

Log Message:
-----------
Use curve twist for the CurveDeform modifier and bones (anything that uses curve_deform_verts() and curve_deform_vector()).
So means minimum twist and twist smoothing are now used.

the Z up quaternion from the path is rotated to match the up axis given.

There was no logical rule for the up vector, some cases flipped the normals when used with the CurveDeform modifier.
Use the default X-Up behavior and match other settings with this. (comments explain this in detail).



- Interpolating quaternions didn't work in some cases, disabled for now.
- 'no_rot_axis' is different from in 2.4x since it now removes rotation from the tilt whereas before it edited the axis before calculating the tilt.

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

Modified: trunk/blender/source/blender/blenkernel/intern/anim.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/anim.c	2009-09-30 22:58:34 UTC (rev 23576)
+++ trunk/blender/source/blender/blenkernel/intern/anim.c	2009-09-30 23:31:10 UTC (rev 23577)
@@ -280,17 +280,27 @@
 	if (quat) {
 		float totfac, q1[4], q2[4];
 
+		/* checks for totfac are needed when 'fac' is 1.0 key_curve_position_weights can assign zero
+		 * to more then one index in data which can give divide by zero error */
+/*
 		totfac= data[0]+data[1];
-		QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
+		if(totfac>0.000001)	QuatInterpol(q1, p0->quat, p1->quat, data[0] / totfac);
+		else				QUATCOPY(q1, p1->quat);
+
 		NormalQuat(q1);
 
 		totfac= data[2]+data[3];
-		QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
+		if(totfac>0.000001)	QuatInterpol(q2, p2->quat, p3->quat, data[2] / totfac);
+		else				QUATCOPY(q1, p3->quat);
 		NormalQuat(q2);
 
 		totfac = data[0]+data[1]+data[2]+data[3];
-		QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
+		if(totfac>0.000001)	QuatInterpol(quat, q1, q2, (data[0]+data[1]) / totfac);
+		else				QUATCOPY(quat, q2);
 		NormalQuat(quat);
+		*/
+		// XXX - find some way to make quat interpolation work correctly, above code fails in rare but nasty cases.
+		QUATCOPY(quat, p1->quat);
 	}
 
 	if(radius)

Modified: trunk/blender/source/blender/blenkernel/intern/lattice.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/lattice.c	2009-09-30 22:58:34 UTC (rev 23576)
+++ trunk/blender/source/blender/blenkernel/intern/lattice.c	2009-09-30 23:31:10 UTC (rev 23577)
@@ -524,30 +524,13 @@
 static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
 {
 	Curve *cu= par->data;
-	float fac, loc[4], dir[3], cent[3], radius;
-	short upflag, index;
-	
-	if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) {
-		upflag= OB_POSZ;
-		cent[0]= 0.0;
-		cent[1]= co[1];
-		cent[2]= co[2];
-		index= 0;
-	}
-	else if(axis==MOD_CURVE_POSY || axis==MOD_CURVE_NEGY) {
-		upflag= OB_POSZ;
-		cent[0]= co[0];
-		cent[1]= 0.0;
-		cent[2]= co[2];
-		index= 1;
-	}
-	else {
-		upflag= OB_POSY;
-		cent[0]= co[0];
-		cent[1]= co[1];
-		cent[2]= 0.0;
-		index= 2;
-	}
+	float fac, loc[4], dir[3], new_quat[4], radius;
+	short /*upflag, */ index;
+
+	index= axis-1;
+	if(index>2)
+		index -= 3; /* negative  */
+
 	/* to be sure, mostly after file load */
 	if(cu->path==NULL) {
 		makeDispListCurveTypes(scene, par, 0);
@@ -555,7 +538,7 @@
 	}
 	
 	/* options */
-	if(ELEM3(axis, OB_NEGX, OB_NEGY, OB_NEGZ)) {
+	if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */
 		if(cu->flag & CU_STRETCH)
 			fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
 		else
@@ -579,9 +562,10 @@
 	}
 #endif // XXX old animation system
 	
-	if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) {	/* returns OK */
-		float q[4], mat[3][3], quat[4];
-		
+	if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) {	/* returns OK */
+		float quat[4], cent[3];
+
+#if 0	// XXX - 2.4x Z-Up, Now use bevel tilt.
 		if(cd->no_rot_axis)	/* set by caller */
 			dir[cd->no_rot_axis-1]= 0.0f;
 		
@@ -597,22 +581,104 @@
 			q[2]= -fac*dir[1];
 			q[3]= -fac*dir[2];
 			QuatMul(quat, q, quat);
-		}		
-		QuatToMat3(quat, mat);
+		}
+#endif
 
-		if(cu->flag & CU_PATH_RADIUS) {
-			float tmat[3][3], rmat[3][3];
-			Mat3Scale(tmat, radius);
-			Mat3MulMat3(rmat, mat, tmat);
-			Mat3CpyMat3(mat, rmat);
+
+		static float q_x90d[4] = {0.70710676908493, 0.70710676908493, 0.0, 0.0};	// float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
+		static float q_y90d[4] = {0.70710676908493, 0.0, 0.70710676908493, 0.0};	// float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
+		static float q_z90d[4] = {0.70710676908493, 0.0, 0.0, 0.70710676908493};	// float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, 90 * (M_PI / 180));
+
+		static float q_nx90d[4] = {0.70710676908493, -0.70710676908493, 0.0, 0.0};	// float rot_axis[3]= {1,0,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
+		static float q_ny90d[4] = {0.70710676908493, 0.0, -0.70710676908493, 0.0};	// float rot_axis[3]= {0,1,0}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
+		static float q_nz90d[4] = {0.70710676908493, 0.0, 0.0, -0.70710676908493};	// float rot_axis[3]= {0,0,2}; AxisAngleToQuat(q, rot_axis, -90 * (M_PI / 180));
+
+
+		if(cd->no_rot_axis) {	/* set by caller */
+
+			/* this is not exactly the same as 2.4x, since the axis is having rotation removed rather then
+			 * changing the axis before calculating the tilt but serves much the same purpose */
+			float dir_flat[3]={0,0,0}, q[4];
+			VECCOPY(dir_flat, dir);
+			dir_flat[cd->no_rot_axis-1]= 0.0f;
+
+			Normalize(dir);
+			Normalize(dir_flat);
+
+			RotationBetweenVectorsToQuat(q, dir, dir_flat); /* Could this be done faster? */
+
+			QuatMul(new_quat, q, new_quat);
 		}
 
+
+		/* Logic for 'cent' orientation *
+		 *
+		 * The way 'co' is copied to 'cent' may seem to have no meaning, but it does.
+		 *
+		 * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark.
+		 * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise
+		 * Notice X,Y,Z Up all have light colors and each ordered CCW.
+		 *
+		 * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
+		 * */
+
+		switch(axis) {
+		case MOD_CURVE_POSX:
+			QuatMul(quat, new_quat, q_y90d);
+
+			cent[0]=  0.0;
+			cent[1]=  co[2];
+			cent[2]=  co[1];
+			break;
+		case MOD_CURVE_NEGX:
+			QuatMul(quat, new_quat, q_ny90d);
+
+			cent[0]=  0.0;
+			cent[1]= -co[1];
+			cent[2]=  co[2];
+
+			break;
+		case MOD_CURVE_POSY:
+			QuatMul(quat, new_quat, q_x90d);
+
+			cent[0]=  co[2];
+			cent[1]=  0.0;
+			cent[2]= -co[0];
+			break;
+		case MOD_CURVE_NEGY:
+			QuatMul(quat, new_quat, q_nx90d);
+
+			cent[0]= -co[0];
+			cent[1]=  0.0;
+			cent[2]= -co[2];
+			break;
+		case MOD_CURVE_POSZ:
+			QuatMul(quat, new_quat, q_z90d);
+
+			cent[0]=  co[1];
+			cent[1]= -co[0];
+			cent[2]=  0.0;
+			break;
+		case MOD_CURVE_NEGZ:
+			QuatMul(quat, new_quat, q_nz90d);
+
+			cent[0]=  co[0];
+			cent[1]= -co[1];
+			cent[2]=  0.0;
+			break;
+		}
+
+		/* scale if enabled */
+		if(cu->flag & CU_PATH_RADIUS)
+			VecMulf(cent, radius);
+		
 		/* local rotation */
-		Mat3MulVecfl(mat, cent);
-		
+		NormalQuat(quat);
+		QuatMulVecf(quat, cent);
+
 		/* translation */
 		VECADD(co, cent, loc);
-		
+
 		if(quatp)
 			QUATCOPY(quatp, quat);
 		





More information about the Bf-blender-cvs mailing list