diff options
author | mano-wii <germano.costa@ig.com.br> | 2020-01-02 18:48:30 +0300 |
---|---|---|
committer | mano-wii <germano.costa@ig.com.br> | 2020-01-02 18:53:46 +0300 |
commit | de530a95dc7b482dc22c933b9b8b2a98c79b5663 (patch) | |
tree | 2be471ce0d6a736c97d344e37542e8a664b4532b /source/blender/editors/transform/transform_generics.c | |
parent | 2e06a6bec3f5ed078a544dea9c4f842e403abbc0 (diff) |
Transform: Pose: Partial support for Auto IK + X-Mirror
Fix T69572
TODO: support `Relative-Mirror` as well.
Maniphest Tasks: T69572
Differential Revision: https://developer.blender.org/D5862
Diffstat (limited to 'source/blender/editors/transform/transform_generics.c')
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 9031dc06e3f..5595c3a0e38 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -31,6 +31,7 @@ #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_brush_types.h" +#include "DNA_constraint_types.h" #include "DNA_gpencil_types.h" #include "DNA_lattice_types.h" #include "DNA_screen_types.h" @@ -785,50 +786,61 @@ static void recalcData_spaceclip(TransInfo *t) * if pose bone (partial) selected, copy data. * context; posemode armature, with mirror editing enabled. * - * \param pid: Optional, apply relative transform when set. + * \param pid: Optional, apply relative transform when set (has no effect on mirrored bones). */ -static void pose_transform_mirror_update(Object *ob, PoseInitData_Mirror *pid) +static void pose_transform_mirror_update(TransInfo *t, + TransDataContainer *tc, + Object *ob, + PoseInitData_Mirror *pid) { float flip_mtx[4][4]; unit_m4(flip_mtx); flip_mtx[0][0] = -1; - for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig; - pchan_orig = pchan_orig->next) { - /* Clear the MIRROR flag from previous runs */ - pchan_orig->bone->flag &= ~BONE_TRANSFORM_MIRROR; - } - - for (bPoseChannel *pchan_orig = ob->pose->chanbase.first; pchan_orig; - pchan_orig = pchan_orig->next) { - /* no layer check, correct mirror is more important */ - if (pchan_orig->bone->flag & BONE_TRANSFORM) { - bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name); - - if (pchan) { - /* also do bbone scaling */ - pchan->bone->xwidth = pchan_orig->bone->xwidth; - pchan->bone->zwidth = pchan_orig->bone->zwidth; - - /* we assume X-axis flipping for now */ - pchan->curve_in_x = pchan_orig->curve_in_x * -1; - pchan->curve_out_x = pchan_orig->curve_out_x * -1; - pchan->roll1 = pchan_orig->roll1 * -1; // XXX? - pchan->roll2 = pchan_orig->roll2 * -1; // XXX? - - float pchan_mtx_final[4][4]; - BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final); - mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx); - mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final); - if (pid) { - mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final); - pid++; - } - BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false); + TransData *td = tc->data; + for (int i = tc->data_len; i--; td++) { + bPoseChannel *pchan_orig = td->extra; + BLI_assert(pchan_orig->bone->flag & BONE_TRANSFORM); + /* No layer check, correct mirror is more important. */ + bPoseChannel *pchan = BKE_pose_channel_get_mirrored(ob->pose, pchan_orig->name); + if (pchan == NULL) { + continue; + } + + /* Also do bbone scaling. */ + pchan->bone->xwidth = pchan_orig->bone->xwidth; + pchan->bone->zwidth = pchan_orig->bone->zwidth; - /* set flag to let autokeyframe know to keyframe the mirrred bone */ - pchan->bone->flag |= BONE_TRANSFORM_MIRROR; + /* We assume X-axis flipping for now. */ + pchan->curve_in_x = pchan_orig->curve_in_x * -1; + pchan->curve_out_x = pchan_orig->curve_out_x * -1; + pchan->roll1 = pchan_orig->roll1 * -1; // XXX? + pchan->roll2 = pchan_orig->roll2 * -1; // XXX? + + float pchan_mtx_final[4][4]; + BKE_pchan_to_mat4(pchan_orig, pchan_mtx_final); + mul_m4_m4m4(pchan_mtx_final, pchan_mtx_final, flip_mtx); + mul_m4_m4m4(pchan_mtx_final, flip_mtx, pchan_mtx_final); + if (pid) { + mul_m4_m4m4(pchan_mtx_final, pid->offset_mtx, pchan_mtx_final); + } + BKE_pchan_apply_mat4(pchan, pchan_mtx_final, false); + + /* In this case we can do target-less IK grabbing. */ + if (t->mode == TFM_TRANSLATION) { + bKinematicConstraint *data = has_targetless_ik(pchan); + if (data == NULL) { + continue; } + mul_v3_m4v3(data->grabtarget, flip_mtx, td->loc); + if (pid) { + /* TODO(germano): Realitve Mirror support */ + } + data->flag |= CONSTRAINT_IK_AUTO; + } + + if (pid) { + pid++; } } } @@ -1045,7 +1057,7 @@ static void recalcData_objects(TransInfo *t) DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); bPose *pose = ob->pose; if (arm->flag & ARM_MIRROR_EDIT || pose->flag & POSE_MIRROR_EDIT) { - pose_transform_mirror_update(ob, NULL); + pose_transform_mirror_update(t, tc, ob, NULL); } } } @@ -1063,7 +1075,7 @@ static void recalcData_objects(TransInfo *t) if (pose->flag & POSE_MIRROR_RELATIVE) { pid = tc->custom.type.data; } - pose_transform_mirror_update(ob, pid); + pose_transform_mirror_update(t, tc, ob, pid); } else { restoreMirrorPoseBones(tc); |