Stretch To: implement a mode similar to Damped Track for rotation.

Most of the time Stretch To is used in actual rigs, like BlenRig
or Rigify, in combination with Damped Track to handle rotation
before the stretch, because it produces rotations more appropriate
for organic deformation, and doesn't flip because of internal
gimbal lock.

The prevalence of this pattern suggests that Stretch To should
support that kind of rotation directly as an option.

Differential Revision: https://developer.blender.org/D6134
This commit is contained in:
Alexander Gavrilov 2019-11-06 17:11:32 +03:00
parent 4e5768b2a7
commit aadc90d0fc
4 changed files with 25 additions and 7 deletions

View File

@ -543,11 +543,14 @@ class ConstraintButtonsPanel:
col.active = con.use_bulge_min or con.use_bulge_max
col.prop(con, "bulge_smooth", text="Smooth")
row = layout.row()
row.label(text="Volume:")
split = layout.split(factor=0.3)
split.label(text="Volume:")
row = split.row()
row.prop(con, "volume", expand=True)
row.label(text="Plane:")
split = layout.split(factor=0.3)
split.label(text="Rotation:")
row = split.row()
row.prop(con, "keep_axis", expand=True)
def FLOOR(self, _context, layout, con):

View File

@ -3242,6 +3242,12 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
float dist, bulge;
/* Remove shear if using the Damped Track mode; the other modes
* do it as a side effect, which is relied on by rigs. */
if (data->plane == SWING_Y) {
orthogonalize_m4_stable(cob->matrix, 1, false);
}
/* store scaling before destroying obmat */
normalize_m4_ex(cob->matrix, size);
@ -3329,6 +3335,10 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
mul_v3_v3(size, scale);
switch (data->plane) {
case SWING_Y:
/* Point the Y axis using Damped Track math. */
damptrack_do_transform(cob->matrix, vec, TRACK_Y);
break;
case PLANE_X:
/* new Y aligns object target connection*/
copy_v3_v3(cob->matrix[1], vec);

View File

@ -930,7 +930,7 @@ typedef enum eStretchTo_VolMode {
/* Stretch To Constraint -> plane mode */
typedef enum eStretchTo_PlaneMode {
PLANE_X = 0,
PLANE_Y = 1,
SWING_Y = 1,
PLANE_Z = 2,
} eStretchTo_PlaneMode;

View File

@ -1811,8 +1811,13 @@ static void rna_def_constraint_stretch_to(BlenderRNA *brna)
};
static const EnumPropertyItem plane_items[] = {
{PLANE_X, "PLANE_X", 0, "X", "Keep X Axis"},
{PLANE_Z, "PLANE_Z", 0, "Z", "Keep Z Axis"},
{PLANE_X, "PLANE_X", 0, "XZ", "Rotate around local X, then Z"},
{PLANE_Z, "PLANE_Z", 0, "ZX", "Rotate around local Z, then X"},
{SWING_Y,
"SWING_Y",
0,
"Swing",
"Use the smallest single axis rotation, similar to Damped Track"},
{0, NULL, 0, NULL, NULL},
};
@ -1836,7 +1841,7 @@ static void rna_def_constraint_stretch_to(BlenderRNA *brna)
prop = RNA_def_property(srna, "keep_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "plane");
RNA_def_property_enum_items(prop, plane_items);
RNA_def_property_ui_text(prop, "Keep Axis", "Axis to maintain during stretch");
RNA_def_property_ui_text(prop, "Keep Axis", "The rotation type and axis order to use");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
prop = RNA_def_property(srna, "rest_length", PROP_FLOAT, PROP_DISTANCE);