Blender V2.61 - r43446
|
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 }