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>2017-03-08 21:17:55 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-03-08 22:22:02 +0300
commit45b764e95b9e34cb17dece1cd37eb80dafa1924f (patch)
treeeb5507c581ae586a20b4585693b694859827fa00 /source/blender/editors/space_view3d/view3d_select.c
parent817e975dee27640947bf7d083db39d1d70120385 (diff)
3D View: new nethod of opengl selection
Intended to replace legacy GL_SELECT, without the limitations of sample queries which can't access depth information. This commit adds VIEW3D_SELECT_PICK_NEAREST and VIEW3D_SELECT_PICK_ALL which access the depth buffers to detect whats under the pointer, so initial selection is always the closest item. The performance of this method depends a lot on the OpenGL implementations glReadPixels. Since reading depth can be slow, buffers are cached for object picking so selecting re-uses depth data, performing 1 draw instead of 3 (for 24, 18, 10 px regions, picking with many items under the pointer). Occlusion queries draw twice when picking nearest, so worst case 6x draw calls per selection. Even with these improvements occlusion queries is faster on AMD hardware. Depth selection is disabled by default, toggle option under select method. May enable by default if this works well on different hardware. Reviewed as D2543
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_select.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 49f24ef634f..0b3468f2c23 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -96,8 +96,12 @@
#include "GPU_draw.h"
+#include "GPU_select.h"
+
#include "view3d_intern.h" /* own include */
+// #include "PIL_time_utildefines.h"
+
float ED_view3d_select_dist_px(void)
{
return 75.0f * U.pixelsize;
@@ -1091,7 +1095,7 @@ static Base *object_mouse_select_menu(
bContext *C, ViewContext *vc, unsigned int *buffer, int hits,
const int mval[2], bool toggle)
{
- int baseCount = 0;
+ short baseCount = 0;
bool ok;
LinkNode *linklist = NULL;
@@ -1236,44 +1240,56 @@ static int mixed_bones_object_selectbuffer(
do_nearest = do_nearest && !enumerate;
+ const int select_mode = (do_nearest ? VIEW3D_SELECT_PICK_NEAREST : VIEW3D_SELECT_PICK_ALL);
+ int hits = 0;
+
+ /* we _must_ end cache before return, use 'goto finally' */
+ GPU_select_cache_begin();
+
BLI_rcti_init_pt_radius(&rect, mval, 14);
- hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, do_nearest);
+ hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode);
if (hits15 == 1) {
- return selectbuffer_ret_hits_15(buffer, hits15);
+ hits = selectbuffer_ret_hits_15(buffer, hits15);
+ goto finally;
}
else if (hits15 > 0) {
has_bones15 = selectbuffer_has_bones(buffer, hits15);
offs = 4 * hits15;
BLI_rcti_init_pt_radius(&rect, mval, 9);
- hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, do_nearest);
+ hits9 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
if (hits9 == 1) {
- return selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
+ goto finally;
}
else if (hits9 > 0) {
has_bones9 = selectbuffer_has_bones(buffer + offs, hits9);
offs += 4 * hits9;
BLI_rcti_init_pt_radius(&rect, mval, 5);
- hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, do_nearest);
+ hits5 = view3d_opengl_select(vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
if (hits5 == 1) {
- return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
+ goto finally;
}
else if (hits5 > 0) {
has_bones5 = selectbuffer_has_bones(buffer + offs, hits5);
}
}
- if (has_bones5) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
- else if (has_bones9) return selectbuffer_ret_hits_9(buffer, hits15, hits9);
- else if (has_bones15) return selectbuffer_ret_hits_15(buffer, hits15);
-
- if (hits5 > 0) return selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
- else if (hits9 > 0) return selectbuffer_ret_hits_9(buffer, hits15, hits9);
- else return selectbuffer_ret_hits_15(buffer, hits15);
+ if (has_bones5) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; }
+ else if (has_bones9) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; }
+ else if (has_bones15) { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; }
+
+ if (hits5 > 0) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; }
+ else if (hits9 > 0) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; }
+ else { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; }
}
-
- return 0;
+
+finally:
+ GPU_select_cache_end();
+
+ return hits;
}
/* returns basact */
@@ -1466,10 +1482,13 @@ static bool ed_object_select_pick(
unsigned int buffer[MAXPICKBUF];
bool do_nearest;
+ // TIMEIT_START(select_time);
+
/* if objects have posemode set, the bones are in the same selection buffer */
-
hits = mixed_bones_object_selectbuffer(&vc, buffer, mval, true, enumerate, &do_nearest);
-
+
+ // TIMEIT_END(select_time);
+
if (hits > 0) {
/* note: bundles are handling in the same way as bones */
const bool has_bones = selectbuffer_has_bones(buffer, hits);
@@ -1908,7 +1927,7 @@ static int do_meta_box_select(ViewContext *vc, rcti *rect, bool select, bool ext
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false);
+ hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
if (extend == false && select)
BKE_mball_deselect_all(mb);
@@ -1942,7 +1961,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, false);
+ hits = view3d_opengl_select(vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
/* clear flag we use to detect point was affected */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next)
@@ -2039,7 +2058,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
/* selection buffer now has bones potentially too, so we add MAXPICKBUF */
vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer");
- hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, false);
+ hits = view3d_opengl_select(vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL);
/*
* LOGIC NOTES (theeth):
* The buffer and ListBase have the same relative order, which makes the selection