diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 101 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_action_types.h | 13 |
2 files changed, 64 insertions, 50 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b44bf751a8a..3bec79eb352 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -577,7 +577,13 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) /* ************ Armature Deform ******************* */ -static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion) +typedef struct bPoseChanDeform { + Mat4 *b_bone_mats; + DualQuat *dual_quat; + DualQuat *b_bone_dual_quats; +} bPoseChanDeform; + +static void pchan_b_bone_defmats(bPoseChannel *pchan, bPoseChanDeform *pdef_info, int use_quaternion) { Bone *bone= pchan->bone; Mat4 *b_bone= b_bone_spline_setup(pchan, 0); @@ -589,11 +595,11 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion) /* allocate b_bone matrices and dual quats */ b_bone_mats= MEM_mallocN((1+bone->segments)*sizeof(Mat4), "BBone defmats"); - pchan->b_bone_mats= b_bone_mats; + pdef_info->b_bone_mats= b_bone_mats; if(use_quaternion) { b_bone_dual_quats= MEM_mallocN((bone->segments)*sizeof(DualQuat), "BBone dqs"); - pchan->b_bone_dual_quats= b_bone_dual_quats; + pdef_info->b_bone_dual_quats= b_bone_dual_quats; } /* first matrix is the inverse arm_mat, to bring points in local bone space @@ -618,9 +624,9 @@ static void pchan_b_bone_defmats(bPoseChannel *pchan, int use_quaternion) } } -static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *co, DualQuat *dq, float defmat[][3]) +static void b_bone_deform(bPoseChanDeform *pdef_info, Bone *bone, float *co, DualQuat *dq, float defmat[][3]) { - Mat4 *b_bone= pchan->b_bone_mats; + Mat4 *b_bone= pdef_info->b_bone_mats; float (*mat)[4]= b_bone[0].mat; float segment, y; int a; @@ -637,7 +643,7 @@ static void b_bone_deform(bPoseChannel *pchan, Bone *bone, float *co, DualQuat * CLAMP(a, 0, bone->segments-1); if(dq) { - copy_dq_dq(dq, &((DualQuat*)pchan->b_bone_dual_quats)[a]); + copy_dq_dq(dq, &(pdef_info->b_bone_dual_quats)[a]); } else { mul_m4_v3(b_bone[a+1].mat, co); @@ -711,7 +717,7 @@ static void pchan_deform_mat_add(bPoseChannel *pchan, float weight, float bbonem add_m3_m3m3(mat, mat, wmat); } -static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, float mat[][3], float *co) +static float dist_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float *vec, DualQuat *dq, float mat[][3], float *co) { Bone *bone= pchan->bone; float fac, contrib=0.0; @@ -732,7 +738,7 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo if(vec) { if(bone->segments>1) // applies on cop and bbonemat - b_bone_deform(pchan, bone, cop, NULL, (mat)?bbonemat:NULL); + b_bone_deform(pdef_info, bone, cop, NULL, (mat)?bbonemat:NULL); else mul_m4_v3(pchan->chan_mat, cop); @@ -745,11 +751,11 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo } else { if(bone->segments>1) { - b_bone_deform(pchan, bone, cop, &bbonedq, NULL); + b_bone_deform(pdef_info, bone, cop, &bbonedq, NULL); add_weighted_dq_dq(dq, &bbonedq, fac); } else - add_weighted_dq_dq(dq, pchan->dual_quat, fac); + add_weighted_dq_dq(dq, pdef_info->dual_quat, fac); } } } @@ -757,7 +763,7 @@ static float dist_bone_deform(bPoseChannel *pchan, float *vec, DualQuat *dq, flo return contrib; } -static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib) +static void pchan_bone_deform(bPoseChannel *pchan, bPoseChanDeform *pdef_info, float weight, float *vec, DualQuat *dq, float mat[][3], float *co, float *contrib) { float cop[3], bbonemat[3][3]; DualQuat bbonedq; @@ -770,7 +776,7 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua if(vec) { if(pchan->bone->segments>1) // applies on cop and bbonemat - b_bone_deform(pchan, pchan->bone, cop, NULL, (mat)?bbonemat:NULL); + b_bone_deform(pdef_info, pchan->bone, cop, NULL, (mat)?bbonemat:NULL); else mul_m4_v3(pchan->chan_mat, cop); @@ -783,11 +789,11 @@ static void pchan_bone_deform(bPoseChannel *pchan, float weight, float *vec, Dua } else { if(pchan->bone->segments>1) { - b_bone_deform(pchan, pchan->bone, cop, &bbonedq, NULL); + b_bone_deform(pdef_info, pchan->bone, cop, &bbonedq, NULL); add_weighted_dq_dq(dq, &bbonedq, weight); } else - add_weighted_dq_dq(dq, pchan->dual_quat, weight); + add_weighted_dq_dq(dq, pdef_info->dual_quat, weight); } (*contrib)+=weight; @@ -798,8 +804,11 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, int numVerts, int deformflag, float (*prevCos)[3], const char *defgrp_name) { + bPoseChanDeform *pdef_info_array; + bPoseChanDeform *pdef_info= NULL; bArmature *arm= armOb->data; bPoseChannel *pchan, **defnrToPC = NULL; + int *defnrToPCIndex= NULL; MDeformVert *dverts = NULL; bDeformGroup *dg; DualQuat *dualquats= NULL; @@ -823,20 +832,24 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, /* bone defmats are already in the channels, chan_mat */ /* initialize B_bone matrices and dual quaternions */ + totchan= BLI_countlist(&armOb->pose->chanbase); + if(use_quaternion) { - totchan= BLI_countlist(&armOb->pose->chanbase); dualquats= MEM_callocN(sizeof(DualQuat)*totchan, "dualquats"); } + + pdef_info_array= MEM_callocN(sizeof(bPoseChanDeform)*totchan, "bPoseChanDeform"); totchan= 0; - for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) { + pdef_info= pdef_info_array; + for(pchan= armOb->pose->chanbase.first; pchan; pchan= pchan->next, pdef_info++) { if(!(pchan->bone->flag & BONE_NO_DEFORM)) { if(pchan->bone->segments > 1) - pchan_b_bone_defmats(pchan, use_quaternion); + pchan_b_bone_defmats(pchan, pdef_info, use_quaternion); if(use_quaternion) { - pchan->dual_quat= &dualquats[totchan++]; - mat4_to_dquat( pchan->dual_quat,pchan->bone->arm_mat, pchan->chan_mat); + pdef_info->dual_quat= &dualquats[totchan++]; + mat4_to_dquat( pdef_info->dual_quat,pchan->bone->arm_mat, pchan->chan_mat); } } } @@ -872,15 +885,19 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, else if(dverts) use_dverts = 1; if(use_dverts) { - defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups, - "defnrToBone"); + defnrToPC = MEM_callocN(sizeof(*defnrToPC) * numGroups, "defnrToBone"); + defnrToPCIndex = MEM_callocN(sizeof(*defnrToPCIndex) * numGroups, "defnrToIndex"); for(i = 0, dg = target->defbase.first; dg; i++, dg = dg->next) { defnrToPC[i] = get_pose_channel(armOb->pose, dg->name); /* exclude non-deforming bones */ if(defnrToPC[i]) { - if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM) + if(defnrToPC[i]->bone->flag & BONE_NO_DEFORM) { defnrToPC[i]= NULL; + } + else { + defnrToPCIndex[i]= BLI_findindex(&armOb->pose->chanbase, defnrToPC[i]); + } } } } @@ -951,10 +968,10 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, for(j = 0; j < dvert->totweight; j++){ int index = dvert->dw[j].def_nr; - pchan = index < numGroups?defnrToPC[index]:NULL; - if(pchan) { + if(index < numGroups && (pchan= defnrToPC[index])) { float weight = dvert->dw[j].weight; - Bone *bone = pchan->bone; + Bone *bone= pchan->bone; + pdef_info= pdef_info_array + defnrToPCIndex[index]; deformed = 1; @@ -965,25 +982,27 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, bone->rad_tail, bone->dist); } - pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib); + pchan_bone_deform(pchan, pdef_info, weight, vec, dq, smat, co, &contrib); } } /* if there are vertexgroups but not groups with bones * (like for softbody groups) */ if(deformed == 0 && use_envelope) { - for(pchan = armOb->pose->chanbase.first; pchan; - pchan = pchan->next) { + pdef_info= pdef_info_array; + for(pchan= armOb->pose->chanbase.first; pchan; + pchan= pchan->next, pdef_info++) { if(!(pchan->bone->flag & BONE_NO_DEFORM)) - contrib += dist_bone_deform(pchan, vec, dq, smat, co); + contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co); } } } else if(use_envelope) { + pdef_info= pdef_info_array; for(pchan = armOb->pose->chanbase.first; pchan; - pchan = pchan->next) { + pchan = pchan->next, pdef_info++) { if(!(pchan->bone->flag & BONE_NO_DEFORM)) - contrib += dist_bone_deform(pchan, vec, dq, smat, co); + contrib += dist_bone_deform(pchan, pdef_info, vec, dq, smat, co); } } @@ -1039,20 +1058,20 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, if(dualquats) MEM_freeN(dualquats); if(defnrToPC) MEM_freeN(defnrToPC); - + if(defnrToPCIndex) MEM_freeN(defnrToPCIndex); + /* free B_bone matrices */ - for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next) { - if(pchan->b_bone_mats) { - MEM_freeN(pchan->b_bone_mats); - pchan->b_bone_mats = NULL; + pdef_info= pdef_info_array; + for(pchan = armOb->pose->chanbase.first; pchan; pchan = pchan->next, pdef_info++) { + if(pdef_info->b_bone_mats) { + MEM_freeN(pdef_info->b_bone_mats); } - if(pchan->b_bone_dual_quats) { - MEM_freeN(pchan->b_bone_dual_quats); - pchan->b_bone_dual_quats = NULL; + if(pdef_info->b_bone_dual_quats) { + MEM_freeN(pdef_info->b_bone_dual_quats); } - - pchan->dual_quat = NULL; } + + MEM_freeN(pdef_info_array); } /* ************ END Armature Deform ******************* */ diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index f7bbf9235ab..6f6e4978cfc 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -203,12 +203,10 @@ typedef struct bPoseChannel { struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */ struct ListBase iktree; /* only while evaluating pose */ - /* only while deform, stores precalculated b_bone deform mats, - dual quaternions */ - void *b_bone_mats; - void *dual_quat; - void *b_bone_dual_quats; - + bMotionPath *mpath; /* motion path cache for this bone */ + struct Object *custom; /* draws custom object instead of default bone shape */ + struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */ + /* transforms - written in by actions or transform */ float loc[3]; float size[3]; @@ -234,9 +232,6 @@ typedef struct bPoseChannel { float iklinweight; /* weight of joint stretch constraint */ float *path; /* totpath x 3 x float */ // XXX depreceated... old animation system (armature only viz) - bMotionPath *mpath; /* motion path cache for this bone */ - struct Object *custom; /* draws custom object instead of default bone shape */ - struct bPoseChannel *custom_tx; /* odd feature, display with another bones transform. needed in rare cases for advanced rigs, since the alternative is highly complicated - campbell */ } bPoseChannel; |