diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2019-09-06 11:54:34 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2019-09-06 12:53:35 +0300 |
commit | e858d21ae42386c57c7f5b4b0982642173f460e5 (patch) | |
tree | 90d36cb8f5bd0ba8be7414b5027553eeca115c77 /source/blender/blenkernel | |
parent | a23ce7f3b78b28550c6e6cfd73404b82dc210529 (diff) |
Transformation Constraint: implement a Mix Mode option.
Allow selecting how the new location/rotation/scale is combined with
the existing transformation. This is most useful for rotation, which
has multiple options, and scale, which previously could only replace.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 58011c8d753..9b32996aa96 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -3802,7 +3802,8 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t /* only evaluate if there is a target */ if (VALID_CONS_TARGET(ct)) { float *from_min, *from_max, *to_min, *to_max; - float loc[3], eul[3], size[3]; + float loc[3], rot[3][3], oldeul[3], size[3]; + float newloc[3], newrot[3][3], neweul[3], newsize[3]; float dbuf[4], sval[3]; float *const dvec = dbuf + 1; int i; @@ -3844,9 +3845,7 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } /* extract components of owner's matrix */ - copy_v3_v3(loc, cob->matrix[3]); - mat4_to_eulO(eul, rot_order, cob->matrix); - mat4_to_size(size, cob->matrix); + mat4_to_loc_rot_size(loc, rot, size, cob->matrix); /* determine where in range current transforms lie */ if (data->expo) { @@ -3878,18 +3877,42 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t to_min = data->to_min_scale; to_max = data->to_max_scale; for (i = 0; i < 3; i++) { - /* multiply with original scale (so that it can still be scaled) */ - /* size[i] *= to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])); */ - /* Stay absolute, else it breaks existing rigs... sigh. */ - size[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])); + newsize[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])); + } + switch (data->mix_mode_scale) { + case TRANS_MIXSCALE_MULTIPLY: + mul_v3_v3(size, newsize); + break; + case TRANS_MIXSCALE_REPLACE: + default: + copy_v3_v3(size, newsize); + break; } break; case TRANS_ROTATION: to_min = data->to_min_rot; to_max = data->to_max_rot; for (i = 0; i < 3; i++) { - /* add to original rotation (so that it can still be rotated) */ - eul[i] += to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])); + neweul[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])); + } + switch (data->mix_mode_rot) { + case TRANS_MIXROT_REPLACE: + eulO_to_mat3(rot, neweul, rot_order); + break; + case TRANS_MIXROT_BEFORE: + eulO_to_mat3(newrot, neweul, rot_order); + mul_m3_m3m3(rot, newrot, rot); + break; + case TRANS_MIXROT_AFTER: + eulO_to_mat3(newrot, neweul, rot_order); + mul_m3_m3m3(rot, rot, newrot); + break; + case TRANS_MIXROT_ADD: + default: + mat3_to_eulO(oldeul, rot_order, rot); + add_v3_v3(neweul, oldeul); + eulO_to_mat3(rot, neweul, rot_order); + break; } break; case TRANS_LOCATION: @@ -3897,14 +3920,22 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t to_min = data->to_min; to_max = data->to_max; for (i = 0; i < 3; i++) { - /* add to original location (so that it can still be moved) */ - loc[i] += (to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]))); + newloc[i] = (to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]))); + } + switch (data->mix_mode_loc) { + case TRANS_MIXLOC_REPLACE: + copy_v3_v3(loc, newloc); + break; + case TRANS_MIXLOC_ADD: + default: + add_v3_v3(loc, newloc); + break; } break; } /* apply to matrix */ - loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, rot_order); + loc_rot_size_to_mat4(cob->matrix, loc, rot, size); } } |