From b5a57b193d098fa343cf053167e1faf5078c28c9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 13 Nov 2011 13:08:15 +0000 Subject: Fix #29041: parenting problem with tree IK for iTaSC and iksolver, where it would use the wrong bone as parent on brancing. Patch by Juha Maki-Kanto. --- source/blender/ikplugin/intern/iksolver_plugin.c | 24 +++++++++++++++++++----- source/blender/ikplugin/intern/itasc_plugin.cpp | 10 +++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) (limited to 'source/blender/ikplugin/intern') diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 7159c09d703..eb3695ea217 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -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; apchan[a]==chanlist[segcount-a-1]; a++); - parent= a-1; + a = t = 0; + while (atotchannel) { + // locate first matching channel + for (;ttotchannel && tree->pchan[t]!=chanlist[segcount-a-1];t++); + if (t>=tree->totchannel) + break; + for(; atotchannel && 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; diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index 2cb3a32ae3e..f4720b7fc41 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -326,11 +326,19 @@ static int initialize_chain(Object *ob, bPoseChannel *pchan_tip, bConstraint *co break; for(; atotchannel && 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; -- cgit v1.2.3