diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 38 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_constraint.c | 8 |
3 files changed, 43 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index e1e4d138fd9..1a3c562941e 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1927,9 +1927,39 @@ static void sizelike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta if (VALID_CONS_TARGET(ct)) { float obsize[3], size[3]; - mat4_to_size(size, ct->matrix); mat4_to_size(obsize, cob->matrix); + /* Compute one uniform scale factor to apply to all three axes. */ + if (data->flag & SIZELIKE_UNIFORM) { + const int all_axes = SIZELIKE_X | SIZELIKE_Y | SIZELIKE_Z; + float total = 1.0f; + + /* If all axes are selected, use the determinant. */ + if ((data->flag & all_axes) == all_axes) { + total = fabsf(mat4_to_volume_scale(ct->matrix)); + } + /* Otherwise multiply individual values. */ + else { + mat4_to_size(size, ct->matrix); + + if (data->flag & SIZELIKE_X) { + total *= size[0]; + } + if (data->flag & SIZELIKE_Y) { + total *= size[1]; + } + if (data->flag & SIZELIKE_Z) { + total *= size[2]; + } + } + + copy_v3_fl(size, cbrt(total)); + } + /* Regular per-axis scaling. */ + else { + mat4_to_size(size, ct->matrix); + } + for (int i = 0; i < 3; i++) { size[i] = powf(size[i], data->power); } @@ -1948,13 +1978,13 @@ static void sizelike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta } } - if ((data->flag & SIZELIKE_X) && (obsize[0] != 0)) { + if ((data->flag & (SIZELIKE_X | SIZELIKE_UNIFORM)) && (obsize[0] != 0)) { mul_v3_fl(cob->matrix[0], size[0] / obsize[0]); } - if ((data->flag & SIZELIKE_Y) && (obsize[1] != 0)) { + if ((data->flag & (SIZELIKE_Y | SIZELIKE_UNIFORM)) && (obsize[1] != 0)) { mul_v3_fl(cob->matrix[1], size[1] / obsize[1]); } - if ((data->flag & SIZELIKE_Z) && (obsize[2] != 0)) { + if ((data->flag & (SIZELIKE_Z | SIZELIKE_UNIFORM)) && (obsize[2] != 0)) { mul_v3_fl(cob->matrix[2], size[2] / obsize[2]); } } diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index eda52fdf14a..17ce279f1b7 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -748,6 +748,7 @@ typedef enum eCopyScale_Flags { SIZELIKE_Z = (1 << 2), SIZELIKE_OFFSET = (1 << 3), SIZELIKE_MULTIPLY = (1 << 4), + SIZELIKE_UNIFORM = (1 << 5), } eCopyScale_Flags; /* bTransformConstraint.to/from */ diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 08d2a03b2a9..539e2a66296 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -1364,6 +1364,14 @@ static void rna_def_constraint_size_like(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Power", "Raise the target's scale to the specified power"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); + prop = RNA_def_property(srna, "use_make_uniform", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_UNIFORM); + RNA_def_property_ui_text(prop, + "Make Uniform", + "Redistribute the copied change in volume equally " + "between the three axes of the owner"); + RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); + prop = RNA_def_property(srna, "use_offset", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_OFFSET); RNA_def_property_ui_text(prop, "Offset", "Combine original scale with copied scale"); |