diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2018-07-09 22:25:44 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2018-08-13 20:37:53 +0300 |
commit | 2aa26de378a6afd64257a79444af932d3e054558 (patch) | |
tree | dfeaa224b2b2a6f2e11f4371a8717c45d5c40181 /source | |
parent | 47af343b6137e4290cc4a842daac25ff8d8cb65f (diff) |
Use full transformation of B-Bone segments in Copy Transforms.
Currently constraints can only read the location along the
spline. This obviously limits opportunities for complex bone
interactions in rigs.
This patch exposes access to rotation and scale as well in
Copy Transforms. However, due to the way how things work,
this data cannot be smoothly interpolated, and abruptly
changes when switching to the next segment.
Reviewers: aligorith
Differential Revision: https://developer.blender.org/D3545
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 31 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_constraint_types.h | 2 |
2 files changed, 29 insertions, 4 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index f4be232b9ae..2a28f333f41 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -579,11 +579,14 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m * PoseChannel by the Armature Object's Matrix to get a worldspace * matrix. */ - if (headtail < 0.000001f) { + bool is_bbone = (pchan->bone) && (pchan->bone->segments > 1) && (flag & CONSTRAINT_BBONE_SHAPE); + bool full_bbone = (flag & CONSTRAINT_BBONE_SHAPE_FULL) != 0; + + if (headtail < 0.000001f && !(is_bbone && full_bbone)) { /* skip length interpolation if set to head */ mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat); } - else if ((pchan->bone) && (pchan->bone->segments > 1) && (flag & CONSTRAINT_BBONE_SHAPE)) { + else if (is_bbone) { /* use point along bbone */ Mat4 bbone[MAX_BBONE_SUBDIV]; float tempmat[4][4]; @@ -629,8 +632,18 @@ static void constraint_target_to_mat4(Object *ob, const char *substring, float m mul_v3_m4v3(loc, pchan->pose_mat, pt); } + /* apply full transformation of the segment if requested */ + if (full_bbone) { + int index = floorf(fac); + CLAMP(index, 0, pchan->bone->segments-1); + + mul_m4_m4m4(tempmat, pchan->pose_mat, bbone[index].mat); + } + else { + copy_m4_m4(tempmat, pchan->pose_mat); + } + /* use interpolated distance for subtarget */ - copy_m4_m4(tempmat, pchan->pose_mat); copy_v3_v3(tempmat[3], loc); mul_m4_m4m4(mat, ob->obmat, tempmat); @@ -701,6 +714,16 @@ static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph), bConstraint unit_m4(ct->matrix); } +/* This is a variant that extracts full transformation from B-Bone segments. + */ +static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph), bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime)) +{ + if (VALID_CONS_TARGET(ct)) + constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->flag | CONSTRAINT_BBONE_SHAPE_FULL, con->headtail); + else if (ct) + unit_m4(ct->matrix); +} + /* This following macro should be used for all standard single-target *_get_tars functions * to save typing and reduce maintenance woes. * (Hopefully all compilers will be happy with the lines with just a space on them. Those are @@ -1906,7 +1929,7 @@ static bConstraintTypeInfo CTI_TRANSLIKE = { NULL, /* new data */ translike_get_tars, /* get constraint targets */ translike_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ + default_get_tarmat_full_bbone, /* get target matrix */ translike_evaluate /* evaluate */ }; diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index e118fd39bb1..50f0b550201 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -528,6 +528,8 @@ typedef enum eBConstraint_Flags { CONSTRAINT_BBONE_SHAPE = (1<<10), /* That constraint has been inserted in local override (i.e. it can be fully edited!). */ CONSTRAINT_STATICOVERRIDE_LOCAL = (1 << 11), + /* use full transformation (not just segment locations) - only set at runtime */ + CONSTRAINT_BBONE_SHAPE_FULL = (1 << 12), } eBConstraint_Flags; /* bConstraint->ownspace/tarspace */ |