diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-08-28 16:56:27 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-08-29 17:22:27 +0300 |
commit | 497297850a49b2ed422ae286703ddc98b23a5366 (patch) | |
tree | cf08f1570144ea16dc0f04669ba785650ae1f717 /source/blender/blenkernel/intern/constraint.c | |
parent | c160853b043724172518bd52a4da361f5291a978 (diff) |
Copy Scale: support copying arbitrary non-uniform scale as uniform.
Uniform scale is superior to non-uniform scale in that it works with
parenting without causing shear. Thus it is a valid desire in some
cases to turn arbitrary scale into guaranteed uniform scale.
Implementing this in the Copy Scale constraint allows one for instance
to 'inherit scale as uniform' by disabling Inherit Scale, and using
Copy Scale from parent with Offset and Make Uniform.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D5614
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 38 |
1 files changed, 34 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]); } } |