diff options
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 342 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_draw.c | 114 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_draw.h | 0 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_draw_cursors.c | 340 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_draw_cursors.h | 31 |
7 files changed, 525 insertions, 306 deletions
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index 5853574dced..6f39a8c3b9c 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -59,6 +59,7 @@ set(SRC transform_convert_sculpt.c transform_convert_sequencer.c transform_convert_tracking.c + transform_draw_cursors.c transform_generics.c transform_gizmo_2d.c transform_gizmo_3d.c @@ -71,6 +72,7 @@ set(SRC transform.h transform_convert.h + transform_draw_cursors.h transform_snap.h ) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 719064ba1d6..7112444655b 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -95,6 +95,7 @@ #include "transform.h" #include "transform_convert.h" +#include "transform_draw_cursors.h" #include "transform_snap.h" /* Disabling, since when you type you know what you are doing, @@ -1684,299 +1685,6 @@ bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], floa return success; } -typedef enum { - UP, - DOWN, - LEFT, - RIGHT, -} ArrowDirection; - -#define POS_INDEX 0 -/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions - * private to this file - merwin - */ - -static void drawArrow(ArrowDirection d, short offset, short length, short size) -{ - immBegin(GPU_PRIM_LINES, 6); - - offset = round_fl_to_short(UI_DPI_FAC * offset); - length = round_fl_to_short(UI_DPI_FAC * length); - size = round_fl_to_short(UI_DPI_FAC * size); - - switch (d) { - case LEFT: - offset = -offset; - length = -length; - size = -size; - ATTR_FALLTHROUGH; - case RIGHT: - immVertex2f(POS_INDEX, offset, 0); - immVertex2f(POS_INDEX, offset + length, 0); - immVertex2f(POS_INDEX, offset + length, 0); - immVertex2f(POS_INDEX, offset + length - size, -size); - immVertex2f(POS_INDEX, offset + length, 0); - immVertex2f(POS_INDEX, offset + length - size, size); - break; - - case DOWN: - offset = -offset; - length = -length; - size = -size; - ATTR_FALLTHROUGH; - case UP: - immVertex2f(POS_INDEX, 0, offset); - immVertex2f(POS_INDEX, 0, offset + length); - immVertex2f(POS_INDEX, 0, offset + length); - immVertex2f(POS_INDEX, -size, offset + length - size); - immVertex2f(POS_INDEX, 0, offset + length); - immVertex2f(POS_INDEX, size, offset + length - size); - break; - } - - immEnd(); -} - -static void drawArrowHead(ArrowDirection d, short size) -{ - size = round_fl_to_short(UI_DPI_FAC * size); - - immBegin(GPU_PRIM_LINES, 4); - - switch (d) { - case LEFT: - size = -size; - ATTR_FALLTHROUGH; - case RIGHT: - immVertex2f(POS_INDEX, 0, 0); - immVertex2f(POS_INDEX, -size, -size); - immVertex2f(POS_INDEX, 0, 0); - immVertex2f(POS_INDEX, -size, size); - break; - - case DOWN: - size = -size; - ATTR_FALLTHROUGH; - case UP: - immVertex2f(POS_INDEX, 0, 0); - immVertex2f(POS_INDEX, -size, -size); - immVertex2f(POS_INDEX, 0, 0); - immVertex2f(POS_INDEX, size, -size); - break; - } - - immEnd(); -} - -static void drawArc(float angle_start, float angle_end, int segments, float size) -{ - segments = round_fl_to_int(segments * UI_DPI_FAC); - - float delta = (angle_end - angle_start) / segments; - float angle; - int a; - - immBegin(GPU_PRIM_LINE_STRIP, segments + 1); - - for (angle = angle_start, a = 0; a < segments; angle += delta, a++) { - immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size); - } - immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size); - - immEnd(); -} - -static bool helpline_poll(bContext *C) -{ - ARegion *ar = CTX_wm_region(C); - - if (ar && ar->regiontype == RGN_TYPE_WINDOW) { - return 1; - } - return 0; -} - -static void drawHelpline(bContext *UNUSED(C), int x, int y, void *customdata) -{ - TransInfo *t = (TransInfo *)customdata; - - if (t->helpline != HLP_NONE) { - float cent[2]; - const float mval[3] = { - x, - y, - 0.0f, - }; - float tmval[2] = { - (float)t->mval[0], - (float)t->mval[1], - }; - - projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO); - /* Offset the values for the area region. */ - const float offset[2] = { - t->ar->winrct.xmin, - t->ar->winrct.ymin, - }; - - for (int i = 0; i < 2; i++) { - cent[i] += offset[i]; - tmval[i] += offset[i]; - } - - GPU_line_smooth(true); - GPU_blend(true); - - GPU_matrix_push(); - - /* Dashed lines first. */ - if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) { - const uint shdr_pos = GPU_vertformat_attr_add( - immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - - UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */ - BLI_assert(shdr_pos == POS_INDEX); - - GPU_line_width(1.0f); - - immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); - - float viewport_size[4]; - GPU_viewport_size_get_f(viewport_size); - immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); - - immUniform1i("colors_len", 0); /* "simple" mode */ - immUniformThemeColor3(TH_VIEW_OVERLAY); - immUniform1f("dash_width", 6.0f * UI_DPI_FAC); - immUniform1f("dash_factor", 0.5f); - - immBegin(GPU_PRIM_LINES, 2); - immVertex2fv(POS_INDEX, cent); - immVertex2f(POS_INDEX, tmval[0], tmval[1]); - immEnd(); - - immUnbindProgram(); - } - - /* And now, solid lines. */ - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - UNUSED_VARS_NDEBUG(pos); /* silence warning */ - BLI_assert(pos == POS_INDEX); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - switch (t->helpline) { - case HLP_SPRING: - immUniformThemeColor3(TH_VIEW_OVERLAY); - - GPU_matrix_translate_3fv(mval); - GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z'); - - GPU_line_width(3.0f); - drawArrow(UP, 5, 10, 5); - drawArrow(DOWN, 5, 10, 5); - break; - case HLP_HARROW: - immUniformThemeColor3(TH_VIEW_OVERLAY); - GPU_matrix_translate_3fv(mval); - - GPU_line_width(3.0f); - drawArrow(RIGHT, 5, 10, 5); - drawArrow(LEFT, 5, 10, 5); - break; - case HLP_VARROW: - immUniformThemeColor3(TH_VIEW_OVERLAY); - - GPU_matrix_translate_3fv(mval); - - GPU_line_width(3.0f); - drawArrow(UP, 5, 10, 5); - drawArrow(DOWN, 5, 10, 5); - break; - case HLP_CARROW: { - /* Draw arrow based on direction defined by custom-points. */ - immUniformThemeColor3(TH_VIEW_OVERLAY); - - GPU_matrix_translate_3fv(mval); - - GPU_line_width(3.0f); - - const int *data = t->mouse.data; - const float dx = data[2] - data[0], dy = data[3] - data[1]; - const float angle = -atan2f(dx, dy); - - GPU_matrix_push(); - - GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z'); - - drawArrow(UP, 5, 10, 5); - drawArrow(DOWN, 5, 10, 5); - - GPU_matrix_pop(); - break; - } - case HLP_ANGLE: { - float dx = tmval[0] - cent[0], dy = tmval[1] - cent[1]; - float angle = atan2f(dy, dx); - float dist = hypotf(dx, dy); - float delta_angle = min_ff(15.0f / (dist / UI_DPI_FAC), (float)M_PI / 4.0f); - float spacing_angle = min_ff(5.0f / (dist / UI_DPI_FAC), (float)M_PI / 12.0f); - - immUniformThemeColor3(TH_VIEW_OVERLAY); - - GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0); - - GPU_line_width(3.0f); - drawArc(angle - delta_angle, angle - spacing_angle, 10, dist); - drawArc(angle + spacing_angle, angle + delta_angle, 10, dist); - - GPU_matrix_push(); - - GPU_matrix_translate_3f( - cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0); - GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z'); - - drawArrowHead(DOWN, 5); - - GPU_matrix_pop(); - - GPU_matrix_translate_3f( - cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0); - GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z'); - - drawArrowHead(UP, 5); - break; - } - case HLP_TRACKBALL: { - unsigned char col[3], col2[3]; - UI_GetThemeColor3ubv(TH_GRID, col); - - GPU_matrix_translate_3fv(mval); - - GPU_line_width(3.0f); - - UI_make_axis_color(col, col2, 'X'); - immUniformColor3ubv(col2); - - drawArrow(RIGHT, 5, 10, 5); - drawArrow(LEFT, 5, 10, 5); - - UI_make_axis_color(col, col2, 'Y'); - immUniformColor3ubv(col2); - - drawArrow(UP, 5, 10, 5); - drawArrow(DOWN, 5, 10, 5); - break; - } - } - - immUnbindProgram(); - GPU_matrix_pop(); - - GPU_line_smooth(false); - GPU_blend(false); - } -} - static bool transinfo_show_overlay(const struct bContext *C, TransInfo *t, ARegion *ar) { /* Don't show overlays when not the active view and when overlay is disabled: T57139 */ @@ -2394,38 +2102,62 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); t->draw_handle_pixel = ED_region_draw_cb_activate( t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL); - t->draw_handle_cursor = WM_paint_cursor_activate( - CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t); + t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), + SPACE_TYPE_ANY, + RGN_TYPE_ANY, + transform_draw_cursor_poll, + transform_draw_cursor_draw, + t); } else if (t->spacetype == SPACE_IMAGE) { t->draw_handle_view = ED_region_draw_cb_activate( t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - t->draw_handle_cursor = WM_paint_cursor_activate( - CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t); + t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), + SPACE_TYPE_ANY, + RGN_TYPE_ANY, + transform_draw_cursor_poll, + transform_draw_cursor_draw, + t); } else if (t->spacetype == SPACE_CLIP) { t->draw_handle_view = ED_region_draw_cb_activate( t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - t->draw_handle_cursor = WM_paint_cursor_activate( - CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t); + t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), + SPACE_TYPE_ANY, + RGN_TYPE_ANY, + transform_draw_cursor_poll, + transform_draw_cursor_draw, + t); } else if (t->spacetype == SPACE_NODE) { t->draw_handle_view = ED_region_draw_cb_activate( t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - t->draw_handle_cursor = WM_paint_cursor_activate( - CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t); + t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), + SPACE_TYPE_ANY, + RGN_TYPE_ANY, + transform_draw_cursor_poll, + transform_draw_cursor_draw, + t); } else if (t->spacetype == SPACE_GRAPH) { t->draw_handle_view = ED_region_draw_cb_activate( t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - t->draw_handle_cursor = WM_paint_cursor_activate( - CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t); + t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), + SPACE_TYPE_ANY, + RGN_TYPE_ANY, + transform_draw_cursor_poll, + transform_draw_cursor_draw, + t); } else if (t->spacetype == SPACE_ACTION) { t->draw_handle_view = ED_region_draw_cb_activate( t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); - t->draw_handle_cursor = WM_paint_cursor_activate( - CTX_wm_manager(C), SPACE_TYPE_ANY, RGN_TYPE_ANY, helpline_poll, drawHelpline, t); + t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), + SPACE_TYPE_ANY, + RGN_TYPE_ANY, + transform_draw_cursor_poll, + transform_draw_cursor_draw, + t); } createTransData(C, t); // make TransData structs from selection diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 4b529765ab0..95506918d98 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -649,7 +649,7 @@ typedef struct TransInfo { short index; short *types[2]; /* this gets used when custom_orientation is V3D_ORIENT_CUSTOM */ - TransformOrientation *custom; + struct TransformOrientation *custom; } orientation; /** backup from view3d, to restore on end. */ short gizmo_flag; diff --git a/source/blender/editors/transform/transform_draw.c b/source/blender/editors/transform/transform_draw.c new file mode 100644 index 00000000000..e44442b7e49 --- /dev/null +++ b/source/blender/editors/transform/transform_draw.c @@ -0,0 +1,114 @@ + +/* -------------------------------------------------------------------- */ +/** \name Auto-Key (Pixel Space) + * \{ */ + +/* just draw a little warning message in the top-right corner of the viewport + * to warn that autokeying is enabled */ +static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) +{ + const char *printable = IFACE_("Auto Keying On"); + float printable_size[2]; + int xco, yco; + + const rcti *rect = ED_region_visible_rect(ar); + + const int font_id = BLF_default(); + BLF_width_and_height( + font_id, printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); + + xco = (rect->xmax - U.widget_unit) - (int)printable_size[0]; + yco = (rect->ymax - U.widget_unit); + + /* warning text (to clarify meaning of overlays) + * - original color was red to match the icon, but that clashes badly with a less nasty border + */ + unsigned char color[3]; + UI_GetThemeColorShade3ubv(TH_TEXT_HI, -50, color); + BLF_color3ubv(font_id, color); +#ifdef WITH_INTERNATIONAL + BLF_draw_default(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); +#else + BLF_draw_default_ascii(xco, yco, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); +#endif + + /* autokey recording icon... */ + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(true); + + xco -= U.widget_unit; + yco -= (int)printable_size[1] / 2; + + UI_icon_draw(xco, yco, ICON_REC); + + GPU_blend(false); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Constraints (View Space) + * \{ */ + +/* called from drawview.c, as an extra per-window draw option */ +void drawPropCircle(const struct bContext *C, TransInfo *t) +{ + if (t->flag & T_PROP_EDIT) { + RegionView3D *rv3d = CTX_wm_region_view3d(C); + float tmat[4][4], imat[4][4]; + int depth_test_enabled; + + if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { + copy_m4_m4(tmat, rv3d->viewmat); + invert_m4_m4(imat, tmat); + } + else { + unit_m4(tmat); + unit_m4(imat); + } + + GPU_matrix_push(); + + if (t->spacetype == SPACE_VIEW3D) { + /* pass */ + } + else if (t->spacetype == SPACE_IMAGE) { + GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]); + } + else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) { + /* only scale y */ + rcti *mask = &t->ar->v2d.mask; + rctf *datamask = &t->ar->v2d.cur; + float xsize = BLI_rctf_size_x(datamask); + float ysize = BLI_rctf_size_y(datamask); + float xmask = BLI_rcti_size_x(mask); + float ymask = BLI_rcti_size_y(mask); + GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask)); + } + + depth_test_enabled = GPU_depth_test_enabled(); + if (depth_test_enabled) { + GPU_depth_test(false); + } + + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformThemeColor(TH_GRID); + + GPU_logic_op_invert_set(true); + imm_drawcircball(t->center_global, t->prop_size, imat, pos); + GPU_logic_op_invert_set(false); + + immUnbindProgram(); + + if (depth_test_enabled) { + GPU_depth_test(true); + } + + GPU_matrix_pop(); + } +} + +/** \} */ diff --git a/source/blender/editors/transform/transform_draw.h b/source/blender/editors/transform/transform_draw.h new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/source/blender/editors/transform/transform_draw.h diff --git a/source/blender/editors/transform/transform_draw_cursors.c b/source/blender/editors/transform/transform_draw_cursors.c new file mode 100644 index 00000000000..b5df1e4e98b --- /dev/null +++ b/source/blender/editors/transform/transform_draw_cursors.c @@ -0,0 +1,340 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + */ + +/** \file + * \ingroup edtransform + */ + +#include "BLI_math.h" + +#include "GPU_immediate.h" +#include "GPU_matrix.h" +#include "GPU_state.h" + +#include "BKE_context.h" + +#include "DNA_screen_types.h" +#include "DNA_userdef_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "transform.h" +#include "transform_draw_cursors.h" /* Own include. */ + +typedef enum { + UP, + DOWN, + LEFT, + RIGHT, +} ArrowDirection; + +#define POS_INDEX 0 +/* NOTE: this --^ is a bit hackish, but simplifies GPUVertFormat usage among functions + * private to this file - merwin + */ + +static void drawArrow(ArrowDirection d, short offset, short length, short size) +{ + immBegin(GPU_PRIM_LINES, 6); + + offset = round_fl_to_short(UI_DPI_FAC * offset); + length = round_fl_to_short(UI_DPI_FAC * length); + size = round_fl_to_short(UI_DPI_FAC * size); + + switch (d) { + case LEFT: + offset = -offset; + length = -length; + size = -size; + ATTR_FALLTHROUGH; + case RIGHT: + immVertex2f(POS_INDEX, offset, 0); + immVertex2f(POS_INDEX, offset + length, 0); + immVertex2f(POS_INDEX, offset + length, 0); + immVertex2f(POS_INDEX, offset + length - size, -size); + immVertex2f(POS_INDEX, offset + length, 0); + immVertex2f(POS_INDEX, offset + length - size, size); + break; + + case DOWN: + offset = -offset; + length = -length; + size = -size; + ATTR_FALLTHROUGH; + case UP: + immVertex2f(POS_INDEX, 0, offset); + immVertex2f(POS_INDEX, 0, offset + length); + immVertex2f(POS_INDEX, 0, offset + length); + immVertex2f(POS_INDEX, -size, offset + length - size); + immVertex2f(POS_INDEX, 0, offset + length); + immVertex2f(POS_INDEX, size, offset + length - size); + break; + } + + immEnd(); +} + +static void drawArrowHead(ArrowDirection d, short size) +{ + size = round_fl_to_short(UI_DPI_FAC * size); + + immBegin(GPU_PRIM_LINES, 4); + + switch (d) { + case LEFT: + size = -size; + ATTR_FALLTHROUGH; + case RIGHT: + immVertex2f(POS_INDEX, 0, 0); + immVertex2f(POS_INDEX, -size, -size); + immVertex2f(POS_INDEX, 0, 0); + immVertex2f(POS_INDEX, -size, size); + break; + + case DOWN: + size = -size; + ATTR_FALLTHROUGH; + case UP: + immVertex2f(POS_INDEX, 0, 0); + immVertex2f(POS_INDEX, -size, -size); + immVertex2f(POS_INDEX, 0, 0); + immVertex2f(POS_INDEX, size, -size); + break; + } + + immEnd(); +} + +static void drawArc(float angle_start, float angle_end, int segments, float size) +{ + segments = round_fl_to_int(segments * UI_DPI_FAC); + + float delta = (angle_end - angle_start) / segments; + float angle; + int a; + + immBegin(GPU_PRIM_LINE_STRIP, segments + 1); + + for (angle = angle_start, a = 0; a < segments; angle += delta, a++) { + immVertex2f(POS_INDEX, cosf(angle) * size, sinf(angle) * size); + } + immVertex2f(POS_INDEX, cosf(angle_end) * size, sinf(angle_end) * size); + + immEnd(); +} + +/** + * Poll callback for cursor drawing: + * #WM_paint_cursor_activate + */ +bool transform_draw_cursor_poll(bContext *C) +{ + ARegion *ar = CTX_wm_region(C); + + if (ar && ar->regiontype == RGN_TYPE_WINDOW) { + return 1; + } + return 0; +} + +/** + * Cursor and help-line drawing, callback for: + * #WM_paint_cursor_activate + */ +void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customdata) +{ + TransInfo *t = (TransInfo *)customdata; + + if (t->helpline != HLP_NONE) { + float cent[2]; + const float mval[3] = { + x, + y, + 0.0f, + }; + float tmval[2] = { + (float)t->mval[0], + (float)t->mval[1], + }; + + projectFloatViewEx(t, t->center_global, cent, V3D_PROJ_TEST_CLIP_ZERO); + /* Offset the values for the area region. */ + const float offset[2] = { + t->ar->winrct.xmin, + t->ar->winrct.ymin, + }; + + for (int i = 0; i < 2; i++) { + cent[i] += offset[i]; + tmval[i] += offset[i]; + } + + GPU_line_smooth(true); + GPU_blend(true); + + GPU_matrix_push(); + + /* Dashed lines first. */ + if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) { + const uint shdr_pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + + UNUSED_VARS_NDEBUG(shdr_pos); /* silence warning */ + BLI_assert(shdr_pos == POS_INDEX); + + GPU_line_width(1.0f); + + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + + float viewport_size[4]; + GPU_viewport_size_get_f(viewport_size); + immUniform2f("viewport_size", viewport_size[2], viewport_size[3]); + + immUniform1i("colors_len", 0); /* "simple" mode */ + immUniformThemeColor3(TH_VIEW_OVERLAY); + immUniform1f("dash_width", 6.0f * UI_DPI_FAC); + immUniform1f("dash_factor", 0.5f); + + immBegin(GPU_PRIM_LINES, 2); + immVertex2fv(POS_INDEX, cent); + immVertex2f(POS_INDEX, tmval[0], tmval[1]); + immEnd(); + + immUnbindProgram(); + } + + /* And now, solid lines. */ + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + UNUSED_VARS_NDEBUG(pos); /* silence warning */ + BLI_assert(pos == POS_INDEX); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + switch (t->helpline) { + case HLP_SPRING: + immUniformThemeColor3(TH_VIEW_OVERLAY); + + GPU_matrix_translate_3fv(mval); + GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z'); + + GPU_line_width(3.0f); + drawArrow(UP, 5, 10, 5); + drawArrow(DOWN, 5, 10, 5); + break; + case HLP_HARROW: + immUniformThemeColor3(TH_VIEW_OVERLAY); + GPU_matrix_translate_3fv(mval); + + GPU_line_width(3.0f); + drawArrow(RIGHT, 5, 10, 5); + drawArrow(LEFT, 5, 10, 5); + break; + case HLP_VARROW: + immUniformThemeColor3(TH_VIEW_OVERLAY); + + GPU_matrix_translate_3fv(mval); + + GPU_line_width(3.0f); + drawArrow(UP, 5, 10, 5); + drawArrow(DOWN, 5, 10, 5); + break; + case HLP_CARROW: { + /* Draw arrow based on direction defined by custom-points. */ + immUniformThemeColor3(TH_VIEW_OVERLAY); + + GPU_matrix_translate_3fv(mval); + + GPU_line_width(3.0f); + + const int *data = t->mouse.data; + const float dx = data[2] - data[0], dy = data[3] - data[1]; + const float angle = -atan2f(dx, dy); + + GPU_matrix_push(); + + GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z'); + + drawArrow(UP, 5, 10, 5); + drawArrow(DOWN, 5, 10, 5); + + GPU_matrix_pop(); + break; + } + case HLP_ANGLE: { + float dx = tmval[0] - cent[0], dy = tmval[1] - cent[1]; + float angle = atan2f(dy, dx); + float dist = hypotf(dx, dy); + float delta_angle = min_ff(15.0f / (dist / UI_DPI_FAC), (float)M_PI / 4.0f); + float spacing_angle = min_ff(5.0f / (dist / UI_DPI_FAC), (float)M_PI / 12.0f); + + immUniformThemeColor3(TH_VIEW_OVERLAY); + + GPU_matrix_translate_3f(cent[0] - tmval[0] + mval[0], cent[1] - tmval[1] + mval[1], 0); + + GPU_line_width(3.0f); + drawArc(angle - delta_angle, angle - spacing_angle, 10, dist); + drawArc(angle + spacing_angle, angle + delta_angle, 10, dist); + + GPU_matrix_push(); + + GPU_matrix_translate_3f( + cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0); + GPU_matrix_rotate_axis(RAD2DEGF(angle - delta_angle), 'Z'); + + drawArrowHead(DOWN, 5); + + GPU_matrix_pop(); + + GPU_matrix_translate_3f( + cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0); + GPU_matrix_rotate_axis(RAD2DEGF(angle + delta_angle), 'Z'); + + drawArrowHead(UP, 5); + break; + } + case HLP_TRACKBALL: { + unsigned char col[3], col2[3]; + UI_GetThemeColor3ubv(TH_GRID, col); + + GPU_matrix_translate_3fv(mval); + + GPU_line_width(3.0f); + + UI_make_axis_color(col, col2, 'X'); + immUniformColor3ubv(col2); + + drawArrow(RIGHT, 5, 10, 5); + drawArrow(LEFT, 5, 10, 5); + + UI_make_axis_color(col, col2, 'Y'); + immUniformColor3ubv(col2); + + drawArrow(UP, 5, 10, 5); + drawArrow(DOWN, 5, 10, 5); + break; + } + } + + immUnbindProgram(); + GPU_matrix_pop(); + + GPU_line_smooth(false); + GPU_blend(false); + } +} diff --git a/source/blender/editors/transform/transform_draw_cursors.h b/source/blender/editors/transform/transform_draw_cursors.h new file mode 100644 index 00000000000..e7696bad5a7 --- /dev/null +++ b/source/blender/editors/transform/transform_draw_cursors.h @@ -0,0 +1,31 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + */ + +/** \file + * \ingroup edtransform + */ + +#ifndef __TRANSFORM_DRAW_CURSORS_H__ +#define __TRANSFORM_DRAW_CURSORS_H__ + +/* Callbacks for #WM_paint_cursor_activate */ +bool transform_draw_cursor_poll(struct bContext *C); +void transform_draw_cursor_draw(struct bContext *C, int x, int y, void *customdata); + +#endif /* __TRANSFORM_DRAW_CURSORS_H__ */ |