Spline IK Bugfixes 1:
authorJoshua Leung <aligorith@gmail.com>
Sun, 1 Nov 2009 22:30:47 +0000 (22:30 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sun, 1 Nov 2009 22:30:47 +0000 (22:30 +0000)
* Fixed crash when reloading a file with Spline IK and/or Damped Track constraints. The targets for these constraints weren't getting relinked.
* Fixed problems with removing Spline IK making some bones unable to be manipulated.
* Jotted down some comments in the Spline IK code noting places where additional tweaks will be added.

source/blender/blenkernel/intern/armature.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/object/object_constraint.c

index 0bb0041..e5bf0fb 100644 (file)
@@ -1682,6 +1682,7 @@ static void splineik_init_tree_from_pchan(Object *ob, bPoseChannel *pchan_tip)
        
        /* perform binding step if required */
        if ((ikData->flag & CONSTRAINT_SPLINEIK_BOUND) == 0) {
+               float segmentLen= (1.0f / (float)segcount);
                int i;
                
                /* setup new empty array for the points list */
@@ -1701,7 +1702,7 @@ static void splineik_init_tree_from_pchan(Object *ob, bPoseChannel *pchan_tip)
                                if (totLength == 0.0f) {
                                        /* 1) equi-spaced joints */
                                        // TODO: maybe this should become an option too, in case we want this option by default
-                                       ikData->points[i]= (1.0f / (float)segcount); // TODO: optimize by puttig this outside the loop!
+                                       ikData->points[i]= segmentLen;
                                }
                                else {
                                         /*     2) to find this point on the curve, we take a step from the previous joint
@@ -1720,6 +1721,12 @@ static void splineik_init_tree_from_pchan(Object *ob, bPoseChannel *pchan_tip)
                ikData->flag |= CONSTRAINT_SPLINEIK_BOUND;
        }
        
+       /* apply corrections for sensitivity to scaling on a copy of the bind points,
+        * since it's easier to determine the positions of all the joints beforehand this way
+        */
+       // TODO: code me!
+       
+       
        /* make a new Spline-IK chain, and store it in the IK chains */
        // TODO: we should check if there is already an IK chain on this, since that would take presidence...
        {
@@ -1801,10 +1808,10 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Object *ob, bPoseChanne
        VECCOPY(pchan->pose_mat[1], splineVec);
        
        
-       /* step 3: determine two vectors which will both be at right angles to the bone vector 
-        *      based on the method described at 
+       /* step 3a: determine two vectors which will both be at right angles to the bone vector 
+        *      based on the "Gram Schmidt process" for finding a set of Orthonormal Vectors, described at 
         *              http://ltcconline.net/greenl/courses/203/Vectors/orthonormalBases.htm
-        *      and normalise them to make sure they they don't act strangely
+        *      and normalise them to make sure they will behave nicely (as unit vectors)
         */
                /* x-axis = dirX - projection(dirX onto splineVec) */
        Projf(axis1, dirX, splineVec); /* project dirX onto splineVec */
@@ -1821,12 +1828,14 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Object *ob, bPoseChanne
        
        Normalize(pchan->pose_mat[2]);
        
+       /* step 3b: rotate these axes for roll control and also to minimise flipping rotations */
+       // NOTE: for controlling flipping rotations, we could look to the curve for guidance...
+               // TODO: code me!
        
-       /* step 4a: multiply all the axes of the bone by the scaling factor to get uniform scaling */
-       // TODO: maybe this can be extended to give non-uniform scaling?
-       //VecMulf(pchan->pose_mat[0], scaleFac);
+       
+       /* step 4: only multiply the y-axis by the scaling factor to get nice volume-preservation */
+       // NOTE: the x+z could get multiplied too, but that may be best left as an option
        VecMulf(pchan->pose_mat[1], scaleFac);
-       //VecMulf(pchan->pose_mat[2], scaleFac);        
        
        /* step 5: set the location of the bone in the matrix */
        VECCOPY(pchan->pose_mat[3], pchan->pose_head);
@@ -1851,6 +1860,8 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_
                                bPoseChannel *pchan= tree->chain[i];
                                splineik_evaluate_bone(tree, ob, pchan, i);
                        }
+                       
+                       // TODO: if another pass is needed to ensure the validity of the chain after blending, it should go here
                }
                
                /* free the tree info now */
@@ -2166,7 +2177,7 @@ void where_is_pose (Scene *scene, Object *ob)
                
                /* 1. clear flags */
                for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                       pchan->flag &= ~(POSE_DONE|POSE_CHAIN|POSE_IKTREE);
+                       pchan->flag &= ~(POSE_DONE|POSE_CHAIN|POSE_IKTREE|POSE_IKSPLINE);
                }
                
                /* 2a. construct the IK tree (standard IK) */
index 5fc5fd8..ebfa701 100644 (file)
@@ -2265,6 +2265,20 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
                                data->target = newlibadr(fd, id->lib, data->target);
                        }
                        break;
+               case CONSTRAINT_TYPE_DAMPTRACK:
+                       {
+                               bDampTrackConstraint *data;
+                               data= ((bDampTrackConstraint*)con->data);
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                       }
+                       break;
+               case CONSTRAINT_TYPE_SPLINEIK:
+                       {
+                               bSplineIKConstraint *data;
+                               data= ((bSplineIKConstraint*)con->data);
+                               data->tar = newlibadr(fd, id->lib, data->tar);
+                       }
+                       break;
                case CONSTRAINT_TYPE_NULL:
                        break;
                }
@@ -10732,6 +10746,18 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
                                expand_doit(fd, mainvar, data->target);
                        }
                        break;
+               case CONSTRAINT_TYPE_DAMPTRACK:
+                       {
+                               bDampTrackConstraint *data = (bDampTrackConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                       }
+                       break;
+               case CONSTRAINT_TYPE_SPLINEIK:
+                       {
+                               bSplineIKConstraint *data = (bSplineIKConstraint*)curcon->data;
+                               expand_doit(fd, mainvar, data->tar);
+                       }
+                       break;
                default:
                        break;
                }
index 15ec8d6..35b1157 100644 (file)
@@ -1450,7 +1450,7 @@ static int pose_ik_clear_exec(bContext *C, wmOperator *op)
        }
        CTX_DATA_END;
        
-       /* */
+       /* refresh depsgraph */
        DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
 
        /* note, notifier might evolve */