Cleanup: replace the visible gizmo linked list with an array
Avoids an allocation per gizmo & simplifies limiting the lookup past the first intersecting 2D gizmo found.
This commit is contained in:
parent
a521ad7568
commit
ad80dc1c89
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_buffer.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_math.h"
|
||||
|
@ -191,14 +192,15 @@ wmGizmo *wm_gizmogroup_find_intersected_gizmo(const wmGizmoGroup *gzgroup,
|
|||
* Adds all gizmos of \a gzgroup that can be selected to the head of \a listbase.
|
||||
* Added items need freeing!
|
||||
*/
|
||||
void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup, ListBase *listbase)
|
||||
void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup,
|
||||
BLI_Buffer *visible_gizmos)
|
||||
{
|
||||
for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) {
|
||||
if ((gz->flag & (WM_GIZMO_HIDDEN | WM_GIZMO_HIDDEN_SELECT)) == 0) {
|
||||
if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) &&
|
||||
(gz->type->draw_select || gz->type->test_select)) ||
|
||||
((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) == 0 && gz->type->test_select)) {
|
||||
BLI_addhead(listbase, BLI_genericNodeN(gz));
|
||||
BLI_buffer_append(visible_gizmos, wmGizmo *, gz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef __WM_GIZMO_INTERN_H__
|
||||
#define __WM_GIZMO_INTERN_H__
|
||||
|
||||
struct BLI_Buffer;
|
||||
struct GHashIterator;
|
||||
struct GizmoGeomInfo;
|
||||
struct wmGizmoMap;
|
||||
|
@ -65,7 +66,7 @@ struct wmGizmo *wm_gizmogroup_find_intersected_gizmo(const struct wmGizmoGroup *
|
|||
const struct wmEvent *event,
|
||||
int *r_part);
|
||||
void wm_gizmogroup_intersectable_gizmos_to_list(const struct wmGizmoGroup *gzgroup,
|
||||
struct ListBase *listbase);
|
||||
struct BLI_Buffer *visible_gizmos);
|
||||
bool wm_gizmogroup_is_visible_in_drawstep(const struct wmGizmoGroup *gzgroup,
|
||||
const eWM_GizmoFlagMapDrawStep drawstep);
|
||||
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "BLI_buffer.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_bits.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_array.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
|
@ -470,24 +470,19 @@ void WM_gizmomap_draw(wmGizmoMap *gzmap,
|
|||
BLI_assert(BLI_listbase_is_empty(&draw_gizmos));
|
||||
}
|
||||
|
||||
static void gizmo_draw_select_3D_loop(const bContext *C,
|
||||
ListBase *visible_gizmos,
|
||||
const wmGizmo *gz_stop,
|
||||
static void gizmo_draw_select_3d_loop(const bContext *C,
|
||||
wmGizmo **visible_gizmos,
|
||||
const int visible_gizmos_len,
|
||||
bool *r_use_select_bias)
|
||||
{
|
||||
int select_id = 0;
|
||||
wmGizmo *gz;
|
||||
|
||||
/* TODO(campbell): this depends on depth buffer being written to,
|
||||
* currently broken for the 3D view. */
|
||||
bool is_depth_prev = false;
|
||||
bool is_depth_skip_prev = false;
|
||||
|
||||
for (LinkData *link = visible_gizmos->first; link; link = link->next, select_id++) {
|
||||
gz = link->data;
|
||||
if (gz == gz_stop) {
|
||||
break;
|
||||
}
|
||||
for (int select_id = 0; select_id < visible_gizmos_len; select_id++) {
|
||||
wmGizmo *gz = visible_gizmos[select_id];
|
||||
if (gz->type->draw_select == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
@ -531,11 +526,11 @@ static void gizmo_draw_select_3D_loop(const bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
|
||||
static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
|
||||
const int visible_gizmos_len,
|
||||
const bContext *C,
|
||||
const int co[2],
|
||||
const int hotspot,
|
||||
const wmGizmo *gz_stop)
|
||||
const int hotspot)
|
||||
{
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
|
@ -554,13 +549,13 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
|
|||
|
||||
GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
|
||||
/* do the drawing */
|
||||
gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop, &use_select_bias);
|
||||
gizmo_draw_select_3d_loop(C, visible_gizmos, visible_gizmos_len, &use_select_bias);
|
||||
|
||||
hits = GPU_select_end();
|
||||
|
||||
if (hits > 0) {
|
||||
GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
|
||||
gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop, &use_select_bias);
|
||||
gizmo_draw_select_3d_loop(C, visible_gizmos, visible_gizmos_len, &use_select_bias);
|
||||
GPU_select_end();
|
||||
}
|
||||
|
||||
|
@ -568,11 +563,6 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
|
|||
CTX_wm_window(C), CTX_data_depsgraph(C), CTX_data_scene(C), ar, v3d, NULL, NULL, NULL);
|
||||
|
||||
if (use_select_bias && (hits > 1)) {
|
||||
wmGizmo **gizmo_table = NULL;
|
||||
BLI_array_staticdeclare(gizmo_table, 1024);
|
||||
for (LinkData *link = visible_gizmos->first; link; link = link->next) {
|
||||
BLI_array_append(gizmo_table, link->data);
|
||||
}
|
||||
float co_direction[3];
|
||||
float co_screen[3] = {co[0], co[1], 0.0f};
|
||||
ED_view3d_win_to_vector(ar, (float[2]){UNPACK2(co)}, co_direction);
|
||||
|
@ -590,7 +580,7 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
|
|||
|
||||
for (int i = 0; i < hits; i++, buf_iter += 4) {
|
||||
BLI_assert(buf_iter[3] != -1);
|
||||
wmGizmo *gz = gizmo_table[buf_iter[3] >> 8];
|
||||
wmGizmo *gz = visible_gizmos[buf_iter[3] >> 8];
|
||||
float co_3d[3];
|
||||
co_screen[2] = int_as_float(buf_iter[1]);
|
||||
GPU_matrix_unproject_model_inverted(co_screen, rv3d->viewinv, rv3d->winmat, viewport, co_3d);
|
||||
|
@ -605,7 +595,6 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
|
|||
hit_found = buf_iter[3];
|
||||
}
|
||||
}
|
||||
BLI_array_free(gizmo_table);
|
||||
return hit_found;
|
||||
}
|
||||
else {
|
||||
|
@ -619,10 +608,12 @@ static int gizmo_find_intersected_3d_intern(ListBase *visible_gizmos,
|
|||
*/
|
||||
static wmGizmo *gizmo_find_intersected_3d(bContext *C,
|
||||
const int co[2],
|
||||
ListBase *visible_gizmos,
|
||||
wmGizmo **visible_gizmos,
|
||||
const int visible_gizmos_len,
|
||||
int *r_part)
|
||||
{
|
||||
wmGizmo *result = NULL;
|
||||
int visible_gizmos_len_trim = visible_gizmos_len;
|
||||
int hit = -1;
|
||||
|
||||
*r_part = 0;
|
||||
|
@ -633,14 +624,15 @@ static wmGizmo *gizmo_find_intersected_3d(bContext *C,
|
|||
/* Search for 3D gizmo's that use the 2D callback for checking intersections. */
|
||||
bool has_3d = false;
|
||||
{
|
||||
int select_id = 0;
|
||||
for (LinkData *link = visible_gizmos->first; link; link = link->next, select_id++) {
|
||||
wmGizmo *gz = link->data;
|
||||
for (int select_id = 0; select_id < visible_gizmos_len; select_id++) {
|
||||
wmGizmo *gz = visible_gizmos[select_id];
|
||||
/* With both defined, favor the 3D, incase the gizmo can be used in 2D or 3D views. */
|
||||
if (gz->type->test_select && (gz->type->draw_select == NULL)) {
|
||||
if ((*r_part = gz->type->test_select(C, gz, co)) != -1) {
|
||||
hit = select_id;
|
||||
result = gz;
|
||||
/* Don't search past this when checking intersections. */
|
||||
visible_gizmos_len_trim = select_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -659,23 +651,19 @@ static wmGizmo *gizmo_find_intersected_3d(bContext *C,
|
|||
10 * U.pixelsize,
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE(hotspot_radii); i++) {
|
||||
hit = gizmo_find_intersected_3d_intern(visible_gizmos, C, co, hotspot_radii[i], result);
|
||||
hit = gizmo_find_intersected_3d_intern(
|
||||
visible_gizmos, visible_gizmos_len_trim, C, co, hotspot_radii[i]);
|
||||
if (hit != -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hit != -1) {
|
||||
LinkData *link = BLI_findlink(visible_gizmos, hit >> 8);
|
||||
if (link != NULL) {
|
||||
*r_part = hit & 255;
|
||||
result = link->data;
|
||||
}
|
||||
else {
|
||||
/* All gizmos should use selection ID they're given as part of the callback,
|
||||
* if they don't it will attempt tp lookup non-existing index. */
|
||||
BLI_assert(0);
|
||||
}
|
||||
const int select_id = hit >> 8;
|
||||
const int select_part = hit & 0xff;
|
||||
BLI_assert(select_id < visible_gizmos_len);
|
||||
*r_part = select_part;
|
||||
result = visible_gizmos[select_id];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +680,7 @@ wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap,
|
|||
int *r_part)
|
||||
{
|
||||
wmGizmo *gz = NULL;
|
||||
ListBase visible_3d_gizmos = {NULL};
|
||||
BLI_buffer_declare_static(wmGizmo *, visible_3d_gizmos, BLI_BUFFER_NOP, 128);
|
||||
bool do_step[WM_GIZMOMAP_DRAWSTEP_MAX];
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(do_step); i++) {
|
||||
|
@ -735,13 +723,14 @@ wmGizmo *wm_gizmomap_highlight_find(wmGizmoMap *gzmap,
|
|||
}
|
||||
}
|
||||
|
||||
if (!BLI_listbase_is_empty(&visible_3d_gizmos)) {
|
||||
if (visible_3d_gizmos.count) {
|
||||
/* 2D gizmos get priority. */
|
||||
if (gz == NULL) {
|
||||
gz = gizmo_find_intersected_3d(C, event->mval, &visible_3d_gizmos, r_part);
|
||||
gz = gizmo_find_intersected_3d(
|
||||
C, event->mval, visible_3d_gizmos.data, visible_3d_gizmos.count, r_part);
|
||||
}
|
||||
BLI_freelistN(&visible_3d_gizmos);
|
||||
}
|
||||
BLI_buffer_free(&visible_3d_gizmos);
|
||||
|
||||
gzmap->update_flag[WM_GIZMOMAP_DRAWSTEP_3D] &= ~GIZMOMAP_IS_REFRESH_CALLBACK;
|
||||
gzmap->update_flag[WM_GIZMOMAP_DRAWSTEP_2D] &= ~GIZMOMAP_IS_REFRESH_CALLBACK;
|
||||
|
|
Loading…
Reference in New Issue