Blender V2.61 - r43446

armature.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  * Contributor(s): Full recode, Ton Roosendaal, Crete 2005
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00031 #include <ctype.h>
00032 #include <stdlib.h>
00033 #include <math.h>
00034 #include <string.h>
00035 #include <stdio.h>
00036 #include <float.h>
00037 
00038 #include "MEM_guardedalloc.h"
00039 
00040 #include "BLI_bpath.h"
00041 #include "BLI_math.h"
00042 #include "BLI_blenlib.h"
00043 #include "BLI_utildefines.h"
00044 
00045 #include "DNA_anim_types.h"
00046 #include "DNA_armature_types.h"
00047 #include "DNA_constraint_types.h"
00048 #include "DNA_mesh_types.h"
00049 #include "DNA_lattice_types.h"
00050 #include "DNA_meshdata_types.h"
00051 #include "DNA_nla_types.h"
00052 #include "DNA_scene_types.h"
00053 #include "DNA_object_types.h"
00054 
00055 #include "BKE_animsys.h"
00056 #include "BKE_armature.h"
00057 #include "BKE_action.h"
00058 #include "BKE_anim.h"
00059 #include "BKE_constraint.h"
00060 #include "BKE_curve.h"
00061 #include "BKE_depsgraph.h"
00062 #include "BKE_DerivedMesh.h"
00063 #include "BKE_deform.h"
00064 #include "BKE_displist.h"
00065 #include "BKE_global.h"
00066 #include "BKE_idprop.h"
00067 #include "BKE_library.h"
00068 #include "BKE_lattice.h"
00069 #include "BKE_main.h"
00070 #include "BKE_object.h"
00071 #include "BKE_scene.h"
00072 
00073 #include "BIK_api.h"
00074 #include "BKE_sketch.h"
00075 
00076 /*  **************** Generic Functions, data level *************** */
00077 
00078 bArmature *add_armature(const char *name)
00079 {
00080     bArmature *arm;
00081     
00082     arm= alloc_libblock (&G.main->armature, ID_AR, name);
00083     arm->deformflag = ARM_DEF_VGROUP|ARM_DEF_ENVELOPE;
00084     arm->flag = ARM_COL_CUSTOM; /* custom bone-group colors */
00085     arm->layer= 1;
00086     return arm;
00087 }
00088 
00089 bArmature *get_armature(Object *ob)
00090 {
00091     if(ob->type==OB_ARMATURE)
00092         return (bArmature *)ob->data;
00093     return NULL;
00094 }
00095 
00096 void free_bonelist (ListBase *lb)
00097 {
00098     Bone *bone;
00099 
00100     for(bone=lb->first; bone; bone=bone->next) {
00101         if(bone->prop) {
00102             IDP_FreeProperty(bone->prop);
00103             MEM_freeN(bone->prop);
00104         }
00105         free_bonelist(&bone->childbase);
00106     }
00107     
00108     BLI_freelistN(lb);
00109 }
00110 
00111 void free_armature(bArmature *arm)
00112 {
00113     if (arm) {
00114         free_bonelist(&arm->bonebase);
00115         
00116         /* free editmode data */
00117         if (arm->edbo) {
00118             BLI_freelistN(arm->edbo);
00119             
00120             MEM_freeN(arm->edbo);
00121             arm->edbo= NULL;
00122         }
00123 
00124         /* free sketch */
00125         if (arm->sketch) {
00126             freeSketch(arm->sketch);
00127             arm->sketch = NULL;
00128         }
00129         
00130         /* free animation data */
00131         if (arm->adt) {
00132             BKE_free_animdata(&arm->id);
00133             arm->adt= NULL;
00134         }
00135     }
00136 }
00137 
00138 void make_local_armature(bArmature *arm)
00139 {
00140     Main *bmain= G.main;
00141     int is_local= FALSE, is_lib= FALSE;
00142     Object *ob;
00143 
00144     if (arm->id.lib==NULL) return;
00145     if (arm->id.us==1) {
00146         id_clear_lib_data(bmain, &arm->id);
00147         return;
00148     }
00149 
00150     for(ob= bmain->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) {
00151         if(ob->data == arm) {
00152             if(ob->id.lib) is_lib= TRUE;
00153             else is_local= TRUE;
00154         }
00155     }
00156 
00157     if(is_local && is_lib == FALSE) {
00158         id_clear_lib_data(bmain, &arm->id);
00159     }
00160     else if(is_local && is_lib) {
00161         bArmature *arm_new= copy_armature(arm);
00162         arm_new->id.us= 0;
00163 
00164         /* Remap paths of new ID using old library as base. */
00165         BKE_id_lib_local_paths(bmain, arm->id.lib, &arm_new->id);
00166 
00167         for(ob= bmain->object.first; ob; ob= ob->id.next) {
00168             if(ob->data == arm) {
00169                 if(ob->id.lib==NULL) {
00170                     ob->data= arm_new;
00171                     arm_new->id.us++;
00172                     arm->id.us--;
00173                 }
00174             }
00175         }
00176     }
00177 }
00178 
00179 static void copy_bonechildren (Bone* newBone, Bone* oldBone, Bone* actBone, Bone **newActBone)
00180 {
00181     Bone    *curBone, *newChildBone;
00182     
00183     if(oldBone == actBone)
00184         *newActBone= newBone;
00185 
00186     if(oldBone->prop)
00187         newBone->prop= IDP_CopyProperty(oldBone->prop);
00188 
00189     /*  Copy this bone's list*/
00190     BLI_duplicatelist(&newBone->childbase, &oldBone->childbase);
00191     
00192     /*  For each child in the list, update it's children*/
00193     newChildBone=newBone->childbase.first;
00194     for (curBone=oldBone->childbase.first;curBone;curBone=curBone->next){
00195         newChildBone->parent=newBone;
00196         copy_bonechildren(newChildBone, curBone, actBone, newActBone);
00197         newChildBone=newChildBone->next;
00198     }
00199 }
00200 
00201 bArmature *copy_armature(bArmature *arm)
00202 {
00203     bArmature *newArm;
00204     Bone        *oldBone, *newBone;
00205     Bone        *newActBone= NULL;
00206     
00207     newArm= copy_libblock(&arm->id);
00208     BLI_duplicatelist(&newArm->bonebase, &arm->bonebase);
00209     
00210     /*  Duplicate the childrens' lists*/
00211     newBone=newArm->bonebase.first;
00212     for (oldBone=arm->bonebase.first;oldBone;oldBone=oldBone->next){
00213         newBone->parent=NULL;
00214         copy_bonechildren (newBone, oldBone, arm->act_bone, &newActBone);
00215         newBone=newBone->next;
00216     };
00217     
00218     newArm->act_bone= newActBone;
00219 
00220     newArm->edbo= NULL;
00221     newArm->act_edbone= NULL;
00222     newArm->sketch= NULL;
00223 
00224     return newArm;
00225 }
00226 
00227 static Bone *get_named_bone_bonechildren (Bone *bone, const char *name)
00228 {
00229     Bone *curBone, *rbone;
00230     
00231     if (!strcmp (bone->name, name))
00232         return bone;
00233     
00234     for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
00235         rbone=get_named_bone_bonechildren (curBone, name);
00236         if (rbone)
00237             return rbone;
00238     }
00239     
00240     return NULL;
00241 }
00242 
00243 
00244 Bone *get_named_bone (bArmature *arm, const char *name)
00245 /*
00246     Walk the list until the bone is found
00247  */
00248 {
00249     Bone *bone=NULL, *curBone;
00250     
00251     if (!arm) return NULL;
00252     
00253     for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
00254         bone = get_named_bone_bonechildren (curBone, name);
00255         if (bone)
00256             return bone;
00257     }
00258     
00259     return bone;
00260 }
00261 
00262 /* Finds the best possible extension to the name on a particular axis. (For renaming, check for unique names afterwards)
00263  *  strip_number: removes number extensions  (TODO: not used)
00264  *  axis: the axis to name on
00265  *  head/tail: the head/tail co-ordinate of the bone on the specified axis
00266  */
00267 int bone_autoside_name (char name[MAXBONENAME], int UNUSED(strip_number), short axis, float head, float tail)
00268 {
00269     unsigned int len;
00270     char    basename[MAXBONENAME]= "";
00271     char    extension[5]= "";
00272 
00273     len= strlen(name);
00274     if (len == 0) return 0;
00275     BLI_strncpy(basename, name, sizeof(basename));
00276     
00277     /* Figure out extension to append: 
00278      *  - The extension to append is based upon the axis that we are working on.
00279      *  - If head happens to be on 0, then we must consider the tail position as well to decide
00280      *    which side the bone is on
00281      *      -> If tail is 0, then it's bone is considered to be on axis, so no extension should be added
00282      *      -> Otherwise, extension is added from perspective of object based on which side tail goes to
00283      *  - If head is non-zero, extension is added from perspective of object based on side head is on
00284      */
00285     if (axis == 2) {
00286         /* z-axis - vertical (top/bottom) */
00287         if (IS_EQ(head, 0)) {
00288             if (tail < 0)
00289                 strcpy(extension, "Bot");
00290             else if (tail > 0)
00291                 strcpy(extension, "Top");
00292         }
00293         else {
00294             if (head < 0)
00295                 strcpy(extension, "Bot");
00296             else
00297                 strcpy(extension, "Top");
00298         }
00299     }
00300     else if (axis == 1) {
00301         /* y-axis - depth (front/back) */
00302         if (IS_EQ(head, 0)) {
00303             if (tail < 0)
00304                 strcpy(extension, "Fr");
00305             else if (tail > 0)
00306                 strcpy(extension, "Bk");
00307         }
00308         else {
00309             if (head < 0)
00310                 strcpy(extension, "Fr");
00311             else
00312                 strcpy(extension, "Bk");
00313         }
00314     }
00315     else {
00316         /* x-axis - horizontal (left/right) */
00317         if (IS_EQ(head, 0)) {
00318             if (tail < 0)
00319                 strcpy(extension, "R");
00320             else if (tail > 0)
00321                 strcpy(extension, "L");
00322         }
00323         else {
00324             if (head < 0)
00325                 strcpy(extension, "R");
00326             else if (head > 0)
00327                 strcpy(extension, "L");
00328         }
00329     }
00330 
00331     /* Simple name truncation 
00332      *  - truncate if there is an extension and it wouldn't be able to fit
00333      *  - otherwise, just append to end
00334      */
00335     if (extension[0]) {
00336         int change = 1;
00337         
00338         while (change) { /* remove extensions */
00339             change = 0;
00340             if (len > 2 && basename[len-2]=='.') {
00341                 if (basename[len-1]=='L' || basename[len-1] == 'R' ) { /* L R */
00342                     basename[len-2] = '\0';
00343                     len-=2;
00344                     change= 1;
00345                 }
00346             } else if (len > 3 && basename[len-3]=='.') {
00347                 if (    (basename[len-2]=='F' && basename[len-1] == 'r') || /* Fr */
00348                         (basename[len-2]=='B' && basename[len-1] == 'k')    /* Bk */
00349                 ) {
00350                     basename[len-3] = '\0';
00351                     len-=3;
00352                     change= 1;
00353                 }
00354             } else if (len > 4 && basename[len-4]=='.') {
00355                 if (    (basename[len-3]=='T' && basename[len-2]=='o' && basename[len-1] == 'p') || /* Top */
00356                         (basename[len-3]=='B' && basename[len-2]=='o' && basename[len-1] == 't')    /* Bot */
00357                 ) {
00358                     basename[len-4] = '\0';
00359                     len-=4;
00360                     change= 1;
00361                 }
00362             }
00363         }
00364 
00365         if ((MAXBONENAME - len) < strlen(extension) + 1) { /* add 1 for the '.' */
00366             strncpy(name, basename, len-strlen(extension));
00367         }
00368 
00369         BLI_snprintf(name, MAXBONENAME, "%s.%s", basename, extension);
00370 
00371         return 1;
00372     }
00373 
00374     else {
00375         return 0;
00376     }
00377 }
00378 
00379 /* ************* B-Bone support ******************* */
00380 
00381 #define MAX_BBONE_SUBDIV    32
00382 
00383 /* data has MAX_BBONE_SUBDIV+1 interpolated points, will become desired amount with equal distances */
00384 static void equalize_bezier(float *data, int desired)
00385 {
00386     float *fp, totdist, ddist, dist, fac1, fac2;
00387     float pdist[MAX_BBONE_SUBDIV+1];
00388     float temp[MAX_BBONE_SUBDIV+1][4];
00389     int a, nr;
00390     
00391     pdist[0]= 0.0f;
00392     for(a=0, fp= data; a<MAX_BBONE_SUBDIV; a++, fp+=4) {
00393         copy_qt_qt(temp[a], fp);
00394         pdist[a+1]= pdist[a]+len_v3v3(fp, fp+4);
00395     }
00396     /* do last point */
00397     copy_qt_qt(temp[a], fp);
00398     totdist= pdist[a];
00399     
00400     /* go over distances and calculate new points */
00401     ddist= totdist/((float)desired);
00402     nr= 1;
00403     for(a=1, fp= data+4; a<desired; a++, fp+=4) {
00404         
00405         dist= ((float)a)*ddist;
00406         
00407         /* we're looking for location (distance) 'dist' in the array */
00408         while((dist>= pdist[nr]) && nr<MAX_BBONE_SUBDIV) {
00409             nr++;
00410         }
00411         
00412         fac1= pdist[nr]- pdist[nr-1];
00413         fac2= pdist[nr]-dist;
00414         fac1= fac2/fac1;
00415         fac2= 1.0f-fac1;
00416         
00417         fp[0]= fac1*temp[nr-1][0]+ fac2*temp[nr][0];
00418         fp[1]= fac1*temp[nr-1][1]+ fac2*temp[nr][1];
00419         fp[2]= fac1*temp[nr-1][2]+ fac2*temp[nr][2];
00420         fp[3]= fac1*temp[nr-1][3]+ fac2*temp[nr][3];
00421     }
00422     /* set last point, needed for orientation calculus */
00423     copy_qt_qt(fp, temp[MAX_BBONE_SUBDIV]);
00424 }
00425 
00426 /* returns pointer to static array, filled with desired amount of bone->segments elements */
00427 /* this calculation is done  within unit bone space */
00428 Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
00429 {
00430     static Mat4 bbone_array[MAX_BBONE_SUBDIV];
00431     static Mat4 bbone_rest_array[MAX_BBONE_SUBDIV];
00432     Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
00433     bPoseChannel *next, *prev;
00434     Bone *bone= pchan->bone;
00435     float h1[3], h2[3], scale[3], length, hlength1, hlength2, roll1=0.0f, roll2;
00436     float mat3[3][3], imat[4][4], posemat[4][4], scalemat[4][4], iscalemat[4][4];
00437     float data[MAX_BBONE_SUBDIV+1][4], *fp;
00438     int a, doscale= 0;
00439 
00440     length= bone->length;
00441 
00442     if(!rest) {
00443         /* check if we need to take non-uniform bone scaling into account */
00444         scale[0]= len_v3(pchan->pose_mat[0]);
00445         scale[1]= len_v3(pchan->pose_mat[1]);
00446         scale[2]= len_v3(pchan->pose_mat[2]);
00447 
00448         if(fabsf(scale[0] - scale[1]) > 1e-6f || fabsf(scale[1] - scale[2]) > 1e-6f) {
00449             unit_m4(scalemat);
00450             scalemat[0][0]= scale[0];
00451             scalemat[1][1]= scale[1];
00452             scalemat[2][2]= scale[2];
00453             invert_m4_m4(iscalemat, scalemat);
00454 
00455             length *= scale[1];
00456             doscale = 1;
00457         }
00458     }
00459     
00460     hlength1= bone->ease1*length*0.390464f;     // 0.5*sqrt(2)*kappa, the handle length for near-perfect circles
00461     hlength2= bone->ease2*length*0.390464f;
00462     
00463     /* evaluate next and prev bones */
00464     if(bone->flag & BONE_CONNECTED)
00465         prev= pchan->parent;
00466     else
00467         prev= NULL;
00468     
00469     next= pchan->child;
00470     
00471     /* find the handle points, since this is inside bone space, the 
00472         first point = (0,0,0)
00473         last point =  (0, length, 0) */
00474     
00475     if(rest) {
00476         invert_m4_m4(imat, pchan->bone->arm_mat);
00477     }
00478     else if(doscale) {
00479         copy_m4_m4(posemat, pchan->pose_mat);
00480         normalize_m4(posemat);
00481         invert_m4_m4(imat, posemat);
00482     }
00483     else
00484         invert_m4_m4(imat, pchan->pose_mat);
00485     
00486     if(prev) {
00487         float difmat[4][4], result[3][3], imat3[3][3];
00488 
00489         /* transform previous point inside this bone space */
00490         if(rest)
00491             copy_v3_v3(h1, prev->bone->arm_head);
00492         else
00493             copy_v3_v3(h1, prev->pose_head);
00494         mul_m4_v3(imat, h1);
00495 
00496         if(prev->bone->segments>1) {
00497             /* if previous bone is B-bone too, use average handle direction */
00498             h1[1]-= length;
00499             roll1= 0.0f;
00500         }
00501 
00502         normalize_v3(h1);
00503         mul_v3_fl(h1, -hlength1);
00504 
00505         if(prev->bone->segments==1) {
00506             /* find the previous roll to interpolate */
00507             if(rest)
00508                 mult_m4_m4m4(difmat, imat, prev->bone->arm_mat);
00509             else
00510                 mult_m4_m4m4(difmat, imat, prev->pose_mat);
00511             copy_m3_m4(result, difmat);             // the desired rotation at beginning of next bone
00512             
00513             vec_roll_to_mat3(h1, 0.0f, mat3);           // the result of vec_roll without roll
00514             
00515             invert_m3_m3(imat3, mat3);
00516             mul_m3_m3m3(mat3, result, imat3);           // the matrix transforming vec_roll to desired roll
00517             
00518             roll1= (float)atan2(mat3[2][0], mat3[2][2]);
00519         }
00520     }
00521     else {
00522         h1[0]= 0.0f; h1[1]= hlength1; h1[2]= 0.0f;
00523         roll1= 0.0f;
00524     }
00525     if(next) {
00526         float difmat[4][4], result[3][3], imat3[3][3];
00527         
00528         /* transform next point inside this bone space */
00529         if(rest)
00530             copy_v3_v3(h2, next->bone->arm_tail);
00531         else
00532             copy_v3_v3(h2, next->pose_tail);
00533         mul_m4_v3(imat, h2);
00534         /* if next bone is B-bone too, use average handle direction */
00535         if(next->bone->segments>1);
00536         else h2[1]-= length;
00537         normalize_v3(h2);
00538         
00539         /* find the next roll to interpolate as well */
00540         if(rest)
00541             mult_m4_m4m4(difmat, imat, next->bone->arm_mat);
00542         else
00543             mult_m4_m4m4(difmat, imat, next->pose_mat);
00544         copy_m3_m4(result, difmat);             // the desired rotation at beginning of next bone
00545         
00546         vec_roll_to_mat3(h2, 0.0f, mat3);           // the result of vec_roll without roll
00547         
00548         invert_m3_m3(imat3, mat3);
00549         mul_m3_m3m3(mat3, imat3, result);           // the matrix transforming vec_roll to desired roll
00550         
00551         roll2= (float)atan2(mat3[2][0], mat3[2][2]);
00552         
00553         /* and only now negate handle */
00554         mul_v3_fl(h2, -hlength2);
00555     }
00556     else {
00557         h2[0]= 0.0f; h2[1]= -hlength2; h2[2]= 0.0f;
00558         roll2= 0.0;
00559     }
00560 
00561     /* make curve */
00562     if(bone->segments > MAX_BBONE_SUBDIV)
00563         bone->segments= MAX_BBONE_SUBDIV;
00564     
00565     forward_diff_bezier(0.0, h1[0],     h2[0],          0.0,        data[0],    MAX_BBONE_SUBDIV, 4*sizeof(float));
00566     forward_diff_bezier(0.0, h1[1],     length + h2[1], length,     data[0]+1,  MAX_BBONE_SUBDIV, 4*sizeof(float));
00567     forward_diff_bezier(0.0, h1[2],     h2[2],          0.0,        data[0]+2,  MAX_BBONE_SUBDIV, 4*sizeof(float));
00568     forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1),    roll2,  data[0]+3,  MAX_BBONE_SUBDIV, 4*sizeof(float));
00569     
00570     equalize_bezier(data[0], bone->segments);   // note: does stride 4!
00571     
00572     /* make transformation matrices for the segments for drawing */
00573     for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) {
00574         sub_v3_v3v3(h1, fp+4, fp);
00575         vec_roll_to_mat3(h1, fp[3], mat3);      // fp[3] is roll
00576 
00577         copy_m4_m3(result_array[a].mat, mat3);
00578         copy_v3_v3(result_array[a].mat[3], fp);
00579 
00580         if(doscale) {
00581             /* correct for scaling when this matrix is used in scaled space */
00582             mul_serie_m4(result_array[a].mat, iscalemat, result_array[a].mat,
00583                 scalemat, NULL, NULL, NULL, NULL, NULL);
00584         }
00585     }
00586     
00587     return result_array;
00588 }
00589 
00590 /* ************ Armature Deform ******************* */
00591 
00592 typedef struct bPoseChanDeform {
00593     Mat4        *b_bone_mats;   
00594     DualQuat    *dual_quat;
00595     DualQuat    *b_bone_dual_quats;
00596 } bPoseChanDeform;
00597 
00598 static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info, int use_quaternion)
00599 {
00600     Bone *bone= pchan->bone;
00601     Mat4 *b_bone= b_bone_spline_setup(pchan, 0);
00602     Mat4 *b_bone_rest= b_bone_spline_setup(pchan, 1);
00603     Mat4 *b_bone_mats;
00604     DualQuat *b_bone_dual_quats= NULL;
00605     float tmat[4][4]= MAT4_UNITY;
00606     int a;
00607     
00608     /* allocate b_bone matrices and dual quats */
00609     b_bone_mats= MEM_mallocN((1+bone->segments)*sizeof(Mat4), "BBone defmats");
00610     pdef_info->b_bone_mats= b_bone_mats;
00611 
00612     if(use_quaternion) {
00613         b_bone_dual_quats= MEM_mallocN((bone->segments)*sizeof(DualQuat), "BBone dqs");
00614         pdef_info->b_bone_dual_quats= b_bone_dual_quats;
00615     }
00616     
00617     /* first matrix is the inverse arm_mat, to bring points in local bone space
00618        for finding out which segment it belongs to */
00619     invert_m4_m4(b_bone_mats[0].mat, bone->arm_mat);
00620 
00621     /* then we make the b_bone_mats:
00622         - first transform to local bone space
00623         - translate over the curve to the bbone mat space
00624         - transform with b_bone matrix
00625         - transform back into global space */
00626 
00627     for(a=0; a<bone->segments; a++) {
00628         invert_m4_m4(tmat, b_bone_rest[a].mat);
00629 
00630         mul_serie_m4(b_bone_mats[a+1].mat, pchan->chan_mat, bone->arm_mat,
00631             b_bone[a].mat, tmat, b_bone_mats[0].mat, NULL, NULL, NULL);
00632 
00633         if(use_quaternion)
00634             mat4_to_dquat( &b_bone_dual_quats[a],bone->arm_mat, b_bone_mats[a+1].mat);
00635     }
00636 }
00637 
00638 static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float *co, DualQuat *dq, float defmat[][3])
00639 {
00640     Mat4 *b_bone= pdef_info->b_bone_mats;
00641     float (*mat)[4]= b_bone[0].mat;
00642     float segment, y;
00643     int a;
00644     
00645     /* need to transform co back to bonespace, only need y */
00646     y= mat[0][1]*co[0] + mat[1][1]*co[1] + mat[2][1]*co[2] + mat[3][1];
00647     
00648     /* now calculate which of the b_bones are deforming this */
00649     segment= bone->length/((float)bone->segments);
00650     a= (int)(y/segment);
00651     
00652     /* note; by clamping it extends deform at endpoints, goes best with
00653        straight joints in restpos. */
00654     CLAMP(a, 0, bone->segments-1);
00655 
00656     if(dq) {
00657         copy_dq_dq(dq, &(pdef_info->b_bone_dual_quats)[a]);
00658     }
00659     else {
00660         mul_m4_v3(b_bone[a+1].mat, co);
00661 
00662         if(defmat)
00663             copy_m3_m4(defmat, b_bone[a+1].mat);
00664     }
00665 }
00666 
00667 /* using vec with dist to bone b1 - b2 */
00668 float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist)
00669 {
00670     float dist=0.0f; 
00671     float bdelta[3];
00672     float pdelta[3];
00673     float hsqr, a, l, rad;
00674     
00675     sub_v3_v3v3(bdelta, b2, b1);
00676     l = normalize_v3(bdelta);
00677     
00678     sub_v3_v3v3(pdelta, vec, b1);
00679     
00680     a = bdelta[0]*pdelta[0] + bdelta[1]*pdelta[1] + bdelta[2]*pdelta[2];
00681     hsqr = ((pdelta[0]*pdelta[0]) + (pdelta[1]*pdelta[1]) + (pdelta[2]*pdelta[2]));
00682     
00683     if (a < 0.0F){
00684         /* If we're past the end of the bone, do a spherical field attenuation thing */
00685         dist= ((b1[0]-vec[0])*(b1[0]-vec[0]) +(b1[1]-vec[1])*(b1[1]-vec[1]) +(b1[2]-vec[2])*(b1[2]-vec[2])) ;
00686         rad= rad1;
00687     }
00688     else if (a > l){
00689         /* If we're past the end of the bone, do a spherical field attenuation thing */
00690         dist= ((b2[0]-vec[0])*(b2[0]-vec[0]) +(b2[1]-vec[1])*(b2[1]-vec[1]) +(b2[2]-vec[2])*(b2[2]-vec[2])) ;
00691         rad= rad2;
00692     }
00693     else {
00694         dist= (hsqr - (a*a));
00695         
00696         if(l!=0.0f) {
00697             rad= a/l;
00698             rad= rad*rad2 + (1.0f-rad)*rad1;
00699         }
00700         else rad= rad1;
00701     }
00702     
00703     a= rad*rad;
00704     if(dist < a) 
00705         return 1.0f;
00706     else {
00707         l= rad+rdist;
00708         l*= l;
00709         if(rdist==0.0f || dist >= l) 
00710             return 0.0f;
00711         else {
00712             a= (float)sqrt(dist)-rad;
00713             return 1.0f-( a*a )/( rdist*rdist );
00714         }
00715     }
00716 }
00717 
00718 static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[][3], float mat[][3])
00719 {
00720     float wmat[3][3];
00721 
00722     if(pchan->bone->segments>1)
00723         copy_m3_m3(wmat, bbonemat);
00724     else
00725         copy_m3_m4(wmat, pchan->chan_mat);
00726 
00727     mul_m3_fl(wmat, weight);
00728     add_m3_m3m3(mat, mat, wmat);
00729 }
00730 
00731 static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float *vec, DualQuat *dq, float mat[][3], float *co)
00732 {
00733     Bone *bone= pchan->bone;
00734     float fac, contrib=0.0;
00735     float cop[3], bbonemat[3][3];
00736     DualQuat bbonedq;
00737 
00738     if(bone==NULL) return 0.0f;
00739     
00740     copy_v3_v3(cop, co);
00741 
00742     fac= distfactor_to_bone(cop, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist);
00743     
00744     if (fac > 0.0f) {
00745         
00746         fac*=bone->weight;
00747         contrib= fac;
00748         if(contrib > 0.0f) {
00749             if(vec) {
00750                 if(bone->segments>1)
00751                     // applies on cop and bbonemat
00752                     b_bone_deform(pdef_info, bone, cop, NULL, (mat)?bbonemat:NULL);
00753                 else
00754                     mul_m4_v3(pchan->chan_mat, cop);
00755 
00756                 //  Make this a delta from the base position
00757                 sub_v3_v3(cop, co);
00758                 madd_v3_v3fl(vec, cop, fac);
00759 
00760                 if(mat)
00761                     pchan_deform_mat_add(pchan, fac, bbonemat, mat);
00762             }
00763             else {
00764                 if(bone->segments>1) {
00765                     b_bone_deform(pdef_info, bone, cop, &bbonedq, NULL);
00766                     add_weighted_dq_dq(dq, &bbonedq, fac);
00767                 }
00768                 else
00769                     add_weighted_dq_dq(dq, pdef_info->dual_quat, fac);
00770             }
00771         }
00772     }
00773     
00774     return contrib;
00775 }
00776 
00777 static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib)
00778 {
00779     float cop[3], bbonemat[3][3];
00780     DualQuat bbonedq;
00781 
00782     if (!weight)
00783         return;
00784 
00785     copy_v3_v3(cop, co);
00786 
00787     if(vec) {
00788         if(pchan->bone->segments>1)
00789             // applies on cop and bbonemat
00790             b_bone_deform(pdef_info, pchan->bone, cop, NULL, (mat)?bbonemat:NULL);
00791         else
00792             mul_m4_v3(pchan->chan_mat, cop);
00793         
00794         vec[0]+=(cop[0]-co[0])*weight;
00795         vec[1]+=(cop[1]-co[1])*weight;
00796         vec[2]+=(cop[2]-co[2])*weight;
00797 
00798         if(mat)
00799             pchan_deform_mat_add(pchan, weight, bbonemat, mat);
00800     }
00801     else {
00802         if(pchan->bone->segments>1) {
00803             b_bone_deform(pdef_info, pchan->bone, cop, &bbonedq, NULL);
00804             add_weighted_dq_dq(dq, &bbonedq, weight);
00805         }
00806         else
00807             add_weighted_dq_dq(dq, pdef_info->dual_quat, weight);
00808     }
00809 
00810     (*contrib)+=weight;
00811 }
00812 
00813 void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
00814                            float (*vertexCos)[3], float (*defMats)[3][3],
00815                            int numVerts, int deformflag, 
00816                            float (*prevCos)[3], const char *defgrp_name)
00817 {
00818     bPoseChanDeform *pdef_info_array;
00819     bPoseChanDeform *pdef_info= NULL;
00820     bArmature *arm= armOb->data;
00821     bPoseChannel *pchan, **defnrToPC = NULL;
00822     int *defnrToPCIndex= NULL;
00823     MDeformVert *dverts = NULL;
00824     bDeformGroup *dg;
00825     DualQuat *dualquats= NULL;
00826     float obinv[4][4], premat[4][4], postmat[4][4];
00827     const short use_envelope = deformflag & ARM_DEF_ENVELOPE;
00828     const short use_quaternion = deformflag & ARM_DEF_QUATERNION;
00829     const short invert_vgroup= deformflag & ARM_DEF_INVERT_VGROUP;
00830     int defbase_tot = 0;        /* safety for vertexgroup index overflow */
00831     int i, target_totvert = 0;  /* safety for vertexgroup overflow */
00832     int use_dverts = 0;
00833     int armature_def_nr;
00834     int totchan;
00835 
00836     if(arm->edbo) return;
00837     
00838     invert_m4_m4(obinv, target->obmat);
00839     copy_m4_m4(premat, target->obmat);
00840     mult_m4_m4m4(postmat, obinv, armOb->obmat);
00841     invert_m4_m4(premat, postmat);
00842 
00843     /* bone defmats are already in the channels, chan_mat */
00844     
00845     /* initialize B_bone matrices and dual quaternions */
00846     totchan= BLI_countlist(&armOb->pose->chanbase);
00847 
00848     if(use_quaternion) {
00849         dualquats= MEM_callocN(sizeof(DualQuat)*totchan, "dualquats");
00850     }
00851     
00852     pdef_info_array= MEM_callocN(sizeof(bPoseChanDeform)*totchan, "bPoseChanDeform");
00853 
00854     totchan= 0;
00855     pdef_info= pdef_info_array;
00856     for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next, pdef_info++) {
00857         if(!(pchan->bone->flag & BONE_NO_DEFORM)) {
00858             if(pchan->bone->segments > 1)
00859                 pchan_b_bone_defmats(pchan, pdef_info, use_quaternion);
00860 
00861             if(use_quaternion) {
00862                 pdef_info->dual_quat= &dualquats[totchan++];
00863                 mat4_to_dquat( pdef_info->dual_quat,pchan->bone->arm_mat, pchan->chan_mat);
00864             }
00865         }
00866     }
00867 
00868     /* get the def_nr for the overall armature vertex group if present */
00869     armature_def_nr= defgroup_name_index(target, defgrp_name);
00870     
00871     if(ELEM(target->type, OB_MESH, OB_LATTICE)) {
00872         defbase_tot = BLI_countlist(&target->defbase);
00873         
00874         if(target->type==OB_MESH) {
00875             Mesh *me= target->data;
00876             dverts = me->dvert;
00877             if(dverts)
00878                 target_totvert = me->totvert;
00879         }
00880         else {
00881             Lattice *lt= target->data;
00882             dverts = lt->dvert;
00883             if(dverts)
00884                 target_totvert = lt->pntsu*lt->pntsv*lt->pntsw;
00885         }
00886     }
00887     
00888     /* get a vertex-deform-index to posechannel array */
00889     if(deformflag & ARM_DEF_VGROUP) {
00890         if(ELEM(target->type, OB_MESH, OB_LATTICE)) {
00891             /* if we have a DerivedMesh, only use dverts if it has them */
00892             if(dm)
00893                 if(dm->getVertData(dm, 0, CD_MDEFORMVERT))
00894                     use_dverts = 1;
00895                 else use_dverts = 0;
00896             else if(dverts) use_dverts = 1;
00897 
00898             if(use_dverts) {
00899                 defnrToPC = MEM_callocN(sizeof(*defnrToPC) * defbase_tot, "defnrToBone");
00900                 defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * defbase_tot, "defnrToIndex");
00901                 for(i = 0, dg = target->defbase.first; dg;
00902                     i++, dg = dg->next) {
00903                     defnrToPC[i] = get_pose_channel(armOb->pose, dg->name);
00904                     /* exclude non-deforming bones */
00905                     if(defnrToPC[i]) {
00906                         if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM) {
00907                             defnrToPC[i]= NULL;
00908                         }
00909                         else {
00910                             defnrToPCIndex[i]= BLI_findindex(&armOb->pose->chanbase, defnrToPC[i]);
00911                         }
00912                     }
00913                 }
00914             }
00915         }
00916     }
00917 
00918     for(i = 0; i < numVerts; i++) {
00919         MDeformVert *dvert;
00920         DualQuat sumdq, *dq = NULL;
00921         float *co, dco[3];
00922         float sumvec[3], summat[3][3];
00923         float *vec = NULL, (*smat)[3] = NULL;
00924         float contrib = 0.0f;
00925         float armature_weight = 1.0f;   /* default to 1 if no overall def group */
00926         float prevco_weight = 1.0f;     /* weight for optional cached vertexcos */
00927 
00928         if(use_quaternion) {
00929             memset(&sumdq, 0, sizeof(DualQuat));
00930             dq= &sumdq;
00931         }
00932         else {
00933             sumvec[0] = sumvec[1] = sumvec[2] = 0.0f;
00934             vec= sumvec;
00935 
00936             if(defMats) {
00937                 zero_m3(summat);
00938                 smat = summat;
00939             }
00940         }
00941 
00942         if(use_dverts || armature_def_nr >= 0) {
00943             if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
00944             else if(dverts && i < target_totvert) dvert = dverts + i;
00945             else dvert = NULL;
00946         } else
00947             dvert = NULL;
00948 
00949         if(armature_def_nr >= 0 && dvert) {
00950             armature_weight= defvert_find_weight(dvert, armature_def_nr);
00951 
00952             if(invert_vgroup) {
00953                 armature_weight= 1.0f-armature_weight;
00954             }
00955 
00956             /* hackish: the blending factor can be used for blending with prevCos too */
00957             if(prevCos) {
00958                 prevco_weight= armature_weight;
00959                 armature_weight= 1.0f;
00960             }
00961         }
00962 
00963         /* check if there's any  point in calculating for this vert */
00964         if(armature_weight == 0.0f) continue;
00965         
00966         /* get the coord we work on */
00967         co= prevCos?prevCos[i]:vertexCos[i];
00968         
00969         /* Apply the object's matrix */
00970         mul_m4_v3(premat, co);
00971         
00972         if(use_dverts && dvert && dvert->totweight) { // use weight groups ?
00973             MDeformWeight *dw= dvert->dw;
00974             int deformed = 0;
00975             unsigned int j;
00976             
00977             for (j= dvert->totweight; j != 0; j--, dw++) {
00978                 const int index = dw->def_nr;
00979                 if(index < defbase_tot && (pchan= defnrToPC[index])) {
00980                     float weight = dw->weight;
00981                     Bone *bone= pchan->bone;
00982                     pdef_info= pdef_info_array + defnrToPCIndex[index];
00983 
00984                     deformed = 1;
00985                     
00986                     if(bone && bone->flag & BONE_MULT_VG_ENV) {
00987                         weight *= distfactor_to_bone(co, bone->arm_head,
00988                                                      bone->arm_tail,
00989                                                      bone->rad_head,
00990                                                      bone->rad_tail,
00991                                                      bone->dist);
00992                     }
00993                     pchan_bone_deform(pchan, pdef_info, weight, vec, dq, smat, co, &contrib);
00994                 }
00995             }
00996             /* if there are vertexgroups but not groups with bones
00997              * (like for softbody groups)
00998              */
00999             if(deformed == 0 && use_envelope) {
01000                 pdef_info= pdef_info_array;
01001                 for(pchan= armOb->pose->chanbase.first; pchan;
01002                     pchan= pchan->next, pdef_info++) {
01003                     if(!(pchan->bone->flag & BONE_NO_DEFORM))
01004                         contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
01005                 }
01006             }
01007         }
01008         else if(use_envelope) {
01009             pdef_info= pdef_info_array;
01010             for(pchan = armOb->pose->chanbase.first; pchan;
01011                 pchan = pchan->next, pdef_info++) {
01012                 if(!(pchan->bone->flag & BONE_NO_DEFORM))
01013                     contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co);
01014             }
01015         }
01016 
01017         /* actually should be EPSILON? weight values and contrib can be like 10e-39 small */
01018         if(contrib > 0.0001f) {
01019             if(use_quaternion) {
01020                 normalize_dq(dq, contrib);
01021 
01022                 if(armature_weight != 1.0f) {
01023                     copy_v3_v3(dco, co);
01024                     mul_v3m3_dq( dco, (defMats)? summat: NULL,dq);
01025                     sub_v3_v3(dco, co);
01026                     mul_v3_fl(dco, armature_weight);
01027                     add_v3_v3(co, dco);
01028                 }
01029                 else
01030                     mul_v3m3_dq( co, (defMats)? summat: NULL,dq);
01031 
01032                 smat = summat;
01033             }
01034             else {
01035                 mul_v3_fl(vec, armature_weight/contrib);
01036                 add_v3_v3v3(co, vec, co);
01037             }
01038 
01039             if(defMats) {
01040                 float pre[3][3], post[3][3], tmpmat[3][3];
01041 
01042                 copy_m3_m4(pre, premat);
01043                 copy_m3_m4(post, postmat);
01044                 copy_m3_m3(tmpmat, defMats[i]);
01045 
01046                 if(!use_quaternion) /* quaternion already is scale corrected */
01047                     mul_m3_fl(smat, armature_weight/contrib);
01048 
01049                 mul_serie_m3(defMats[i], tmpmat, pre, smat, post,
01050                     NULL, NULL, NULL, NULL);
01051             }
01052         }
01053         
01054         /* always, check above code */
01055         mul_m4_v3(postmat, co);
01056         
01057         
01058         /* interpolate with previous modifier position using weight group */
01059         if(prevCos) {
01060             float mw= 1.0f - prevco_weight;
01061             vertexCos[i][0]= prevco_weight*vertexCos[i][0] + mw*co[0];
01062             vertexCos[i][1]= prevco_weight*vertexCos[i][1] + mw*co[1];
01063             vertexCos[i][2]= prevco_weight*vertexCos[i][2] + mw*co[2];
01064         }
01065     }
01066 
01067     if(dualquats) MEM_freeN(dualquats);
01068     if(defnrToPC) MEM_freeN(defnrToPC);
01069     if(defnrToPCIndex) MEM_freeN(defnrToPCIndex);
01070 
01071     /* free B_bone matrices */
01072     pdef_info= pdef_info_array;
01073     for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) {
01074         if(pdef_info->b_bone_mats) {
01075             MEM_freeN(pdef_info->b_bone_mats);
01076         }
01077         if(pdef_info->b_bone_dual_quats) {
01078             MEM_freeN(pdef_info->b_bone_dual_quats);
01079         }
01080     }
01081 
01082     MEM_freeN(pdef_info_array);
01083 }
01084 
01085 /* ************ END Armature Deform ******************* */
01086 
01087 void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int UNUSED(root), int UNUSED(posed))
01088 {
01089     copy_m4_m4(M_accumulatedMatrix, bone->arm_mat);
01090 }
01091 
01092 /* **************** Space to Space API ****************** */
01093 
01094 /* Convert World-Space Matrix to Pose-Space Matrix */
01095 void armature_mat_world_to_pose(Object *ob, float inmat[][4], float outmat[][4]) 
01096 {
01097     float obmat[4][4];
01098     
01099     /* prevent crashes */
01100     if (ob==NULL) return;
01101     
01102     /* get inverse of (armature) object's matrix  */
01103     invert_m4_m4(obmat, ob->obmat);
01104     
01105     /* multiply given matrix by object's-inverse to find pose-space matrix */
01106     mult_m4_m4m4(outmat, inmat, obmat);
01107 }
01108 
01109 /* Convert Wolrd-Space Location to Pose-Space Location
01110  * NOTE: this cannot be used to convert to pose-space location of the supplied
01111  *      pose-channel into its local space (i.e. 'visual'-keyframing) 
01112  */
01113 void armature_loc_world_to_pose(Object *ob, float *inloc, float *outloc) 
01114 {
01115     float xLocMat[4][4]= MAT4_UNITY;
01116     float nLocMat[4][4];
01117     
01118     /* build matrix for location */
01119     copy_v3_v3(xLocMat[3], inloc);
01120 
01121     /* get bone-space cursor matrix and extract location */
01122     armature_mat_world_to_pose(ob, xLocMat, nLocMat);
01123     copy_v3_v3(outloc, nLocMat[3]);
01124 }
01125 
01126 /* Convert Pose-Space Matrix to Bone-Space Matrix 
01127  * NOTE: this cannot be used to convert to pose-space transforms of the supplied
01128  *      pose-channel into its local space (i.e. 'visual'-keyframing)
01129  */
01130 void armature_mat_pose_to_bone(bPoseChannel *pchan, float inmat[][4], float outmat[][4])
01131 {
01132     float pc_trans[4][4], inv_trans[4][4];
01133     float pc_posemat[4][4], inv_posemat[4][4];
01134     float pose_mat[4][4];
01135 
01136     /* paranoia: prevent crashes with no pose-channel supplied */
01137     if (pchan==NULL) return;
01138 
01139     /* default flag */
01140     if((pchan->bone->flag & BONE_NO_LOCAL_LOCATION)==0) {
01141         /* get the inverse matrix of the pchan's transforms */
01142         switch(pchan->rotmode) {
01143         case ROT_MODE_QUAT:
01144             loc_quat_size_to_mat4(pc_trans, pchan->loc, pchan->quat, pchan->size);
01145             break;
01146         case ROT_MODE_AXISANGLE:
01147             loc_axisangle_size_to_mat4(pc_trans, pchan->loc, pchan->rotAxis, pchan->rotAngle, pchan->size);
01148             break;
01149         default: /* euler */
01150             loc_eul_size_to_mat4(pc_trans, pchan->loc, pchan->eul, pchan->size);
01151         }
01152 
01153         copy_m4_m4(pose_mat, pchan->pose_mat);
01154     }
01155     else {
01156         /* local location, this is not default, different calculation
01157          * note: only tested for location with pose bone snapping.
01158          * If this is not useful in other cases the BONE_NO_LOCAL_LOCATION
01159          * case may have to be split into its own function. */
01160         unit_m4(pc_trans);
01161         copy_v3_v3(pc_trans[3], pchan->loc);
01162 
01163         /* use parents rotation/scale space + own absolute position */
01164         if(pchan->parent)   copy_m4_m4(pose_mat, pchan->parent->pose_mat);
01165         else                unit_m4(pose_mat);
01166 
01167         copy_v3_v3(pose_mat[3], pchan->pose_mat[3]);
01168     }
01169 
01170 
01171     invert_m4_m4(inv_trans, pc_trans);
01172     
01173     /* Remove the pchan's transforms from it's pose_mat.
01174      * This should leave behind the effects of restpose + 
01175      * parenting + constraints
01176      */
01177     mult_m4_m4m4(pc_posemat, pose_mat, inv_trans);
01178     
01179     /* get the inverse of the leftovers so that we can remove 
01180      * that component from the supplied matrix
01181      */
01182     invert_m4_m4(inv_posemat, pc_posemat);
01183     
01184     /* get the new matrix */
01185     mult_m4_m4m4(outmat, inv_posemat, inmat);
01186 }
01187 
01188 /* Convert Pose-Space Location to Bone-Space Location
01189  * NOTE: this cannot be used to convert to pose-space location of the supplied
01190  *      pose-channel into its local space (i.e. 'visual'-keyframing) 
01191  */
01192 void armature_loc_pose_to_bone(bPoseChannel *pchan, float *inloc, float *outloc) 
01193 {
01194     float xLocMat[4][4]= MAT4_UNITY;
01195     float nLocMat[4][4];
01196     
01197     /* build matrix for location */
01198     copy_v3_v3(xLocMat[3], inloc);
01199 
01200     /* get bone-space cursor matrix and extract location */
01201     armature_mat_pose_to_bone(pchan, xLocMat, nLocMat);
01202     copy_v3_v3(outloc, nLocMat[3]);
01203 }
01204 
01205 /* same as object_mat3_to_rot() */
01206 void pchan_mat3_to_rot(bPoseChannel *pchan, float mat[][3], short use_compat)
01207 {
01208     switch(pchan->rotmode) {
01209     case ROT_MODE_QUAT:
01210         mat3_to_quat(pchan->quat, mat);
01211         break;
01212     case ROT_MODE_AXISANGLE:
01213         mat3_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, mat);
01214         break;
01215     default: /* euler */
01216         if(use_compat)  mat3_to_compatible_eulO(pchan->eul, pchan->eul, pchan->rotmode, mat);
01217         else            mat3_to_eulO(pchan->eul, pchan->rotmode, mat);
01218     }
01219 }
01220 
01221 /* Apply a 4x4 matrix to the pose bone,
01222  * similar to object_apply_mat4()
01223  */
01224 void pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat)
01225 {
01226     float rot[3][3];
01227     mat4_to_loc_rot_size(pchan->loc, rot, pchan->size, mat);
01228     pchan_mat3_to_rot(pchan, rot, use_compat);
01229 }
01230 
01231 /* Remove rest-position effects from pose-transform for obtaining
01232  * 'visual' transformation of pose-channel.
01233  * (used by the Visual-Keyframing stuff)
01234  */
01235 void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4])
01236 {
01237     float imat[4][4];
01238     
01239     invert_m4_m4(imat, arm_mat);
01240     mult_m4_m4m4(delta_mat, imat, pose_mat);
01241 }
01242 
01243 /* **************** Rotation Mode Conversions ****************************** */
01244 /* Used for Objects and Pose Channels, since both can have multiple rotation representations */
01245 
01246 /* Called from RNA when rotation mode changes 
01247  *  - the result should be that the rotations given in the provided pointers have had conversions 
01248  *    applied (as appropriate), such that the rotation of the element hasn't 'visually' changed 
01249  */
01250 void BKE_rotMode_change_values (float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode)
01251 {
01252     /* check if any change - if so, need to convert data */
01253     if (newMode > 0) { /* to euler */
01254         if (oldMode == ROT_MODE_AXISANGLE) {
01255             /* axis-angle to euler */
01256             axis_angle_to_eulO( eul, newMode,axis, *angle);
01257         }
01258         else if (oldMode == ROT_MODE_QUAT) {
01259             /* quat to euler */
01260             normalize_qt(quat);
01261             quat_to_eulO( eul, newMode,quat);
01262         }
01263         /* else { no conversion needed } */
01264     }
01265     else if (newMode == ROT_MODE_QUAT) { /* to quat */
01266         if (oldMode == ROT_MODE_AXISANGLE) {
01267             /* axis angle to quat */
01268             axis_angle_to_quat(quat, axis, *angle);
01269         }
01270         else if (oldMode > 0) {
01271             /* euler to quat */
01272             eulO_to_quat( quat,eul, oldMode);
01273         }
01274         /* else { no conversion needed } */
01275     }
01276     else if (newMode == ROT_MODE_AXISANGLE) { /* to axis-angle */
01277         if (oldMode > 0) {
01278             /* euler to axis angle */
01279             eulO_to_axis_angle( axis, angle,eul, oldMode);
01280         }
01281         else if (oldMode == ROT_MODE_QUAT) {
01282             /* quat to axis angle */
01283             normalize_qt(quat);
01284             quat_to_axis_angle( axis, angle,quat);
01285         }
01286         
01287         /* when converting to axis-angle, we need a special exception for the case when there is no axis */
01288         if (IS_EQF(axis[0], axis[1]) && IS_EQF(axis[1], axis[2])) {
01289             /* for now, rotate around y-axis then (so that it simply becomes the roll) */
01290             axis[1]= 1.0f;
01291         }
01292     }
01293 }
01294 
01295 /* **************** The new & simple (but OK!) armature evaluation ********* */ 
01296 
01297 /*  ****************** And how it works! ****************************************
01298 
01299   This is the bone transformation trick; they're hierarchical so each bone(b)
01300   is in the coord system of bone(b-1):
01301 
01302   arm_mat(b)= arm_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) 
01303   
01304   -> yoffs is just the y axis translation in parent's coord system
01305   -> d_root is the translation of the bone root, also in parent's coord system
01306 
01307   pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b)
01308 
01309   we then - in init deform - store the deform in chan_mat, such that:
01310 
01311   pose_mat(b)= arm_mat(b) * chan_mat(b)
01312   
01313   *************************************************************************** */
01314 /*  Computes vector and roll based on a rotation. "mat" must
01315      contain only a rotation, and no scaling. */ 
01316 void mat3_to_vec_roll(float mat[][3], float *vec, float *roll) 
01317 {
01318     if (vec)
01319         copy_v3_v3(vec, mat[1]);
01320 
01321     if (roll) {
01322         float vecmat[3][3], vecmatinv[3][3], rollmat[3][3];
01323 
01324         vec_roll_to_mat3(mat[1], 0.0f, vecmat);
01325         invert_m3_m3(vecmatinv, vecmat);
01326         mul_m3_m3m3(rollmat, vecmatinv, mat);
01327 
01328         *roll= (float)atan2(rollmat[2][0], rollmat[2][2]);
01329     }
01330 }
01331 
01332 /*  Calculates the rest matrix of a bone based
01333     On its vector and a roll around that vector */
01334 void vec_roll_to_mat3(float *vec, float roll, float mat[][3])
01335 {
01336     float   nor[3], axis[3], target[3]={0,1,0};
01337     float   theta;
01338     float   rMatrix[3][3], bMatrix[3][3];
01339 
01340     normalize_v3_v3(nor, vec);
01341     
01342     /*  Find Axis & Amount for bone matrix*/
01343     cross_v3_v3v3(axis,target,nor);
01344 
01345     /* was 0.0000000000001, caused bug [#23954], smaller values give unstable
01346      * roll when toggling editmode.
01347      *
01348      * was 0.00001, causes bug [#27675], with 0.00000495,
01349      * so a value inbetween these is needed.
01350      */
01351     if (dot_v3v3(axis,axis) > 0.000001f) {
01352         /* if nor is *not* a multiple of target ... */
01353         normalize_v3(axis);
01354         
01355         theta= angle_normalized_v3v3(target, nor);
01356         
01357         /*  Make Bone matrix*/
01358         vec_rot_to_mat3( bMatrix,axis, theta);
01359     }
01360     else {
01361         /* if nor is a multiple of target ... */
01362         float updown;
01363         
01364         /* point same direction, or opposite? */
01365         updown = ( dot_v3v3(target,nor) > 0 ) ? 1.0f : -1.0f;
01366         
01367         /* I think this should work ... */
01368         bMatrix[0][0]=updown; bMatrix[0][1]=0.0;    bMatrix[0][2]=0.0;
01369         bMatrix[1][0]=0.0;    bMatrix[1][1]=updown; bMatrix[1][2]=0.0;
01370         bMatrix[2][0]=0.0;    bMatrix[2][1]=0.0;    bMatrix[2][2]=1.0;
01371     }
01372     
01373     /*  Make Roll matrix*/
01374     vec_rot_to_mat3( rMatrix,nor, roll);
01375     
01376     /*  Combine and output result*/
01377     mul_m3_m3m3(mat, rMatrix, bMatrix);
01378 }
01379 
01380 
01381 /* recursive part, calculates restposition of entire tree of children */
01382 /* used by exiting editmode too */
01383 void where_is_armature_bone(Bone *bone, Bone *prevbone)
01384 {
01385     float vec[3];
01386     
01387     /* Bone Space */
01388     sub_v3_v3v3(vec, bone->tail, bone->head);
01389     vec_roll_to_mat3(vec, bone->roll, bone->bone_mat);
01390 
01391     bone->length= len_v3v3(bone->head, bone->tail);
01392     
01393     /* this is called on old file reading too... */
01394     if(bone->xwidth==0.0f) {
01395         bone->xwidth= 0.1f;
01396         bone->zwidth= 0.1f;
01397         bone->segments= 1;
01398     }
01399     
01400     if(prevbone) {
01401         float offs_bone[4][4];  // yoffs(b-1) + root(b) + bonemat(b)
01402         
01403         /* bone transform itself */
01404         copy_m4_m3(offs_bone, bone->bone_mat);
01405                 
01406         /* The bone's root offset (is in the parent's coordinate system) */
01407         copy_v3_v3(offs_bone[3], bone->head);
01408 
01409         /* Get the length translation of parent (length along y axis) */
01410         offs_bone[3][1]+= prevbone->length;
01411         
01412         /* Compose the matrix for this bone  */
01413         mult_m4_m4m4(bone->arm_mat, prevbone->arm_mat, offs_bone);
01414     }
01415     else {
01416         copy_m4_m3(bone->arm_mat, bone->bone_mat);
01417         copy_v3_v3(bone->arm_mat[3], bone->head);
01418     }
01419     
01420     /* and the kiddies */
01421     prevbone= bone;
01422     for(bone= bone->childbase.first; bone; bone= bone->next) {
01423         where_is_armature_bone(bone, prevbone);
01424     }
01425 }
01426 
01427 /* updates vectors and matrices on rest-position level, only needed 
01428    after editing armature itself, now only on reading file */
01429 void where_is_armature (bArmature *arm)
01430 {
01431     Bone *bone;
01432     
01433     /* hierarchical from root to children */
01434     for(bone= arm->bonebase.first; bone; bone= bone->next) {
01435         where_is_armature_bone(bone, NULL);
01436     }
01437 }
01438 
01439 /* if bone layer is protected, copy the data from from->pose
01440  * when used with linked libraries this copies from the linked pose into the local pose */
01441 static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected)
01442 {
01443     bPose *pose= ob->pose, *frompose= from->pose;
01444     bPoseChannel *pchan, *pchanp, pchanw;
01445     bConstraint *con;
01446     int error = 0;
01447     
01448     if (frompose==NULL) return;
01449 
01450     /* in some cases when rigs change, we cant synchronize
01451      * to avoid crashing check for possible errors here */
01452     for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
01453         if (pchan->bone->layer & layer_protected) {
01454             if(get_pose_channel(frompose, pchan->name) == NULL) {
01455                 printf("failed to sync proxy armature because '%s' is missing pose channel '%s'\n", from->id.name, pchan->name);
01456                 error = 1;
01457             }
01458         }
01459     }
01460 
01461     if(error)
01462         return;
01463     
01464     /* clear all transformation values from library */
01465     rest_pose(frompose);
01466     
01467     /* copy over all of the proxy's bone groups */
01468         /* TODO for later - implement 'local' bone groups as for constraints
01469          *  Note: this isn't trivial, as bones reference groups by index not by pointer, 
01470          *       so syncing things correctly needs careful attention
01471          */
01472     BLI_freelistN(&pose->agroups);
01473     BLI_duplicatelist(&pose->agroups, &frompose->agroups);
01474     pose->active_group= frompose->active_group;
01475     
01476     for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
01477         pchanp= get_pose_channel(frompose, pchan->name);
01478 
01479         if (pchan->bone->layer & layer_protected) {
01480             ListBase proxylocal_constraints = {NULL, NULL};
01481             
01482             /* copy posechannel to temp, but restore important pointers */
01483             pchanw= *pchanp;
01484             pchanw.prev= pchan->prev;
01485             pchanw.next= pchan->next;
01486             pchanw.parent= pchan->parent;
01487             pchanw.child= pchan->child;
01488             
01489             /* this is freed so copy a copy, else undo crashes */
01490             if(pchanw.prop) {
01491                 pchanw.prop= IDP_CopyProperty(pchanw.prop);
01492 
01493                 /* use the values from the the existing props */
01494                 if(pchan->prop) {
01495                     IDP_SyncGroupValues(pchanw.prop, pchan->prop);
01496                 }
01497             }
01498 
01499             /* constraints - proxy constraints are flushed... local ones are added after 
01500              *  1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
01501              *  2. copy proxy-pchan's constraints on-to new
01502              *  3. add extracted local constraints back on top 
01503              *
01504              *  note for copy_constraints: when copying constraints, disable 'do_extern' otherwise we get the libs direct linked in this blend.
01505              */
01506             extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
01507             copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
01508             BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
01509             
01510             /* constraints - set target ob pointer to own object */
01511             for (con= pchanw.constraints.first; con; con= con->next) {
01512                 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
01513                 ListBase targets = {NULL, NULL};
01514                 bConstraintTarget *ct;
01515                 
01516                 if (cti && cti->get_constraint_targets) {
01517                     cti->get_constraint_targets(con, &targets);
01518                     
01519                     for (ct= targets.first; ct; ct= ct->next) {
01520                         if (ct->tar == from)
01521                             ct->tar = ob;
01522                     }
01523                     
01524                     if (cti->flush_constraint_targets)
01525                         cti->flush_constraint_targets(con, &targets, 0);
01526                 }
01527             }
01528             
01529             /* free stuff from current channel */
01530             free_pose_channel(pchan);
01531             
01532             /* the final copy */
01533             *pchan= pchanw;
01534         }
01535         else {
01536             /* always copy custom shape */
01537             pchan->custom= pchanp->custom;
01538             pchan->custom_tx= pchanp->custom_tx;
01539 
01540             /* ID-Property Syncing */
01541             {
01542                 IDProperty *prop_orig= pchan->prop;
01543                 if(pchanp->prop) {
01544                     pchan->prop= IDP_CopyProperty(pchanp->prop);
01545                     if(prop_orig) {
01546                         /* copy existing values across when types match */
01547                         IDP_SyncGroupValues(pchan->prop, prop_orig);
01548                     }
01549                 }
01550                 else {
01551                     pchan->prop= NULL;
01552                 }
01553                 if (prop_orig) {
01554                     IDP_FreeProperty(prop_orig);
01555                     MEM_freeN(prop_orig);
01556                 }
01557             }
01558         }
01559     }
01560 }
01561 
01562 static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int counter)
01563 {
01564     bPoseChannel *pchan = verify_pose_channel (pose, bone->name);   // verify checks and/or adds
01565 
01566     pchan->bone= bone;
01567     pchan->parent= parchan;
01568     
01569     counter++;
01570     
01571     for(bone= bone->childbase.first; bone; bone= bone->next) {
01572         counter= rebuild_pose_bone(pose, bone, pchan, counter);
01573         /* for quick detecting of next bone in chain, only b-bone uses it now */
01574         if(bone->flag & BONE_CONNECTED)
01575             pchan->child= get_pose_channel(pose, bone->name);
01576     }
01577     
01578     return counter;
01579 }
01580 
01581 /* only after leave editmode, duplicating, validating older files, library syncing */
01582 /* NOTE: pose->flag is set for it */
01583 void armature_rebuild_pose(Object *ob, bArmature *arm)
01584 {
01585     Bone *bone;
01586     bPose *pose;
01587     bPoseChannel *pchan, *next;
01588     int counter=0;
01589         
01590     /* only done here */
01591     if(ob->pose==NULL) {
01592         /* create new pose */
01593         ob->pose= MEM_callocN(sizeof(bPose), "new pose");
01594         
01595         /* set default settings for animviz */
01596         animviz_settings_init(&ob->pose->avs);
01597     }
01598     pose= ob->pose;
01599     
01600     /* clear */
01601     for(pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
01602         pchan->bone= NULL;
01603         pchan->child= NULL;
01604     }
01605     
01606     /* first step, check if all channels are there */
01607     for(bone= arm->bonebase.first; bone; bone= bone->next) {
01608         counter= rebuild_pose_bone(pose, bone, NULL, counter);
01609     }
01610 
01611     /* and a check for garbage */
01612     for(pchan= pose->chanbase.first; pchan; pchan= next) {
01613         next= pchan->next;
01614         if(pchan->bone==NULL) {
01615             free_pose_channel(pchan);
01616             free_pose_channels_hash(pose);
01617             BLI_freelinkN(&pose->chanbase, pchan);
01618         }
01619     }
01620     // printf("rebuild pose %s, %d bones\n", ob->id.name, counter);
01621     
01622     /* synchronize protected layers with proxy */
01623     if(ob->proxy) {
01624         object_copy_proxy_drivers(ob, ob->proxy);
01625         pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected);
01626     }
01627     
01628     update_pose_constraint_flags(ob->pose); // for IK detection for example
01629     
01630     /* the sorting */
01631     if(counter>1)
01632         DAG_pose_sort(ob);
01633     
01634     ob->pose->flag &= ~POSE_RECALC;
01635     ob->pose->flag |= POSE_WAS_REBUILT;
01636 
01637     make_pose_channels_hash(ob->pose);
01638 }
01639 
01640 
01641 /* ********************** SPLINE IK SOLVER ******************* */
01642 
01643 /* Temporary evaluation tree data used for Spline IK */
01644 typedef struct tSplineIK_Tree {
01645     struct tSplineIK_Tree *next, *prev;
01646     
01647     int     type;                   /* type of IK that this serves (CONSTRAINT_TYPE_KINEMATIC or ..._SPLINEIK) */
01648     
01649     short free_points;              /* free the point positions array */
01650     short chainlen;                 /* number of bones in the chain */
01651     
01652     float *points;                  /* parametric positions for the joints along the curve */
01653     bPoseChannel **chain;           /* chain of bones to affect using Spline IK (ordered from the tip) */
01654     
01655     bPoseChannel *root;             /* bone that is the root node of the chain */
01656     
01657     bConstraint *con;               /* constraint for this chain */
01658     bSplineIKConstraint *ikData;    /* constraint settings for this chain */
01659 } tSplineIK_Tree;
01660 
01661 /* ----------- */
01662 
01663 /* Tag the bones in the chain formed by the given bone for IK */
01664 static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPoseChannel *pchan_tip)
01665 {
01666     bPoseChannel *pchan, *pchanRoot=NULL;
01667     bPoseChannel *pchanChain[255];
01668     bConstraint *con = NULL;
01669     bSplineIKConstraint *ikData = NULL;
01670     float boneLengths[255], *jointPoints;
01671     float totLength = 0.0f;
01672     short free_joints = 0;
01673     int segcount = 0;
01674     
01675     /* find the SplineIK constraint */
01676     for (con= pchan_tip->constraints.first; con; con= con->next) {
01677         if (con->type == CONSTRAINT_TYPE_SPLINEIK) {
01678             ikData= con->data;
01679             
01680             /* target can only be curve */
01681             if ((ikData->tar == NULL) || (ikData->tar->type != OB_CURVE))  
01682                 continue;
01683             /* skip if disabled */
01684             if ( (con->enforce == 0.0f) || (con->flag & (CONSTRAINT_DISABLE|CONSTRAINT_OFF)) )
01685                 continue;
01686             
01687             /* otherwise, constraint is ok... */
01688             break;
01689         }
01690     }
01691     if (con == NULL)
01692         return;
01693         
01694     /* make sure that the constraint targets are ok 
01695      *  - this is a workaround for a depsgraph bug...
01696      */
01697     if (ikData->tar) {
01698         Curve *cu= ikData->tar->data;
01699         
01700         /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
01701          *      currently for paths to work it needs to go through the bevlist/displist system (ton) 
01702          */
01703         
01704         /* only happens on reload file, but violates depsgraph still... fix! */
01705         if ((cu->path==NULL) || (cu->path->data==NULL))
01706             makeDispListCurveTypes(scene, ikData->tar, 0);
01707     }
01708     
01709     /* find the root bone and the chain of bones from the root to the tip 
01710      * NOTE: this assumes that the bones are connected, but that may not be true...
01711      */
01712     for (pchan= pchan_tip; pchan && (segcount < ikData->chainlen); pchan= pchan->parent, segcount++) {
01713         /* store this segment in the chain */
01714         pchanChain[segcount]= pchan;
01715         
01716         /* if performing rebinding, calculate the length of the bone */
01717         boneLengths[segcount]= pchan->bone->length;
01718         totLength += boneLengths[segcount];
01719     }
01720     
01721     if (segcount == 0)
01722         return;
01723     else
01724         pchanRoot= pchanChain[segcount-1];
01725     
01726     /* perform binding step if required */
01727     if ((ikData->flag & CONSTRAINT_SPLINEIK_BOUND) == 0) {
01728         float segmentLen= (1.0f / (float)segcount);
01729         int i;
01730         
01731         /* setup new empty array for the points list */
01732         if (ikData->points) 
01733             MEM_freeN(ikData->points);
01734         ikData->numpoints= ikData->chainlen+1; 
01735         ikData->points= MEM_callocN(sizeof(float)*ikData->numpoints, "Spline IK Binding");
01736         
01737         /* bind 'tip' of chain (i.e. first joint = tip of bone with the Spline IK Constraint) */
01738         ikData->points[0] = 1.0f;
01739         
01740         /* perform binding of the joints to parametric positions along the curve based 
01741          * proportion of the total length that each bone occupies
01742          */
01743         for (i = 0; i < segcount; i++) {
01744             /* 'head' joints, travelling towards the root of the chain
01745              *  - 2 methods; the one chosen depends on whether we've got usable lengths
01746              */
01747             if ((ikData->flag & CONSTRAINT_SPLINEIK_EVENSPLITS) || (totLength == 0.0f)) {
01748                 /* 1) equi-spaced joints */
01749                 ikData->points[i+1]= ikData->points[i] - segmentLen;
01750             }
01751             else {
01752                 /*  2) to find this point on the curve, we take a step from the previous joint
01753                  *    a distance given by the proportion that this bone takes
01754                  */
01755                 ikData->points[i+1]= ikData->points[i] - (boneLengths[i] / totLength);
01756             }
01757         }
01758         
01759         /* spline has now been bound */
01760         ikData->flag |= CONSTRAINT_SPLINEIK_BOUND;
01761     }
01762     
01763     /* apply corrections for sensitivity to scaling on a copy of the bind points,
01764      * since it's easier to determine the positions of all the joints beforehand this way
01765      */
01766     if ((ikData->flag & CONSTRAINT_SPLINEIK_SCALE_LIMITED) && (totLength != 0.0f)) {
01767         Curve *cu= (Curve *)ikData->tar->data;
01768         float splineLen, maxScale;
01769         int i;
01770         
01771         /* make a copy of the points array, that we'll store in the tree 
01772          *  - although we could just multiply the points on the fly, this approach means that
01773          *    we can introduce per-segment stretchiness later if it is necessary
01774          */
01775         jointPoints= MEM_dupallocN(ikData->points);
01776         free_joints= 1;
01777         
01778         /* get the current length of the curve */
01779         // NOTE: this is assumed to be correct even after the curve was resized
01780         splineLen= cu->path->totdist;
01781         
01782         /* calculate the scale factor to multiply all the path values by so that the 
01783          * bone chain retains its current length, such that
01784          *  maxScale * splineLen = totLength
01785          */
01786         maxScale = totLength / splineLen;
01787         
01788         /* apply scaling correction to all of the temporary points */
01789         // TODO: this is really not adequate enough on really short chains
01790         for (i = 0; i < segcount; i++)
01791             jointPoints[i] *= maxScale;
01792     }
01793     else {
01794         /* just use the existing points array */
01795         jointPoints= ikData->points;
01796         free_joints= 0;
01797     }
01798     
01799     /* make a new Spline-IK chain, and store it in the IK chains */
01800     // TODO: we should check if there is already an IK chain on this, since that would take presidence...
01801     {
01802         /* make new tree */
01803         tSplineIK_Tree *tree= MEM_callocN(sizeof(tSplineIK_Tree), "SplineIK Tree");
01804         tree->type= CONSTRAINT_TYPE_SPLINEIK;
01805         
01806         tree->chainlen= segcount;
01807         
01808         /* copy over the array of links to bones in the chain (from tip to root) */
01809         tree->chain= MEM_callocN(sizeof(bPoseChannel*)*segcount, "SplineIK Chain");
01810         memcpy(tree->chain, pchanChain, sizeof(bPoseChannel*)*segcount);
01811         
01812         /* store reference to joint position array */
01813         tree->points= jointPoints;
01814         tree->free_points= free_joints;
01815         
01816         /* store references to different parts of the chain */
01817         tree->root= pchanRoot;
01818         tree->con= con;
01819         tree->ikData= ikData;
01820         
01821         /* AND! link the tree to the root */
01822         BLI_addtail(&pchanRoot->siktree, tree);
01823     }
01824     
01825     /* mark root channel having an IK tree */
01826     pchanRoot->flag |= POSE_IKSPLINE;
01827 }
01828 
01829 /* Tag which bones are members of Spline IK chains */
01830 static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime))
01831 {
01832     bPoseChannel *pchan;
01833     
01834     /* find the tips of Spline IK chains, which are simply the bones which have been tagged as such */
01835     for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
01836         if (pchan->constflag & PCHAN_HAS_SPLINEIK)
01837             splineik_init_tree_from_pchan(scene, ob, pchan);
01838     }
01839 }
01840 
01841 /* ----------- */
01842 
01843 /* Evaluate spline IK for a given bone */
01844 static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan, int index, float ctime)
01845 {
01846     bSplineIKConstraint *ikData= tree->ikData;
01847     float poseHead[3], poseTail[3], poseMat[4][4]; 
01848     float splineVec[3], scaleFac, radius=1.0f;
01849     
01850     /* firstly, calculate the bone matrix the standard way, since this is needed for roll control */
01851     where_is_pose_bone(scene, ob, pchan, ctime, 1);
01852     
01853     copy_v3_v3(poseHead, pchan->pose_head);
01854     copy_v3_v3(poseTail, pchan->pose_tail);
01855     
01856     /* step 1: determine the positions for the endpoints of the bone */
01857     {
01858         float vec[4], dir[3], rad;
01859         float tailBlendFac= 1.0f;
01860         
01861         /* determine if the bone should still be affected by SplineIK */
01862         if (tree->points[index+1] >= 1.0f) {
01863             /* spline doesn't affect the bone anymore, so done... */
01864             pchan->flag |= POSE_DONE;
01865             return;
01866         }
01867         else if ((tree->points[index] >= 1.0f) && (tree->points[index+1] < 1.0f)) {
01868             /* blending factor depends on the amount of the bone still left on the chain */
01869             tailBlendFac= (1.0f - tree->points[index+1]) / (tree->points[index] - tree->points[index+1]);
01870         }
01871         
01872         /* tail endpoint */
01873         if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad, NULL) ) {
01874             /* apply curve's object-mode transforms to the position 
01875              * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
01876              */
01877             if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0)
01878                 mul_m4_v3(ikData->tar->obmat, vec);
01879             
01880             /* convert the position to pose-space, then store it */
01881             mul_m4_v3(ob->imat, vec);
01882             interp_v3_v3v3(poseTail, pchan->pose_tail, vec, tailBlendFac);
01883             
01884             /* set the new radius */
01885             radius= rad;
01886         }
01887         
01888         /* head endpoint */
01889         if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad, NULL) ) {
01890             /* apply curve's object-mode transforms to the position 
01891              * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
01892              */
01893             if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0)
01894                 mul_m4_v3(ikData->tar->obmat, vec);
01895             
01896             /* store the position, and convert it to pose space */
01897             mul_m4_v3(ob->imat, vec);
01898             copy_v3_v3(poseHead, vec);
01899             
01900             /* set the new radius (it should be the average value) */
01901             radius = (radius+rad) / 2;
01902         }
01903     }
01904     
01905     /* step 2: determine the implied transform from these endpoints 
01906      *  - splineVec: the vector direction that the spline applies on the bone
01907      *  - scaleFac: the factor that the bone length is scaled by to get the desired amount
01908      */
01909     sub_v3_v3v3(splineVec, poseTail, poseHead);
01910     scaleFac= len_v3(splineVec) / pchan->bone->length;
01911     
01912     /* step 3: compute the shortest rotation needed to map from the bone rotation to the current axis 
01913      *  - this uses the same method as is used for the Damped Track Constraint (see the code there for details)
01914      */
01915     {
01916         float dmat[3][3], rmat[3][3], tmat[3][3];
01917         float raxis[3], rangle;
01918         
01919         /* compute the raw rotation matrix from the bone's current matrix by extracting only the
01920          * orientation-relevant axes, and normalising them
01921          */
01922         copy_v3_v3(rmat[0], pchan->pose_mat[0]);
01923         copy_v3_v3(rmat[1], pchan->pose_mat[1]);
01924         copy_v3_v3(rmat[2], pchan->pose_mat[2]);
01925         normalize_m3(rmat);
01926         
01927         /* also, normalise the orientation imposed by the bone, now that we've extracted the scale factor */
01928         normalize_v3(splineVec);
01929         
01930         /* calculate smallest axis-angle rotation necessary for getting from the
01931          * current orientation of the bone, to the spline-imposed direction
01932          */
01933         cross_v3_v3v3(raxis, rmat[1], splineVec);
01934         
01935         rangle= dot_v3v3(rmat[1], splineVec);
01936         rangle= acos( MAX2(-1.0f, MIN2(1.0f, rangle)) );
01937         
01938         /* multiply the magnitude of the angle by the influence of the constraint to 
01939          * control the influence of the SplineIK effect 
01940          */
01941         rangle *= tree->con->enforce;
01942         
01943         /* construct rotation matrix from the axis-angle rotation found above 
01944          *  - this call takes care to make sure that the axis provided is a unit vector first
01945          */
01946         axis_angle_to_mat3(dmat, raxis, rangle);
01947         
01948         /* combine these rotations so that the y-axis of the bone is now aligned as the spline dictates,
01949          * while still maintaining roll control from the existing bone animation
01950          */
01951         mul_m3_m3m3(tmat, dmat, rmat); // m1, m3, m2
01952         normalize_m3(tmat); /* attempt to reduce shearing, though I doubt this'll really help too much now... */
01953         copy_m4_m3(poseMat, tmat);
01954     }
01955     
01956     /* step 4: set the scaling factors for the axes */
01957     {
01958         /* only multiply the y-axis by the scaling factor to get nice volume-preservation */
01959         mul_v3_fl(poseMat[1], scaleFac);
01960         
01961         /* set the scaling factors of the x and z axes from... */
01962         switch (ikData->xzScaleMode) {
01963             case CONSTRAINT_SPLINEIK_XZS_ORIGINAL:
01964             {
01965                 /* original scales get used */
01966                 float scale;
01967                 
01968                 /* x-axis scale */
01969                 scale= len_v3(pchan->pose_mat[0]);
01970                 mul_v3_fl(poseMat[0], scale);
01971                 /* z-axis scale */
01972                 scale= len_v3(pchan->pose_mat[2]);
01973                 mul_v3_fl(poseMat[2], scale);
01974             }
01975                 break;
01976             case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC:
01977             {
01978                 /* 'volume preservation' */
01979                 float scale;
01980                 
01981                 /* calculate volume preservation factor which is 
01982                  * basically the inverse of the y-scaling factor 
01983                  */
01984                 if (fabsf(scaleFac) != 0.0f) {
01985                     scale= 1.0f / fabsf(scaleFac);
01986                     
01987                     /* we need to clamp this within sensible values */
01988                     // NOTE: these should be fine for now, but should get sanitised in future
01989                     CLAMP(scale, 0.0001f, 100000.0f);
01990                 }
01991                 else
01992                     scale= 1.0f;
01993                 
01994                 /* apply the scaling */
01995                 mul_v3_fl(poseMat[0], scale);
01996                 mul_v3_fl(poseMat[2], scale);
01997             }
01998                 break;
01999         }
02000         
02001         /* finally, multiply the x and z scaling by the radius of the curve too, 
02002          * to allow automatic scales to get tweaked still
02003          */
02004         if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
02005             mul_v3_fl(poseMat[0], radius);
02006             mul_v3_fl(poseMat[2], radius);
02007         }
02008     }
02009     
02010     /* step 5: set the location of the bone in the matrix */
02011     if (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) {
02012         /* when the 'no-root' option is affected, the chain can retain
02013          * the shape but be moved elsewhere
02014          */
02015         copy_v3_v3(poseHead, pchan->pose_head);
02016     }
02017     else if (tree->con->enforce < 1.0f) {
02018         /* when the influence is too low
02019          *  - blend the positions for the 'root' bone
02020          *  - stick to the parent for any other
02021          */
02022         if (pchan->parent) {
02023             copy_v3_v3(poseHead, pchan->pose_head);
02024         }
02025         else {
02026             // FIXME: this introduces popping artifacts when we reach 0.0
02027             interp_v3_v3v3(poseHead, pchan->pose_head, poseHead, tree->con->enforce);
02028         }
02029     }
02030     copy_v3_v3(poseMat[3], poseHead);
02031     
02032     /* finally, store the new transform */
02033     copy_m4_m4(pchan->pose_mat, poseMat);
02034     copy_v3_v3(pchan->pose_head, poseHead);
02035     
02036     /* recalculate tail, as it's now outdated after the head gets adjusted above! */
02037     where_is_pose_bone_tail(pchan);
02038     
02039     /* done! */
02040     pchan->flag |= POSE_DONE;
02041 }
02042 
02043 /* Evaluate the chain starting from the nominated bone */
02044 static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
02045 {
02046     tSplineIK_Tree *tree;
02047     
02048     /* for each pose-tree, execute it if it is spline, otherwise just free it */
02049     while ((tree = pchan_root->siktree.first) != NULL) {
02050         int i;
02051         
02052         /* walk over each bone in the chain, calculating the effects of spline IK
02053          *  - the chain is traversed in the opposite order to storage order (i.e. parent to children)
02054          *    so that dependencies are correct
02055          */
02056         for (i= tree->chainlen-1; i >= 0; i--) {
02057             bPoseChannel *pchan= tree->chain[i];
02058             splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime);
02059         }
02060         
02061         /* free the tree info specific to SplineIK trees now */
02062         if (tree->chain) MEM_freeN(tree->chain);
02063         if (tree->free_points) MEM_freeN(tree->points);
02064         
02065         /* free this tree */
02066         BLI_freelinkN(&pchan_root->siktree, tree);
02067     }
02068 }
02069 
02070 /* ********************** THE POSE SOLVER ******************* */
02071 
02072 /* loc/rot/size to given mat4 */
02073 void pchan_to_mat4(bPoseChannel *pchan, float chan_mat[4][4])
02074 {
02075     float smat[3][3];
02076     float rmat[3][3];
02077     float tmat[3][3];
02078     
02079     /* get scaling matrix */
02080     size_to_mat3(smat, pchan->size);
02081     
02082     /* rotations may either be quats, eulers (with various rotation orders), or axis-angle */
02083     if (pchan->rotmode > 0) {
02084         /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */
02085         eulO_to_mat3(rmat, pchan->eul, pchan->rotmode);
02086     }
02087     else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
02088         /* axis-angle - not really that great for 3D-changing orientations */
02089         axis_angle_to_mat3(rmat, pchan->rotAxis, pchan->rotAngle);
02090     }
02091     else {
02092         /* quats are normalised before use to eliminate scaling issues */
02093         float quat[4];
02094         
02095         /* NOTE: we now don't normalise the stored values anymore, since this was kindof evil in some cases
02096          * but if this proves to be too problematic, switch back to the old system of operating directly on 
02097          * the stored copy
02098          */
02099         normalize_qt_qt(quat, pchan->quat);
02100         quat_to_mat3(rmat, quat);
02101     }
02102     
02103     /* calculate matrix of bone (as 3x3 matrix, but then copy the 4x4) */
02104     mul_m3_m3m3(tmat, rmat, smat);
02105     copy_m4_m3(chan_mat, tmat);
02106     
02107     /* prevent action channels breaking chains */
02108     /* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */
02109     if ((pchan->bone==NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
02110         copy_v3_v3(chan_mat[3], pchan->loc);
02111     }
02112 }
02113 
02114 /* loc/rot/size to mat4 */
02115 /* used in constraint.c too */
02116 void pchan_calc_mat(bPoseChannel *pchan)
02117 {
02118     /* this is just a wrapper around the copy of this function which calculates the matrix 
02119      * and stores the result in any given channel
02120      */
02121     pchan_to_mat4(pchan, pchan->chan_mat);
02122 }
02123 
02124 #if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
02125 
02126 /* NLA strip modifiers */
02127 static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseChannel *pchan)
02128 {
02129     bActionModifier *amod;
02130     bActionStrip *strip, *strip2;
02131     float scene_cfra= (float)scene->r.cfra;
02132     int do_modif;
02133 
02134     for (strip=armob->nlastrips.first; strip; strip=strip->next) {
02135         do_modif=0;
02136         
02137         if (scene_cfra>=strip->start && scene_cfra<=strip->end)
02138             do_modif=1;
02139         
02140         if ((scene_cfra > strip->end) && (strip->flag & ACTSTRIP_HOLDLASTFRAME)) {
02141             do_modif=1;
02142             
02143             /* if there are any other strips active, ignore modifiers for this strip - 
02144              * 'hold' option should only hold action modifiers if there are 
02145              * no other active strips */
02146             for (strip2=strip->next; strip2; strip2=strip2->next) {
02147                 if (strip2 == strip) continue;
02148                 
02149                 if (scene_cfra>=strip2->start && scene_cfra<=strip2->end) {
02150                     if (!(strip2->flag & ACTSTRIP_MUTE))
02151                         do_modif=0;
02152                 }
02153             }
02154             
02155             /* if there are any later, activated, strips with 'hold' set, they take precedence, 
02156              * so ignore modifiers for this strip */
02157             for (strip2=strip->next; strip2; strip2=strip2->next) {
02158                 if (scene_cfra < strip2->start) continue;
02159                 if ((strip2->flag & ACTSTRIP_HOLDLASTFRAME) && !(strip2->flag & ACTSTRIP_MUTE)) {
02160                     do_modif=0;
02161                 }
02162             }
02163         }
02164         
02165         if (do_modif) {
02166             /* temporal solution to prevent 2 strips accumulating */
02167             if(scene_cfra==strip->end && strip->next && strip->next->start==scene_cfra)
02168                 continue;
02169             
02170             for(amod= strip->modifiers.first; amod; amod= amod->next) {
02171                 switch (amod->type) {
02172                 case ACTSTRIP_MOD_DEFORM:
02173                 {
02174                     /* validate first */
02175                     if(amod->ob && amod->ob->type==OB_CURVE && amod->channel[0]) {
02176                         
02177                         if( strcmp(pchan->name, amod->channel)==0 ) {
02178                             float mat4[4][4], mat3[3][3];
02179                             
02180                             curve_deform_vector(scene, amod->ob, armob, bone->arm_mat[3], pchan->pose_mat[3], mat3, amod->no_rot_axis);
02181                             copy_m4_m4(mat4, pchan->pose_mat);
02182                             mul_m4_m3m4(pchan->pose_mat, mat3, mat4);
02183                             
02184                         }
02185                     }
02186                 }
02187                     break;
02188                 case ACTSTRIP_MOD_NOISE:    
02189                 {
02190                     if( strcmp(pchan->name, amod->channel)==0 ) {
02191                         float nor[3], loc[3], ofs;
02192                         float eul[3], size[3], eulo[3], sizeo[3];
02193                         
02194                         /* calculate turbulance */
02195                         ofs = amod->turbul / 200.0f;
02196                         
02197                         /* make a copy of starting conditions */
02198                         copy_v3_v3(loc, pchan->pose_mat[3]);
02199                         mat4_to_eul( eul,pchan->pose_mat);
02200                         mat4_to_size( size,pchan->pose_mat);
02201                         copy_v3_v3(eulo, eul);
02202                         copy_v3_v3(sizeo, size);
02203                         
02204                         /* apply noise to each set of channels */
02205                         if (amod->channels & 4) {
02206                             /* for scaling */
02207                             nor[0] = BLI_gNoise(amod->noisesize, size[0]+ofs, size[1], size[2], 0, 0) - ofs;
02208                             nor[1] = BLI_gNoise(amod->noisesize, size[0], size[1]+ofs, size[2], 0, 0) - ofs;    
02209                             nor[2] = BLI_gNoise(amod->noisesize, size[0], size[1], size[2]+ofs, 0, 0) - ofs;
02210                             add_v3_v3(size, nor);
02211                             
02212                             if (sizeo[0] != 0)
02213                                 mul_v3_fl(pchan->pose_mat[0], size[0] / sizeo[0]);
02214                             if (sizeo[1] != 0)
02215                                 mul_v3_fl(pchan->pose_mat[1], size[1] / sizeo[1]);
02216                             if (sizeo[2] != 0)
02217                                 mul_v3_fl(pchan->pose_mat[2], size[2] / sizeo[2]);
02218                         }
02219                         if (amod->channels & 2) {
02220                             /* for rotation */
02221                             nor[0] = BLI_gNoise(amod->noisesize, eul[0]+ofs, eul[1], eul[2], 0, 0) - ofs;
02222                             nor[1] = BLI_gNoise(amod->noisesize, eul[0], eul[1]+ofs, eul[2], 0, 0) - ofs;   
02223                             nor[2] = BLI_gNoise(amod->noisesize, eul[0], eul[1], eul[2]+ofs, 0, 0) - ofs;
02224                             
02225                             compatible_eul(nor, eulo);
02226                             add_v3_v3(eul, nor);
02227                             compatible_eul(eul, eulo);
02228                             
02229                             loc_eul_size_to_mat4(pchan->pose_mat, loc, eul, size);
02230                         }
02231                         if (amod->channels & 1) {
02232                             /* for location */
02233                             nor[0] = BLI_gNoise(amod->noisesize, loc[0]+ofs, loc[1], loc[2], 0, 0) - ofs;
02234                             nor[1] = BLI_gNoise(amod->noisesize, loc[0], loc[1]+ofs, loc[2], 0, 0) - ofs;   
02235                             nor[2] = BLI_gNoise(amod->noisesize, loc[0], loc[1], loc[2]+ofs, 0, 0) - ofs;
02236                             
02237                             add_v3_v3v3(pchan->pose_mat[3], loc, nor);
02238                         }
02239                     }
02240                 }
02241                     break;
02242                 }
02243             }
02244         }
02245     }
02246 }
02247 
02248 #endif
02249 
02250 /* calculate tail of posechannel */
02251 void where_is_pose_bone_tail(bPoseChannel *pchan)
02252 {
02253     float vec[3];
02254     
02255     copy_v3_v3(vec, pchan->pose_mat[1]);
02256     mul_v3_fl(vec, pchan->bone->length);
02257     add_v3_v3v3(pchan->pose_tail, pchan->pose_head, vec);
02258 }
02259 
02260 /* The main armature solver, does all constraints excluding IK */
02261 /* pchan is validated, as having bone and parent pointer
02262  * 'do_extra': when zero skips loc/size/rot, constraints and strip modifiers.
02263  */
02264 void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, int do_extra)
02265 {
02266     Bone *bone, *parbone;
02267     bPoseChannel *parchan;
02268     float vec[3];
02269     
02270     /* set up variables for quicker access below */
02271     bone= pchan->bone;
02272     parbone= bone->parent;
02273     parchan= pchan->parent;
02274     
02275     /* this gives a chan_mat with actions (ipos) results */
02276     if(do_extra)    pchan_calc_mat(pchan);
02277     else            unit_m4(pchan->chan_mat);
02278 
02279     /* construct the posemat based on PoseChannels, that we do before applying constraints */
02280     /* pose_mat(b)= pose_mat(b-1) * yoffs(b-1) * d_root(b) * bone_mat(b) * chan_mat(b) */
02281     
02282     if(parchan) {
02283         float offs_bone[4][4];  // yoffs(b-1) + root(b) + bonemat(b)
02284         
02285         /* bone transform itself */
02286         copy_m4_m3(offs_bone, bone->bone_mat);
02287         
02288         /* The bone's root offset (is in the parent's coordinate system) */
02289         copy_v3_v3(offs_bone[3], bone->head);
02290         
02291         /* Get the length translation of parent (length along y axis) */
02292         offs_bone[3][1]+= parbone->length;
02293         
02294         /* Compose the matrix for this bone  */
02295         if((bone->flag & BONE_HINGE) && (bone->flag & BONE_NO_SCALE)) { // uses restposition rotation, but actual position
02296             float tmat[4][4];
02297             /* the rotation of the parent restposition */
02298             copy_m4_m4(tmat, parbone->arm_mat);
02299             mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
02300         }
02301         else if(bone->flag & BONE_HINGE) {  // same as above but apply parent scale
02302             float tmat[4][4];
02303 
02304             /* apply the parent matrix scale */
02305             float tsmat[4][4], tscale[3];
02306 
02307             /* the rotation of the parent restposition */
02308             copy_m4_m4(tmat, parbone->arm_mat);
02309 
02310             /* extract the scale of the parent matrix */
02311             mat4_to_size(tscale, parchan->pose_mat);
02312             size_to_mat4(tsmat, tscale);
02313             mult_m4_m4m4(tmat, tsmat, tmat);
02314 
02315             mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
02316         }
02317         else if(bone->flag & BONE_NO_SCALE) {
02318             float orthmat[4][4];
02319             
02320             /* do transform, with an ortho-parent matrix */
02321             copy_m4_m4(orthmat, parchan->pose_mat);
02322             normalize_m4(orthmat);
02323             mul_serie_m4(pchan->pose_mat, orthmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
02324         }
02325         else
02326             mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL);
02327         
02328         /* in these cases we need to compute location separately */
02329         if(bone->flag & (BONE_HINGE|BONE_NO_SCALE|BONE_NO_LOCAL_LOCATION)) {
02330             float bone_loc[3], chan_loc[3];
02331 
02332             mul_v3_m4v3(bone_loc, parchan->pose_mat, offs_bone[3]);
02333             copy_v3_v3(chan_loc, pchan->chan_mat[3]);
02334 
02335             /* no local location is not transformed by bone matrix */
02336             if(!(bone->flag & BONE_NO_LOCAL_LOCATION))
02337                 mul_mat3_m4_v3(offs_bone, chan_loc);
02338 
02339             /* for hinge we use armature instead of pose mat */
02340             if(bone->flag & BONE_HINGE) mul_mat3_m4_v3(parbone->arm_mat, chan_loc);
02341             else mul_mat3_m4_v3(parchan->pose_mat, chan_loc);
02342 
02343             add_v3_v3v3(pchan->pose_mat[3], bone_loc, chan_loc);
02344         }
02345     }
02346     else {
02347         mult_m4_m4m4(pchan->pose_mat, bone->arm_mat, pchan->chan_mat);
02348 
02349         /* optional location without arm_mat rotation */
02350         if(bone->flag & BONE_NO_LOCAL_LOCATION)
02351             add_v3_v3v3(pchan->pose_mat[3], bone->arm_mat[3], pchan->chan_mat[3]);
02352         
02353         /* only rootbones get the cyclic offset (unless user doesn't want that) */
02354         if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0)
02355             add_v3_v3(pchan->pose_mat[3], ob->pose->cyclic_offset);
02356     }
02357     
02358     if(do_extra) {
02359 
02360 #if 0   /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
02361         /* do NLA strip modifiers - i.e. curve follow */
02362         do_strip_modifiers(scene, ob, bone, pchan);
02363 #endif
02364 
02365         /* Do constraints */
02366         if (pchan->constraints.first) {
02367             bConstraintOb *cob;
02368 
02369             /* make a copy of location of PoseChannel for later */
02370             copy_v3_v3(vec, pchan->pose_mat[3]);
02371 
02372             /* prepare PoseChannel for Constraint solving
02373              * - makes a copy of matrix, and creates temporary struct to use
02374              */
02375             cob= constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE);
02376 
02377             /* Solve PoseChannel's Constraints */
02378             solve_constraints(&pchan->constraints, cob, ctime); // ctime doesnt alter objects
02379 
02380             /* cleanup after Constraint Solving
02381              * - applies matrix back to pchan, and frees temporary struct used
02382              */
02383             constraints_clear_evalob(cob);
02384 
02385             /* prevent constraints breaking a chain */
02386             if(pchan->bone->flag & BONE_CONNECTED) {
02387                 copy_v3_v3(pchan->pose_mat[3], vec);
02388             }
02389         }
02390     }
02391     
02392     /* calculate head */
02393     copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]);
02394     /* calculate tail */
02395     where_is_pose_bone_tail(pchan);
02396 }
02397 
02398 /* This only reads anim data from channels, and writes to channels */
02399 /* This is the only function adding poses */
02400 void where_is_pose (Scene *scene, Object *ob)
02401 {
02402     bArmature *arm;
02403     Bone *bone;
02404     bPoseChannel *pchan;
02405     float imat[4][4];
02406     float ctime;
02407     
02408     if(ob->type!=OB_ARMATURE) return;
02409     arm = ob->data;
02410     
02411     if(ELEM(NULL, arm, scene)) return;
02412     if((ob->pose==NULL) || (ob->pose->flag & POSE_RECALC)) 
02413         armature_rebuild_pose(ob, arm);
02414        
02415     ctime= BKE_curframe(scene); /* not accurate... */
02416     
02417     /* In editmode or restposition we read the data from the bones */
02418     if(arm->edbo || (arm->flag & ARM_RESTPOS)) {
02419         
02420         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
02421             bone= pchan->bone;
02422             if(bone) {
02423                 copy_m4_m4(pchan->pose_mat, bone->arm_mat);
02424                 copy_v3_v3(pchan->pose_head, bone->arm_head);
02425                 copy_v3_v3(pchan->pose_tail, bone->arm_tail);
02426             }
02427         }
02428     }
02429     else {
02430         invert_m4_m4(ob->imat, ob->obmat);  // imat is needed 
02431         
02432         /* 1. clear flags */
02433         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
02434             pchan->flag &= ~(POSE_DONE|POSE_CHAIN|POSE_IKTREE|POSE_IKSPLINE);
02435         }
02436         
02437         /* 2a. construct the IK tree (standard IK) */
02438         BIK_initialize_tree(scene, ob, ctime);
02439         
02440         /* 2b. construct the Spline IK trees 
02441          *  - this is not integrated as an IK plugin, since it should be able
02442          *    to function in conjunction with standard IK
02443          */
02444         splineik_init_tree(scene, ob, ctime);
02445         
02446         /* 3. the main loop, channels are already hierarchical sorted from root to children */
02447         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
02448             /* 4a. if we find an IK root, we handle it separated */
02449             if(pchan->flag & POSE_IKTREE) {
02450                 BIK_execute_tree(scene, ob, pchan, ctime);
02451             }
02452             /* 4b. if we find a Spline IK root, we handle it separated too */
02453             else if(pchan->flag & POSE_IKSPLINE) {
02454                 splineik_execute_tree(scene, ob, pchan, ctime);
02455             }
02456             /* 5. otherwise just call the normal solver */
02457             else if(!(pchan->flag & POSE_DONE)) {
02458                 where_is_pose_bone(scene, ob, pchan, ctime, 1);
02459             }
02460         }
02461         /* 6. release the IK tree */
02462         BIK_release_tree(scene, ob, ctime);
02463     }
02464         
02465     /* calculating deform matrices */
02466     for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
02467         if(pchan->bone) {
02468             invert_m4_m4(imat, pchan->bone->arm_mat);
02469             mult_m4_m4m4(pchan->chan_mat, pchan->pose_mat, imat);
02470         }
02471     }
02472 }
02473 
02474 
02475 /* Returns total selected vgroups,
02476  * wpi.defbase_sel is assumed malloc'd, all values are set */
02477 int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_tot)
02478 {
02479     bDeformGroup *defgroup;
02480     unsigned int i;
02481     Object *armob= object_pose_armature_get(ob);
02482     int dg_flags_sel_tot= 0;
02483 
02484     if(armob) {
02485         bPose *pose= armob->pose;
02486         for (i= 0, defgroup= ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
02487             bPoseChannel *pchan= get_pose_channel(pose, defgroup->name);
02488             if(pchan && (pchan->bone->flag & BONE_SELECTED)) {
02489                 dg_selection[i]= TRUE;
02490                 dg_flags_sel_tot++;
02491             }
02492             else {
02493                 dg_selection[i]= FALSE;
02494             }
02495         }
02496     }
02497     else {
02498         memset(dg_selection, FALSE, sizeof(char) * defbase_tot);
02499     }
02500 
02501     return dg_flags_sel_tot;
02502 }