Fix #29041: parenting problem with tree IK for iTaSC and iksolver, where it
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 13 Nov 2011 13:08:15 +0000 (13:08 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 13 Nov 2011 13:08:15 +0000 (13:08 +0000)
would use the wrong bone as parent on brancing. Patch by Juha Maki-Kanto.

intern/itasc/kdl/chain.hpp
source/blender/ikplugin/intern/iksolver_plugin.c
source/blender/ikplugin/intern/itasc_plugin.cpp

index a2b4905622e2f1e1d74c6d4928285be582b6ad40..81c606b73c028ee3fc7d8338dbcc20d9402b1a61 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "segment.hpp"
 #include <string>
+#include <Eigen/StdVector>
 
 namespace KDL {
     /**
index 7159c09d703dcf4da694d9739bf4a2dff4db42ac..eb3695ea21739730c1d3f2efdfd39532ba2e719f 100644 (file)
@@ -62,8 +62,8 @@ static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_t
        PoseTarget *target;
        bConstraint *con;
        bKinematicConstraint *data;
-       int a, segcount= 0, size, newsize, *oldparent, parent;
-       
+       int a, t, segcount= 0, size, newsize, *oldparent, parent;
+
        /* find IK constraint, and validate it */
        for(con= pchan_tip->constraints.first; con; con= con->next) {
                if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
@@ -114,7 +114,7 @@ static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_t
        if(tree==NULL) {
                /* make new tree */
                tree= MEM_callocN(sizeof(PoseTree), "posetree");
-       
+
                tree->type= CONSTRAINT_TYPE_KINEMATIC;
                
                tree->iterations= data->iterations;
@@ -138,13 +138,27 @@ static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_t
 
                /* skip common pose channels and add remaining*/
                size= MIN2(segcount, tree->totchannel);
-               for(a=0; a<size && tree->pchan[a]==chanlist[segcount-a-1]; a++);
-               parent= a-1;
+               a = t = 0;
+               while (a<size && t<tree->totchannel) {
+                       // locate first matching channel
+                       for (;t<tree->totchannel && tree->pchan[t]!=chanlist[segcount-a-1];t++);
+                       if (t>=tree->totchannel)
+                               break;
+                       for(; a<size && t<tree->totchannel && tree->pchan[t]==chanlist[segcount-a-1]; a++, t++);
+               }
 
                segcount= segcount-a;
                target->tip= tree->totchannel + segcount - 1;
 
                if (segcount > 0) {
+                       for(parent = a - 1; parent < tree->totchannel; parent++)
+                               if(tree->pchan[parent] == chanlist[segcount-1]->parent)
+                                       break;
+                       
+                       /* shouldn't happen, but could with dependency cycles */
+                       if(parent == tree->totchannel)
+                               parent = a - 1;
+
                        /* resize array */
                        newsize= tree->totchannel + segcount;
                        oldchan= tree->pchan;
index 2cb3a32ae3edb391a301e20f2a594a6c91a23b64..f4720b7fc412179d722624e49652a9e6f5a4a1e8 100644 (file)
@@ -326,11 +326,19 @@ static int initialize_chain(Object *ob, bPoseChannel *pchan_tip, bConstraint *co
                                break;
                        for(; a<size && t<tree->totchannel && tree->pchan[t]==chanlist[segcount-a-1]; a++, t++);
                }
-               parent= a-1;
+
                segcount= segcount-a;
                target->tip= tree->totchannel + segcount - 1;
 
                if (segcount > 0) {
+                       for(parent = a - 1; parent < tree->totchannel; parent++)
+                               if(tree->pchan[parent] == chanlist[segcount-1]->parent)
+                                       break;
+                       
+                       /* shouldn't happen, but could with dependency cycles */
+                       if(parent == tree->totchannel)
+                               parent = a - 1;
+
                        /* resize array */
                        newsize= tree->totchannel + segcount;
                        oldchan= tree->pchan;