Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-08-10 10:32:40 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-08-10 10:32:40 +0300
commite18a2c4ed7b311fef620ac8faa09c9ce1490abc7 (patch)
treedac6e58843b62e4efac32563a052cd1ec657eaac
parent3daf5cc1ceb4854ba7ca481b9e2f1a5ed19bd2cb (diff)
Gizmo: support for 2D selection checks for 3D gizmos
This means 3D manipulators can use their own logic for checking if the cursor intersects.
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c2
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c83
2 files changed, 55 insertions, 30 deletions
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
index 5efc74b5bb8..3ba9fa71601 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
@@ -169,7 +169,7 @@ void wm_gizmogroup_intersectable_gizmos_to_list(const wmGizmoGroup *gzgroup, Lis
{
for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) {
if ((gz->flag & WM_GIZMO_HIDDEN) == 0) {
- if (((gzgroup->type->flag & WM_GIZMOGROUPTYPE_3D) && gz->type->draw_select) ||
+ 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));
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 9321ec674a9..0b54f0cbec1 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -453,7 +453,9 @@ void WM_gizmomap_draw(
BLI_assert(BLI_listbase_is_empty(&draw_gizmos));
}
-static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmos)
+static void gizmo_draw_select_3D_loop(
+ const bContext *C, ListBase *visible_gizmos,
+ const wmGizmo *gz_stop)
{
int select_id = 0;
wmGizmo *gz;
@@ -462,8 +464,14 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo
bool is_depth_prev = false;
bool is_depth_skip_prev = false;
- for (LinkData *link = visible_gizmos->first; link; link = link->next) {
+ for (LinkData *link = visible_gizmos->first; link; link = link->next, select_id++) {
gz = link->data;
+ if (gz == gz_stop) {
+ break;
+ }
+ if (gz->type->draw_select == NULL) {
+ continue;
+ }
bool is_depth = (gz->parent_gzgroup->type->flag & WM_GIZMOGROUPTYPE_DEPTH_3D) != 0;
if (is_depth == is_depth_prev) {
@@ -490,9 +498,6 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo
/* pass the selection id shifted by 8 bits. Last 8 bits are used for selected gizmo part id */
gz->type->draw_select(C, gz, select_id << 8);
-
-
- select_id++;
}
if (is_depth_prev) {
@@ -505,7 +510,7 @@ static void gizmo_draw_select_3D_loop(const bContext *C, ListBase *visible_gizmo
static int gizmo_find_intersected_3d_intern(
ListBase *visible_gizmos, const bContext *C, const int co[2],
- const int hotspot)
+ const int hotspot, const wmGizmo *gz_stop)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -525,13 +530,13 @@ static int gizmo_find_intersected_3d_intern(
else
GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_ALL, 0);
/* do the drawing */
- gizmo_draw_select_3D_loop(C, visible_gizmos);
+ gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop);
hits = GPU_select_end();
if (do_passes && (hits > 0)) {
GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
- gizmo_draw_select_3D_loop(C, visible_gizmos);
+ gizmo_draw_select_3D_loop(C, visible_gizmos, gz_stop);
GPU_select_end();
}
@@ -552,36 +557,56 @@ static wmGizmo *gizmo_find_intersected_3d(
wmGizmo *result = NULL;
int hit = -1;
- int hotspot_radii[] = {
- 3 * U.pixelsize,
- /* This runs on mouse move, careful doing too many tests! */
- 10 * U.pixelsize,
- };
-
*r_part = 0;
/* set up view matrices */
view3d_operator_needs_opengl(C);
- hit = -1;
-
- for (int i = 0; i < ARRAY_SIZE(hotspot_radii); i++) {
- hit = gizmo_find_intersected_3d_intern(visible_gizmos, C, co, hotspot_radii[i]);
- if (hit != -1) {
- break;
+ /* 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;
+ if (gz->type->test_select) {
+ if ((*r_part = gz->type->test_select(C, gz, co)) != -1) {
+ hit = select_id;
+ result = gz;
+ break;
+ }
+ }
+ else {
+ has_3d = true;
+ }
}
}
- if (hit != -1) {
- LinkData *link = BLI_findlink(visible_gizmos, hit >> 8);
- if (link != NULL) {
- *r_part = hit & 255;
- result = link->data;
+ /* Search for 3D intersections if they're before 2D that have been found (if any).
+ * This way we always use the first hit. */
+ if (has_3d) {
+ const int hotspot_radii[] = {
+ 3 * U.pixelsize,
+ /* This runs on mouse move, careful doing too many tests! */
+ 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);
+ if (hit != -1) {
+ break;
+ }
}
- 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);
+
+ 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);
+ }
}
}