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:
authormano-wii <germano.costa@ig.com.br>2020-01-02 18:48:30 +0300
committermano-wii <germano.costa@ig.com.br>2020-01-02 18:53:46 +0300
commitde530a95dc7b482dc22c933b9b8b2a98c79b5663 (patch)
tree2be471ce0d6a736c97d344e37542e8a664b4532b /source/blender/editors/transform/transform_generics.c
parent2e06a6bec3f5ed078a544dea9c4f842e403abbc0 (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.c88
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);