[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