Commit: 7de12d7847c168391ca96eb909c07639edbc0023 Author: Alexander Gavrilov Date: Tue Jun 15 13:52:23 2021 +0300 Branches: temp-angavrilov https://developer.blender.org/rB7de12d7847c168391ca96eb909c07639edbc0023
Armature: apply Y scale to B-Bone segments. This fixes a strange behavior where the segments were not actually scaled in the Y direction to match their actual length, thus producing gaps or overlap depending on the shape of the curve. For transformation the change should be very small if enough segments are used, but this will affect the results of the Copy Transforms and Armature constraints, so a backwards compatibility option is provided. Newly created bones default to the new behavior. =================================================================== M release/scripts/startup/bl_ui/properties_data_bone.py M source/blender/blenkernel/BKE_armature.h M source/blender/blenkernel/intern/armature.c M source/blender/draw/engines/overlay/overlay_armature.c M source/blender/makesdna/DNA_armature_types.h M source/blender/makesrna/intern/rna_armature.c =================================================================== diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index c842af9af88..3de439842b6 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -160,6 +160,8 @@ class BONE_PT_curved(BoneButtonsPanel, Panel): col.prop(bbone, "bbone_easeout", text="Out") col.prop(bone, "use_scale_easing") + topcol.prop(bone, "use_unscaled_segments") + col = topcol.column(align=True) col.prop(bone, "bbone_handle_type_start", text="Start Handle") diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index ee0f41937e2..2b217ca3025 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -469,7 +469,7 @@ typedef struct BBoneSplineParameters { float length; /* Non-uniform scale correction. */ - bool do_scale; + bool do_scale, do_scale_segments; float scale[3]; /* Handle control bone data. */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index f29074c827c..71c25cd1eb6 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -944,6 +944,8 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan, param->segments = bone->segments; param->length = bone->length; + param->do_scale_segments = (bone->bbone_flag & BBONE_SCALE_SEGMENTS) != 0; + if (!rest) { float scale[3]; @@ -1309,6 +1311,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, const float axis[3], float roll, float scalex, + float scaley, float scalez, float result[4][4]) { @@ -1326,6 +1329,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param, /* BBone scale... */ mul_v3_fl(result[0], scalex); + mul_v3_fl(result[1], scaley); mul_v3_fl(result[2], scalez); } @@ -1393,6 +1397,8 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, equalize_cubic_bezier( bezt_controls, MAX_BBONE_SUBDIV, param->segments, segment_scales, bezt_points); + const float scale_fac = param->segments / length; + /* Deformation uses N+1 matrices computed at points between the segments. */ if (for_deform) { /* Bezier derivatives. */ @@ -1405,6 +1411,32 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, sub_v3_v3v3(bezt_deriv2[i], bezt_deriv1[i + 1], bezt_deriv1[i]); } + /* Inner segment points. */ + float points[MAX_BBONE_SUBDIV][3], tangents[MAX_BBONE_SUBDIV][3]; + + copy_v3_v3(points[0], bezt_controls[0]); + + for (int a = 1; a < param->segments; a++) { + evaluate_cubic_bezier(bezt_controls, bezt_points[a], points[a], tangents[a]); + } + + /* Segment lengths. */ + float seg_length[MAX_BBONE_SUBDIV + 1]; + + if (param->do_scale_segments) { + for (int a = 1; a < param->segments; a++) { + seg_length[a] = len_v3v3(points[a - 1], points[a]) * scale_fac; + } + + seg_length[param->segments] = len_v3v3(points[param->segments - 1], bezt_controls[3]) * + scale_fac; + } + else { + for (int a = 1; a <= param->segments; a++) { + seg_length[a] = 1; + } + } + /* End points require special handling to fix zero length handles. */ ease_handle_axis(bezt_deriv1[0], bezt_deriv2[0], axis); make_bbone_spline_matrix(param, @@ -1413,19 +1445,26 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, axis, roll1, param->scale_in[0], + seg_length[1], param->scale_in[2], result_array[0].mat); for (int a = 1; a < param->segments; a++) { - evaluate_cubic_bezier(bezt_controls, bezt_points[a], cur, axis); - float fac = ((float)a) / param->segments; float roll = interpf(roll2, roll1, fac); float scalex = interpf(param->scale_out[0], param->scale_in[0], fac); float scalez = interpf(param->scale_out[2], param->scale_in[2], fac); + float scaley = sqrtf(seg_length[a] * seg_length[a + 1]); - make_bbone_spline_matrix( - param, scalemats, cur, axis, roll, scalex, scalez, result_array[a].mat); + make_bbone_spline_matrix(param, + scalemats, + points[a], + tangents[a], + roll, + scalex, + scaley, + scalez, + result_array[a].mat); } negate_v3(bezt_deriv2[1]); @@ -1436,6 +1475,7 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, axis, roll2, param->scale_out[0], + seg_length[param->segments], param->scale_out[2], result_array[param->segments].mat); } @@ -1452,9 +1492,10 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param, float roll = interpf(roll2, roll1, fac); float scalex = interpf(param->scale_out[0], param->scale_in[0], fac); float scalez = interpf(param->scale_out[2], param->scale_in[2], fac); + float scaley = param->do_scale_segments ? len_v3(axis) * scale_fac : 1; make_bbone_spline_matrix( - param, scalemats, prev, axis, roll, scalex, scalez, result_array[a].mat); + param, scalemats, prev, axis, roll, scalex, scaley, scalez, result_array[a].mat); copy_v3_v3(prev, cur); } } diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c index e38695c76ab..1c82a4971a7 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.c +++ b/source/blender/draw/engines/overlay/overlay_armature.c @@ -1267,6 +1267,8 @@ static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_B param.segments = ebone->segments; param.length = ebone->length; + param.do_scale_segments = !!(ebone->bbone_flag & BBONE_SCALE_SEGMENTS); + /* Get "next" and "prev" bones - these are used for handle calculations. */ if (ebone->bbone_prev_type == BBONE_HANDLE_AUTO) { /* Use connected parent. */ diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index f0ffb608942..8242f01bb37 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -292,6 +292,8 @@ typedef enum eBone_BBoneFlag { BBONE_ADD_PARENT_END_ROLL = (1 << 0), /** Multiply B-Bone easing values with Scale Length. */ BBONE_SCALE_EASING = (1 << 1), + /** Apply Y scale to B-Bone segments. */ + BBONE_SCALE_SEGMENTS = (1 << 2), } eBone_BBoneFlag; /* bone->bbone_prev/next_flag */ diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index a4094630266..e0a8969b7b7 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -740,6 +740,15 @@ void rna_def_bone_curved_common(StructRNA *srna, bool is_posebone, bool is_editb 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); + + prop = RNA_def_property(srna, "use_unscaled_segments", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, + "Unscaled Segments (Legacy)", + "Do not apply scaling necessary to fit segments to the curve length " + "without gaps or overlap for compatibility with old files"); + RNA_def_property_boolean_negative_sdna(prop, NULL, "bbone_flag", BBONE_SCALE_SEGMENTS); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_DEF_CURVEBONE_UPDATE(prop, is_posebone, is_editbone); } /* Scale In/Out */ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs