[Bf-blender-cvs] [ddc3edb91da] temp-angavrilov-constraints: Experimental: add B-Bone lengthwise scaling options.

Alexander Gavrilov noreply at git.blender.org
Fri Dec 11 17:19:22 CET 2020


Commit: ddc3edb91dac6da0e9bb7661f2dcc589f111f609
Author: Alexander Gavrilov
Date:   Fri Dec 11 19:17:39 2020 +0300
Branches: temp-angavrilov-constraints
https://developer.blender.org/rBddc3edb91dac6da0e9bb7661f2dcc589f111f609

Experimental: add B-Bone lengthwise scaling options.

- Lengthwise scale factors in addition to X and Y.
- Option to multiply ease by the length scale.
- Option to actually apply Y scale to segments (for backward compat).

===================================================================

M	release/scripts/startup/bl_ui/properties_data_bone.py
M	source/blender/blenkernel/BKE_armature.h
M	source/blender/blenkernel/intern/action.c
M	source/blender/blenkernel/intern/armature.c
M	source/blender/blenloader/intern/versioning_290.c
M	source/blender/draw/engines/overlay/overlay_armature.c
M	source/blender/editors/armature/armature_add.c
M	source/blender/editors/armature/armature_intern.h
M	source/blender/editors/armature/armature_utils.c
M	source/blender/editors/armature/pose_transform.c
M	source/blender/editors/armature/pose_utils.c
M	source/blender/makesdna/DNA_action_types.h
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 170d7910339..cd2baee84d7 100644
--- a/release/scripts/startup/bl_ui/properties_data_bone.py
+++ b/release/scripts/startup/bl_ui/properties_data_bone.py
@@ -170,14 +170,19 @@ class BONE_PT_curved(BoneButtonsPanel, Panel):
         col = topcol.column(align=True)
         col.prop(bbone, "bbone_scaleinx", text="Scale In X")
         col.prop(bbone, "bbone_scaleiny", text="In Y")
+        col.prop(bbone, "bbone_scalein_len", text="In Len")
 
         col = topcol.column(align=True)
         col.prop(bbone, "bbone_scaleoutx", text="Scale Out X")
         col.prop(bbone, "bbone_scaleouty", text="Out Y")
+        col.prop(bbone, "bbone_scaleout_len", text="Out Len")
+
+        topcol.prop(bone, "use_scale_segments")
 
         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")
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index db44a771095..ecb4acf3fa7 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -81,8 +81,8 @@ typedef struct EditBone {
   float curve_in_x, curve_in_y;
   float curve_out_x, curve_out_y;
   float ease1, ease2;
-  float scale_in_x, scale_in_y;
-  float scale_out_x, scale_out_y;
+  float scale_in_x, scale_in_y, scale_in_len;
+  float scale_out_x, scale_out_y, scale_out_len;
 
   /** for envelope scaling */
   float oldlength;
@@ -281,7 +281,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. */
@@ -294,7 +294,7 @@ typedef struct BBoneSplineParameters {
   /* Control values. */
   float ease1, ease2;
   float roll1, roll2;
-  float scale_in_x, scale_in_y, scale_out_x, scale_out_y;
+  float scale_in_x, scale_in_y, scale_in_len, scale_out_x, scale_out_y, scale_out_len;
   float curve_in_x, curve_in_y, curve_out_x, curve_out_y;
 } BBoneSplineParameters;
 
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 499f81f3669..0aa4abea594 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -648,8 +648,8 @@ bPoseChannel *BKE_pose_channel_verify(bPose *pose, const char *name)
   unit_axis_angle(chan->rotAxis, &chan->rotAngle);
   chan->size[0] = chan->size[1] = chan->size[2] = 1.0f;
 
-  chan->scale_in_x = chan->scale_in_y = 1.0f;
-  chan->scale_out_x = chan->scale_out_y = 1.0f;
+  chan->scale_in_x = chan->scale_in_y = chan->scale_in_len = 1.0f;
+  chan->scale_out_x = chan->scale_out_y = chan->scale_out_len = 1.0f;
 
   chan->limitmin[0] = chan->limitmin[1] = chan->limitmin[2] = -M_PI;
   chan->limitmax[0] = chan->limitmax[1] = chan->limitmax[2] = M_PI;
@@ -1662,8 +1662,8 @@ void BKE_pose_rest(bPose *pose, bool selected_bones_only)
     pchan->curve_in_x = pchan->curve_in_y = 0.0f;
     pchan->curve_out_x = pchan->curve_out_y = 0.0f;
     pchan->ease1 = pchan->ease2 = 0.0f;
-    pchan->scale_in_x = pchan->scale_in_y = 1.0f;
-    pchan->scale_out_x = pchan->scale_out_y = 1.0f;
+    pchan->scale_in_x = pchan->scale_in_y = pchan->scale_in_len = 1.0f;
+    pchan->scale_out_x = pchan->scale_out_y = pchan->scale_in_len = 1.0f;
 
     pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
   }
@@ -1693,8 +1693,10 @@ void BKE_pose_copy_pchan_result(bPoseChannel *pchanto, const bPoseChannel *pchan
   pchanto->ease2 = pchanfrom->ease2;
   pchanto->scale_in_x = pchanfrom->scale_in_x;
   pchanto->scale_in_y = pchanfrom->scale_in_y;
+  pchanto->scale_in_len = pchanfrom->scale_in_len;
   pchanto->scale_out_x = pchanfrom->scale_out_x;
   pchanto->scale_out_y = pchanfrom->scale_out_y;
+  pchanto->scale_out_len = pchanfrom->scale_out_len;
 
   pchanto->rotmode = pchanfrom->rotmode;
   pchanto->flag = pchanfrom->flag;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index bd544badfcb..54ef0a309c8 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -850,6 +850,7 @@ bool bone_autoside_name(
 static void equalize_cubic_bezier(const float control[4][3],
                                   int temp_segments,
                                   int final_segments,
+                                  const float *segment_scales,
                                   float *r_t_points)
 {
   float(*coords)[3] = BLI_array_alloca(coords, temp_segments + 1);
@@ -874,12 +875,26 @@ static void equalize_cubic_bezier(const float control[4][3],
   }
 
   /* Go over distances and calculate new parameter values. */
-  float dist_step = pdist[temp_segments] / final_segments;
+  float dist_step = pdist[temp_segments];
+  float dist = 0;
 
   r_t_points[0] = 0.0f;
 
+  if (segment_scales) {
+    float sum = 0.0f;
+
+    for (int i = 0; i < final_segments; i++) {
+      sum += segment_scales[i];
+    }
+
+    dist_step /= sum;
+  }
+  else {
+    dist_step /= final_segments;
+  }
+
   for (int i = 1, nr = 1; i <= final_segments; i++) {
-    float dist = i * dist_step;
+    dist += (segment_scales ? segment_scales[i - 1] : 1) * dist_step;
 
     /* We're looking for location (distance) 'dist' in the array. */
     while ((nr < temp_segments) && (dist >= pdist[nr])) {
@@ -956,6 +971,8 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
   param->segments = bone->segments;
   param->length = bone->length;
 
+  param->do_scale_segments = !!(bone->flag & BONE_SCALE_SEGMENTS);
+
   if (!rest) {
     float scale[3];
 
@@ -1114,8 +1131,10 @@ void BKE_pchan_bbone_spline_params_get(struct bPoseChannel *pchan,
 
     param->scale_in_x = bone->scale_in_x * (!rest ? pchan->scale_in_x : 1.0f);
     param->scale_in_y = bone->scale_in_y * (!rest ? pchan->scale_in_y : 1.0f);
+    param->scale_in_len = bone->scale_in_len * (!rest ? pchan->scale_in_len : 1.0f);
     param->scale_out_x = bone->scale_out_x * (!rest ? pchan->scale_out_x : 1.0f);
     param->scale_out_y = bone->scale_out_y * (!rest ? pchan->scale_out_y : 1.0f);
+    param->scale_out_len = bone->scale_out_len * (!rest ? pchan->scale_out_len : 1.0f);
 
     /* Extra curve x / y */
     param->curve_in_x = bone->curve_in_x + (!rest ? pchan->curve_in_x : 0.0f);
@@ -1123,6 +1142,16 @@ 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_y = bone->curve_out_y + (!rest ? pchan->curve_out_y : 0.0f);
+
+    if (bone->flag & BONE_SCALE_EASING) {
+      param->ease1 *= param->scale_in_len;
+      param->curve_in_x *= param->scale_in_len;
+      param->curve_in_y *= param->scale_in_len;
+
+      param->ease2 *= param->scale_out_len;
+      param->curve_out_x *= param->scale_out_len;
+      param->curve_out_y *= param->scale_out_len;
+    }
   }
 }
 
@@ -1264,6 +1293,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param,
                                      float roll,
                                      float scalex,
                                      float scaley,
+                                     float scale_len,
                                      float result[4][4])
 {
   float mat3[3][3];
@@ -1280,6 +1310,7 @@ static void make_bbone_spline_matrix(BBoneSplineParameters *param,
 
   /* BBone scale... */
   mul_v3_fl(result[0], scalex);
+  mul_v3_fl(result[1], scale_len);
   mul_v3_fl(result[2], scaley);
 }
 
@@ -1326,9 +1357,23 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param,
   copy_v3_v3(bezt_controls[1], h1);
   zero_v3(bezt_controls[0]);
 
+  /* Compute lengthwise segment scale. */
+  const float scale_fac = param->segments / length;
+  float segment_scales[MAX_BBONE_SUBDIV];
+
+  CLAMP_MIN(param->scale_in_len, 0.0001f);
+  CLAMP_MIN(param->scale_out_len, 0.0001f);
+
+  for (int i = 0; i < param->segments; i++) {
+    float fac = (0.5f + i) / param->segments;
+    segment_scales[i] = interpf(param->scale_out_len, param->scale_in_len, fac);
+  }
+
+  /* Compute segment vertex offsets along the curve length. */
   float bezt_points[MAX_BBONE_SUBDIV + 1];
 
-  equalize_cubic_bezier(bezt_controls, MAX_BBONE_SUBDIV, param->segments, bezt_points);
+  equalize_cubic_bezier(
+      bezt_controls, MAX_BBONE_SUBDIV, param->segments, segment_scales, bezt_points);
 
   /* Deformation uses N+1 matrices computed at points between the segments. */
   if (for_deform) {
@@ -1342,6 +1387,20 @@ 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];
+    float seg_length[MAX_BBONE_SUBDIV + 1];
+
+    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]);
+
+      seg_length[a] = len_v3v3(points[a - 1], points[a]);
+    }
+
+    seg_length[param->segments] = len_v3v3(points[param->segments - 1], bezt_controls[3]);
+
     /* 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,
@@ -1351,18 +1410,25 @@ int BKE_pchan_bbone_spline_compute(BBoneSplineParameters *param,
                              roll1,
                              param->scale_in_x,
                              param->scale_in_y,
+                             param->do_scale_segments ? seg_length[1] * scale_fac : 1,
                              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;
    

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list