Armature: add automatic B-Bone Scale toggles.
Currently B-Bone scaling can only be controlled via their properties, thus requiring up to 8 drivers per joint between B-Bones to transfer scaling factors from the handle bone. A Scale Easing option is added to multiply the easing value by the Y scale channels to synchronize them - this produces a natural scaling effect where both the shape of the curve and the scale is affected. In addition, four toggles are added for each handle, which multiply each of the X, Y, Z and Ease values by the matching Local Scale channel of the handle bone, thus replacing trivial drivers. The Scale Easing option has no effect on this process since it's easy to just enable both Length and Ease buttons. Differential Revision: https://developer.blender.org/D9870
This commit is contained in:
parent
638c16f410
commit
b6030711a2
Notes:
blender-bot
2023-02-14 06:42:53 +01:00
Referenced by issue #89621, Bendy bones saved in 3.0 break in older versions Referenced by issue #89361, Bendy bones fail to version in this one file Referenced by issue #83908, Streamlining advanced rigging of B-Bone chains.
|
@ -176,20 +176,47 @@ class BONE_PT_curved(BoneButtonsPanel, Panel):
|
|||
col = topcol.column(align=True)
|
||||
col.prop(bbone, "bbone_easein", text="Ease In")
|
||||
col.prop(bbone, "bbone_easeout", text="Out")
|
||||
col.prop(bone, "use_scale_easing")
|
||||
|
||||
col = topcol.column(align=True)
|
||||
col.prop(bone, "bbone_handle_type_start", text="Start Handle")
|
||||
|
||||
col = col.column(align=True)
|
||||
col.active = (bone.bbone_handle_type_start != 'AUTO')
|
||||
col.prop_search(bone, "bbone_custom_handle_start", arm, bone_list, text="Custom")
|
||||
col2 = col.column(align=True)
|
||||
col2.active = (bone.bbone_handle_type_start != 'AUTO')
|
||||
col2.prop_search(bone, "bbone_custom_handle_start", arm, bone_list, text="Custom")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.use_property_split = False
|
||||
split = row.split(factor=0.4)
|
||||
split.alignment = 'RIGHT'
|
||||
split.label(text="Scale")
|
||||
split2 = split.split(factor=0.7)
|
||||
row2 = split2.row(align=True)
|
||||
row2.prop(bone, "bbone_handle_use_scale_start", index=0, text="X", toggle=True)
|
||||
row2.prop(bone, "bbone_handle_use_scale_start", index=1, text="Y", toggle=True)
|
||||
row2.prop(bone, "bbone_handle_use_scale_start", index=2, text="Z", toggle=True)
|
||||
split2.prop(bone, "bbone_handle_use_ease_start", text="Ease", toggle=True)
|
||||
row.label(icon="BLANK1")
|
||||
|
||||
col = topcol.column(align=True)
|
||||
col.prop(bone, "bbone_handle_type_end", text="End Handle")
|
||||
|
||||
col = col.column(align=True)
|
||||
col.active = (bone.bbone_handle_type_end != 'AUTO')
|
||||
col.prop_search(bone, "bbone_custom_handle_end", arm, bone_list, text="Custom")
|
||||
col2 = col.column(align=True)
|
||||
col2.active = (bone.bbone_handle_type_end != 'AUTO')
|
||||
col2.prop_search(bone, "bbone_custom_handle_end", arm, bone_list, text="Custom")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.use_property_split = False
|
||||
split = row.split(factor=0.4)
|
||||
split.alignment = 'RIGHT'
|
||||
split.label(text="Scale")
|
||||
split2 = split.split(factor=0.7)
|
||||
row2 = split2.row(align=True)
|
||||
row2.prop(bone, "bbone_handle_use_scale_end", index=0, text="X", toggle=True)
|
||||
row2.prop(bone, "bbone_handle_use_scale_end", index=1, text="Y", toggle=True)
|
||||
row2.prop(bone, "bbone_handle_use_scale_end", index=2, text="Z", toggle=True)
|
||||
split2.prop(bone, "bbone_handle_use_ease_end", text="Ease", toggle=True)
|
||||
row.label(icon="BLANK1")
|
||||
|
||||
|
||||
class BONE_PT_relations(BoneButtonsPanel, Panel):
|
||||
|
|
|
@ -959,7 +959,7 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
|
|||
{
|
||||
bPoseChannel *next, *prev;
|
||||
Bone *bone = pchan->bone;
|
||||
float imat[4][4], posemat[4][4];
|
||||
float imat[4][4], posemat[4][4], tmpmat[4][4];
|
||||
float delta[3];
|
||||
|
||||
memset(param, 0, sizeof(*param));
|
||||
|
@ -996,6 +996,11 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
|
|||
invert_m4_m4(imat, pchan->pose_mat);
|
||||
}
|
||||
|
||||
float prev_scale[3], next_scale[3];
|
||||
|
||||
copy_v3_fl(prev_scale, 1.0f);
|
||||
copy_v3_fl(next_scale, 1.0f);
|
||||
|
||||
if (prev) {
|
||||
float h1[3];
|
||||
bool done = false;
|
||||
|
@ -1041,6 +1046,12 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
|
|||
if (!param->prev_bbone) {
|
||||
/* Find the previous roll to interpolate. */
|
||||
mul_m4_m4m4(param->prev_mat, imat, rest ? prev->bone->arm_mat : prev->pose_mat);
|
||||
|
||||
/* Retrieve the local scale of the bone if necessary. */
|
||||
if ((bone->bbone_prev_flag & BBONE_HANDLE_SCALE_ANY) && !rest) {
|
||||
BKE_armature_mat_pose_to_bone(prev, prev->pose_mat, tmpmat);
|
||||
mat4_to_size(prev_scale, tmpmat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1088,6 +1099,12 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
|
|||
|
||||
/* Find the next roll to interpolate as well. */
|
||||
mul_m4_m4m4(param->next_mat, imat, rest ? next->bone->arm_mat : next->pose_mat);
|
||||
|
||||
/* Retrieve the local scale of the bone if necessary. */
|
||||
if ((bone->bbone_next_flag & BBONE_HANDLE_SCALE_ANY) && !rest) {
|
||||
BKE_armature_mat_pose_to_bone(next, next->pose_mat, tmpmat);
|
||||
mat4_to_size(next_scale, tmpmat);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add effects from bbone properties over the top
|
||||
|
@ -1137,6 +1154,47 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
|
|||
|
||||
param->curve_out_x = bone->curve_out_x + (!rest ? pchan->curve_out_x : 0.0f);
|
||||
param->curve_out_z = bone->curve_out_z + (!rest ? pchan->curve_out_z : 0.0f);
|
||||
|
||||
if (bone->bbone_flag & BBONE_SCALE_EASING) {
|
||||
param->ease1 *= param->scale_in[1];
|
||||
param->curve_in_x *= param->scale_in[1];
|
||||
param->curve_in_z *= param->scale_in[1];
|
||||
|
||||
param->ease2 *= param->scale_out[1];
|
||||
param->curve_out_x *= param->scale_out[1];
|
||||
param->curve_out_z *= param->scale_out[1];
|
||||
}
|
||||
|
||||
/* Custom handle scale. */
|
||||
if (bone->bbone_prev_flag & BBONE_HANDLE_SCALE_X) {
|
||||
param->scale_in[0] *= prev_scale[0];
|
||||
}
|
||||
if (bone->bbone_prev_flag & BBONE_HANDLE_SCALE_Y) {
|
||||
param->scale_in[1] *= prev_scale[1];
|
||||
}
|
||||
if (bone->bbone_prev_flag & BBONE_HANDLE_SCALE_Z) {
|
||||
param->scale_in[2] *= prev_scale[2];
|
||||
}
|
||||
if (bone->bbone_prev_flag & BBONE_HANDLE_SCALE_EASE) {
|
||||
param->ease1 *= prev_scale[1];
|
||||
param->curve_in_x *= prev_scale[1];
|
||||
param->curve_in_z *= prev_scale[1];
|
||||
}
|
||||
|
||||
if (bone->bbone_next_flag & BBONE_HANDLE_SCALE_X) {
|
||||
param->scale_out[0] *= next_scale[0];
|
||||
}
|
||||
if (bone->bbone_next_flag & BBONE_HANDLE_SCALE_Y) {
|
||||
param->scale_out[1] *= next_scale[1];
|
||||
}
|
||||
if (bone->bbone_next_flag & BBONE_HANDLE_SCALE_Z) {
|
||||
param->scale_out[2] *= next_scale[2];
|
||||
}
|
||||
if (bone->bbone_next_flag & BBONE_HANDLE_SCALE_EASE) {
|
||||
param->ease2 *= next_scale[1];
|
||||
param->curve_out_x *= next_scale[1];
|
||||
param->curve_out_z *= next_scale[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1180,6 +1180,16 @@ static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_B
|
|||
param.curve_out_x = ebone->curve_out_x;
|
||||
param.curve_out_z = ebone->curve_out_z;
|
||||
|
||||
if (ebone->bbone_flag & BBONE_SCALE_EASING) {
|
||||
param.ease1 *= param.scale_in[1];
|
||||
param.curve_in_x *= param.scale_in[1];
|
||||
param.curve_in_z *= param.scale_in[1];
|
||||
|
||||
param.ease2 *= param.scale_out[1];
|
||||
param.curve_out_x *= param.scale_out[1];
|
||||
param.curve_out_z *= param.scale_out[1];
|
||||
}
|
||||
|
||||
ebone->segments = BKE_pchan_bbone_spline_compute(¶m, false, (Mat4 *)result_array);
|
||||
}
|
||||
|
||||
|
|
|
@ -302,8 +302,25 @@ typedef enum eBone_BBoneHandleType {
|
|||
typedef enum eBone_BBoneFlag {
|
||||
/** Add the parent Out roll to the In roll. */
|
||||
BBONE_ADD_PARENT_END_ROLL = (1 << 0),
|
||||
/** Multiply B-Bone easing values with Scale Length. */
|
||||
BBONE_SCALE_EASING = (1 << 1),
|
||||
} eBone_BBoneFlag;
|
||||
|
||||
/* bone->bbone_prev/next_flag */
|
||||
typedef enum eBone_BBoneHandleFlag {
|
||||
/** Use handle bone scaling for scale X. */
|
||||
BBONE_HANDLE_SCALE_X = (1 << 0),
|
||||
/** Use handle bone scaling for scale Y (length). */
|
||||
BBONE_HANDLE_SCALE_Y = (1 << 1),
|
||||
/** Use handle bone scaling for scale Z. */
|
||||
BBONE_HANDLE_SCALE_Z = (1 << 2),
|
||||
/** Use handle bone scaling for easing. */
|
||||
BBONE_HANDLE_SCALE_EASE = (1 << 3),
|
||||
/** Is handle scale required? */
|
||||
BBONE_HANDLE_SCALE_ANY = BBONE_HANDLE_SCALE_X | BBONE_HANDLE_SCALE_Y | BBONE_HANDLE_SCALE_Z |
|
||||
BBONE_HANDLE_SCALE_EASE,
|
||||
} eBone_BBoneHandleFlag;
|
||||
|
||||
#define MAXBONENAME 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -769,6 +769,13 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone, bool is_editb
|
|||
RNA_def_property_ui_text(prop, "Ease Out", "Length of second Bezier Handle (for B-Bones only)");
|
||||
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
|
||||
|
||||
if (is_posebone == false) {
|
||||
prop = RNA_def_property(srna, "use_scale_easing", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Scale Easing", "Multiply the final easing values by the Scale In/Out Y factors");
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "bbone_flag", BBONE_SCALE_EASING);
|
||||
RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone);
|
||||
}
|
||||
|
||||
/* Scale In/Out */
|
||||
prop = RNA_def_property(srna, "bbone_scalein", PROP_FLOAT, PROP_XYZ);
|
||||
|
@ -1053,6 +1060,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
|
|||
RNA_def_property_ui_range(prop, 0.0f, 1000.0f, 1, RNA_TRANSLATION_PREC_DEFAULT);
|
||||
RNA_def_property_ui_text(prop, "B-Bone Display Z Width", "B-Bone Z size");
|
||||
|
||||
/* B-Bone Start Handle settings. */
|
||||
prop = RNA_def_property(srna, "bbone_handle_type_start", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "bbone_prev_type");
|
||||
RNA_def_property_enum_items(prop, prop_bbone_handle_type);
|
||||
|
@ -1077,6 +1085,26 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
|
|||
RNA_def_property_ui_text(
|
||||
prop, "B-Bone Start Handle", "Bone that serves as the start handle for the B-Bone curve");
|
||||
|
||||
prop = RNA_def_property(srna, "bbone_handle_use_scale_start", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Start Handle Scale",
|
||||
"Multiply B-Bone Scale In channels by the local scale values of the start handle. "
|
||||
"This is done after the Scale Easing option and isn't affected by it");
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "bbone_prev_flag", BBONE_HANDLE_SCALE_X);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "bbone_handle_use_ease_start", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Start Handle Ease",
|
||||
"Multiply the B-Bone Ease In channel by the local Y scale value of the start handle. "
|
||||
"This is done after the Scale Easing option and isn't affected by it");
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "bbone_prev_flag", BBONE_HANDLE_SCALE_EASE);
|
||||
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
|
||||
|
||||
/* B-Bone End Handle settings. */
|
||||
prop = RNA_def_property(srna, "bbone_handle_type_end", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "bbone_next_type");
|
||||
RNA_def_property_enum_items(prop, prop_bbone_handle_type);
|
||||
|
@ -1101,6 +1129,25 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
|
|||
RNA_def_property_ui_text(
|
||||
prop, "B-Bone End Handle", "Bone that serves as the end handle for the B-Bone curve");
|
||||
|
||||
prop = RNA_def_property(srna, "bbone_handle_use_scale_end", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"End Handle Scale",
|
||||
"Multiply B-Bone Scale Out channels by the local scale values of the end handle. "
|
||||
"This is done after the Scale Easing option and isn't affected by it");
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "bbone_next_flag", BBONE_HANDLE_SCALE_X);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
|
||||
|
||||
prop = RNA_def_property(srna, "bbone_handle_use_ease_end", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"End Handle Ease",
|
||||
"Multiply the B-Bone Ease Out channel by the local Y scale value of the end handle. "
|
||||
"This is done after the Scale Easing option and isn't affected by it");
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "bbone_next_flag", BBONE_HANDLE_SCALE_EASE);
|
||||
RNA_def_property_update(prop, 0, "rna_Armature_update_data");
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue