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:
authorAlexander Gavrilov <angavrilov@gmail.com>2019-09-04 14:59:18 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2019-09-06 07:58:13 +0300
commitf8362836a5c8feff3715ca823025caba249208c2 (patch)
treec3406460a139947c4613b86e392a1f4ffb6a5e2d /source/blender
parentf4056e9ec3a89afbc592af3e3d169d2d584a9937 (diff)
Copy Transforms: add a mixing mode option.
Allow combining location, rotation and scale at the same time, using one constraint. The mixing modes are based on matrix multiplication, but handle scale in a way that avoids creating shear. Reviewers: brecht Differential Revision: https://developer.blender.org/D5640
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/constraint.c36
-rw-r--r--source/blender/editors/transform/transform_convert.c9
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c29
4 files changed, 83 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 803aae76422..317973cc0c1 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -2090,13 +2090,43 @@ static void translike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void translike_evaluate(bConstraint *UNUSED(con), bConstraintOb *cob, ListBase *targets)
+static void translike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
{
+ bTransLikeConstraint *data = con->data;
bConstraintTarget *ct = targets->first;
if (VALID_CONS_TARGET(ct)) {
- /* just copy the entire transform matrix of the target */
- copy_m4_m4(cob->matrix, ct->matrix);
+ if (data->mix_mode == TRANSLIKE_MIX_REPLACE) {
+ /* just copy the entire transform matrix of the target */
+ copy_m4_m4(cob->matrix, ct->matrix);
+ }
+ else {
+ float old_loc[3], old_rot[3][3], old_size[3];
+ float new_loc[3], new_rot[3][3], new_size[3];
+
+ /* Separate matrices so they can be combined in a way that avoids shear. */
+ mat4_to_loc_rot_size(old_loc, old_rot, old_size, cob->matrix);
+ mat4_to_loc_rot_size(new_loc, new_rot, new_size, ct->matrix);
+
+ switch (data->mix_mode) {
+ case TRANSLIKE_MIX_BEFORE:
+ mul_v3_m4v3(new_loc, ct->matrix, old_loc);
+ mul_m3_m3m3(new_rot, new_rot, old_rot);
+ mul_v3_v3(new_size, old_size);
+ break;
+
+ case TRANSLIKE_MIX_AFTER:
+ mul_v3_m4v3(new_loc, cob->matrix, new_loc);
+ mul_m3_m3m3(new_rot, old_rot, new_rot);
+ mul_v3_v3(new_size, old_size);
+ break;
+
+ default:
+ BLI_assert(false);
+ }
+
+ loc_rot_size_to_mat4(cob->matrix, new_loc, new_rot, new_size);
+ }
}
}
diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c
index 14eee2318cd..cbb291414bf 100644
--- a/source/blender/editors/transform/transform_convert.c
+++ b/source/blender/editors/transform/transform_convert.c
@@ -1335,6 +1335,15 @@ bool constraints_list_needinv(TransInfo *t, ListBase *list)
return true;
}
}
+ else if (con->type == CONSTRAINT_TYPE_TRANSLIKE) {
+ /* Copy Transforms constraint only does this in the Before mode. */
+ bTransLikeConstraint *data = (bTransLikeConstraint *)con->data;
+
+ if (ELEM(data->mix_mode, TRANSLIKE_MIX_BEFORE) &&
+ ELEM(t->mode, TFM_ROTATION, TFM_TRANSLATION)) {
+ return true;
+ }
+ }
else if (con->type == CONSTRAINT_TYPE_TRANSFORM) {
/* Transform constraint needs it for rotation at least (r.57309),
* but doing so when translating may also mess things up [#36203]
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index a7f900ddc9b..d123cf21db9 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -307,6 +307,8 @@ typedef struct bSameVolumeConstraint {
/* Copy Transform Constraint */
typedef struct bTransLikeConstraint {
struct Object *tar;
+ char mix_mode;
+ char _pad[7];
/** MAX_ID_NAME-2. */
char subtarget[64];
} bTransLikeConstraint;
@@ -790,6 +792,16 @@ typedef enum eCopyScale_Flags {
SIZELIKE_UNIFORM = (1 << 5),
} eCopyScale_Flags;
+/* bTransLikeConstraint.mix_mode */
+typedef enum eCopyTransforms_MixMode {
+ /* Replace rotation channel values. */
+ TRANSLIKE_MIX_REPLACE = 0,
+ /* Multiply the copied transformation on the left, with anti-shear scale handling. */
+ TRANSLIKE_MIX_BEFORE,
+ /* Multiply the copied transformation on the right, with anti-shear scale handling. */
+ TRANSLIKE_MIX_AFTER,
+} eCopyTransforms_MixMode;
+
/* bTransformConstraint.to/from */
typedef enum eTransform_ToFrom {
TRANS_LOCATION = 0,
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 79e38717569..658addece8a 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -1515,6 +1515,28 @@ static void rna_def_constraint_same_volume(BlenderRNA *brna)
static void rna_def_constraint_transform_like(BlenderRNA *brna)
{
StructRNA *srna;
+ PropertyRNA *prop;
+
+ static const EnumPropertyItem mix_mode_items[] = {
+ {TRANSLIKE_MIX_REPLACE,
+ "REPLACE",
+ 0,
+ "Replace",
+ "Replace the original transformation with copied"},
+ {TRANSLIKE_MIX_BEFORE,
+ "BEFORE",
+ 0,
+ "Before Original",
+ "Apply copied transformation before original, as if the constraint target is a parent. "
+ "Scale is handled specially to avoid creating shear"},
+ {TRANSLIKE_MIX_AFTER,
+ "AFTER",
+ 0,
+ "After Original",
+ "Apply copied transformation after original, as if the constraint target is a child. "
+ "Scale is handled specially to avoid creating shear"},
+ {0, NULL, 0, NULL, NULL},
+ };
srna = RNA_def_struct(brna, "CopyTransformsConstraint", "Constraint");
RNA_def_struct_ui_text(
@@ -1527,6 +1549,13 @@ static void rna_def_constraint_transform_like(BlenderRNA *brna)
RNA_def_struct_ui_icon(srna, ICON_CON_TRANSLIKE);
rna_def_constraint_target_common(srna);
+
+ prop = RNA_def_property(srna, "mix_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "mix_mode");
+ RNA_def_property_enum_items(prop, mix_mode_items);
+ RNA_def_property_ui_text(
+ prop, "Mix Mode", "Specify how the copied and existing transformations are combined");
+ RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
}
static void rna_def_constraint_minmax(BlenderRNA *brna)