Gizmo: add new cage2d draw style for circular shapes
`ED_GIZMO_CAGE2D_STYLE_CIRCLE` now draw circles. The previous `ED_GIZMO_CAGE2D_STYLE_CIRCLE`, which drew rectangles, is renamed to `ED_GIZMO_CAGE2D_STYLE_RECTANGLE`. The meaning of `ED_GIZMO_CAGE2D_STYLE_BOX` is now unclear and probably needs to be renamed too. Ref T104280 Maniphest Tasks: T104280 Differential Revision: https://developer.blender.org/D17174
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* 2D Gizmo
|
* 2D Gizmo
|
||||||
*
|
*
|
||||||
* \brief Rectangular gizmo acting as a 'cage' around its content.
|
* \brief Rectangular or circular gizmo acting as a 'cage' around its content.
|
||||||
* Interacting scales or translates the gizmo.
|
* Interacting scales or translates the gizmo.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -41,6 +41,8 @@
|
|||||||
#include "../gizmo_library_intern.h"
|
#include "../gizmo_library_intern.h"
|
||||||
|
|
||||||
#define GIZMO_MARGIN_OFFSET_SCALE 1.5f
|
#define GIZMO_MARGIN_OFFSET_SCALE 1.5f
|
||||||
|
/* The same as in `draw_cache.c` */
|
||||||
|
#define CIRCLE_RESOL 32
|
||||||
|
|
||||||
static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
|
static bool gizmo_calc_rect_view_scale(const wmGizmo *gz, const float dims[2], float scale[2])
|
||||||
{
|
{
|
||||||
@@ -472,7 +474,7 @@ static void imm_draw_point_aspect_2d(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cage2d_draw_circle_wire(const rctf *r,
|
static void cage2d_draw_rect_wire(const rctf *r,
|
||||||
const float margin[2],
|
const float margin[2],
|
||||||
const float color[3],
|
const float color[3],
|
||||||
const int transform_flag,
|
const int transform_flag,
|
||||||
@@ -533,7 +535,27 @@ static void cage2d_draw_circle_wire(const rctf *r,
|
|||||||
immUnbindProgram();
|
immUnbindProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cage2d_draw_circle_handles(const rctf *r,
|
static void cage2d_draw_circle_wire(const float color[3],
|
||||||
|
const float size[2],
|
||||||
|
const float margin,
|
||||||
|
const float line_width)
|
||||||
|
{
|
||||||
|
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||||
|
|
||||||
|
immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR);
|
||||||
|
immUniformColor3fv(color);
|
||||||
|
|
||||||
|
float viewport[4];
|
||||||
|
GPU_viewport_size_get_f(viewport);
|
||||||
|
immUniform2fv("viewportSize", &viewport[2]);
|
||||||
|
immUniform1f("lineWidth", line_width * U.pixelsize + margin);
|
||||||
|
|
||||||
|
imm_draw_circle_wire_aspect_3d(pos, 0.0f, 0.0f, size[0], size[1], CIRCLE_RESOL);
|
||||||
|
|
||||||
|
immUnbindProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cage2d_draw_rect_handles(const rctf *r,
|
||||||
const float margin[2],
|
const float margin[2],
|
||||||
const float color[3],
|
const float color[3],
|
||||||
const int transform_flag,
|
const int transform_flag,
|
||||||
@@ -609,7 +631,13 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||||||
if (select) {
|
if (select) {
|
||||||
/* Expand for hot-spot. */
|
/* Expand for hot-spot. */
|
||||||
const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
|
const float size[2] = {size_real[0] + margin[0] / 2, size_real[1] + margin[1] / 2};
|
||||||
|
if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||||
|
/* Only scaling is needed for now. */
|
||||||
|
GPU_select_load_id(select_id | ED_GIZMO_CAGE2D_PART_SCALE);
|
||||||
|
cage2d_draw_circle_wire(
|
||||||
|
gz->color, size_real, 0.5f * (margin[0] + margin[1]), gz->line_width);
|
||||||
|
}
|
||||||
|
else {
|
||||||
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) {
|
if (transform_flag & ED_GIZMO_CAGE_XFORM_FLAG_SCALE) {
|
||||||
int scale_parts[] = {
|
int scale_parts[] = {
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
||||||
@@ -644,6 +672,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||||||
draw_options);
|
draw_options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
const rctf r = {
|
const rctf r = {
|
||||||
.xmin = -size_real[0],
|
.xmin = -size_real[0],
|
||||||
@@ -688,25 +717,31 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz,
|
|||||||
draw_options);
|
draw_options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
else {
|
||||||
float color[4], black[3] = {0, 0, 0};
|
float color[4], black[3] = {0, 0, 0};
|
||||||
gizmo_color_get(gz, highlight, color);
|
gizmo_color_get(gz, highlight, color);
|
||||||
|
|
||||||
GPU_blend(GPU_BLEND_ALPHA);
|
GPU_blend(GPU_BLEND_ALPHA);
|
||||||
|
|
||||||
float outline_line_width = gz->line_width + 3.0f;
|
float outline_line_width = gz->line_width + 3.0f;
|
||||||
cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
|
|
||||||
cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
|
if (draw_style == ED_GIZMO_CAGE2D_STYLE_RECTANGLE) {
|
||||||
|
cage2d_draw_rect_wire(&r, margin, black, transform_flag, draw_options, outline_line_width);
|
||||||
|
cage2d_draw_rect_wire(&r, margin, color, transform_flag, draw_options, gz->line_width);
|
||||||
|
|
||||||
/* corner gizmos */
|
/* corner gizmos */
|
||||||
cage2d_draw_circle_handles(&r, margin, color, transform_flag, true);
|
cage2d_draw_rect_handles(&r, margin, color, transform_flag, true);
|
||||||
cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false);
|
cage2d_draw_rect_handles(&r, margin, black, transform_flag, false);
|
||||||
|
}
|
||||||
GPU_blend(GPU_BLEND_NONE);
|
else if (draw_style == ED_GIZMO_CAGE2D_STYLE_CIRCLE) {
|
||||||
|
cage2d_draw_circle_wire(black, size_real, 0.0f, outline_line_width);
|
||||||
|
cage2d_draw_circle_wire(color, size_real, 0.0f, gz->line_width);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BLI_assert(0);
|
BLI_assert(0);
|
||||||
}
|
}
|
||||||
|
GPU_blend(GPU_BLEND_NONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GPU_matrix_pop();
|
GPU_matrix_pop();
|
||||||
@@ -1188,6 +1223,7 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
|
|||||||
/* rna */
|
/* rna */
|
||||||
static EnumPropertyItem rna_enum_draw_style[] = {
|
static EnumPropertyItem rna_enum_draw_style[] = {
|
||||||
{ED_GIZMO_CAGE2D_STYLE_BOX, "BOX", 0, "Box", ""},
|
{ED_GIZMO_CAGE2D_STYLE_BOX, "BOX", 0, "Box", ""},
|
||||||
|
{ED_GIZMO_CAGE2D_STYLE_RECTANGLE, "RECTANGLE", 0, "Rectangle", ""},
|
||||||
{ED_GIZMO_CAGE2D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
|
{ED_GIZMO_CAGE2D_STYLE_CIRCLE, "CIRCLE", 0, "Circle", ""},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, NULL, 0, NULL, NULL},
|
||||||
};
|
};
|
||||||
@@ -1209,7 +1245,7 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
|
|||||||
RNA_def_enum(gzt->srna,
|
RNA_def_enum(gzt->srna,
|
||||||
"draw_style",
|
"draw_style",
|
||||||
rna_enum_draw_style,
|
rna_enum_draw_style,
|
||||||
ED_GIZMO_CAGE2D_STYLE_CIRCLE,
|
ED_GIZMO_CAGE2D_STYLE_RECTANGLE,
|
||||||
"Draw Style",
|
"Draw Style",
|
||||||
"");
|
"");
|
||||||
RNA_def_enum_flag(gzt->srna,
|
RNA_def_enum_flag(gzt->srna,
|
||||||
|
|||||||
@@ -106,8 +106,12 @@ enum {
|
|||||||
|
|
||||||
/* draw_style */
|
/* draw_style */
|
||||||
enum {
|
enum {
|
||||||
|
/** Display the hover region (edge or corner) of the underlying rectangle. */
|
||||||
ED_GIZMO_CAGE2D_STYLE_BOX = 0,
|
ED_GIZMO_CAGE2D_STYLE_BOX = 0,
|
||||||
ED_GIZMO_CAGE2D_STYLE_CIRCLE = 1,
|
/** Display a rectangular wire plus dots on four corners while hovering. */
|
||||||
|
ED_GIZMO_CAGE2D_STYLE_RECTANGLE,
|
||||||
|
/** Display a circular wire while hovering. */
|
||||||
|
ED_GIZMO_CAGE2D_STYLE_CIRCLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -125,17 +129,20 @@ enum {
|
|||||||
/** #wmGizmo.highlight_part */
|
/** #wmGizmo.highlight_part */
|
||||||
enum {
|
enum {
|
||||||
ED_GIZMO_CAGE2D_PART_TRANSLATE = 0,
|
ED_GIZMO_CAGE2D_PART_TRANSLATE = 0,
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X = 1,
|
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X = 2,
|
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y = 3,
|
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y = 4,
|
|
||||||
/* Corners */
|
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y = 5,
|
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y = 6,
|
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y = 7,
|
|
||||||
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y = 8,
|
|
||||||
|
|
||||||
ED_GIZMO_CAGE2D_PART_ROTATE = 9,
|
ED_GIZMO_CAGE2D_PART_SCALE,
|
||||||
|
/* Edges */
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X,
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X,
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y,
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y,
|
||||||
|
/* Corners */
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y,
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y,
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y,
|
||||||
|
ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y,
|
||||||
|
|
||||||
|
ED_GIZMO_CAGE2D_PART_ROTATE,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** #wmGizmo.highlight_part */
|
/** #wmGizmo.highlight_part */
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ void imm_draw_circle_fill_aspect_2d(
|
|||||||
* Use this version when #GPUVertFormat has a vec3 position.
|
* Use this version when #GPUVertFormat has a vec3 position.
|
||||||
*/
|
*/
|
||||||
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments);
|
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments);
|
||||||
|
void imm_draw_circle_wire_aspect_3d(
|
||||||
|
uint pos, float x, float y, float radius_x, float radius_y, int nsegments);
|
||||||
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments);
|
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments);
|
||||||
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments);
|
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments);
|
||||||
|
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ void imm_draw_circle_wire_aspect_2d(
|
|||||||
{
|
{
|
||||||
imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, radius_x, radius_y, nsegments);
|
imm_draw_circle(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, radius_x, radius_y, nsegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imm_draw_circle_fill_aspect_2d(
|
void imm_draw_circle_fill_aspect_2d(
|
||||||
uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
|
uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
|
||||||
{
|
{
|
||||||
@@ -329,19 +330,24 @@ void imm_draw_disk_partial_fill_3d(uint pos,
|
|||||||
GPU_PRIM_TRI_STRIP, pos, x, y, z, rad_inner, rad_outer, nsegments, start, sweep);
|
GPU_PRIM_TRI_STRIP, pos, x, y, z, rad_inner, rad_outer, nsegments, start, sweep);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void imm_draw_circle_3D(
|
static void imm_draw_circle_3D(GPUPrimType prim_type,
|
||||||
GPUPrimType prim_type, uint pos, float x, float y, float radius, int nsegments)
|
uint pos,
|
||||||
|
float x,
|
||||||
|
float y,
|
||||||
|
float radius_x,
|
||||||
|
float radius_y,
|
||||||
|
int nsegments)
|
||||||
{
|
{
|
||||||
if (prim_type == GPU_PRIM_LINE_LOOP) {
|
if (prim_type == GPU_PRIM_LINE_LOOP) {
|
||||||
/* NOTE(Metal/AMD): For small primitives, line list more efficient than line strip. */
|
/* NOTE(Metal/AMD): For small primitives, line list more efficient than line strip. */
|
||||||
immBegin(GPU_PRIM_LINES, nsegments * 2);
|
immBegin(GPU_PRIM_LINES, nsegments * 2);
|
||||||
|
|
||||||
const float angle = (float)(2 * M_PI) / (float)nsegments;
|
const float angle = (float)(2 * M_PI) / (float)nsegments;
|
||||||
float xprev = cosf(-angle) * radius;
|
float xprev = cosf(-angle) * radius_x;
|
||||||
float yprev = sinf(-angle) * radius;
|
float yprev = sinf(-angle) * radius_y;
|
||||||
const float alpha = 2.0f * cosf(angle);
|
const float alpha = 2.0f * cosf(angle);
|
||||||
|
|
||||||
float xr = radius;
|
float xr = radius_x;
|
||||||
float yr = 0;
|
float yr = 0;
|
||||||
|
|
||||||
for (int i = 0; i < nsegments; i++) {
|
for (int i = 0; i < nsegments; i++) {
|
||||||
@@ -349,21 +355,23 @@ static void imm_draw_circle_3D(
|
|||||||
if (i) {
|
if (i) {
|
||||||
immVertex3f(pos, x + xr, y + yr, 0.0f);
|
immVertex3f(pos, x + xr, y + yr, 0.0f);
|
||||||
}
|
}
|
||||||
|
/* cos[(n + 1)a] = 2cos(a)cos(na) - cos[(n - 1)a]. */
|
||||||
const float xnext = alpha * xr - xprev;
|
const float xnext = alpha * xr - xprev;
|
||||||
|
/* sin[(n + 1)a] = 2cos(a)sin(na) - sin[(n - 1)a]. */
|
||||||
const float ynext = alpha * yr - yprev;
|
const float ynext = alpha * yr - yprev;
|
||||||
xprev = xr;
|
xprev = xr;
|
||||||
yprev = yr;
|
yprev = yr;
|
||||||
xr = xnext;
|
xr = xnext;
|
||||||
yr = ynext;
|
yr = ynext;
|
||||||
}
|
}
|
||||||
immVertex3f(pos, x + radius, y, 0.0f);
|
immVertex3f(pos, x + radius_x, y, 0.0f);
|
||||||
immEnd();
|
immEnd();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
immBegin(prim_type, nsegments);
|
immBegin(prim_type, nsegments);
|
||||||
for (int i = 0; i < nsegments; i++) {
|
for (int i = 0; i < nsegments; i++) {
|
||||||
float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
float angle = (float)(2 * M_PI) * ((float)i / (float)nsegments);
|
||||||
immVertex3f(pos, x + radius * cosf(angle), y + radius * sinf(angle), 0.0f);
|
immVertex3f(pos, x + radius_x * cosf(angle), y + radius_y * sinf(angle), 0.0f);
|
||||||
}
|
}
|
||||||
immEnd();
|
immEnd();
|
||||||
}
|
}
|
||||||
@@ -371,17 +379,23 @@ static void imm_draw_circle_3D(
|
|||||||
|
|
||||||
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
|
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
|
||||||
{
|
{
|
||||||
imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, pos, x, y, radius, nsegments);
|
imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, pos, x, y, radius, radius, nsegments);
|
||||||
|
}
|
||||||
|
|
||||||
|
void imm_draw_circle_wire_aspect_3d(
|
||||||
|
uint shdr_pos, float x, float y, float radius_x, float radius_y, int nsegments)
|
||||||
|
{
|
||||||
|
imm_draw_circle_3D(GPU_PRIM_LINE_LOOP, shdr_pos, x, y, radius_x, radius_y, nsegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments)
|
void imm_draw_circle_dashed_3d(uint pos, float x, float y, float radius, int nsegments)
|
||||||
{
|
{
|
||||||
imm_draw_circle_3D(GPU_PRIM_LINES, pos, x, y, radius, nsegments / 2);
|
imm_draw_circle_3D(GPU_PRIM_LINES, pos, x, y, radius, radius, nsegments / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments)
|
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments)
|
||||||
{
|
{
|
||||||
imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius, nsegments);
|
imm_draw_circle_3D(GPU_PRIM_TRI_FAN, pos, x, y, radius, radius, nsegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
|
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
|
||||||
|
|||||||
Reference in New Issue
Block a user