[Bf-blender-cvs] [9797b95f617] master: Animation: Pose sliding tools improvements

Christoph Lendenfeld noreply at git.blender.org
Fri May 14 11:02:21 CEST 2021


Commit: 9797b95f617561dc87b702e1bce829a551260689
Author: Christoph Lendenfeld
Date:   Fri May 14 10:46:19 2021 +0200
Branches: master
https://developer.blender.org/rB9797b95f617561dc87b702e1bce829a551260689

Animation: Pose sliding tools improvements

Improve the "In Betweens" tools:
- Push Pose from Rest Pose
- Relax Pose to Rest Pose
- Push Pose from Breakdown
- Relax Pose to Breakdown
- Pose Breakdowner

These all now use the same new sliding tool:
- Actual visual indication of the blending/pushing percentage applied.
- Mouse wrapping to allow for extrapolation without having to worry
  about the initial placement of the mouse. This also means these tools
  are actually usable when chosen from the menu.
- Precision mode by holding {key Shift}.
- Snapping to 10% increments by holding {key Ctrl}.
- Overshoot protection; by default the tool doesn't allow overshoot
  (lower than 0% or higher than 100%), and it can be enabled by pressing
  {key E}.
- Bones are hidden while sliding, so the pose itself can be seen more
  clearly. This can be toggled by pressing {key H} while using the tool.

Reviewed By: #animation_rigging, zeddb, sybren, #user_interface, brecht, Severin, looch

Maniphest Tasks: T81836

Differential Revision: https://developer.blender.org/D9054

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

M	source/blender/editors/armature/CMakeLists.txt
M	source/blender/editors/armature/pose_slide.c

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

diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt
index 98c050950be..7266b1b88d7 100644
--- a/source/blender/editors/armature/CMakeLists.txt
+++ b/source/blender/editors/armature/CMakeLists.txt
@@ -19,6 +19,7 @@ set(INC
   ../include
   ../../blenkernel
   ../../blenlib
+  ../../blenfont
   ../../blentranslation
   ../../depsgraph
   ../../gpu
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 93d36abe792..edac5dc61c9 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -33,6 +33,7 @@
 #include "DNA_armature_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_vec_types.h"
 
 #include "BKE_fcurve.h"
 #include "BKE_nla.h"
@@ -50,15 +51,28 @@
 #include "WM_types.h"
 
 #include "UI_interface.h"
+#include "UI_resources.h"
 
 #include "ED_armature.h"
 #include "ED_keyframes_draw.h"
 #include "ED_markers.h"
 #include "ED_numinput.h"
 #include "ED_screen.h"
+#include "ED_space_api.h"
+
+#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
+#include "GPU_matrix.h"
+#include "GPU_state.h"
 
 #include "armature_intern.h"
 
+#include "BLF_api.h"
+
+/* Pixel distance from 0% to 100%. */
+#define SLIDE_PIXEL_DISTANCE (300 * U.pixelsize)
+#define OVERSHOOT_RANGE_DELTA 0.2f
+
 /* **************************************************** */
 /* == POSE 'SLIDING' TOOLS ==
  *
@@ -110,15 +124,36 @@ typedef struct tPoseSlideOp {
   /** unused for now, but can later get used for storing runtime settings.... */
   short flag;
 
+  /* Store overlay settings when invoking the operator. Bones will be temporarily hidden. */
+  int overlay_flag;
+
   /** which transforms/channels are affected (ePoseSlide_Channels) */
   short channels;
   /** axis-limits for transforms (ePoseSlide_AxisLock) */
   short axislock;
 
-  /** 0-1 value for determining the influence of whatever is relevant */
+  /* Allow overshoot or clamp between 0% and 100%. */
+  bool overshoot;
+
+  /* Reduces percentage delta from mouse movement. */
+  bool precision;
+
+  /* Move percentage in 10% steps. */
+  bool increments;
+
+  /* Draw callback handler. */
+  void *draw_handle;
+
+  /* Accumulative, unclamped and unrounded percentage. */
+  float raw_percentage;
+
+  /* 0-1 value for determining the influence of whatever is relevant. */
   float percentage;
 
-  /** numeric input */
+  /* Last cursor position in screen space used for mouse movement delta calculation. */
+  int last_cursor_x;
+
+  /* Numeric input. */
   NumInput num;
 
   struct tPoseSlideObject *ob_data_array;
@@ -187,6 +222,240 @@ static const EnumPropertyItem prop_axis_lock_types[] = {
 
 /* ------------------------------------ */
 
+static void draw_overshoot_triangle(const uint8_t color[4],
+                                    const bool facing_right,
+                                    const float x,
+                                    const float y)
+{
+  const uint shdr_pos_2d = GPU_vertformat_attr_add(
+      immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+  immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+  GPU_blend(GPU_BLEND_ALPHA);
+  GPU_polygon_smooth(true);
+  immUniformColor3ubvAlpha(color, 225);
+  const float triangle_side_length = facing_right ? 6 * U.pixelsize : -6 * U.pixelsize;
+  const float triangle_offset = facing_right ? 2 * U.pixelsize : -2 * U.pixelsize;
+
+  immBegin(GPU_PRIM_TRIS, 3);
+  immVertex2f(shdr_pos_2d, x + triangle_offset + triangle_side_length, y);
+  immVertex2f(shdr_pos_2d, x + triangle_offset, y + triangle_side_length / 2);
+  immVertex2f(shdr_pos_2d, x + triangle_offset, y - triangle_side_length / 2);
+  immEnd();
+
+  GPU_polygon_smooth(false);
+  GPU_blend(GPU_BLEND_NONE);
+  immUnbindProgram();
+}
+
+static void draw_ticks(const float start_percentage,
+                       const float end_percentage,
+                       const struct vec2f line_start,
+                       const float base_tick_height,
+                       const float line_width,
+                       const uint8_t color_overshoot[4],
+                       const uint8_t color_line[4])
+{
+  /* Use percentage represented as 0-100 int to avoid floating point precision problems. */
+  const int tick_increment = 10;
+
+  /* Round initial_tick_percentage up to the next tick_increment. */
+  int tick_percentage = ceil((start_percentage * 100) / tick_increment) * tick_increment;
+  float tick_height = base_tick_height;
+
+  while (tick_percentage <= (int)(end_percentage * 100)) {
+    /* Different ticks have different heights. Multiples of 100% are the tallest, 50% is a bit
+     * smaller and the rest is the minimum size. */
+    if (tick_percentage % 100 == 0) {
+      tick_height = base_tick_height;
+    }
+    else if (tick_percentage % 50 == 0) {
+      tick_height = base_tick_height * 0.8;
+    }
+    else {
+      tick_height = base_tick_height * 0.5;
+    }
+
+    const float x = line_start.x +
+                    (((float)tick_percentage / 100) - start_percentage) * SLIDE_PIXEL_DISTANCE;
+    const struct rctf tick_rect = {.xmin = x - (line_width / 2),
+                                   .xmax = x + (line_width / 2),
+                                   .ymin = line_start.y - (tick_height / 2),
+                                   .ymax = line_start.y + (tick_height / 2)};
+
+    if (tick_percentage < 0 || tick_percentage > 100) {
+      UI_draw_roundbox_3ub_alpha(&tick_rect, true, 1, color_overshoot, 255);
+    }
+    else {
+      UI_draw_roundbox_3ub_alpha(&tick_rect, true, 1, color_line, 255);
+    }
+    tick_percentage += tick_increment;
+  }
+}
+
+static void draw_main_line(const struct rctf main_line_rect, 
+                           const float percentage,
+                           const bool overshoot,
+                           const uint8_t color_overshoot[4],
+                           const uint8_t color_line[4])
+{
+  if (overshoot) {
+    /* In overshoot mode, draw the 0-100% range differently to provide a visual reference. */
+    const float line_zero_percent = main_line_rect.xmin -
+                                    ((percentage - 0.5f - OVERSHOOT_RANGE_DELTA) *
+                                     SLIDE_PIXEL_DISTANCE);
+
+    const float clamped_line_zero_percent = clamp_f(
+        line_zero_percent, main_line_rect.xmin, main_line_rect.xmax);
+    const float clamped_line_hundred_percent = clamp_f(
+        line_zero_percent + SLIDE_PIXEL_DISTANCE, main_line_rect.xmin, main_line_rect.xmax);
+
+    const struct rctf left_overshoot_line_rect = {.xmin = main_line_rect.xmin,
+                                                  .xmax = clamped_line_zero_percent,
+                                                  .ymin = main_line_rect.ymin,
+                                                  .ymax = main_line_rect.ymax};
+    const struct rctf right_overshoot_line_rect = {.xmin = clamped_line_hundred_percent,
+                                                   .xmax = main_line_rect.xmax,
+                                                   .ymin = main_line_rect.ymin,
+                                                   .ymax = main_line_rect.ymax};
+    UI_draw_roundbox_3ub_alpha(&left_overshoot_line_rect, true, 0, color_overshoot, 255);
+    UI_draw_roundbox_3ub_alpha(&right_overshoot_line_rect, true, 0, color_overshoot, 255);
+
+    const struct rctf non_overshoot_line_rect = {.xmin = clamped_line_zero_percent,
+                                                 .xmax = clamped_line_hundred_percent,
+                                                 .ymin = main_line_rect.ymin,
+                                                 .ymax = main_line_rect.ymax};
+    UI_draw_roundbox_3ub_alpha(&non_overshoot_line_rect, true, 0, color_line, 255);
+  }
+  else {
+    UI_draw_roundbox_3ub_alpha(&main_line_rect, true, 0, color_line, 255);
+  }
+}
+
+static void draw_backdrop(const int fontid,
+                          const struct rctf main_line_rect,
+                          const float color_bg[4],
+                          const short region_y_size,
+                          const float base_tick_height)
+{
+  float string_pixel_size[2];
+  const char *percentage_placeholder = "000%%";
+  BLF_width_and_height(fontid,
+                       percentage_placeholder,
+                       sizeof(percentage_placeholder),
+                       &string_pixel_size[0],
+                       &string_pixel_size[1]);
+  const struct vec2f pad = {.x = (region_y_size - base_tick_height) / 2, .y = 2.0f * U.pixelsize};
+  const struct rctf backdrop_rect = {.xmin = main_line_rect.xmin - string_pixel_size[0] - pad.x,
+                                     .xmax = main_line_rect.xmax + pad.x,
+                                     .ymin = pad.y,
+                                     .ymax = region_y_size - pad.y};
+  UI_draw_roundbox_aa(&backdrop_rect, true, 4.0f, color_bg);
+}
+
+/* Draw an on screen Slider for a Pose Slide Operator. */
+static void pose_slide_draw_2d_slider(const struct bContext *UNUSED(C), ARegion *region, void *arg)
+{
+  tPoseSlideOp *pso = arg;
+
+  /* Only draw in region from which the Operator was started. */
+  if (region != pso->region) {
+    return;
+  }
+
+  uint8_t color_text[4];
+  uint8_t color_line[4];
+  uint8_t color_handle[4];
+  uint8_t color_overshoot[4];
+  float color_bg[4];
+
+  /* Get theme colors. */
+  UI_GetThemeColor4ubv(TH_TEXT, color_text);
+  UI_GetThemeColor4ubv(TH_TEXT, color_line);
+  UI_GetThemeColor4ubv(TH_TEXT, color_overshoot);
+  UI_GetThemeColor4ubv(TH_ACTIVE, color_handle);
+  UI_GetThemeColor3fv(TH_BACK, color_bg);
+
+  color_bg[3] = 0.5f;
+  color_overshoot[0] = color_overshoot[0] * 0.7;
+  color_overshoot[1] = color_overshoot[1] * 0.7;
+  color_overshoot[2] = color_overshoot[2] * 0.7;
+
+  /* Get the default font. */
+  const uiStyle *style = UI_style_get();
+  const uiFontStyle *fstyle = &style->widget;
+  const int fontid = fstyle->uifont_id;
+  BLF_color3ubv(fontid, color_text);
+  BLF_rotation(fontid, 0.0f);
+
+  const float line_width = 1.5 * U.pixelsize;
+  const float base_tick_height = 12.0 * U.pixel

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list