Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2019-05-06 10:47:45 +0300
committerSebastian Parborg <darkdefende@gmail.com>2019-05-06 10:47:45 +0300
commit09181540b5aa889df6aa24bea4ce9a4823e0c18d (patch)
tree9d4daaf5f0f41883d64b8e6f21bca49e7cfcea84 /source/blender/editors/transform/transform_generics.c
parentf999c40d77f32594e3fdd5800758e70aa9a314f3 (diff)
Implement mirroring in pose mode (absolute and relative)
Added working X-mirroring in pose mode with an optional relative mirror mode. Reviewed By: Campbell Barton Differential Revision: http://developer.blender.org/D4765
Diffstat (limited to 'source/blender/editors/transform/transform_generics.c')
-rw-r--r--source/blender/editors/transform/transform_generics.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index a840c04ab5a..05bb9785112 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -781,6 +781,45 @@ 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.
+ */
+static void pose_transform_mirror_update(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) {
+ /* 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) {
+ /* 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);
+ }
+ }
+ }
+}
+
/* helper for recalcData() - for object transforms, typically in the 3D view */
static void recalcData_objects(TransInfo *t)
{
@@ -992,6 +1031,19 @@ static void recalcData_objects(TransInfo *t)
Object *ob = tc->poseobj;
bArmature *arm = ob->data;
+ if (arm->flag & ARM_MIRROR_EDIT) {
+ if (t->state != TRANS_CANCEL) {
+ PoseInitData_Mirror *pid = NULL;
+ if (arm->flag & ARM_MIRROR_RELATIVE) {
+ pid = tc->custom.type.data;
+ }
+ pose_transform_mirror_update(ob, pid);
+ }
+ else {
+ restoreMirrorPoseBones(tc);
+ }
+ }
+
/* if animtimer is running, and the object already has animation data,
* check if the auto-record feature means that we should record 'samples'
* (i.e. un-editable animation values)