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-09 19:15:58 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-03-09 21:00:49 +0300
commit62cc226101fab61b5ae2f18f8cbe8f1e5ac6ce82 (patch)
tree52a6a05b1c103c0601b2465892163bc36325241d /source/blender/editors
parent9de9f25b2455808335b5373003695610599daab7 (diff)
3D View: x-ray support for depth picking
Selection loop would draw the selection ignoring xray. Now draw in a separate pass after clearing the depth buffer, as with regular drawing. Also disable depth sorting, caller can sort the hit-list by depth if needed.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/space_view3d/drawobject.c44
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c82
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h8
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c77
4 files changed, 136 insertions, 75 deletions
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 90d33dc5995..898f155cc92 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -8174,6 +8174,50 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
ED_view3d_clear_mats_rv3d(rv3d);
}
+
+/**
+ * Drawing for selection picking,
+ * caller must have called 'GPU_select_load_id(base->selcode)' first.
+ */
+void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag)
+{
+ BLI_assert(dflag & DRAW_PICKING && dflag & DRAW_CONSTCOLOR);
+ draw_object(scene, ar, v3d, base, dflag);
+
+ /* we draw duplicators for selection too */
+ if ((base->object->transflag & OB_DUPLI)) {
+ ListBase *lb;
+ DupliObject *dob;
+ Base tbase;
+
+ tbase.flag = OB_FROMDUPLI;
+ lb = object_duplilist(G.main->eval_ctx, scene, base->object);
+
+ for (dob = lb->first; dob; dob = dob->next) {
+ float omat[4][4];
+ char dt;
+ short dtx;
+
+ tbase.object = dob->ob;
+ copy_m4_m4(omat, dob->ob->obmat);
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+
+ /* extra service: draw the duplicator in drawtype of parent */
+ /* MIN2 for the drawtype to allow bounding box objects in groups for lods */
+ dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
+ dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
+
+ draw_object(scene, ar, v3d, &tbase, dflag);
+
+ tbase.object->dt = dt;
+ tbase.object->dtx = dtx;
+
+ copy_m4_m4(dob->ob->obmat, omat);
+ }
+ free_object_duplilist(lb);
+ }
+}
+
/* ***************** BACKBUF SEL (BBS) ********* */
static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const float co[3],
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 0c5cf1bd936..3fb2761d40e 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -100,6 +100,7 @@
#include "GPU_material.h"
#include "GPU_compositing.h"
#include "GPU_extensions.h"
+#include "GPU_select.h"
#include "view3d_intern.h" /* own include */
@@ -2023,6 +2024,35 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, const
glDepthMask(GL_TRUE);
}
+/* clears zbuffer and draws it over,
+ * note that in the select version we don't care about transparent flag as with regular drawing */
+static void view3d_draw_xray_select(Scene *scene, ARegion *ar, View3D *v3d, bool *clear)
+{
+ /* Not ideal, but we need to read from the previous depths before clearing
+ * otherwise we could have a function to load the depths after drawing.
+ *
+ * Clearing the depth buffer isn't all that common between drawing objects so accept this for now.
+ */
+ if (U.gpu_select_pick_deph) {
+ GPU_select_load_id(-1);
+ }
+
+ View3DAfter *v3da;
+ if (*clear && v3d->zbuf) {
+ glClear(GL_DEPTH_BUFFER_BIT);
+ *clear = false;
+ }
+
+ v3d->xray = true;
+ while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
+ if (GPU_select_load_id(v3da->base->selcol)) {
+ draw_object_select(scene, ar, v3d, v3da->base, v3da->dflag);
+ }
+ MEM_freeN(v3da);
+ }
+ v3d->xray = false;
+}
+
/* *********************** */
/*
@@ -2487,6 +2517,58 @@ void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaover
U.obcenter_dia = obcenter_dia;
}
+void ED_view3d_draw_select_loop(
+ ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
+ bool use_obedit_skip, bool use_nearest)
+{
+ short code = 1;
+ const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR;
+
+ if (vc->obedit && vc->obedit->type == OB_MBALL) {
+ draw_object(scene, ar, v3d, BASACT, dflag);
+ }
+ else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
+ /* if not drawing sketch, draw bones */
+ if (!BDR_drawSketchNames(vc)) {
+ draw_object(scene, ar, v3d, BASACT, dflag);
+ }
+ }
+ else {
+ Base *base;
+
+ for (base = scene->base.first; base; base = base->next) {
+ if (base->lay & v3d->lay) {
+
+ if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
+ (use_obedit_skip && (scene->obedit->data == base->object->data)))
+ {
+ base->selcol = 0;
+ }
+ else {
+ base->selcol = code;
+
+ if (use_nearest && (base->object->dtx & OB_DRAWXRAY)) {
+ ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag);
+ }
+ else {
+ if (GPU_select_load_id(code)) {
+ draw_object_select(scene, ar, v3d, base, dflag);
+ }
+ }
+ code++;
+ }
+ }
+ }
+
+ if (use_nearest) {
+ bool xrayclear = true;
+ if (v3d->afterdraw_xray.first) {
+ view3d_draw_xray_select(scene, ar, v3d, &xrayclear);
+ }
+ }
+ }
+}
+
typedef struct View3DShadow {
struct View3DShadow *next, *prev;
GPULamp *lamp;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 87b3d95cd4e..c2b8d1f8bda 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -143,6 +143,8 @@ void draw_motion_paths_cleanup(View3D *v3d);
/* drawobject.c */
void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, const short dflag);
+void draw_object_select(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag);
+
bool draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const char dt);
void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline);
void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
@@ -195,7 +197,11 @@ void draw_sim_debug_data(Scene *scene, View3D *v3d, ARegion *ar);
void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar);
void ED_view3d_draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, bool alphaoverride);
void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d);
-void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);
+void ED_view3d_draw_select_loop(
+ ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar,
+ bool use_obedit_skip, bool use_nearest);
+
+void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag);\
void circf(float x, float y, float rad);
void circ(float x, float y, float rad);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index e8deaabec7a..8230a0de6b9 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1091,78 +1091,6 @@ void view3d_viewmatrix_set(Scene *scene, const View3D *v3d, RegionView3D *rv3d)
}
}
-static void view3d_select_loop(ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar, bool use_obedit_skip)
-{
- short code = 1;
- char dt;
- short dtx;
-
- if (vc->obedit && vc->obedit->type == OB_MBALL) {
- draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
- }
- else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
- /* if not drawing sketch, draw bones */
- if (!BDR_drawSketchNames(vc)) {
- draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
- }
- }
- else {
- Base *base;
-
- v3d->xray = true; /* otherwise it postpones drawing */
- for (base = scene->base.first; base; base = base->next) {
- if (base->lay & v3d->lay) {
-
- if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
- (use_obedit_skip && (scene->obedit->data == base->object->data)))
- {
- base->selcol = 0;
- }
- else {
- base->selcol = code;
-
- if (GPU_select_load_id(code)) {
- draw_object(scene, ar, v3d, base, DRAW_PICKING | DRAW_CONSTCOLOR);
-
- /* we draw duplicators for selection too */
- if ((base->object->transflag & OB_DUPLI)) {
- ListBase *lb;
- DupliObject *dob;
- Base tbase;
-
- tbase.flag = OB_FROMDUPLI;
- lb = object_duplilist(G.main->eval_ctx, scene, base->object);
-
- for (dob = lb->first; dob; dob = dob->next) {
- float omat[4][4];
-
- tbase.object = dob->ob;
- copy_m4_m4(omat, dob->ob->obmat);
- copy_m4_m4(dob->ob->obmat, dob->mat);
-
- /* extra service: draw the duplicator in drawtype of parent */
- /* MIN2 for the drawtype to allow bounding box objects in groups for lods */
- dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
- dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
-
- draw_object(scene, ar, v3d, &tbase, DRAW_PICKING | DRAW_CONSTCOLOR);
-
- tbase.object->dt = dt;
- tbase.object->dtx = dtx;
-
- copy_m4_m4(dob->ob->obmat, omat);
- }
- free_object_duplilist(lb);
- }
- }
- code++;
- }
- }
- }
- v3d->xray = false; /* restore */
- }
-}
-
/**
* Optionally cache data for multiple calls to #view3d_opengl_select
*
@@ -1200,6 +1128,7 @@ int view3d_opengl_select(
(is_pick_select == false) &&
(select_mode == VIEW3D_SELECT_PICK_NEAREST) &&
GPU_select_query_check_active());
+ const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST);
char gpu_select_mode;
@@ -1256,7 +1185,7 @@ int view3d_opengl_select(
GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
- view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip);
+ ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
hits = GPU_select_end();
@@ -1264,7 +1193,7 @@ int view3d_opengl_select(
if (do_passes) {
GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
- view3d_select_loop(vc, scene, v3d, ar, use_obedit_skip);
+ ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
GPU_select_end();
}