199 lines
5.4 KiB
C
199 lines
5.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Copyright 2001-2002 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. */
|
|
|
|
enum eArrowDirection {
|
|
UP,
|
|
DOWN,
|
|
LEFT,
|
|
RIGHT,
|
|
};
|
|
|
|
#define ARROW_WIDTH (2.0f * U.pixelsize)
|
|
#define DASH_WIDTH (1.0f)
|
|
#define DASH_LENGTH (8.0f * DASH_WIDTH * U.pixelsize)
|
|
|
|
static void drawArrow(const uint pos_id, const enum eArrowDirection dir)
|
|
{
|
|
int offset = 5.0f * UI_SCALE_FAC;
|
|
int length = (6.0f * UI_SCALE_FAC) + (4.0f * U.pixelsize);
|
|
int size = (3.0f * UI_SCALE_FAC) + (2.0f * U.pixelsize);
|
|
|
|
/* To line up the arrow point nicely, one end has to be extended by half its width. But
|
|
* being on a 45 degree angle, Pythagoras says a movement of `sqrt(2) / 2 * (line width / 2)`. */
|
|
float adjust = (M_SQRT2 * ARROW_WIDTH / 4.0f);
|
|
|
|
if (ELEM(dir, LEFT, DOWN)) {
|
|
offset = -offset;
|
|
length = -length;
|
|
size = -size;
|
|
adjust = -adjust;
|
|
}
|
|
|
|
immBegin(GPU_PRIM_LINES, 6);
|
|
|
|
if (ELEM(dir, LEFT, RIGHT)) {
|
|
immVertex2f(pos_id, offset, 0);
|
|
immVertex2f(pos_id, offset + length, 0);
|
|
immVertex2f(pos_id, offset + length + adjust, adjust);
|
|
immVertex2f(pos_id, offset + length - size, -size);
|
|
immVertex2f(pos_id, offset + length, 0);
|
|
immVertex2f(pos_id, offset + length - size, size);
|
|
}
|
|
else {
|
|
immVertex2f(pos_id, 0, offset);
|
|
immVertex2f(pos_id, 0, offset + length);
|
|
immVertex2f(pos_id, adjust, offset + length + adjust);
|
|
immVertex2f(pos_id, -size, offset + length - size);
|
|
immVertex2f(pos_id, 0, offset + length);
|
|
immVertex2f(pos_id, size, offset + length - size);
|
|
}
|
|
|
|
immEnd();
|
|
}
|
|
|
|
bool transform_draw_cursor_poll(bContext *C)
|
|
{
|
|
ARegion *region = CTX_wm_region(C);
|
|
return (region && ELEM(region->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_PREVIEW)) ? 1 : 0;
|
|
}
|
|
|
|
void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customdata)
|
|
{
|
|
TransInfo *t = (TransInfo *)customdata;
|
|
|
|
if (t->helpline == HLP_NONE) {
|
|
return;
|
|
}
|
|
|
|
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->region->winrct.xmin,
|
|
t->region->winrct.ymin,
|
|
};
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
cent[i] += offset[i];
|
|
tmval[i] += offset[i];
|
|
}
|
|
|
|
float viewport_size[4];
|
|
GPU_viewport_size_get_f(viewport_size);
|
|
|
|
GPU_line_smooth(true);
|
|
GPU_blend(GPU_BLEND_ALPHA);
|
|
const uint pos_id = GPU_vertformat_attr_add(
|
|
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
/* Dashed lines first. */
|
|
if (ELEM(t->helpline, HLP_SPRING, HLP_ANGLE)) {
|
|
GPU_line_width(DASH_WIDTH);
|
|
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
|
|
immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
|
|
immUniform1i("colors_len", 0); /* "simple" mode */
|
|
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
|
immUniform1f("dash_width", DASH_LENGTH);
|
|
immUniform1f("udash_factor", 0.5f);
|
|
immBegin(GPU_PRIM_LINES, 2);
|
|
immVertex2fv(pos_id, cent);
|
|
immVertex2f(pos_id, tmval[0], tmval[1]);
|
|
immEnd();
|
|
immUnbindProgram();
|
|
}
|
|
|
|
/* And now, solid lines. */
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
|
immUniformThemeColor3(TH_VIEW_OVERLAY);
|
|
immUniform2fv("viewportSize", &viewport_size[2]);
|
|
immUniform1f("lineWidth", ARROW_WIDTH);
|
|
|
|
GPU_matrix_push();
|
|
GPU_matrix_translate_3fv(mval);
|
|
|
|
switch (t->helpline) {
|
|
case HLP_SPRING:
|
|
GPU_matrix_rotate_axis(-RAD2DEGF(atan2f(cent[0] - tmval[0], cent[1] - tmval[1])), 'Z');
|
|
drawArrow(pos_id, UP);
|
|
drawArrow(pos_id, DOWN);
|
|
break;
|
|
case HLP_HARROW:
|
|
drawArrow(pos_id, RIGHT);
|
|
drawArrow(pos_id, LEFT);
|
|
break;
|
|
case HLP_VARROW:
|
|
drawArrow(pos_id, UP);
|
|
drawArrow(pos_id, DOWN);
|
|
break;
|
|
case HLP_CARROW: {
|
|
/* Draw arrow based on direction defined by custom-points. */
|
|
const int *data = t->mouse.data;
|
|
const float angle = -atan2f(data[2] - data[0], data[3] - data[1]);
|
|
GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
|
|
drawArrow(pos_id, UP);
|
|
drawArrow(pos_id, DOWN);
|
|
break;
|
|
}
|
|
case HLP_ANGLE: {
|
|
GPU_matrix_push();
|
|
float angle = atan2f(tmval[1] - cent[1], tmval[0] - cent[0]);
|
|
GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
|
|
GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
|
|
drawArrow(pos_id, DOWN);
|
|
GPU_matrix_pop();
|
|
GPU_matrix_translate_3f(cosf(angle), sinf(angle), 0);
|
|
GPU_matrix_rotate_axis(RAD2DEGF(angle), 'Z');
|
|
drawArrow(pos_id, UP);
|
|
break;
|
|
}
|
|
case HLP_TRACKBALL: {
|
|
uchar col[3], col2[3];
|
|
UI_GetThemeColor3ubv(TH_GRID, col);
|
|
UI_make_axis_color(col, col2, 'X');
|
|
immUniformColor3ubv(col2);
|
|
drawArrow(pos_id, RIGHT);
|
|
drawArrow(pos_id, LEFT);
|
|
UI_make_axis_color(col, col2, 'Y');
|
|
immUniformColor3ubv(col2);
|
|
drawArrow(pos_id, UP);
|
|
drawArrow(pos_id, DOWN);
|
|
break;
|
|
}
|
|
case HLP_NONE:
|
|
break;
|
|
}
|
|
|
|
GPU_matrix_pop();
|
|
immUnbindProgram();
|
|
GPU_line_smooth(false);
|
|
GPU_blend(GPU_BLEND_NONE);
|
|
}
|