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
This commit is contained in:
Alexander Gavrilov 2018-07-09 22:25:44 +03:00
parent 47af343b61
commit 2aa26de378
2 changed files with 29 additions and 4 deletions

View File

@ -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 */
};

View File

@ -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 */