Blender V2.61 - r43446

iksolver_plugin.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Original author: Benoit Bolsee
00024  * Contributor(s): 
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  */
00028 
00034 #include "MEM_guardedalloc.h"
00035 
00036 #include "BIK_api.h"
00037 #include "BLI_blenlib.h"
00038 #include "BLI_math.h"
00039 #include "BLI_utildefines.h"
00040 
00041 #include "BKE_armature.h"
00042 #include "BKE_constraint.h"
00043 
00044 #include "DNA_object_types.h"
00045 #include "DNA_action_types.h"
00046 #include "DNA_constraint_types.h"
00047 #include "DNA_armature_types.h"
00048 
00049 #include "IK_solver.h"
00050 #include "iksolver_plugin.h"
00051 
00052 #include <string.h> /* memcpy */
00053 
00054 /* ********************** THE IK SOLVER ******************* */
00055 
00056 /* allocates PoseTree, and links that to root bone/channel */
00057 /* Note: detecting the IK chain is duplicate code... in drawarmature.c and in transform_conversions.c */
00058 static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_tip)
00059 {
00060     bPoseChannel *curchan, *pchan_root=NULL, *chanlist[256], **oldchan;
00061     PoseTree *tree;
00062     PoseTarget *target;
00063     bConstraint *con;
00064     bKinematicConstraint *data;
00065     int a, t, segcount= 0, size, newsize, *oldparent, parent;
00066 
00067     /* find IK constraint, and validate it */
00068     for(con= pchan_tip->constraints.first; con; con= con->next) {
00069         if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
00070             data=(bKinematicConstraint*)con->data;
00071             if (data->flag & CONSTRAINT_IK_AUTO) break;
00072             if (data->tar==NULL) continue;
00073             if (data->tar->type==OB_ARMATURE && data->subtarget[0]==0) continue;
00074             if ((con->flag & (CONSTRAINT_DISABLE|CONSTRAINT_OFF))==0 && (con->enforce != 0.0f)) break;
00075         }
00076     }
00077     if(con==NULL) return;
00078     
00079     /* exclude tip from chain? */
00080     if(!(data->flag & CONSTRAINT_IK_TIP))
00081         pchan_tip= pchan_tip->parent;
00082     
00083     /* Find the chain's root & count the segments needed */
00084     for (curchan = pchan_tip; curchan; curchan=curchan->parent){
00085         pchan_root = curchan;
00086         
00087         curchan->flag |= POSE_CHAIN;    // don't forget to clear this
00088         chanlist[segcount]=curchan;
00089         segcount++;
00090         
00091         if(segcount==data->rootbone || segcount>255) break; // 255 is weak
00092     }
00093     if (!segcount) return;
00094 
00095     /* setup the chain data */
00096     
00097     /* we make tree-IK, unless all existing targets are in this chain */
00098     for(tree= pchan_root->iktree.first; tree; tree= tree->next) {
00099         for(target= tree->targets.first; target; target= target->next) {
00100             curchan= tree->pchan[target->tip];
00101             if(curchan->flag & POSE_CHAIN)
00102                 curchan->flag &= ~POSE_CHAIN;
00103             else
00104                 break;
00105         }
00106         if(target) break;
00107     }
00108 
00109     /* create a target */
00110     target= MEM_callocN(sizeof(PoseTarget), "posetarget");
00111     target->con= con;
00112     pchan_tip->flag &= ~POSE_CHAIN;
00113 
00114     if(tree==NULL) {
00115         /* make new tree */
00116         tree= MEM_callocN(sizeof(PoseTree), "posetree");
00117 
00118         tree->type= CONSTRAINT_TYPE_KINEMATIC;
00119         
00120         tree->iterations= data->iterations;
00121         tree->totchannel= segcount;
00122         tree->stretch = (data->flag & CONSTRAINT_IK_STRETCH);
00123         
00124         tree->pchan= MEM_callocN(segcount*sizeof(void*), "ik tree pchan");
00125         tree->parent= MEM_callocN(segcount*sizeof(int), "ik tree parent");
00126         for(a=0; a<segcount; a++) {
00127             tree->pchan[a]= chanlist[segcount-a-1];
00128             tree->parent[a]= a-1;
00129         }
00130         target->tip= segcount-1;
00131         
00132         /* AND! link the tree to the root */
00133         BLI_addtail(&pchan_root->iktree, tree);
00134     }
00135     else {
00136         tree->iterations= MAX2(data->iterations, tree->iterations);
00137         tree->stretch= tree->stretch && !(data->flag & CONSTRAINT_IK_STRETCH);
00138 
00139         /* skip common pose channels and add remaining*/
00140         size= MIN2(segcount, tree->totchannel);
00141         a = t = 0;
00142         while (a<size && t<tree->totchannel) {
00143             // locate first matching channel
00144             for (;t<tree->totchannel && tree->pchan[t]!=chanlist[segcount-a-1];t++);
00145             if (t>=tree->totchannel)
00146                 break;
00147             for(; a<size && t<tree->totchannel && tree->pchan[t]==chanlist[segcount-a-1]; a++, t++);
00148         }
00149 
00150         segcount= segcount-a;
00151         target->tip= tree->totchannel + segcount - 1;
00152 
00153         if (segcount > 0) {
00154             for(parent = a - 1; parent < tree->totchannel; parent++)
00155                 if(tree->pchan[parent] == chanlist[segcount-1]->parent)
00156                     break;
00157             
00158             /* shouldn't happen, but could with dependency cycles */
00159             if(parent == tree->totchannel)
00160                 parent = a - 1;
00161 
00162             /* resize array */
00163             newsize= tree->totchannel + segcount;
00164             oldchan= tree->pchan;
00165             oldparent= tree->parent;
00166 
00167             tree->pchan= MEM_callocN(newsize*sizeof(void*), "ik tree pchan");
00168             tree->parent= MEM_callocN(newsize*sizeof(int), "ik tree parent");
00169             memcpy(tree->pchan, oldchan, sizeof(void*)*tree->totchannel);
00170             memcpy(tree->parent, oldparent, sizeof(int)*tree->totchannel);
00171             MEM_freeN(oldchan);
00172             MEM_freeN(oldparent);
00173 
00174             /* add new pose channels at the end, in reverse order */
00175             for(a=0; a<segcount; a++) {
00176                 tree->pchan[tree->totchannel+a]= chanlist[segcount-a-1];
00177                 tree->parent[tree->totchannel+a]= tree->totchannel+a-1;
00178             }
00179             tree->parent[tree->totchannel]= parent;
00180             
00181             tree->totchannel= newsize;
00182         }
00183 
00184         /* move tree to end of list, for correct evaluation order */
00185         BLI_remlink(&pchan_root->iktree, tree);
00186         BLI_addtail(&pchan_root->iktree, tree);
00187     }
00188 
00189     /* add target to the tree */
00190     BLI_addtail(&tree->targets, target);
00191     /* mark root channel having an IK tree */
00192     pchan_root->flag |= POSE_IKTREE;
00193 }
00194 
00195 
00196 /* transform from bone(b) to bone(b+1), store in chan_mat */
00197 static void make_dmats(bPoseChannel *pchan)
00198 {
00199     if (pchan->parent) {
00200         float iR_parmat[4][4];
00201         invert_m4_m4(iR_parmat, pchan->parent->pose_mat);
00202         mult_m4_m4m4(pchan->chan_mat, iR_parmat,  pchan->pose_mat); // delta mat
00203     }
00204     else copy_m4_m4(pchan->chan_mat, pchan->pose_mat);
00205 }
00206 
00207 /* applies IK matrix to pchan, IK is done separated */
00208 /* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */
00209 /* to make this work, the diffmats have to be precalculated! Stored in chan_mat */
00210 static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3])   // nr = to detect if this is first bone
00211 {
00212     float vec[3], ikmat[4][4];
00213     
00214     copy_m4_m3(ikmat, ik_mat);
00215     
00216     if (pchan->parent)
00217         mul_serie_m4(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat, NULL, NULL, NULL, NULL, NULL);
00218     else 
00219         mult_m4_m4m4(pchan->pose_mat, pchan->chan_mat, ikmat);
00220 
00221     /* calculate head */
00222     copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]);
00223     /* calculate tail */
00224     copy_v3_v3(vec, pchan->pose_mat[1]);
00225     mul_v3_fl(vec, pchan->bone->length);
00226     add_v3_v3v3(pchan->pose_tail, pchan->pose_head, vec);
00227 
00228     pchan->flag |= POSE_DONE;
00229 }
00230 
00231 
00232 /* called from within the core where_is_pose loop, all animsystems and constraints
00233 were executed & assigned. Now as last we do an IK pass */
00234 static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
00235 {
00236     float R_parmat[3][3], identity[3][3];
00237     float iR_parmat[3][3];
00238     float R_bonemat[3][3];
00239     float goalrot[3][3], goalpos[3];
00240     float rootmat[4][4], imat[4][4];
00241     float goal[4][4], goalinv[4][4];
00242     float irest_basis[3][3], full_basis[3][3];
00243     float end_pose[4][4], world_pose[4][4];
00244     float length, basis[3][3], rest_basis[3][3], start[3], *ikstretch=NULL;
00245     float resultinf=0.0f;
00246     int a, flag, hasstretch=0, resultblend=0;
00247     bPoseChannel *pchan;
00248     IK_Segment *seg, *parent, **iktree, *iktarget;
00249     IK_Solver *solver;
00250     PoseTarget *target;
00251     bKinematicConstraint *data, *poleangledata=NULL;
00252     Bone *bone;
00253 
00254     if (tree->totchannel == 0)
00255         return;
00256     
00257     iktree= MEM_mallocN(sizeof(void*)*tree->totchannel, "ik tree");
00258 
00259     for(a=0; a<tree->totchannel; a++) {
00260         pchan= tree->pchan[a];
00261         bone= pchan->bone;
00262         
00263         /* set DoF flag */
00264         flag= 0;
00265         if(!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP))
00266             flag |= IK_XDOF;
00267         if(!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP))
00268             flag |= IK_YDOF;
00269         if(!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP))
00270             flag |= IK_ZDOF;
00271         
00272         if(tree->stretch && (pchan->ikstretch > 0.0f)) {
00273             flag |= IK_TRANS_YDOF;
00274             hasstretch = 1;
00275         }
00276         
00277         seg= iktree[a]= IK_CreateSegment(flag);
00278         
00279         /* find parent */
00280         if(a == 0)
00281             parent= NULL;
00282         else
00283             parent= iktree[tree->parent[a]];
00284             
00285         IK_SetParent(seg, parent);
00286             
00287         /* get the matrix that transforms from prevbone into this bone */
00288         copy_m3_m4(R_bonemat, pchan->pose_mat);
00289         
00290         /* gather transformations for this IK segment */
00291         
00292         if (pchan->parent)
00293             copy_m3_m4(R_parmat, pchan->parent->pose_mat);
00294         else
00295             unit_m3(R_parmat);
00296         
00297         /* bone offset */
00298         if (pchan->parent && (a > 0))
00299             sub_v3_v3v3(start, pchan->pose_head, pchan->parent->pose_tail);
00300         else
00301             /* only root bone (a = 0) has no parent */
00302             start[0]= start[1]= start[2]= 0.0f;
00303         
00304         /* change length based on bone size */
00305         length= bone->length*len_v3(R_bonemat[1]);
00306         
00307         /* compute rest basis and its inverse */
00308         copy_m3_m3(rest_basis, bone->bone_mat);
00309         copy_m3_m3(irest_basis, bone->bone_mat);
00310         transpose_m3(irest_basis);
00311         
00312         /* compute basis with rest_basis removed */
00313         invert_m3_m3(iR_parmat, R_parmat);
00314         mul_m3_m3m3(full_basis, iR_parmat, R_bonemat);
00315         mul_m3_m3m3(basis, irest_basis, full_basis);
00316         
00317         /* basis must be pure rotation */
00318         normalize_m3(basis);
00319         
00320         /* transform offset into local bone space */
00321         normalize_m3(iR_parmat);
00322         mul_m3_v3(iR_parmat, start);
00323         
00324         IK_SetTransform(seg, start, rest_basis, basis, length);
00325         
00326         if (pchan->ikflag & BONE_IK_XLIMIT)
00327             IK_SetLimit(seg, IK_X, pchan->limitmin[0], pchan->limitmax[0]);
00328         if (pchan->ikflag & BONE_IK_YLIMIT)
00329             IK_SetLimit(seg, IK_Y, pchan->limitmin[1], pchan->limitmax[1]);
00330         if (pchan->ikflag & BONE_IK_ZLIMIT)
00331             IK_SetLimit(seg, IK_Z, pchan->limitmin[2], pchan->limitmax[2]);
00332         
00333         IK_SetStiffness(seg, IK_X, pchan->stiffness[0]);
00334         IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]);
00335         IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]);
00336         
00337         if(tree->stretch && (pchan->ikstretch > 0.0f)) {
00338             float ikstretch = pchan->ikstretch*pchan->ikstretch;
00339             IK_SetStiffness(seg, IK_TRANS_Y, MIN2(1.0f-ikstretch, 0.99f));
00340             IK_SetLimit(seg, IK_TRANS_Y, 0.001, 1e10);
00341         }
00342     }
00343 
00344     solver= IK_CreateSolver(iktree[0]);
00345 
00346     /* set solver goals */
00347 
00348     /* first set the goal inverse transform, assuming the root of tree was done ok! */
00349     pchan= tree->pchan[0];
00350     if (pchan->parent)
00351         /* transform goal by parent mat, so this rotation is not part of the
00352            segment's basis. otherwise rotation limits do not work on the
00353            local transform of the segment itself. */
00354         copy_m4_m4(rootmat, pchan->parent->pose_mat);
00355     else
00356         unit_m4(rootmat);
00357     copy_v3_v3(rootmat[3], pchan->pose_head);
00358     
00359     mult_m4_m4m4(imat, ob->obmat, rootmat);
00360     invert_m4_m4(goalinv, imat);
00361     
00362     for (target=tree->targets.first; target; target=target->next) {
00363         float polepos[3];
00364         int poleconstrain= 0;
00365         
00366         data= (bKinematicConstraint*)target->con->data;
00367         
00368         /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
00369          * strictly speaking, it is a posechannel)
00370          */
00371         get_constraint_target_matrix(scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
00372         
00373         /* and set and transform goal */
00374         mult_m4_m4m4(goal, goalinv, rootmat);
00375         
00376         copy_v3_v3(goalpos, goal[3]);
00377         copy_m3_m4(goalrot, goal);
00378         
00379         /* same for pole vector target */
00380         if(data->poletar) {
00381             get_constraint_target_matrix(scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
00382             
00383             if(data->flag & CONSTRAINT_IK_SETANGLE) {
00384                 /* don't solve IK when we are setting the pole angle */
00385                 break;
00386             }
00387             else {
00388                 mult_m4_m4m4(goal, goalinv, rootmat);
00389                 copy_v3_v3(polepos, goal[3]);
00390                 poleconstrain= 1;
00391 
00392                 /* for pole targets, we blend the result of the ik solver
00393                  * instead of the target position, otherwise we can't get
00394                  * a smooth transition */
00395                 resultblend= 1;
00396                 resultinf= target->con->enforce;
00397                 
00398                 if(data->flag & CONSTRAINT_IK_GETANGLE) {
00399                     poleangledata= data;
00400                     data->flag &= ~CONSTRAINT_IK_GETANGLE;
00401                 }
00402             }
00403         }
00404 
00405         /* do we need blending? */
00406         if (!resultblend && target->con->enforce != 1.0f) {
00407             float q1[4], q2[4], q[4];
00408             float fac= target->con->enforce;
00409             float mfac= 1.0f-fac;
00410             
00411             pchan= tree->pchan[target->tip];
00412             
00413             /* end effector in world space */
00414             copy_m4_m4(end_pose, pchan->pose_mat);
00415             copy_v3_v3(end_pose[3], pchan->pose_tail);
00416             mul_serie_m4(world_pose, goalinv, ob->obmat, end_pose, NULL, NULL, NULL, NULL, NULL);
00417             
00418             /* blend position */
00419             goalpos[0]= fac*goalpos[0] + mfac*world_pose[3][0];
00420             goalpos[1]= fac*goalpos[1] + mfac*world_pose[3][1];
00421             goalpos[2]= fac*goalpos[2] + mfac*world_pose[3][2];
00422             
00423             /* blend rotation */
00424             mat3_to_quat( q1,goalrot);
00425             mat4_to_quat( q2,world_pose);
00426             interp_qt_qtqt(q, q1, q2, mfac);
00427             quat_to_mat3( goalrot,q);
00428         }
00429         
00430         iktarget= iktree[target->tip];
00431         
00432         if(data->weight != 0.0f) {
00433             if(poleconstrain)
00434                 IK_SolverSetPoleVectorConstraint(solver, iktarget, goalpos,
00435                     polepos, data->poleangle, (poleangledata == data));
00436             IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
00437         }
00438         if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0f))
00439             if((data->flag & CONSTRAINT_IK_AUTO)==0)
00440                 IK_SolverAddGoalOrientation(solver, iktarget, goalrot,
00441                     data->orientweight);
00442     }
00443 
00444     /* solve */
00445     IK_Solve(solver, 0.0f, tree->iterations);
00446 
00447     if(poleangledata)
00448         poleangledata->poleangle= IK_SolverGetPoleAngle(solver);
00449 
00450     IK_FreeSolver(solver);
00451 
00452     /* gather basis changes */
00453     tree->basis_change= MEM_mallocN(sizeof(float[3][3])*tree->totchannel, "ik basis change");
00454     if(hasstretch)
00455         ikstretch= MEM_mallocN(sizeof(float)*tree->totchannel, "ik stretch");
00456     
00457     for(a=0; a<tree->totchannel; a++) {
00458         IK_GetBasisChange(iktree[a], tree->basis_change[a]);
00459         
00460         if(hasstretch) {
00461             /* have to compensate for scaling received from parent */
00462             float parentstretch, stretch;
00463             
00464             pchan= tree->pchan[a];
00465             parentstretch= (tree->parent[a] >= 0)? ikstretch[tree->parent[a]]: 1.0f;
00466             
00467             if(tree->stretch && (pchan->ikstretch > 0.0f)) {
00468                 float trans[3], length;
00469                 
00470                 IK_GetTranslationChange(iktree[a], trans);
00471                 length= pchan->bone->length*len_v3(pchan->pose_mat[1]);
00472                 
00473                 ikstretch[a]= (length == 0.0f)? 1.0f: (trans[1]+length)/length;
00474             }
00475             else
00476                 ikstretch[a] = 1.0;
00477             
00478             stretch= (parentstretch == 0.0f)? 1.0f: ikstretch[a]/parentstretch;
00479             
00480             mul_v3_fl(tree->basis_change[a][0], stretch);
00481             mul_v3_fl(tree->basis_change[a][1], stretch);
00482             mul_v3_fl(tree->basis_change[a][2], stretch);
00483         }
00484 
00485         if(resultblend && resultinf!=1.0f) {
00486             unit_m3(identity);
00487             blend_m3_m3m3(tree->basis_change[a], identity,
00488                 tree->basis_change[a], resultinf);
00489         }
00490         
00491         IK_FreeSegment(iktree[a]);
00492     }
00493     
00494     MEM_freeN(iktree);
00495     if(ikstretch) MEM_freeN(ikstretch);
00496 }
00497 
00498 static void free_posetree(PoseTree *tree)
00499 {
00500     BLI_freelistN(&tree->targets);
00501     if(tree->pchan) MEM_freeN(tree->pchan);
00502     if(tree->parent) MEM_freeN(tree->parent);
00503     if(tree->basis_change) MEM_freeN(tree->basis_change);
00504     MEM_freeN(tree);
00505 }
00506 
00509 
00510 void iksolver_initialize_tree(struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
00511 {
00512     bPoseChannel *pchan;
00513     
00514     for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
00515         if(pchan->constflag & PCHAN_HAS_IK) // flag is set on editing constraints
00516             initialize_posetree(ob, pchan); // will attach it to root!
00517     }
00518     ob->pose->flag &= ~POSE_WAS_REBUILT;
00519 }
00520 
00521 void iksolver_execute_tree(struct Scene *scene, struct Object *ob,  struct bPoseChannel *pchan, float ctime)
00522 {
00523     while(pchan->iktree.first) {
00524         PoseTree *tree= pchan->iktree.first;
00525         int a;
00526         
00527         /* stop on the first tree that isn't a standard IK chain */
00528         if (tree->type != CONSTRAINT_TYPE_KINEMATIC)
00529             return;
00530         
00531         /* 4. walk over the tree for regular solving */
00532         for(a=0; a<tree->totchannel; a++) {
00533             if(!(tree->pchan[a]->flag & POSE_DONE)) // successive trees can set the flag
00534                 where_is_pose_bone(scene, ob, tree->pchan[a], ctime, 1);
00535             // tell blender that this channel was controlled by IK, it's cleared on each where_is_pose()
00536             tree->pchan[a]->flag |= POSE_CHAIN;
00537         }
00538         /* 5. execute the IK solver */
00539         execute_posetree(scene, ob, tree);
00540         
00541         /* 6. apply the differences to the channels, 
00542               we need to calculate the original differences first */
00543         for(a=0; a<tree->totchannel; a++) {
00544             make_dmats(tree->pchan[a]);
00545         }
00546         
00547         for(a=0; a<tree->totchannel; a++) {
00548             /* sets POSE_DONE */
00549             where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
00550         }
00551         
00552         /* 7. and free */
00553         BLI_remlink(&pchan->iktree, tree);
00554         free_posetree(tree);
00555     }
00556 }
00557