bugfix [#21483] Twisting when Dupliframing a Surface Circle (Nurbs) along a Curve.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 8 Oct 2010 07:29:08 +0000 (07:29 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 8 Oct 2010 07:29:08 +0000 (07:29 +0000)
use the curve's twist for follow path constraint and parent-path.

source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/object.c
source/blender/blenlib/BLI_math_rotation.h
source/blender/blenlib/intern/math_rotation.c

index fe69f13bbdae338ed0ed40f940fb71e0d20bd59c..3df395244f44f1903dc50b0c4658f6dd605482cb 100644 (file)
@@ -1201,7 +1201,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
        
        if (VALID_CONS_TARGET(ct)) {
                Curve *cu= ct->tar->data;
-               float q[4], vec[4], dir[3], quat[4], radius, x1;
+               float vec[4], dir[3], radius;
                float totmat[4][4];
                float curvetime;
                
@@ -1217,7 +1217,8 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                        makeDispListCurveTypes(cob->scene, ct->tar, 0);
                
                if (cu->path && cu->path->data) {
-                       if ((data->followflag & FOLLOWPATH_STATIC) == 0) { 
+                       float quat[4];
+                       if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
                                /* animated position along curve depending on time */
                                if (cob->scene)
                                        curvetime= bsystem_time(cob->scene, ct->tar, cu->ctime, 0.0) - data->offset;
@@ -1238,8 +1239,10 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                                curvetime= data->offset_fac;
                        }
                        
-                       if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius, NULL) ) {
+                       if ( where_on_path(ct->tar, curvetime, vec, dir, (data->followflag & FOLLOWPATH_FOLLOW) ? quat : NULL, &radius, NULL) ) { /* quat_pt is quat or NULL*/
                                if (data->followflag & FOLLOWPATH_FOLLOW) {
+#if 0
+                                       float x1, q[4];
                                        vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag);
                                        
                                        normalize_v3(dir);
@@ -1249,10 +1252,13 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                                        q[2]= -x1*dir[1];
                                        q[3]= -x1*dir[2];
                                        mul_qt_qtqt(quat, q, quat);
-                                       
+#else
+                                       quat_apply_track(quat, data->trackflag, data->upflag);
+#endif
+
                                        quat_to_mat4(totmat, quat);
                                }
-                               
+
                                if (data->followflag & FOLLOWPATH_RADIUS) {
                                        float tmat[4][4], rmat[4][4];
                                        scale_m4_fl(tmat, radius);
index 71e5049f2cc718206699efa030b3e33d3ce9e5d6..638cab58229599a7e092966c38ac1c8a26800c8e 100644 (file)
@@ -633,7 +633,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
 
                /* zero the axis which is not used,
                 * the big block of text above now applies to these 3 lines */
-               quat_apply_track(quat, axis-1);
+               quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */
                vec_apply_track(cent, axis-1);
                cent[axis < 4 ? axis-1 : axis-4]= 0.0f;
 
index d9ee67920eb357883d74ee8e90b4260f1c2d6ed3..0c437db335b9ac18732e636f45fd25efbf9c7509 100644 (file)
@@ -1791,9 +1791,10 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
        
        
        /* vec: 4 items! */
-        if( where_on_path(par, ctime, vec, dir, NULL, &radius, NULL) ) {
+       if( where_on_path(par, ctime, vec, dir, cu->flag & CU_FOLLOW ? quat:NULL, &radius, NULL) ) {
 
                if(cu->flag & CU_FOLLOW) {
+#if 0
                        vec_to_quat( quat,dir, ob->trackflag, ob->upflag);
                        
                        /* the tilt */
@@ -1804,8 +1805,11 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
                        q[2]= -x1*dir[1];
                        q[3]= -x1*dir[2];
                        mul_qt_qtqt(quat, q, quat);
-                       
-                       quat_to_mat4( mat,quat);
+#else
+                       quat_apply_track(quat, ob->trackflag, ob->upflag);
+#endif
+
+                       quat_to_mat4(mat,quat);                 
                }
                
                if(cu->flag & CU_PATH_RADIUS) {
index 4b33efc5578f7f0faabd3c4dbfd8fd66582d025c..321fd28a62f2530d51d815af842926b3980ef188 100644 (file)
@@ -169,7 +169,7 @@ void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
 void mat4_to_dquat(DualQuat *r, float base[4][4], float M[4][4]);
 void dquat_to_mat4(float R[4][4], DualQuat *dq);
 
-void quat_apply_track(float quat[4], short axis);
+void quat_apply_track(float quat[4], short axis, short upflag);
 void vec_apply_track(float vec[3], short axis);
 
 float lens_to_angle(float lens);
index be383fdc73c0db97315e85aeaaaf9ea0464c032a..c4f12a5efc1c432c171bcae0e33fecbac484d32b 100644 (file)
@@ -1531,25 +1531,27 @@ void copy_dq_dq(DualQuat *dq1, DualQuat *dq2)
 }
 
 /* axis matches eTrackToAxis_Modes */
-void quat_apply_track(float quat[4], short axis)
-{
-       /* axis calculated as follows */        
-       /* float axis[3]= {1,0,0}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180));   
-          float axis[3]= {0,1,0}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180));   
-          float axis[3]= {0,0,2}; axis_angle_to_quat(q, axis, 90 * (M_PI / 180));   
-          float axis[3]= {1,0,0}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180));  
-          float axis[3]= {0,1,0}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180));  
-          float axis[3]= {0,0,2}; axis_angle_to_quat(q, axis, -90 * (M_PI / 180)); */
-
-       /* notice x/y flipped intentionally */
-       const float quat_track[][4]= {{0.70710676908493, 0.0, -0.70710676908493, 0.0},  /* pos-y */ 
-                                     {0.70710676908493, 0.70710676908493, 0.0, 0.0},  /* pos-x */ 
-                                     {0.70710676908493, 0.0, 0.0, 0.70710676908493},  /* pos-z */ 
-                                     {0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* neg-y */ 
-                                     {0.70710676908493, -0.70710676908493, 0.0, 0.0}, /* neg-x */ 
-                                     {0.70710676908493, 0.0, 0.0, -0.70710676908493}};/* neg-z */ 
-       
+void quat_apply_track(float quat[4], short axis, short upflag)
+{      
+       /* rotations are hard coded to match vec_to_quat */
+       const float quat_track[][4]= {{0.70710676908493, 0.0, -0.70710676908493, 0.0},  /* pos-y90 */ 
+                                     {0.5, 0.5, 0.5, 0.5},  /* Quaternion((1,0,0), radians(90)) * Quaternion((0,1,0), radians(90)) */ 
+                                     {0.70710676908493, 0.0, 0.0, 0.70710676908493},  /* pos-z90 */ 
+                                     {0.70710676908493, 0.0, 0.70710676908493, 0.0}, /* neg-y90 */ 
+                                     {0.5, -0.5, -0.5, 0.5}, /* Quaternion((1,0,0), radians(-90)) * Quaternion((0,1,0), radians(-90)) */ 
+                                     {1, 0, 0, 0}};/* no rotation */ 
+
        mul_qt_qtqt(quat, quat, quat_track[axis]);
+
+       if(axis>2)
+               axis= axis-3;
+
+       /* 90d rotation when the second */
+       if(upflag != (2-axis)>>1) { // [0->1, 1->0, 2->0]
+               float q[4]= {0.70710676908493, 0, 0, 0};
+               q[axis+1] = ((axis==1)) ? 0.70710676908493 : -0.70710676908493; /* flip non Y axis */
+               mul_qt_qtqt(quat, quat, q);
+       }
 }
 
 void vec_apply_track(float vec[3], short axis)
@@ -1565,9 +1567,9 @@ void vec_apply_track(float vec[3], short axis)
                vec[2]=  -tvec[1];
                break;
        case 1: /* pos-y */
-               vec[0]=  tvec[2];
+               /* vec[0]= tvec[0]; */
                /* vec[1]=  0.0; */
-               vec[2]= -tvec[0];
+               /* vec[2]= tvec[2]; */ 
                break;
        case 2: /* pos-z */
                vec[0]=  tvec[1];
@@ -1580,12 +1582,12 @@ void vec_apply_track(float vec[3], short axis)
                vec[2]= -tvec[2];
                break;
        case 4: /* neg-y */
-               vec[0]= -tvec[0];
+               vec[0]= -tvec[2];
                /* vec[1]=  0.0; */
-               vec[2]= -tvec[2];
+               vec[2]= tvec[0];
                break;
        case 5: /* neg-z */
-               vec[0]=  tvec[0];
+               vec[0]= -tvec[0];
                vec[1]= -tvec[1];
                /* vec[2]=  0.0; */
                break;