diff --git a/release/scripts/ui/properties_data_bone.py b/release/scripts/ui/properties_data_bone.py index 40877a6be08..2c47ac03d7d 100644 --- a/release/scripts/ui/properties_data_bone.py +++ b/release/scripts/ui/properties_data_bone.py @@ -189,7 +189,9 @@ class BONE_PT_relations(BoneButtonsPanel): sub.prop(bone, "connected") sub.prop(bone, "hinge", text="Inherit Rotation") sub.prop(bone, "inherit_scale", text="Inherit Scale") - + sub = col.column() + sub.active = (not bone.parent or not bone.connected) + sub.prop(bone, "local_location", text="Local Location") class BONE_PT_display(BoneButtonsPanel): bl_label = "Display" diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index f9def718a4b..f70bdc8636b 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2220,39 +2220,43 @@ void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float cti /* the rotation of the parent restposition */ copy_m4_m4(tmat, parbone->arm_mat); - - /* the location of actual parent transform */ - VECCOPY(tmat[3], offs_bone[3]); - offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f; - mul_m4_v3(parchan->pose_mat, tmat[3]); - mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); } else if(bone->flag & BONE_NO_SCALE) { float orthmat[4][4]; - /* get the official transform, but we only use the vector from it (optimize...) */ - mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - VECCOPY(vec, pchan->pose_mat[3]); - - /* do this again, but with an ortho-parent matrix */ + /* do transform, with an ortho-parent matrix */ copy_m4_m4(orthmat, parchan->pose_mat); normalize_m4(orthmat); mul_serie_m4(pchan->pose_mat, orthmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - - /* copy correct transform */ - VECCOPY(pchan->pose_mat[3], vec); - } - else - mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - } - else { - if(bone->flag & BONE_NO_LOCAL_LOCATION) { - mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat); - add_v3_v3v3(pchan->pose_mat[3], bone->arm_mat[3], pchan->chan_mat[3]); } else - mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat); + mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); + + /* in these cases we need to compute location separately */ + if(bone->flag & (BONE_HINGE|BONE_NO_SCALE|BONE_NO_LOCAL_LOCATION)) { + float bone_loc[3], chan_loc[3]; + + mul_v3_m4v3(bone_loc, parchan->pose_mat, offs_bone[3]); + copy_v3_v3(chan_loc, pchan->chan_mat[3]); + + /* no local location is not transformed by bone matrix */ + if(!(bone->flag & BONE_NO_LOCAL_LOCATION)) + mul_mat3_m4_v3(offs_bone, chan_loc); + + /* for hinge we use armature instead of pose mat */ + if(bone->flag & BONE_HINGE) mul_m4_v3(parbone->arm_mat, chan_loc); + else mul_m4_v3(parchan->pose_mat, chan_loc); + + add_v3_v3v3(pchan->pose_mat[3], bone_loc, chan_loc); + } + } + else { + mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat); + + /* optional location without arm_mat rotation */ + if(bone->flag & BONE_NO_LOCAL_LOCATION) + add_v3_v3v3(pchan->pose_mat[3], bone->arm_mat[3], pchan->chan_mat[3]); /* only rootbones get the cyclic offset (unless user doesn't want that) */ if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0) diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 0a678b30764..403d8449a67 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -604,6 +604,11 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr /* proper way to get parent transform + own transform + constraints transform */ copy_m3_m4(omat, ob->obmat); + if (t->mode==TFM_TRANSLATION && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) + unit_m3(bmat); + else + copy_m3_m3(bmat, pchan->bone->bone_mat); + if (pchan->parent) { if(pchan->bone->flag & BONE_HINGE) copy_m3_m4(pmat, pchan->parent->bone->arm_mat); @@ -613,17 +618,12 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr if (constraints_list_needinv(t, &pchan->constraints)) { copy_m3_m4(tmat, pchan->constinv); invert_m3_m3(cmat, tmat); - mul_serie_m3(td->mtx, pchan->bone->bone_mat, pmat, omat, cmat, 0,0,0,0); // dang mulserie swaps args + mul_serie_m3(td->mtx, bmat, pmat, omat, cmat, 0,0,0,0); // dang mulserie swaps args } else - mul_serie_m3(td->mtx, pchan->bone->bone_mat, pmat, omat, 0,0,0,0,0); // dang mulserie swaps args + mul_serie_m3(td->mtx, bmat, pmat, omat, 0,0,0,0,0); // dang mulserie swaps args } else { - if (t->mode==TFM_TRANSLATION && (pchan->bone->flag & BONE_NO_LOCAL_LOCATION)) - unit_m3(bmat); - else - copy_m3_m3(bmat, pchan->bone->bone_mat); - if (constraints_list_needinv(t, &pchan->constraints)) { copy_m3_m4(tmat, pchan->constinv); invert_m3_m3(cmat, tmat);