DRW: Selection Occlusion #105498
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
|
@ -138,29 +140,44 @@ static void select_cache_init(void *vedata)
|
|||
DRWState state = DRW_STATE_DEFAULT;
|
||||
state |= RV3D_CLIPPING_ENABLED(draw_ctx->v3d, draw_ctx->rv3d) ? DRW_STATE_CLIP_PLANES : 0;
|
||||
|
||||
bool retopology_occlusion = RETOPOLOGY_ENABLED(draw_ctx->v3d) && !XRAY_ENABLED(draw_ctx->v3d);
|
||||
float retopology_offset = RETOPOLOGY_OFFSET(draw_ctx->v3d);
|
||||
|
||||
{
|
||||
DRW_PASS_CREATE(psl->depth_only_pass, state);
|
||||
pd->shgrp_depth_only = DRW_shgroup_create(sh->select_id_uniform, psl->depth_only_pass);
|
||||
/* Not setting ID because this pass only draws to the depth buffer. */
|
||||
DRW_shgroup_uniform_float_copy(pd->shgrp_depth_only, "retopologyOffset", retopology_offset);
|
||||
|
||||
if (retopology_occlusion) {
|
||||
pd->shgrp_occlude = DRW_shgroup_create(sh->select_id_uniform, psl->depth_only_pass);
|
||||
fclem marked this conversation as resolved
Outdated
|
||||
/* Not setting ID because this pass only draws to the depth buffer. */
|
||||
DRW_shgroup_uniform_float_copy(pd->shgrp_occlude, "retopologyOffset", 0.0f);
|
||||
}
|
||||
|
||||
DRW_PASS_CREATE(psl->select_id_face_pass, state);
|
||||
if (e_data.context.select_mode & SCE_SELECT_FACE) {
|
||||
pd->shgrp_face_flat = DRW_shgroup_create(sh->select_id_flat, psl->select_id_face_pass);
|
||||
DRW_shgroup_uniform_float_copy(pd->shgrp_face_flat, "retopologyOffset", retopology_offset);
|
||||
}
|
||||
else {
|
||||
pd->shgrp_face_unif = DRW_shgroup_create(sh->select_id_uniform, psl->select_id_face_pass);
|
||||
DRW_shgroup_uniform_int_copy(pd->shgrp_face_unif, "id", 0);
|
||||
DRW_shgroup_uniform_float_copy(pd->shgrp_face_unif, "retopologyOffset", retopology_offset);
|
||||
}
|
||||
|
||||
if (e_data.context.select_mode & SCE_SELECT_EDGE) {
|
||||
DRW_PASS_CREATE(psl->select_id_edge_pass, state | DRW_STATE_FIRST_VERTEX_CONVENTION);
|
||||
|
||||
pd->shgrp_edge = DRW_shgroup_create(sh->select_id_flat, psl->select_id_edge_pass);
|
||||
DRW_shgroup_uniform_float_copy(pd->shgrp_edge, "retopologyOffset", retopology_offset);
|
||||
}
|
||||
|
||||
if (e_data.context.select_mode & SCE_SELECT_VERTEX) {
|
||||
DRW_PASS_CREATE(psl->select_id_vert_pass, state);
|
||||
pd->shgrp_vert = DRW_shgroup_create(sh->select_id_flat, psl->select_id_vert_pass);
|
||||
DRW_shgroup_uniform_float_copy(pd->shgrp_vert, "sizeVertex", 2 * G_draw.block.size_vertex);
|
||||
DRW_shgroup_uniform_float_copy(pd->shgrp_vert, "retopologyOffset", retopology_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,6 +214,14 @@ static void select_cache_populate(void *vedata, Object *ob)
|
|||
SELECTID_StorageList *stl = ((SELECTID_Data *)vedata)->stl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
if (!DRW_object_is_in_edit_mode(ob)) {
|
||||
if (ob->dt >= OB_SOLID) {
|
||||
struct GPUBatch *geom_faces = DRW_mesh_batch_cache_get_surface(ob->data);
|
||||
DRW_shgroup_call_obmat(stl->g_data->shgrp_occlude, geom_faces, ob->object_to_world);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SELECTID_ObjectData *sel_data = (SELECTID_ObjectData *)DRW_drawdata_get(
|
||||
&ob->id, &draw_engine_select_type);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ typedef struct SELECTID_Shaders {
|
|||
|
||||
typedef struct SELECTID_PrivateData {
|
||||
DRWShadingGroup *shgrp_depth_only;
|
||||
DRWShadingGroup *shgrp_occlude;
|
||||
DRWShadingGroup *shgrp_face_unif;
|
||||
DRWShadingGroup *shgrp_face_flat;
|
||||
DRWShadingGroup *shgrp_edge;
|
||||
|
|
|
@ -11,6 +11,7 @@ GPU_SHADER_INTERFACE_INFO(select_id_iface, "").flat(Type::INT, "id");
|
|||
GPU_SHADER_CREATE_INFO(select_id_flat)
|
||||
.push_constant(Type::FLOAT, "sizeVertex")
|
||||
.push_constant(Type::INT, "offset")
|
||||
.push_constant(Type::FLOAT, "retopologyOffset")
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.vertex_in(1, Type::INT, "index")
|
||||
.vertex_out(select_id_iface)
|
||||
|
@ -24,6 +25,7 @@ GPU_SHADER_CREATE_INFO(select_id_uniform)
|
|||
.define("UNIFORM_ID")
|
||||
.push_constant(Type::FLOAT, "sizeVertex")
|
||||
.push_constant(Type::INT, "id")
|
||||
.push_constant(Type::FLOAT, "retopologyOffset")
|
||||
.vertex_in(0, Type::VEC3, "pos")
|
||||
.fragment_out(0, Type::UINT, "fragColor")
|
||||
.vertex_source("select_id_vert.glsl")
|
||||
|
|
|
@ -8,8 +8,12 @@ void main()
|
|||
#endif
|
||||
|
||||
vec3 world_pos = point_object_to_world(pos);
|
||||
gl_Position = point_world_to_ndc(world_pos);
|
||||
vec3 view_pos = point_world_to_view(world_pos);
|
||||
gl_Position = point_view_to_ndc(view_pos);
|
||||
gl_PointSize = sizeVertex;
|
||||
|
||||
/* Offset Z position for retopology selection occlusion. */
|
||||
gl_Position.z += get_homogenous_z_offset(view_pos.z, gl_Position.w, retopologyOffset);
|
||||
|
||||
view_clipping_distances(world_pos);
|
||||
}
|
||||
|
|
|
@ -2770,6 +2770,25 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
|
|||
drw_engines_cache_populate(obj_eval);
|
||||
}
|
||||
|
||||
if (RETOPOLOGY_ENABLED(v3d) && !XRAY_ENABLED(v3d)) {
|
||||
DEGObjectIterSettings deg_iter_settings = {0};
|
||||
deg_iter_settings.depsgraph = depsgraph;
|
||||
deg_iter_settings.flags = DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS;
|
||||
DEG_OBJECT_ITER_BEGIN (°_iter_settings, ob) {
|
||||
Jeroen Bakker
commented
Draw manager should be as functionality agnostic as much as possible. Adding this if-statement might be ok as we also check if bone overlay is enabled. But the if statements inside the iterator should be done by the draw engines. Selection engine is currently being redesigned. I think @fclem @pragma37 can do a better review of this part keeping in mind the new design. Draw manager should be as functionality agnostic as much as possible. Adding this if-statement might be ok as we also check if bone overlay is enabled. But the if statements inside the iterator should be done by the draw engines.
Selection engine is currently being redesigned. I think @fclem @pragma37 can do a better review of this part keeping in mind the new design.
Clément Foucault
commented
Well this is extending the already existing edit mode selection path. I really don't see the problem as other part of the draw-manager are state aware of the View3D. Obviously this will need to be fitted to the new selection engine but that's not a project for the 3.6 release. Also note that #102177 is only targeting object selection mode. Well this is extending the already existing edit mode selection path. I really don't see the problem as other part of the draw-manager are state aware of the View3D. Obviously this will need to be fitted to the new selection engine but that's not a project for the 3.6 release.
Also note that #102177 is only targeting object selection mode.
|
||||
if (ob->type != OB_MESH) {
|
||||
/* The iterator has evaluated meshes for all solid objects.
|
||||
* It also has non-mesh objects however, which are not supported here. */
|
||||
continue;
|
||||
}
|
||||
if (DRW_object_is_in_edit_mode(ob)) {
|
||||
/* Only background (non-edit) objects are used for occlusion. */
|
||||
continue;
|
||||
}
|
||||
drw_engines_cache_populate(ob);
|
||||
}
|
||||
DEG_OBJECT_ITER_END;
|
||||
bonj marked this conversation as resolved
Outdated
Germano Cavalcante
commented
It might be interesting to put this code inside a condition that checks if it's not X-Ray or wireframe. It may even improve readability. Why only objects of type It might be interesting to put this code inside a condition that checks if it's not X-Ray or wireframe. It may even improve readability.
Why only objects of type `OB_MESH` have the depth drawn? It may be good to comment on the reason.
Germano Cavalcante
commented
Not that it's a problem, but another way to make comments more localized could be:
I'm wondering if Grease Pencil and Image-type Empties couldn't contribute to the depth. But if it matches what you see in the Meshes edit overlay then it's OK. Not that it's a problem, but another way to make comments more localized could be:
```
if (ob->type != OB_MESH) {
/* Non-mesh objects are not supported here. */
continue;
}
if (DRW_object_is_in_edit_mode(ob)) {
/* Only background (non-edit) objects are used for occlusion. */
continue;
}
```
I'm wondering if Grease Pencil and Image-type Empties couldn't contribute to the depth. But if it matches what you see in the Meshes edit overlay then it's OK.
|
||||
}
|
||||
|
||||
drw_engines_cache_finish();
|
||||
|
||||
drw_task_graph_deinit();
|
||||
|
|
|
@ -4551,7 +4551,10 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
|
|||
|
||||
prop = RNA_def_property(srna, "show_retopology", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "overlay.edit_flag", V3D_OVERLAY_EDIT_RETOPOLOGY);
|
||||
RNA_def_property_ui_text(prop, "Retopology", "Use retopology display");
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Retopology",
|
||||
"Hide the solid mesh and offset the overlay towards the view. "
|
||||
"Selection is occluded by inactive geometry, unless X-Ray is enabled");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "retopology_offset", PROP_FLOAT, PROP_DISTANCE);
|
||||
|
|
This feels weird to me. Why is this group using
id == 0
whenshgrp_depth_only
doesn't? I think it is better to be consistent and set it for both cases. Also I wouldn't mind adding a comment saying this id isn't actually used since the pass is written on a depth only framebuffer.