diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2020-11-04 19:29:27 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2021-07-02 15:15:05 +0300 |
commit | bc8ae58727bf078df1fc5803a9de5c9eb984aeb7 (patch) | |
tree | 64037beefa7b8a8cf9201c51360d8fa310cc791c /source/blender/blenkernel | |
parent | 01e1944cd455448e8634ab2c44ca8a96c73af628 (diff) |
Copy Transforms: implement Remove Target Shear and more Mix options.
This constraint can be naturally viewed as a prototype for a future
4x4 matrix math node (or subset thereof), since its basic semantics
already is matrix assignment. Thus it makes sense to add math options
to this constraint to increase flexibility in the meantime.
This patch adds support for several operations that would be useful:
- An option to remove shear in the incoming target matrix.
Shear is known to cause issues for various mathematical operations,
so an option to remove it at key points is useful.
Constraints based on Euler like Copy Rotation and Limit Rotation
already have always enabled shear removal built in, because their
math doesn't work correctly with shear.
In the future node system shear removal would be a separate node
(and currently Limit Rotation can be used as a Remove Shear constraint).
However removing shear from the result of the target space conversion
before mixing (similar to Copy Rotation) has to be built into
Copy Transforms itself as an option.
- More ways to combine the target and owner matrices.
Similar to multiple Inherit Scale modes for parenting, there are
multiple ways one may want to combine matrices based on context.
This implements 3 variants for each of the Before/After modes
(one of them already existing).
- Full implements regular matrix multiplication as the most basic
option. The downside is the risk of creating shear.
- Aligned emulates the 'anti-shear' Aligned Inherit Scale mode,
and basically uses Full for location, and Split for rotation/scale.
(This choice already existed.)
- Split Channels combines location, rotation and scale separately.
Looking at D7547 there is demand for Split Channels in some cases,
so I think it makes sense to include it in Copy Transforms too, so that
the Mix menu items can be identical for it and the Action constraint.
Differential Revision: https://developer.blender.org/D9469
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 193b6d82d03..41da728fa5b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2235,17 +2235,47 @@ static void translike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t bConstraintTarget *ct = targets->first; if (VALID_CONS_TARGET(ct)) { + float target_mat[4][4]; + + copy_m4_m4(target_mat, ct->matrix); + + /* Remove the shear of the target matrix if enabled. + * Use Y as the axis since it's the natural default for bones. */ + if (data->flag & TRANSLIKE_REMOVE_TARGET_SHEAR) { + orthogonalize_m4_stable(target_mat, 1, false); + } + + /* Finally, combine the matrices. */ switch (data->mix_mode) { case TRANSLIKE_MIX_REPLACE: - copy_m4_m4(cob->matrix, ct->matrix); + copy_m4_m4(cob->matrix, target_mat); + break; + + /* Simple matrix multiplication. */ + case TRANSLIKE_MIX_BEFORE_FULL: + mul_m4_m4m4(cob->matrix, target_mat, cob->matrix); + break; + + case TRANSLIKE_MIX_AFTER_FULL: + mul_m4_m4m4(cob->matrix, cob->matrix, target_mat); break; + /* Aligned Inherit Scale emulation. */ case TRANSLIKE_MIX_BEFORE: - mul_m4_m4m4_aligned_scale(cob->matrix, ct->matrix, cob->matrix); + mul_m4_m4m4_aligned_scale(cob->matrix, target_mat, cob->matrix); break; case TRANSLIKE_MIX_AFTER: - mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, ct->matrix); + mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, target_mat); + break; + + /* Fully separate handling of channels. */ + case TRANSLIKE_MIX_BEFORE_SPLIT: + mul_m4_m4m4_split_channels(cob->matrix, target_mat, cob->matrix); + break; + + case TRANSLIKE_MIX_AFTER_SPLIT: + mul_m4_m4m4_split_channels(cob->matrix, cob->matrix, target_mat); break; default: |