|
Blender
V2.59
|
00001 /* 00002 * $Id: armature.c 37546 2011-06-16 07:59:22Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Full recode, Ton Roosendaal, Crete 2005 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <ctype.h> 00034 #include <stdlib.h> 00035 #include <math.h> 00036 #include <string.h> 00037 #include <stdio.h> 00038 #include <float.h> 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_math.h" 00043 #include "BLI_blenlib.h" 00044 #include "BLI_utildefines.h" 00045 00046 #include "DNA_anim_types.h" 00047 #include "DNA_armature_types.h" 00048 #include "DNA_constraint_types.h" 00049 #include "DNA_mesh_types.h" 00050 #include "DNA_lattice_types.h" 00051 #include "DNA_meshdata_types.h" 00052 #include "DNA_nla_types.h" 00053 #include "DNA_scene_types.h" 00054 #include "DNA_object_types.h" 00055 00056 #include "BKE_animsys.h" 00057 #include "BKE_armature.h" 00058 #include "BKE_action.h" 00059 #include "BKE_anim.h" 00060 #include "BKE_constraint.h" 00061 #include "BKE_curve.h" 00062 #include "BKE_depsgraph.h" 00063 #include "BKE_DerivedMesh.h" 00064 #include "BKE_deform.h" 00065 #include "BKE_displist.h" 00066 #include "BKE_global.h" 00067 #include "BKE_idprop.h" 00068 #include "BKE_library.h" 00069 #include "BKE_lattice.h" 00070 #include "BKE_main.h" 00071 #include "BKE_object.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 local=0, lib=0; 00142 Object *ob; 00143 00144 if (arm->id.lib==NULL) return; 00145 if (arm->id.us==1) { 00146 arm->id.lib= NULL; 00147 arm->id.flag= LIB_LOCAL; 00148 new_id(&bmain->armature, (ID*)arm, NULL); 00149 return; 00150 } 00151 00152 for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { 00153 if(ob->data == arm) { 00154 if(ob->id.lib) lib= 1; 00155 else local= 1; 00156 } 00157 } 00158 00159 if(local && lib==0) { 00160 arm->id.lib= NULL; 00161 arm->id.flag= LIB_LOCAL; 00162 new_id(&bmain->armature, (ID *)arm, NULL); 00163 } 00164 else if(local && lib) { 00165 bArmature *armn= copy_armature(arm); 00166 armn->id.us= 0; 00167 00168 for(ob= bmain->object.first; ob; ob= ob->id.next) { 00169 if(ob->data == arm) { 00170 if(ob->id.lib==NULL) { 00171 ob->data= armn; 00172 armn->id.us++; 00173 arm->id.us--; 00174 } 00175 } 00176 } 00177 } 00178 } 00179 00180 static void copy_bonechildren (Bone* newBone, Bone* oldBone, Bone* actBone, Bone **newActBone) 00181 { 00182 Bone *curBone, *newChildBone; 00183 00184 if(oldBone == actBone) 00185 *newActBone= newBone; 00186 00187 if(oldBone->prop) 00188 newBone->prop= IDP_CopyProperty(oldBone->prop); 00189 00190 /* Copy this bone's list*/ 00191 BLI_duplicatelist(&newBone->childbase, &oldBone->childbase); 00192 00193 /* For each child in the list, update it's children*/ 00194 newChildBone=newBone->childbase.first; 00195 for (curBone=oldBone->childbase.first;curBone;curBone=curBone->next){ 00196 newChildBone->parent=newBone; 00197 copy_bonechildren(newChildBone, curBone, actBone, newActBone); 00198 newChildBone=newChildBone->next; 00199 } 00200 } 00201 00202 bArmature *copy_armature(bArmature *arm) 00203 { 00204 bArmature *newArm; 00205 Bone *oldBone, *newBone; 00206 Bone *newActBone= NULL; 00207 00208 newArm= copy_libblock (arm); 00209 BLI_duplicatelist(&newArm->bonebase, &arm->bonebase); 00210 00211 /* Duplicate the childrens' lists*/ 00212 newBone=newArm->bonebase.first; 00213 for (oldBone=arm->bonebase.first;oldBone;oldBone=oldBone->next){ 00214 newBone->parent=NULL; 00215 copy_bonechildren (newBone, oldBone, arm->act_bone, &newActBone); 00216 newBone=newBone->next; 00217 }; 00218 00219 newArm->act_bone= newActBone; 00220 00221 newArm->edbo= NULL; 00222 newArm->act_edbone= NULL; 00223 newArm->sketch= NULL; 00224 00225 return newArm; 00226 } 00227 00228 static Bone *get_named_bone_bonechildren (Bone *bone, const char *name) 00229 { 00230 Bone *curBone, *rbone; 00231 00232 if (!strcmp (bone->name, name)) 00233 return bone; 00234 00235 for (curBone=bone->childbase.first; curBone; curBone=curBone->next){ 00236 rbone=get_named_bone_bonechildren (curBone, name); 00237 if (rbone) 00238 return rbone; 00239 } 00240 00241 return NULL; 00242 } 00243 00244 00245 Bone *get_named_bone (bArmature *arm, const char *name) 00246 /* 00247 Walk the list until the bone is found 00248 */ 00249 { 00250 Bone *bone=NULL, *curBone; 00251 00252 if (!arm) return NULL; 00253 00254 for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){ 00255 bone = get_named_bone_bonechildren (curBone, name); 00256 if (bone) 00257 return bone; 00258 } 00259 00260 return bone; 00261 } 00262 00263 /* Finds the best possible extension to the name on a particular axis. (For renaming, check for unique names afterwards) 00264 * strip_number: removes number extensions (TODO: not used) 00265 * axis: the axis to name on 00266 * head/tail: the head/tail co-ordinate of the bone on the specified axis 00267 */ 00268 int bone_autoside_name (char name[MAXBONENAME], int UNUSED(strip_number), short axis, float head, float tail) 00269 { 00270 unsigned int len; 00271 char basename[MAXBONENAME]= ""; 00272 char extension[5]= ""; 00273 00274 len= strlen(name); 00275 if (len == 0) return 0; 00276 BLI_strncpy(basename, name, sizeof(basename)); 00277 00278 /* Figure out extension to append: 00279 * - The extension to append is based upon the axis that we are working on. 00280 * - If head happens to be on 0, then we must consider the tail position as well to decide 00281 * which side the bone is on 00282 * -> If tail is 0, then it's bone is considered to be on axis, so no extension should be added 00283 * -> Otherwise, extension is added from perspective of object based on which side tail goes to 00284 * - If head is non-zero, extension is added from perspective of object based on side head is on 00285 */ 00286 if (axis == 2) { 00287 /* z-axis - vertical (top/bottom) */ 00288 if (IS_EQ(head, 0)) { 00289 if (tail < 0) 00290 strcpy(extension, "Bot"); 00291 else if (tail > 0) 00292 strcpy(extension, "Top"); 00293 } 00294 else { 00295 if (head < 0) 00296 strcpy(extension, "Bot"); 00297 else 00298 strcpy(extension, "Top"); 00299 } 00300 } 00301 else if (axis == 1) { 00302 /* y-axis - depth (front/back) */ 00303 if (IS_EQ(head, 0)) { 00304 if (tail < 0) 00305 strcpy(extension, "Fr"); 00306 else if (tail > 0) 00307 strcpy(extension, "Bk"); 00308 } 00309 else { 00310 if (head < 0) 00311 strcpy(extension, "Fr"); 00312 else 00313 strcpy(extension, "Bk"); 00314 } 00315 } 00316 else { 00317 /* x-axis - horizontal (left/right) */ 00318 if (IS_EQ(head, 0)) { 00319 if (tail < 0) 00320 strcpy(extension, "R"); 00321 else if (tail > 0) 00322 strcpy(extension, "L"); 00323 } 00324 else { 00325 if (head < 0) 00326 strcpy(extension, "R"); 00327 else if (head > 0) 00328 strcpy(extension, "L"); 00329 } 00330 } 00331 00332 /* Simple name truncation 00333 * - truncate if there is an extension and it wouldn't be able to fit 00334 * - otherwise, just append to end 00335 */ 00336 if (extension[0]) { 00337 int change = 1; 00338 00339 while (change) { /* remove extensions */ 00340 change = 0; 00341 if (len > 2 && basename[len-2]=='.') { 00342 if (basename[len-1]=='L' || basename[len-1] == 'R' ) { /* L R */ 00343 basename[len-2] = '\0'; 00344 len-=2; 00345 change= 1; 00346 } 00347 } else if (len > 3 && basename[len-3]=='.') { 00348 if ( (basename[len-2]=='F' && basename[len-1] == 'r') || /* Fr */ 00349 (basename[len-2]=='B' && basename[len-1] == 'k') /* Bk */ 00350 ) { 00351 basename[len-3] = '\0'; 00352 len-=3; 00353 change= 1; 00354 } 00355 } else if (len > 4 && basename[len-4]=='.') { 00356 if ( (basename[len-3]=='T' && basename[len-2]=='o' && basename[len-1] == 'p') || /* Top */ 00357 (basename[len-3]=='B' && basename[len-2]=='o' && basename[len-1] == 't') /* Bot */ 00358 ) { 00359 basename[len-4] = '\0'; 00360 len-=4; 00361 change= 1; 00362 } 00363 } 00364 } 00365 00366 if ((MAXBONENAME - len) < strlen(extension) + 1) { /* add 1 for the '.' */ 00367 strncpy(name, basename, len-strlen(extension)); 00368 } 00369 00370 BLI_snprintf(name, MAXBONENAME, "%s.%s", basename, extension); 00371 00372 return 1; 00373 } 00374 00375 else { 00376 return 0; 00377 } 00378 } 00379 00380 /* ************* B-Bone support ******************* */ 00381 00382 #define MAX_BBONE_SUBDIV 32 00383 00384 /* data has MAX_BBONE_SUBDIV+1 interpolated points, will become desired amount with equal distances */ 00385 static void equalize_bezier(float *data, int desired) 00386 { 00387 float *fp, totdist, ddist, dist, fac1, fac2; 00388 float pdist[MAX_BBONE_SUBDIV+1]; 00389 float temp[MAX_BBONE_SUBDIV+1][4]; 00390 int a, nr; 00391 00392 pdist[0]= 0.0f; 00393 for(a=0, fp= data; a<MAX_BBONE_SUBDIV; a++, fp+=4) { 00394 QUATCOPY(temp[a], fp); 00395 pdist[a+1]= pdist[a]+len_v3v3(fp, fp+4); 00396 } 00397 /* do last point */ 00398 QUATCOPY(temp[a], fp); 00399 totdist= pdist[a]; 00400 00401 /* go over distances and calculate new points */ 00402 ddist= totdist/((float)desired); 00403 nr= 1; 00404 for(a=1, fp= data+4; a<desired; a++, fp+=4) { 00405 00406 dist= ((float)a)*ddist; 00407 00408 /* we're looking for location (distance) 'dist' in the array */ 00409 while((dist>= pdist[nr]) && nr<MAX_BBONE_SUBDIV) { 00410 nr++; 00411 } 00412 00413 fac1= pdist[nr]- pdist[nr-1]; 00414 fac2= pdist[nr]-dist; 00415 fac1= fac2/fac1; 00416 fac2= 1.0f-fac1; 00417 00418 fp[0]= fac1*temp[nr-1][0]+ fac2*temp[nr][0]; 00419 fp[1]= fac1*temp[nr-1][1]+ fac2*temp[nr][1]; 00420 fp[2]= fac1*temp[nr-1][2]+ fac2*temp[nr][2]; 00421 fp[3]= fac1*temp[nr-1][3]+ fac2*temp[nr][3]; 00422 } 00423 /* set last point, needed for orientation calculus */ 00424 QUATCOPY(fp, temp[MAX_BBONE_SUBDIV]); 00425 } 00426 00427 /* returns pointer to static array, filled with desired amount of bone->segments elements */ 00428 /* this calculation is done within unit bone space */ 00429 Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) 00430 { 00431 static Mat4 bbone_array[MAX_BBONE_SUBDIV]; 00432 static Mat4 bbone_rest_array[MAX_BBONE_SUBDIV]; 00433 Mat4 *result_array= (rest)? bbone_rest_array: bbone_array; 00434 bPoseChannel *next, *prev; 00435 Bone *bone= pchan->bone; 00436 float h1[3], h2[3], scale[3], length, hlength1, hlength2, roll1=0.0f, roll2; 00437 float mat3[3][3], imat[4][4], posemat[4][4], scalemat[4][4], iscalemat[4][4]; 00438 float data[MAX_BBONE_SUBDIV+1][4], *fp; 00439 int a, doscale= 0; 00440 00441 length= bone->length; 00442 00443 if(!rest) { 00444 /* check if we need to take non-uniform bone scaling into account */ 00445 scale[0]= len_v3(pchan->pose_mat[0]); 00446 scale[1]= len_v3(pchan->pose_mat[1]); 00447 scale[2]= len_v3(pchan->pose_mat[2]); 00448 00449 if(fabsf(scale[0] - scale[1]) > 1e-6f || fabsf(scale[1] - scale[2]) > 1e-6f) { 00450 unit_m4(scalemat); 00451 scalemat[0][0]= scale[0]; 00452 scalemat[1][1]= scale[1]; 00453 scalemat[2][2]= scale[2]; 00454 invert_m4_m4(iscalemat, scalemat); 00455 00456 length *= scale[1]; 00457 doscale = 1; 00458 } 00459 } 00460 00461 hlength1= bone->ease1*length*0.390464f; // 0.5*sqrt(2)*kappa, the handle length for near-perfect circles 00462 hlength2= bone->ease2*length*0.390464f; 00463 00464 /* evaluate next and prev bones */ 00465 if(bone->flag & BONE_CONNECTED) 00466 prev= pchan->parent; 00467 else 00468 prev= NULL; 00469 00470 next= pchan->child; 00471 00472 /* find the handle points, since this is inside bone space, the 00473 first point = (0,0,0) 00474 last point = (0, length, 0) */ 00475 00476 if(rest) { 00477 invert_m4_m4(imat, pchan->bone->arm_mat); 00478 } 00479 else if(doscale) { 00480 copy_m4_m4(posemat, pchan->pose_mat); 00481 normalize_m4(posemat); 00482 invert_m4_m4(imat, posemat); 00483 } 00484 else 00485 invert_m4_m4(imat, pchan->pose_mat); 00486 00487 if(prev) { 00488 float difmat[4][4], result[3][3], imat3[3][3]; 00489 00490 /* transform previous point inside this bone space */ 00491 if(rest) 00492 VECCOPY(h1, prev->bone->arm_head) 00493 else 00494 VECCOPY(h1, prev->pose_head) 00495 mul_m4_v3(imat, h1); 00496 00497 if(prev->bone->segments>1) { 00498 /* if previous bone is B-bone too, use average handle direction */ 00499 h1[1]-= length; 00500 roll1= 0.0f; 00501 } 00502 00503 normalize_v3(h1); 00504 mul_v3_fl(h1, -hlength1); 00505 00506 if(prev->bone->segments==1) { 00507 /* find the previous roll to interpolate */ 00508 if(rest) 00509 mul_m4_m4m4(difmat, prev->bone->arm_mat, imat); 00510 else 00511 mul_m4_m4m4(difmat, prev->pose_mat, imat); 00512 copy_m3_m4(result, difmat); // the desired rotation at beginning of next bone 00513 00514 vec_roll_to_mat3(h1, 0.0f, mat3); // the result of vec_roll without roll 00515 00516 invert_m3_m3(imat3, mat3); 00517 mul_m3_m3m3(mat3, result, imat3); // the matrix transforming vec_roll to desired roll 00518 00519 roll1= (float)atan2(mat3[2][0], mat3[2][2]); 00520 } 00521 } 00522 else { 00523 h1[0]= 0.0f; h1[1]= hlength1; h1[2]= 0.0f; 00524 roll1= 0.0f; 00525 } 00526 if(next) { 00527 float difmat[4][4], result[3][3], imat3[3][3]; 00528 00529 /* transform next point inside this bone space */ 00530 if(rest) 00531 VECCOPY(h2, next->bone->arm_tail) 00532 else 00533 VECCOPY(h2, next->pose_tail) 00534 mul_m4_v3(imat, h2); 00535 /* if next bone is B-bone too, use average handle direction */ 00536 if(next->bone->segments>1); 00537 else h2[1]-= length; 00538 normalize_v3(h2); 00539 00540 /* find the next roll to interpolate as well */ 00541 if(rest) 00542 mul_m4_m4m4(difmat, next->bone->arm_mat, imat); 00543 else 00544 mul_m4_m4m4(difmat, next->pose_mat, imat); 00545 copy_m3_m4(result, difmat); // the desired rotation at beginning of next bone 00546 00547 vec_roll_to_mat3(h2, 0.0f, mat3); // the result of vec_roll without roll 00548 00549 invert_m3_m3(imat3, mat3); 00550 mul_m3_m3m3(mat3, imat3, result); // the matrix transforming vec_roll to desired roll 00551 00552 roll2= (float)atan2(mat3[2][0], mat3[2][2]); 00553 00554 /* and only now negate handle */ 00555 mul_v3_fl(h2, -hlength2); 00556 } 00557 else { 00558 h2[0]= 0.0f; h2[1]= -hlength2; h2[2]= 0.0f; 00559 roll2= 0.0; 00560 } 00561 00562 /* make curve */ 00563 if(bone->segments > MAX_BBONE_SUBDIV) 00564 bone->segments= MAX_BBONE_SUBDIV; 00565 00566 forward_diff_bezier(0.0, h1[0], h2[0], 0.0, data[0], MAX_BBONE_SUBDIV, 4*sizeof(float)); 00567 forward_diff_bezier(0.0, h1[1], length + h2[1], length, data[0]+1, MAX_BBONE_SUBDIV, 4*sizeof(float)); 00568 forward_diff_bezier(0.0, h1[2], h2[2], 0.0, data[0]+2, MAX_BBONE_SUBDIV, 4*sizeof(float)); 00569 forward_diff_bezier(roll1, roll1 + 0.390464f*(roll2-roll1), roll2 - 0.390464f*(roll2-roll1), roll2, data[0]+3, MAX_BBONE_SUBDIV, 4*sizeof(float)); 00570 00571 equalize_bezier(data[0], bone->segments); // note: does stride 4! 00572 00573 /* make transformation matrices for the segments for drawing */ 00574 for(a=0, fp= data[0]; a<bone->segments; a++, fp+=4) { 00575 sub_v3_v3v3(h1, fp+4, fp); 00576 vec_roll_to_mat3(h1, fp[3], mat3); // fp[3] is roll 00577 00578 copy_m4_m3(result_array[a].mat, mat3); 00579 VECCOPY(result_array[a].mat[3], fp); 00580 00581 if(doscale) { 00582 /* correct for scaling when this matrix is used in scaled space */ 00583 mul_serie_m4(result_array[a].mat, iscalemat, result_array[a].mat, 00584 scalemat, NULL, NULL, NULL, NULL, NULL); 00585 } 00586 } 00587 00588 return result_array; 00589 } 00590 00591 /* ************ Armature Deform ******************* */ 00592 00593 typedef struct bPoseChanDeform { 00594 Mat4 *b_bone_mats; 00595 DualQuat *dual_quat; 00596 DualQuat *b_bone_dual_quats; 00597 } bPoseChanDeform; 00598 00599 static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info, int use_quaternion) 00600 { 00601 Bone *bone= pchan->bone; 00602 Mat4 *b_bone= b_bone_spline_setup(pchan, 0); 00603 Mat4 *b_bone_rest= b_bone_spline_setup(pchan, 1); 00604 Mat4 *b_bone_mats; 00605 DualQuat *b_bone_dual_quats= NULL; 00606 float tmat[4][4]= MAT4_UNITY; 00607 int a; 00608 00609 /* allocate b_bone matrices and dual quats */ 00610 b_bone_mats= MEM_mallocN((1+bone->segments)*sizeof(Mat4), "BBone defmats"); 00611 pdef_info->b_bone_mats= b_bone_mats; 00612 00613 if(use_quaternion) { 00614 b_bone_dual_quats= MEM_mallocN((bone->segments)*sizeof(DualQuat), "BBone dqs"); 00615 pdef_info->b_bone_dual_quats= b_bone_dual_quats; 00616 } 00617 00618 /* first matrix is the inverse arm_mat, to bring points in local bone space 00619 for finding out which segment it belongs to */ 00620 invert_m4_m4(b_bone_mats[0].mat, bone->arm_mat); 00621 00622 /* then we make the b_bone_mats: 00623 - first transform to local bone space 00624 - translate over the curve to the bbone mat space 00625 - transform with b_bone matrix 00626 - transform back into global space */ 00627 00628 for(a=0; a<bone->segments; a++) { 00629 invert_m4_m4(tmat, b_bone_rest[a].mat); 00630 00631 mul_serie_m4(b_bone_mats[a+1].mat, pchan->chan_mat, bone->arm_mat, 00632 b_bone[a].mat, tmat, b_bone_mats[0].mat, NULL, NULL, NULL); 00633 00634 if(use_quaternion) 00635 mat4_to_dquat( &b_bone_dual_quats[a],bone->arm_mat, b_bone_mats[a+1].mat); 00636 } 00637 } 00638 00639 static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float *co, DualQuat *dq, float defmat[][3]) 00640 { 00641 Mat4 *b_bone= pdef_info->b_bone_mats; 00642 float (*mat)[4]= b_bone[0].mat; 00643 float segment, y; 00644 int a; 00645 00646 /* need to transform co back to bonespace, only need y */ 00647 y= mat[0][1]*co[0] + mat[1][1]*co[1] + mat[2][1]*co[2] + mat[3][1]; 00648 00649 /* now calculate which of the b_bones are deforming this */ 00650 segment= bone->length/((float)bone->segments); 00651 a= (int)(y/segment); 00652 00653 /* note; by clamping it extends deform at endpoints, goes best with 00654 straight joints in restpos. */ 00655 CLAMP(a, 0, bone->segments-1); 00656 00657 if(dq) { 00658 copy_dq_dq(dq, &(pdef_info->b_bone_dual_quats)[a]); 00659 } 00660 else { 00661 mul_m4_v3(b_bone[a+1].mat, co); 00662 00663 if(defmat) 00664 copy_m3_m4(defmat, b_bone[a+1].mat); 00665 } 00666 } 00667 00668 /* using vec with dist to bone b1 - b2 */ 00669 float distfactor_to_bone (float vec[3], float b1[3], float b2[3], float rad1, float rad2, float rdist) 00670 { 00671 float dist=0.0f; 00672 float bdelta[3]; 00673 float pdelta[3]; 00674 float hsqr, a, l, rad; 00675 00676 sub_v3_v3v3(bdelta, b2, b1); 00677 l = normalize_v3(bdelta); 00678 00679 sub_v3_v3v3(pdelta, vec, b1); 00680 00681 a = bdelta[0]*pdelta[0] + bdelta[1]*pdelta[1] + bdelta[2]*pdelta[2]; 00682 hsqr = ((pdelta[0]*pdelta[0]) + (pdelta[1]*pdelta[1]) + (pdelta[2]*pdelta[2])); 00683 00684 if (a < 0.0F){ 00685 /* If we're past the end of the bone, do a spherical field attenuation thing */ 00686 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])) ; 00687 rad= rad1; 00688 } 00689 else if (a > l){ 00690 /* If we're past the end of the bone, do a spherical field attenuation thing */ 00691 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])) ; 00692 rad= rad2; 00693 } 00694 else { 00695 dist= (hsqr - (a*a)); 00696 00697 if(l!=0.0f) { 00698 rad= a/l; 00699 rad= rad*rad2 + (1.0f-rad)*rad1; 00700 } 00701 else rad= rad1; 00702 } 00703 00704 a= rad*rad; 00705 if(dist < a) 00706 return 1.0f; 00707 else { 00708 l= rad+rdist; 00709 l*= l; 00710 if(rdist==0.0f || dist >= l) 00711 return 0.0f; 00712 else { 00713 a= (float)sqrt(dist)-rad; 00714 return 1.0f-( a*a )/( rdist*rdist ); 00715 } 00716 } 00717 } 00718 00719 static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonemat[][3], float mat[][3]) 00720 { 00721 float wmat[3][3]; 00722 00723 if(pchan->bone->segments>1) 00724 copy_m3_m3(wmat, bbonemat); 00725 else 00726 copy_m3_m4(wmat, pchan->chan_mat); 00727 00728 mul_m3_fl(wmat, weight); 00729 add_m3_m3m3(mat, mat, wmat); 00730 } 00731 00732 static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float *vec, DualQuat *dq, float mat[][3], float *co) 00733 { 00734 Bone *bone= pchan->bone; 00735 float fac, contrib=0.0; 00736 float cop[3], bbonemat[3][3]; 00737 DualQuat bbonedq; 00738 00739 if(bone==NULL) return 0.0f; 00740 00741 VECCOPY (cop, co); 00742 00743 fac= distfactor_to_bone(cop, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist); 00744 00745 if (fac > 0.0f) { 00746 00747 fac*=bone->weight; 00748 contrib= fac; 00749 if(contrib > 0.0f) { 00750 if(vec) { 00751 if(bone->segments>1) 00752 // applies on cop and bbonemat 00753 b_bone_deform(pdef_info, bone, cop, NULL, (mat)?bbonemat:NULL); 00754 else 00755 mul_m4_v3(pchan->chan_mat, cop); 00756 00757 // Make this a delta from the base position 00758 sub_v3_v3(cop, co); 00759 madd_v3_v3fl(vec, cop, fac); 00760 00761 if(mat) 00762 pchan_deform_mat_add(pchan, fac, bbonemat, mat); 00763 } 00764 else { 00765 if(bone->segments>1) { 00766 b_bone_deform(pdef_info, bone, cop, &bbonedq, NULL); 00767 add_weighted_dq_dq(dq, &bbonedq, fac); 00768 } 00769 else 00770 add_weighted_dq_dq(dq, pdef_info->dual_quat, fac); 00771 } 00772 } 00773 } 00774 00775 return contrib; 00776 } 00777 00778 static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib) 00779 { 00780 float cop[3], bbonemat[3][3]; 00781 DualQuat bbonedq; 00782 00783 if (!weight) 00784 return; 00785 00786 VECCOPY(cop, co); 00787 00788 if(vec) { 00789 if(pchan->bone->segments>1) 00790 // applies on cop and bbonemat 00791 b_bone_deform(pdef_info, pchan->bone, cop, NULL, (mat)?bbonemat:NULL); 00792 else 00793 mul_m4_v3(pchan->chan_mat, cop); 00794 00795 vec[0]+=(cop[0]-co[0])*weight; 00796 vec[1]+=(cop[1]-co[1])*weight; 00797 vec[2]+=(cop[2]-co[2])*weight; 00798 00799 if(mat) 00800 pchan_deform_mat_add(pchan, weight, bbonemat, mat); 00801 } 00802 else { 00803 if(pchan->bone->segments>1) { 00804 b_bone_deform(pdef_info, pchan->bone, cop, &bbonedq, NULL); 00805 add_weighted_dq_dq(dq, &bbonedq, weight); 00806 } 00807 else 00808 add_weighted_dq_dq(dq, pdef_info->dual_quat, weight); 00809 } 00810 00811 (*contrib)+=weight; 00812 } 00813 00814 void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, 00815 float (*vertexCos)[3], float (*defMats)[3][3], 00816 int numVerts, int deformflag, 00817 float (*prevCos)[3], const char *defgrp_name) 00818 { 00819 bPoseChanDeform *pdef_info_array; 00820 bPoseChanDeform *pdef_info= NULL; 00821 bArmature *arm= armOb->data; 00822 bPoseChannel *pchan, **defnrToPC = NULL; 00823 int *defnrToPCIndex= NULL; 00824 MDeformVert *dverts = NULL; 00825 bDeformGroup *dg; 00826 DualQuat *dualquats= NULL; 00827 float obinv[4][4], premat[4][4], postmat[4][4]; 00828 const short use_envelope = deformflag & ARM_DEF_ENVELOPE; 00829 const short use_quaternion = deformflag & ARM_DEF_QUATERNION; 00830 const short invert_vgroup= deformflag & ARM_DEF_INVERT_VGROUP; 00831 int numGroups = 0; /* safety for vertexgroup index overflow */ 00832 int i, target_totvert = 0; /* safety for vertexgroup overflow */ 00833 int use_dverts = 0; 00834 int armature_def_nr; 00835 int totchan; 00836 00837 if(arm->edbo) return; 00838 00839 invert_m4_m4(obinv, target->obmat); 00840 copy_m4_m4(premat, target->obmat); 00841 mul_m4_m4m4(postmat, armOb->obmat, obinv); 00842 invert_m4_m4(premat, postmat); 00843 00844 /* bone defmats are already in the channels, chan_mat */ 00845 00846 /* initialize B_bone matrices and dual quaternions */ 00847 totchan= BLI_countlist(&armOb->pose->chanbase); 00848 00849 if(use_quaternion) { 00850 dualquats= MEM_callocN(sizeof(DualQuat)*totchan, "dualquats"); 00851 } 00852 00853 pdef_info_array= MEM_callocN(sizeof(bPoseChanDeform)*totchan, "bPoseChanDeform"); 00854 00855 totchan= 0; 00856 pdef_info= pdef_info_array; 00857 for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next, pdef_info++) { 00858 if(!(pchan->bone->flag & BONE_NO_DEFORM)) { 00859 if(pchan->bone->segments > 1) 00860 pchan_b_bone_defmats(pchan, pdef_info, use_quaternion); 00861 00862 if(use_quaternion) { 00863 pdef_info->dual_quat= &dualquats[totchan++]; 00864 mat4_to_dquat( pdef_info->dual_quat,pchan->bone->arm_mat, pchan->chan_mat); 00865 } 00866 } 00867 } 00868 00869 /* get the def_nr for the overall armature vertex group if present */ 00870 armature_def_nr= defgroup_name_index(target, defgrp_name); 00871 00872 if(ELEM(target->type, OB_MESH, OB_LATTICE)) { 00873 numGroups = BLI_countlist(&target->defbase); 00874 00875 if(target->type==OB_MESH) { 00876 Mesh *me= target->data; 00877 dverts = me->dvert; 00878 if(dverts) 00879 target_totvert = me->totvert; 00880 } 00881 else { 00882 Lattice *lt= target->data; 00883 dverts = lt->dvert; 00884 if(dverts) 00885 target_totvert = lt->pntsu*lt->pntsv*lt->pntsw; 00886 } 00887 } 00888 00889 /* get a vertex-deform-index to posechannel array */ 00890 if(deformflag & ARM_DEF_VGROUP) { 00891 if(ELEM(target->type, OB_MESH, OB_LATTICE)) { 00892 /* if we have a DerivedMesh, only use dverts if it has them */ 00893 if(dm) 00894 if(dm->getVertData(dm, 0, CD_MDEFORMVERT)) 00895 use_dverts = 1; 00896 else use_dverts = 0; 00897 else if(dverts) use_dverts = 1; 00898 00899 if(use_dverts) { 00900 defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups, "defnrToBone"); 00901 defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * numGroups, "defnrToIndex"); 00902 for(i = 0, dg = target->defbase.first; dg; 00903 i++, dg = dg->next) { 00904 defnrToPC[i] = get_pose_channel(armOb->pose, dg->name); 00905 /* exclude non-deforming bones */ 00906 if(defnrToPC[i]) { 00907 if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM) { 00908 defnrToPC[i]= NULL; 00909 } 00910 else { 00911 defnrToPCIndex[i]= BLI_findindex(&armOb->pose->chanbase, defnrToPC[i]); 00912 } 00913 } 00914 } 00915 } 00916 } 00917 } 00918 00919 for(i = 0; i < numVerts; i++) { 00920 MDeformVert *dvert; 00921 DualQuat sumdq, *dq = NULL; 00922 float *co, dco[3]; 00923 float sumvec[3], summat[3][3]; 00924 float *vec = NULL, (*smat)[3] = NULL; 00925 float contrib = 0.0f; 00926 float armature_weight = 1.0f; /* default to 1 if no overall def group */ 00927 float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ 00928 int j; 00929 00930 if(use_quaternion) { 00931 memset(&sumdq, 0, sizeof(DualQuat)); 00932 dq= &sumdq; 00933 } 00934 else { 00935 sumvec[0] = sumvec[1] = sumvec[2] = 0.0f; 00936 vec= sumvec; 00937 00938 if(defMats) { 00939 zero_m3(summat); 00940 smat = summat; 00941 } 00942 } 00943 00944 if(use_dverts || armature_def_nr >= 0) { 00945 if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT); 00946 else if(dverts && i < target_totvert) dvert = dverts + i; 00947 else dvert = NULL; 00948 } else 00949 dvert = NULL; 00950 00951 if(armature_def_nr >= 0 && dvert) { 00952 armature_weight= defvert_find_weight(dvert, armature_def_nr); 00953 00954 if(invert_vgroup) { 00955 armature_weight= 1.0f-armature_weight; 00956 } 00957 00958 /* hackish: the blending factor can be used for blending with prevCos too */ 00959 if(prevCos) { 00960 prevco_weight= armature_weight; 00961 armature_weight= 1.0f; 00962 } 00963 } 00964 00965 /* check if there's any point in calculating for this vert */ 00966 if(armature_weight == 0.0f) continue; 00967 00968 /* get the coord we work on */ 00969 co= prevCos?prevCos[i]:vertexCos[i]; 00970 00971 /* Apply the object's matrix */ 00972 mul_m4_v3(premat, co); 00973 00974 if(use_dverts && dvert && dvert->totweight) { // use weight groups ? 00975 int deformed = 0; 00976 00977 for(j = 0; j < dvert->totweight; j++){ 00978 int index = dvert->dw[j].def_nr; 00979 if(index < numGroups && (pchan= defnrToPC[index])) { 00980 float weight = dvert->dw[j].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 VECCOPY(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 mul_m4_m4m4(outmat, obmat, inmat); 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 VECCOPY(xLocMat[3], inloc); 01120 01121 /* get bone-space cursor matrix and extract location */ 01122 armature_mat_world_to_pose(ob, xLocMat, nLocMat); 01123 VECCOPY(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 mul_m4_m4m4(pc_posemat, inv_trans, pose_mat); 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 mul_m4_m4m4(outmat, inmat, inv_posemat); 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 VECCOPY(xLocMat[3], inloc); 01199 01200 /* get bone-space cursor matrix and extract location */ 01201 armature_mat_pose_to_bone(pchan, xLocMat, nLocMat); 01202 VECCOPY(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 mul_m4_m4m4(delta_mat, pose_mat, imat); 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 VECCOPY(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 mul_m4_m4m4(bone->arm_mat, offs_bone, prevbone->arm_mat); 01414 } 01415 else { 01416 copy_m4_m3(bone->arm_mat, bone->bone_mat); 01417 VECCOPY(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 pchanw.path= NULL; 01489 01490 /* this is freed so copy a copy, else undo crashes */ 01491 if(pchanw.prop) { 01492 pchanw.prop= IDP_CopyProperty(pchanw.prop); 01493 01494 /* use the values from the the existing props */ 01495 if(pchan->prop) { 01496 IDP_SyncGroupValues(pchanw.prop, pchan->prop); 01497 } 01498 } 01499 01500 /* constraints - proxy constraints are flushed... local ones are added after 01501 * 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints 01502 * 2. copy proxy-pchan's constraints on-to new 01503 * 3. add extracted local constraints back on top 01504 * 01505 * note for copy_constraints: when copying constraints, disable 'do_extern' otherwise we get the libs direct linked in this blend. 01506 */ 01507 extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints); 01508 copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE); 01509 BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints); 01510 01511 /* constraints - set target ob pointer to own object */ 01512 for (con= pchanw.constraints.first; con; con= con->next) { 01513 bConstraintTypeInfo *cti= constraint_get_typeinfo(con); 01514 ListBase targets = {NULL, NULL}; 01515 bConstraintTarget *ct; 01516 01517 if (cti && cti->get_constraint_targets) { 01518 cti->get_constraint_targets(con, &targets); 01519 01520 for (ct= targets.first; ct; ct= ct->next) { 01521 if (ct->tar == from) 01522 ct->tar = ob; 01523 } 01524 01525 if (cti->flush_constraint_targets) 01526 cti->flush_constraint_targets(con, &targets, 0); 01527 } 01528 } 01529 01530 /* free stuff from current channel */ 01531 free_pose_channel(pchan); 01532 01533 /* the final copy */ 01534 *pchan= pchanw; 01535 } 01536 else { 01537 /* always copy custom shape */ 01538 pchan->custom= pchanp->custom; 01539 pchan->custom_tx= pchanp->custom_tx; 01540 01541 /* ID-Property Syncing */ 01542 { 01543 IDProperty *prop_orig= pchan->prop; 01544 if(pchanp->prop) { 01545 pchan->prop= IDP_CopyProperty(pchanp->prop); 01546 if(prop_orig) { 01547 /* copy existing values across when types match */ 01548 IDP_SyncGroupValues(pchan->prop, prop_orig); 01549 } 01550 } 01551 else { 01552 pchan->prop= NULL; 01553 } 01554 if (prop_orig) { 01555 IDP_FreeProperty(prop_orig); 01556 MEM_freeN(prop_orig); 01557 } 01558 } 01559 } 01560 } 01561 } 01562 01563 static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int counter) 01564 { 01565 bPoseChannel *pchan = verify_pose_channel (pose, bone->name); // verify checks and/or adds 01566 01567 pchan->bone= bone; 01568 pchan->parent= parchan; 01569 01570 counter++; 01571 01572 for(bone= bone->childbase.first; bone; bone= bone->next) { 01573 counter= rebuild_pose_bone(pose, bone, pchan, counter); 01574 /* for quick detecting of next bone in chain, only b-bone uses it now */ 01575 if(bone->flag & BONE_CONNECTED) 01576 pchan->child= get_pose_channel(pose, bone->name); 01577 } 01578 01579 return counter; 01580 } 01581 01582 /* only after leave editmode, duplicating, validating older files, library syncing */ 01583 /* NOTE: pose->flag is set for it */ 01584 void armature_rebuild_pose(Object *ob, bArmature *arm) 01585 { 01586 Bone *bone; 01587 bPose *pose; 01588 bPoseChannel *pchan, *next; 01589 int counter=0; 01590 01591 /* only done here */ 01592 if(ob->pose==NULL) { 01593 /* create new pose */ 01594 ob->pose= MEM_callocN(sizeof(bPose), "new pose"); 01595 01596 /* set default settings for animviz */ 01597 animviz_settings_init(&ob->pose->avs); 01598 } 01599 pose= ob->pose; 01600 01601 /* clear */ 01602 for(pchan= pose->chanbase.first; pchan; pchan= pchan->next) { 01603 pchan->bone= NULL; 01604 pchan->child= NULL; 01605 } 01606 01607 /* first step, check if all channels are there */ 01608 for(bone= arm->bonebase.first; bone; bone= bone->next) { 01609 counter= rebuild_pose_bone(pose, bone, NULL, counter); 01610 } 01611 01612 /* and a check for garbage */ 01613 for(pchan= pose->chanbase.first; pchan; pchan= next) { 01614 next= pchan->next; 01615 if(pchan->bone==NULL) { 01616 free_pose_channel(pchan); 01617 free_pose_channels_hash(pose); 01618 BLI_freelinkN(&pose->chanbase, pchan); 01619 } 01620 } 01621 // printf("rebuild pose %s, %d bones\n", ob->id.name, counter); 01622 01623 /* synchronize protected layers with proxy */ 01624 if(ob->proxy) { 01625 object_copy_proxy_drivers(ob, ob->proxy); 01626 pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected); 01627 } 01628 01629 update_pose_constraint_flags(ob->pose); // for IK detection for example 01630 01631 /* the sorting */ 01632 if(counter>1) 01633 DAG_pose_sort(ob); 01634 01635 ob->pose->flag &= ~POSE_RECALC; 01636 ob->pose->flag |= POSE_WAS_REBUILT; 01637 01638 make_pose_channels_hash(ob->pose); 01639 } 01640 01641 01642 /* ********************** SPLINE IK SOLVER ******************* */ 01643 01644 /* Temporary evaluation tree data used for Spline IK */ 01645 typedef struct tSplineIK_Tree { 01646 struct tSplineIK_Tree *next, *prev; 01647 01648 int type; /* type of IK that this serves (CONSTRAINT_TYPE_KINEMATIC or ..._SPLINEIK) */ 01649 01650 short free_points; /* free the point positions array */ 01651 short chainlen; /* number of bones in the chain */ 01652 01653 float *points; /* parametric positions for the joints along the curve */ 01654 bPoseChannel **chain; /* chain of bones to affect using Spline IK (ordered from the tip) */ 01655 01656 bPoseChannel *root; /* bone that is the root node of the chain */ 01657 01658 bConstraint *con; /* constraint for this chain */ 01659 bSplineIKConstraint *ikData; /* constraint settings for this chain */ 01660 } tSplineIK_Tree; 01661 01662 /* ----------- */ 01663 01664 /* Tag the bones in the chain formed by the given bone for IK */ 01665 static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPoseChannel *pchan_tip) 01666 { 01667 bPoseChannel *pchan, *pchanRoot=NULL; 01668 bPoseChannel *pchanChain[255]; 01669 bConstraint *con = NULL; 01670 bSplineIKConstraint *ikData = NULL; 01671 float boneLengths[255], *jointPoints; 01672 float totLength = 0.0f; 01673 short free_joints = 0; 01674 int segcount = 0; 01675 01676 /* find the SplineIK constraint */ 01677 for (con= pchan_tip->constraints.first; con; con= con->next) { 01678 if (con->type == CONSTRAINT_TYPE_SPLINEIK) { 01679 ikData= con->data; 01680 01681 /* target can only be curve */ 01682 if ((ikData->tar == NULL) || (ikData->tar->type != OB_CURVE)) 01683 continue; 01684 /* skip if disabled */ 01685 if ( (con->enforce == 0.0f) || (con->flag & (CONSTRAINT_DISABLE|CONSTRAINT_OFF)) ) 01686 continue; 01687 01688 /* otherwise, constraint is ok... */ 01689 break; 01690 } 01691 } 01692 if (con == NULL) 01693 return; 01694 01695 /* make sure that the constraint targets are ok 01696 * - this is a workaround for a depsgraph bug... 01697 */ 01698 if (ikData->tar) { 01699 Curve *cu= ikData->tar->data; 01700 01701 /* note: when creating constraints that follow path, the curve gets the CU_PATH set now, 01702 * currently for paths to work it needs to go through the bevlist/displist system (ton) 01703 */ 01704 01705 /* only happens on reload file, but violates depsgraph still... fix! */ 01706 if ((cu->path==NULL) || (cu->path->data==NULL)) 01707 makeDispListCurveTypes(scene, ikData->tar, 0); 01708 } 01709 01710 /* find the root bone and the chain of bones from the root to the tip 01711 * NOTE: this assumes that the bones are connected, but that may not be true... 01712 */ 01713 for (pchan= pchan_tip; pchan && (segcount < ikData->chainlen); pchan= pchan->parent, segcount++) { 01714 /* store this segment in the chain */ 01715 pchanChain[segcount]= pchan; 01716 01717 /* if performing rebinding, calculate the length of the bone */ 01718 boneLengths[segcount]= pchan->bone->length; 01719 totLength += boneLengths[segcount]; 01720 } 01721 01722 if (segcount == 0) 01723 return; 01724 else 01725 pchanRoot= pchanChain[segcount-1]; 01726 01727 /* perform binding step if required */ 01728 if ((ikData->flag & CONSTRAINT_SPLINEIK_BOUND) == 0) { 01729 float segmentLen= (1.0f / (float)segcount); 01730 int i; 01731 01732 /* setup new empty array for the points list */ 01733 if (ikData->points) 01734 MEM_freeN(ikData->points); 01735 ikData->numpoints= ikData->chainlen+1; 01736 ikData->points= MEM_callocN(sizeof(float)*ikData->numpoints, "Spline IK Binding"); 01737 01738 /* bind 'tip' of chain (i.e. first joint = tip of bone with the Spline IK Constraint) */ 01739 ikData->points[0] = 1.0f; 01740 01741 /* perform binding of the joints to parametric positions along the curve based 01742 * proportion of the total length that each bone occupies 01743 */ 01744 for (i = 0; i < segcount; i++) { 01745 /* 'head' joints, travelling towards the root of the chain 01746 * - 2 methods; the one chosen depends on whether we've got usable lengths 01747 */ 01748 if ((ikData->flag & CONSTRAINT_SPLINEIK_EVENSPLITS) || (totLength == 0.0f)) { 01749 /* 1) equi-spaced joints */ 01750 ikData->points[i+1]= ikData->points[i] - segmentLen; 01751 } 01752 else { 01753 /* 2) to find this point on the curve, we take a step from the previous joint 01754 * a distance given by the proportion that this bone takes 01755 */ 01756 ikData->points[i+1]= ikData->points[i] - (boneLengths[i] / totLength); 01757 } 01758 } 01759 01760 /* spline has now been bound */ 01761 ikData->flag |= CONSTRAINT_SPLINEIK_BOUND; 01762 } 01763 01764 /* apply corrections for sensitivity to scaling on a copy of the bind points, 01765 * since it's easier to determine the positions of all the joints beforehand this way 01766 */ 01767 if ((ikData->flag & CONSTRAINT_SPLINEIK_SCALE_LIMITED) && (totLength != 0.0f)) { 01768 Curve *cu= (Curve *)ikData->tar->data; 01769 float splineLen, maxScale; 01770 int i; 01771 01772 /* make a copy of the points array, that we'll store in the tree 01773 * - although we could just multiply the points on the fly, this approach means that 01774 * we can introduce per-segment stretchiness later if it is necessary 01775 */ 01776 jointPoints= MEM_dupallocN(ikData->points); 01777 free_joints= 1; 01778 01779 /* get the current length of the curve */ 01780 // NOTE: this is assumed to be correct even after the curve was resized 01781 splineLen= cu->path->totdist; 01782 01783 /* calculate the scale factor to multiply all the path values by so that the 01784 * bone chain retains its current length, such that 01785 * maxScale * splineLen = totLength 01786 */ 01787 maxScale = totLength / splineLen; 01788 01789 /* apply scaling correction to all of the temporary points */ 01790 // TODO: this is really not adequate enough on really short chains 01791 for (i = 0; i < segcount; i++) 01792 jointPoints[i] *= maxScale; 01793 } 01794 else { 01795 /* just use the existing points array */ 01796 jointPoints= ikData->points; 01797 free_joints= 0; 01798 } 01799 01800 /* make a new Spline-IK chain, and store it in the IK chains */ 01801 // TODO: we should check if there is already an IK chain on this, since that would take presidence... 01802 { 01803 /* make new tree */ 01804 tSplineIK_Tree *tree= MEM_callocN(sizeof(tSplineIK_Tree), "SplineIK Tree"); 01805 tree->type= CONSTRAINT_TYPE_SPLINEIK; 01806 01807 tree->chainlen= segcount; 01808 01809 /* copy over the array of links to bones in the chain (from tip to root) */ 01810 tree->chain= MEM_callocN(sizeof(bPoseChannel*)*segcount, "SplineIK Chain"); 01811 memcpy(tree->chain, pchanChain, sizeof(bPoseChannel*)*segcount); 01812 01813 /* store reference to joint position array */ 01814 tree->points= jointPoints; 01815 tree->free_points= free_joints; 01816 01817 /* store references to different parts of the chain */ 01818 tree->root= pchanRoot; 01819 tree->con= con; 01820 tree->ikData= ikData; 01821 01822 /* AND! link the tree to the root */ 01823 BLI_addtail(&pchanRoot->iktree, tree); 01824 } 01825 01826 /* mark root channel having an IK tree */ 01827 pchanRoot->flag |= POSE_IKSPLINE; 01828 } 01829 01830 /* Tag which bones are members of Spline IK chains */ 01831 static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime)) 01832 { 01833 bPoseChannel *pchan; 01834 01835 /* find the tips of Spline IK chains, which are simply the bones which have been tagged as such */ 01836 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 01837 if (pchan->constflag & PCHAN_HAS_SPLINEIK) 01838 splineik_init_tree_from_pchan(scene, ob, pchan); 01839 } 01840 } 01841 01842 /* ----------- */ 01843 01844 /* Evaluate spline IK for a given bone */ 01845 static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan, int index, float ctime) 01846 { 01847 bSplineIKConstraint *ikData= tree->ikData; 01848 float poseHead[3], poseTail[3], poseMat[4][4]; 01849 float splineVec[3], scaleFac, radius=1.0f; 01850 01851 /* firstly, calculate the bone matrix the standard way, since this is needed for roll control */ 01852 where_is_pose_bone(scene, ob, pchan, ctime, 1); 01853 01854 VECCOPY(poseHead, pchan->pose_head); 01855 VECCOPY(poseTail, pchan->pose_tail); 01856 01857 /* step 1: determine the positions for the endpoints of the bone */ 01858 { 01859 float vec[4], dir[3], rad; 01860 float tailBlendFac= 1.0f; 01861 01862 /* determine if the bone should still be affected by SplineIK */ 01863 if (tree->points[index+1] >= 1.0f) { 01864 /* spline doesn't affect the bone anymore, so done... */ 01865 pchan->flag |= POSE_DONE; 01866 return; 01867 } 01868 else if ((tree->points[index] >= 1.0f) && (tree->points[index+1] < 1.0f)) { 01869 /* blending factor depends on the amount of the bone still left on the chain */ 01870 tailBlendFac= (1.0f - tree->points[index+1]) / (tree->points[index] - tree->points[index+1]); 01871 } 01872 01873 /* tail endpoint */ 01874 if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad, NULL) ) { 01875 /* apply curve's object-mode transforms to the position 01876 * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root) 01877 */ 01878 if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0) 01879 mul_m4_v3(ikData->tar->obmat, vec); 01880 01881 /* convert the position to pose-space, then store it */ 01882 mul_m4_v3(ob->imat, vec); 01883 interp_v3_v3v3(poseTail, pchan->pose_tail, vec, tailBlendFac); 01884 01885 /* set the new radius */ 01886 radius= rad; 01887 } 01888 01889 /* head endpoint */ 01890 if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad, NULL) ) { 01891 /* apply curve's object-mode transforms to the position 01892 * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root) 01893 */ 01894 if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0) 01895 mul_m4_v3(ikData->tar->obmat, vec); 01896 01897 /* store the position, and convert it to pose space */ 01898 mul_m4_v3(ob->imat, vec); 01899 VECCOPY(poseHead, vec); 01900 01901 /* set the new radius (it should be the average value) */ 01902 radius = (radius+rad) / 2; 01903 } 01904 } 01905 01906 /* step 2: determine the implied transform from these endpoints 01907 * - splineVec: the vector direction that the spline applies on the bone 01908 * - scaleFac: the factor that the bone length is scaled by to get the desired amount 01909 */ 01910 sub_v3_v3v3(splineVec, poseTail, poseHead); 01911 scaleFac= len_v3(splineVec) / pchan->bone->length; 01912 01913 /* step 3: compute the shortest rotation needed to map from the bone rotation to the current axis 01914 * - this uses the same method as is used for the Damped Track Constraint (see the code there for details) 01915 */ 01916 { 01917 float dmat[3][3], rmat[3][3], tmat[3][3]; 01918 float raxis[3], rangle; 01919 01920 /* compute the raw rotation matrix from the bone's current matrix by extracting only the 01921 * orientation-relevant axes, and normalising them 01922 */ 01923 VECCOPY(rmat[0], pchan->pose_mat[0]); 01924 VECCOPY(rmat[1], pchan->pose_mat[1]); 01925 VECCOPY(rmat[2], pchan->pose_mat[2]); 01926 normalize_m3(rmat); 01927 01928 /* also, normalise the orientation imposed by the bone, now that we've extracted the scale factor */ 01929 normalize_v3(splineVec); 01930 01931 /* calculate smallest axis-angle rotation necessary for getting from the 01932 * current orientation of the bone, to the spline-imposed direction 01933 */ 01934 cross_v3_v3v3(raxis, rmat[1], splineVec); 01935 01936 rangle= dot_v3v3(rmat[1], splineVec); 01937 rangle= acos( MAX2(-1.0f, MIN2(1.0f, rangle)) ); 01938 01939 /* multiply the magnitude of the angle by the influence of the constraint to 01940 * control the influence of the SplineIK effect 01941 */ 01942 rangle *= tree->con->enforce; 01943 01944 /* construct rotation matrix from the axis-angle rotation found above 01945 * - this call takes care to make sure that the axis provided is a unit vector first 01946 */ 01947 axis_angle_to_mat3(dmat, raxis, rangle); 01948 01949 /* combine these rotations so that the y-axis of the bone is now aligned as the spline dictates, 01950 * while still maintaining roll control from the existing bone animation 01951 */ 01952 mul_m3_m3m3(tmat, dmat, rmat); // m1, m3, m2 01953 normalize_m3(tmat); /* attempt to reduce shearing, though I doubt this'll really help too much now... */ 01954 copy_m4_m3(poseMat, tmat); 01955 } 01956 01957 /* step 4: set the scaling factors for the axes */ 01958 { 01959 /* only multiply the y-axis by the scaling factor to get nice volume-preservation */ 01960 mul_v3_fl(poseMat[1], scaleFac); 01961 01962 /* set the scaling factors of the x and z axes from... */ 01963 switch (ikData->xzScaleMode) { 01964 case CONSTRAINT_SPLINEIK_XZS_ORIGINAL: 01965 { 01966 /* original scales get used */ 01967 float scale; 01968 01969 /* x-axis scale */ 01970 scale= len_v3(pchan->pose_mat[0]); 01971 mul_v3_fl(poseMat[0], scale); 01972 /* z-axis scale */ 01973 scale= len_v3(pchan->pose_mat[2]); 01974 mul_v3_fl(poseMat[2], scale); 01975 } 01976 break; 01977 case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC: 01978 { 01979 /* 'volume preservation' */ 01980 float scale; 01981 01982 /* calculate volume preservation factor which is 01983 * basically the inverse of the y-scaling factor 01984 */ 01985 if (fabsf(scaleFac) != 0.0f) { 01986 scale= 1.0f / fabsf(scaleFac); 01987 01988 /* we need to clamp this within sensible values */ 01989 // NOTE: these should be fine for now, but should get sanitised in future 01990 CLAMP(scale, 0.0001f, 100000.0f); 01991 } 01992 else 01993 scale= 1.0f; 01994 01995 /* apply the scaling */ 01996 mul_v3_fl(poseMat[0], scale); 01997 mul_v3_fl(poseMat[2], scale); 01998 } 01999 break; 02000 } 02001 02002 /* finally, multiply the x and z scaling by the radius of the curve too, 02003 * to allow automatic scales to get tweaked still 02004 */ 02005 if ((ikData->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) { 02006 mul_v3_fl(poseMat[0], radius); 02007 mul_v3_fl(poseMat[2], radius); 02008 } 02009 } 02010 02011 /* step 5: set the location of the bone in the matrix */ 02012 if (ikData->flag & CONSTRAINT_SPLINEIK_NO_ROOT) { 02013 /* when the 'no-root' option is affected, the chain can retain 02014 * the shape but be moved elsewhere 02015 */ 02016 VECCOPY(poseHead, pchan->pose_head); 02017 } 02018 else if (tree->con->enforce < 1.0f) { 02019 /* when the influence is too low 02020 * - blend the positions for the 'root' bone 02021 * - stick to the parent for any other 02022 */ 02023 if (pchan->parent) { 02024 VECCOPY(poseHead, pchan->pose_head); 02025 } 02026 else { 02027 // FIXME: this introduces popping artifacts when we reach 0.0 02028 interp_v3_v3v3(poseHead, pchan->pose_head, poseHead, tree->con->enforce); 02029 } 02030 } 02031 VECCOPY(poseMat[3], poseHead); 02032 02033 /* finally, store the new transform */ 02034 copy_m4_m4(pchan->pose_mat, poseMat); 02035 VECCOPY(pchan->pose_head, poseHead); 02036 02037 /* recalculate tail, as it's now outdated after the head gets adjusted above! */ 02038 where_is_pose_bone_tail(pchan); 02039 02040 /* done! */ 02041 pchan->flag |= POSE_DONE; 02042 } 02043 02044 /* Evaluate the chain starting from the nominated bone */ 02045 static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime) 02046 { 02047 tSplineIK_Tree *tree; 02048 02049 /* for each pose-tree, execute it if it is spline, otherwise just free it */ 02050 for (tree= pchan_root->iktree.first; tree; tree= pchan_root->iktree.first) { 02051 /* only evaluate if tagged for Spline IK */ 02052 if (tree->type == CONSTRAINT_TYPE_SPLINEIK) { 02053 int i; 02054 02055 /* walk over each bone in the chain, calculating the effects of spline IK 02056 * - the chain is traversed in the opposite order to storage order (i.e. parent to children) 02057 * so that dependencies are correct 02058 */ 02059 for (i= tree->chainlen-1; i >= 0; i--) { 02060 bPoseChannel *pchan= tree->chain[i]; 02061 splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime); 02062 } 02063 02064 /* free the tree info specific to SplineIK trees now */ 02065 if (tree->chain) MEM_freeN(tree->chain); 02066 if (tree->free_points) MEM_freeN(tree->points); 02067 } 02068 02069 /* free this tree */ 02070 BLI_freelinkN(&pchan_root->iktree, tree); 02071 } 02072 } 02073 02074 /* ********************** THE POSE SOLVER ******************* */ 02075 02076 /* loc/rot/size to given mat4 */ 02077 void pchan_to_mat4(bPoseChannel *pchan, float chan_mat[4][4]) 02078 { 02079 float smat[3][3]; 02080 float rmat[3][3]; 02081 float tmat[3][3]; 02082 02083 /* get scaling matrix */ 02084 size_to_mat3(smat, pchan->size); 02085 02086 /* rotations may either be quats, eulers (with various rotation orders), or axis-angle */ 02087 if (pchan->rotmode > 0) { 02088 /* euler rotations (will cause gimble lock, but this can be alleviated a bit with rotation orders) */ 02089 eulO_to_mat3(rmat, pchan->eul, pchan->rotmode); 02090 } 02091 else if (pchan->rotmode == ROT_MODE_AXISANGLE) { 02092 /* axis-angle - not really that great for 3D-changing orientations */ 02093 axis_angle_to_mat3(rmat, pchan->rotAxis, pchan->rotAngle); 02094 } 02095 else { 02096 /* quats are normalised before use to eliminate scaling issues */ 02097 float quat[4]; 02098 02099 /* NOTE: we now don't normalise the stored values anymore, since this was kindof evil in some cases 02100 * but if this proves to be too problematic, switch back to the old system of operating directly on 02101 * the stored copy 02102 */ 02103 normalize_qt_qt(quat, pchan->quat); 02104 quat_to_mat3(rmat, quat); 02105 } 02106 02107 /* calculate matrix of bone (as 3x3 matrix, but then copy the 4x4) */ 02108 mul_m3_m3m3(tmat, rmat, smat); 02109 copy_m4_m3(chan_mat, tmat); 02110 02111 /* prevent action channels breaking chains */ 02112 /* need to check for bone here, CONSTRAINT_TYPE_ACTION uses this call */ 02113 if ((pchan->bone==NULL) || !(pchan->bone->flag & BONE_CONNECTED)) { 02114 VECCOPY(chan_mat[3], pchan->loc); 02115 } 02116 } 02117 02118 /* loc/rot/size to mat4 */ 02119 /* used in constraint.c too */ 02120 void pchan_calc_mat(bPoseChannel *pchan) 02121 { 02122 /* this is just a wrapper around the copy of this function which calculates the matrix 02123 * and stores the result in any given channel 02124 */ 02125 pchan_to_mat4(pchan, pchan->chan_mat); 02126 } 02127 02128 /* NLA strip modifiers */ 02129 static void do_strip_modifiers(Scene *scene, Object *armob, Bone *bone, bPoseChannel *pchan) 02130 { 02131 bActionModifier *amod; 02132 bActionStrip *strip, *strip2; 02133 float scene_cfra= (float)scene->r.cfra; 02134 int do_modif; 02135 02136 for (strip=armob->nlastrips.first; strip; strip=strip->next) { 02137 do_modif=0; 02138 02139 if (scene_cfra>=strip->start && scene_cfra<=strip->end) 02140 do_modif=1; 02141 02142 if ((scene_cfra > strip->end) && (strip->flag & ACTSTRIP_HOLDLASTFRAME)) { 02143 do_modif=1; 02144 02145 /* if there are any other strips active, ignore modifiers for this strip - 02146 * 'hold' option should only hold action modifiers if there are 02147 * no other active strips */ 02148 for (strip2=strip->next; strip2; strip2=strip2->next) { 02149 if (strip2 == strip) continue; 02150 02151 if (scene_cfra>=strip2->start && scene_cfra<=strip2->end) { 02152 if (!(strip2->flag & ACTSTRIP_MUTE)) 02153 do_modif=0; 02154 } 02155 } 02156 02157 /* if there are any later, activated, strips with 'hold' set, they take precedence, 02158 * so ignore modifiers for this strip */ 02159 for (strip2=strip->next; strip2; strip2=strip2->next) { 02160 if (scene_cfra < strip2->start) continue; 02161 if ((strip2->flag & ACTSTRIP_HOLDLASTFRAME) && !(strip2->flag & ACTSTRIP_MUTE)) { 02162 do_modif=0; 02163 } 02164 } 02165 } 02166 02167 if (do_modif) { 02168 /* temporal solution to prevent 2 strips accumulating */ 02169 if(scene_cfra==strip->end && strip->next && strip->next->start==scene_cfra) 02170 continue; 02171 02172 for(amod= strip->modifiers.first; amod; amod= amod->next) { 02173 switch (amod->type) { 02174 case ACTSTRIP_MOD_DEFORM: 02175 { 02176 /* validate first */ 02177 if(amod->ob && amod->ob->type==OB_CURVE && amod->channel[0]) { 02178 02179 if( strcmp(pchan->name, amod->channel)==0 ) { 02180 float mat4[4][4], mat3[3][3]; 02181 02182 curve_deform_vector(scene, amod->ob, armob, bone->arm_mat[3], pchan->pose_mat[3], mat3, amod->no_rot_axis); 02183 copy_m4_m4(mat4, pchan->pose_mat); 02184 mul_m4_m3m4(pchan->pose_mat, mat3, mat4); 02185 02186 } 02187 } 02188 } 02189 break; 02190 case ACTSTRIP_MOD_NOISE: 02191 { 02192 if( strcmp(pchan->name, amod->channel)==0 ) { 02193 float nor[3], loc[3], ofs; 02194 float eul[3], size[3], eulo[3], sizeo[3]; 02195 02196 /* calculate turbulance */ 02197 ofs = amod->turbul / 200.0f; 02198 02199 /* make a copy of starting conditions */ 02200 VECCOPY(loc, pchan->pose_mat[3]); 02201 mat4_to_eul( eul,pchan->pose_mat); 02202 mat4_to_size( size,pchan->pose_mat); 02203 VECCOPY(eulo, eul); 02204 VECCOPY(sizeo, size); 02205 02206 /* apply noise to each set of channels */ 02207 if (amod->channels & 4) { 02208 /* for scaling */ 02209 nor[0] = BLI_gNoise(amod->noisesize, size[0]+ofs, size[1], size[2], 0, 0) - ofs; 02210 nor[1] = BLI_gNoise(amod->noisesize, size[0], size[1]+ofs, size[2], 0, 0) - ofs; 02211 nor[2] = BLI_gNoise(amod->noisesize, size[0], size[1], size[2]+ofs, 0, 0) - ofs; 02212 add_v3_v3(size, nor); 02213 02214 if (sizeo[0] != 0) 02215 mul_v3_fl(pchan->pose_mat[0], size[0] / sizeo[0]); 02216 if (sizeo[1] != 0) 02217 mul_v3_fl(pchan->pose_mat[1], size[1] / sizeo[1]); 02218 if (sizeo[2] != 0) 02219 mul_v3_fl(pchan->pose_mat[2], size[2] / sizeo[2]); 02220 } 02221 if (amod->channels & 2) { 02222 /* for rotation */ 02223 nor[0] = BLI_gNoise(amod->noisesize, eul[0]+ofs, eul[1], eul[2], 0, 0) - ofs; 02224 nor[1] = BLI_gNoise(amod->noisesize, eul[0], eul[1]+ofs, eul[2], 0, 0) - ofs; 02225 nor[2] = BLI_gNoise(amod->noisesize, eul[0], eul[1], eul[2]+ofs, 0, 0) - ofs; 02226 02227 compatible_eul(nor, eulo); 02228 add_v3_v3(eul, nor); 02229 compatible_eul(eul, eulo); 02230 02231 loc_eul_size_to_mat4(pchan->pose_mat, loc, eul, size); 02232 } 02233 if (amod->channels & 1) { 02234 /* for location */ 02235 nor[0] = BLI_gNoise(amod->noisesize, loc[0]+ofs, loc[1], loc[2], 0, 0) - ofs; 02236 nor[1] = BLI_gNoise(amod->noisesize, loc[0], loc[1]+ofs, loc[2], 0, 0) - ofs; 02237 nor[2] = BLI_gNoise(amod->noisesize, loc[0], loc[1], loc[2]+ofs, 0, 0) - ofs; 02238 02239 add_v3_v3v3(pchan->pose_mat[3], loc, nor); 02240 } 02241 } 02242 } 02243 break; 02244 } 02245 } 02246 } 02247 } 02248 } 02249 02250 /* calculate tail of posechannel */ 02251 void where_is_pose_bone_tail(bPoseChannel *pchan) 02252 { 02253 float vec[3]; 02254 02255 VECCOPY(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 VECCOPY(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 mul_m4_m4m4(tmat, tmat, tsmat); 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 mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, bone->arm_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 /* do NLA strip modifiers - i.e. curve follow */ 02360 do_strip_modifiers(scene, ob, bone, pchan); 02361 02362 /* Do constraints */ 02363 if (pchan->constraints.first) { 02364 bConstraintOb *cob; 02365 02366 /* make a copy of location of PoseChannel for later */ 02367 VECCOPY(vec, pchan->pose_mat[3]); 02368 02369 /* prepare PoseChannel for Constraint solving 02370 * - makes a copy of matrix, and creates temporary struct to use 02371 */ 02372 cob= constraints_make_evalob(scene, ob, pchan, CONSTRAINT_OBTYPE_BONE); 02373 02374 /* Solve PoseChannel's Constraints */ 02375 solve_constraints(&pchan->constraints, cob, ctime); // ctime doesnt alter objects 02376 02377 /* cleanup after Constraint Solving 02378 * - applies matrix back to pchan, and frees temporary struct used 02379 */ 02380 constraints_clear_evalob(cob); 02381 02382 /* prevent constraints breaking a chain */ 02383 if(pchan->bone->flag & BONE_CONNECTED) { 02384 VECCOPY(pchan->pose_mat[3], vec); 02385 } 02386 } 02387 } 02388 02389 /* calculate head */ 02390 VECCOPY(pchan->pose_head, pchan->pose_mat[3]); 02391 /* calculate tail */ 02392 where_is_pose_bone_tail(pchan); 02393 } 02394 02395 /* This only reads anim data from channels, and writes to channels */ 02396 /* This is the only function adding poses */ 02397 void where_is_pose (Scene *scene, Object *ob) 02398 { 02399 bArmature *arm; 02400 Bone *bone; 02401 bPoseChannel *pchan; 02402 float imat[4][4]; 02403 float ctime; 02404 02405 if(ob->type!=OB_ARMATURE) return; 02406 arm = ob->data; 02407 02408 if(ELEM(NULL, arm, scene)) return; 02409 if((ob->pose==NULL) || (ob->pose->flag & POSE_RECALC)) 02410 armature_rebuild_pose(ob, arm); 02411 02412 ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0); /* not accurate... */ 02413 02414 /* In editmode or restposition we read the data from the bones */ 02415 if(arm->edbo || (arm->flag & ARM_RESTPOS)) { 02416 02417 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 02418 bone= pchan->bone; 02419 if(bone) { 02420 copy_m4_m4(pchan->pose_mat, bone->arm_mat); 02421 VECCOPY(pchan->pose_head, bone->arm_head); 02422 VECCOPY(pchan->pose_tail, bone->arm_tail); 02423 } 02424 } 02425 } 02426 else { 02427 invert_m4_m4(ob->imat, ob->obmat); // imat is needed 02428 02429 /* 1. clear flags */ 02430 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 02431 pchan->flag &= ~(POSE_DONE|POSE_CHAIN|POSE_IKTREE|POSE_IKSPLINE); 02432 } 02433 02434 /* 2a. construct the IK tree (standard IK) */ 02435 BIK_initialize_tree(scene, ob, ctime); 02436 02437 /* 2b. construct the Spline IK trees 02438 * - this is not integrated as an IK plugin, since it should be able 02439 * to function in conjunction with standard IK 02440 */ 02441 splineik_init_tree(scene, ob, ctime); 02442 02443 /* 3. the main loop, channels are already hierarchical sorted from root to children */ 02444 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 02445 /* 4a. if we find an IK root, we handle it separated */ 02446 if(pchan->flag & POSE_IKTREE) { 02447 BIK_execute_tree(scene, ob, pchan, ctime); 02448 } 02449 /* 4b. if we find a Spline IK root, we handle it separated too */ 02450 else if(pchan->flag & POSE_IKSPLINE) { 02451 splineik_execute_tree(scene, ob, pchan, ctime); 02452 } 02453 /* 5. otherwise just call the normal solver */ 02454 else if(!(pchan->flag & POSE_DONE)) { 02455 where_is_pose_bone(scene, ob, pchan, ctime, 1); 02456 } 02457 } 02458 /* 6. release the IK tree */ 02459 BIK_release_tree(scene, ob, ctime); 02460 } 02461 02462 /* calculating deform matrices */ 02463 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { 02464 if(pchan->bone) { 02465 invert_m4_m4(imat, pchan->bone->arm_mat); 02466 mul_m4_m4m4(pchan->chan_mat, imat, pchan->pose_mat); 02467 } 02468 } 02469 }