diff options
Diffstat (limited to 'source')
14 files changed, 268 insertions, 19 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 64a5caf80d4..950adf3ddc5 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -293,6 +293,7 @@ data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_facefill_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_frag.glsl SRC) data_to_c_simple(modes/shaders/edit_mesh_overlay_mesh_analysis_vert.glsl SRC) +data_to_c_simple(modes/shaders/edit_mesh_skin_root_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_handle_vert.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_handle_geom.glsl SRC) data_to_c_simple(modes/shaders/edit_curve_overlay_loosevert_vert.glsl SRC) diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl index 1f68935403c..511c243b474 100644 --- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl @@ -140,6 +140,10 @@ float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); } +float min_v4(vec4 v) +{ + return min(min(v.x, v.y), min(v.z, v.w)); +} float max_v2(vec2 v) { return max(v.x, v.y); @@ -148,6 +152,10 @@ float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); } +float max_v4(vec4 v) +{ + return max(max(v.x, v.y), max(v.z, v.w)); +} float sum(vec2 v) { diff --git a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl index 86f53522bc6..6531ceb8dbe 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl @@ -70,6 +70,18 @@ float light_translucent_power_with_falloff(LightData ld, vec3 N, vec4 l_vector) #define scube(x) shadows_cube_data[x] #define scascade(x) shadows_cascade_data[x] +float shadow_cube_radial_depth(vec3 cubevec, float tex_id, int shadow_id) +{ + float depth = sample_cube(sssShadowCubes, cubevec, tex_id).r; + /* To reverting the constant bias from shadow rendering. (Tweaked for 16bit shadowmaps) */ + const float depth_bias = 3.1e-5; + depth = saturate(depth - depth_bias); + + depth = linear_depth(true, depth, sd(shadow_id).sh_far, sd(shadow_id).sh_near); + depth *= length(cubevec / max_v3(abs(cubevec))); + return depth; +} + vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, vec2 rand, float sss_scale) { int shadow_id = int(ld.l_shadowid); @@ -79,12 +91,12 @@ vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, vec2 rand, f /* We use the full l_vector.xyz so that the spread is minimize * if the shading point is further away from the light source */ /* TODO(fclem) do something better than this. */ - // vec3 T, B; - // make_orthonormal_basis(L.xyz / L.w, T, B); - // rand.xy *= data.sh_blur; - // W = W + T * rand.x + B * rand.y; + vec3 T, B; + make_orthonormal_basis(L.xyz / L.w, T, B); - float s, dist; + vec3 n; + vec4 depths; + float d, dist; int data_id = int(sd(shadow_id).sh_data_index); if (ld.l_type == SUN) { vec4 view_z = vec4(dot(W - cameraPos, cameraForward)); @@ -105,20 +117,62 @@ vec3 light_translucent(LightData ld, vec3 W, vec3 N, vec4 l_vector, vec2 rand, f return vec3(0.0); } - float tex_id = scascade(data_id).sh_tex_index; - s = sample_cascade(sssShadowCascades, shpos.xy, tex_id + id).r; - s *= range; + float tex_id = scascade(data_id).sh_tex_index + id; + + /* Assume cascades have same height and width. */ + vec2 ofs = vec2(1.0, 0.0) / float(textureSize(sssShadowCascades, 0).x); + d = sample_cascade(sssShadowCascades, shpos.xy, tex_id).r; + depths.x = sample_cascade(sssShadowCascades, shpos.xy + ofs.xy, tex_id).r; + depths.y = sample_cascade(sssShadowCascades, shpos.xy + ofs.yx, tex_id).r; + depths.z = sample_cascade(sssShadowCascades, shpos.xy - ofs.xy, tex_id).r; + depths.w = sample_cascade(sssShadowCascades, shpos.xy - ofs.yx, tex_id).r; + + /* To reverting the constant bias from shadow rendering. (Tweaked for 16bit shadowmaps) */ + float depth_bias = 3.1e-5; + depths = saturate(depths - depth_bias); + d = saturate(d - depth_bias); + + /* Size of a texel in world space. + * FIXME This is only correct if l_right is the same right vector used for shadowmap creation. + * This won't work if the shadow matrix is rotated (soft shadows). + * TODO precompute */ + float unit_world_in_uv_space = length(mat3(scascade(data_id).shadowmat[int(id)]) * ld.l_right); + float dx_scale = 2.0 * ofs.x / unit_world_in_uv_space; + + d *= range; + depths *= range; + + /* This is the normal of the occluder in world space. */ + // vec3 T = ld.l_forward * dx + ld.l_right * dx_scale; + // vec3 B = ld.l_forward * dy + ld.l_up * dx_scale; + // n = normalize(cross(T, B)); } else { + float ofs = 1.0 / float(textureSize(sssShadowCubes, 0).x); + vec3 cubevec = transform_point(scube(data_id).shadowmat, W); dist = length(cubevec); cubevec /= dist; /* tex_id == data_id for cube shadowmap */ float tex_id = float(data_id); - s = sample_cube(sssShadowCubes, cubevec, tex_id).r; - s = length(cubevec / max_v3(abs(cubevec))) * - linear_depth(true, s, sd(shadow_id).sh_far, sd(shadow_id).sh_near); + d = shadow_cube_radial_depth(cubevec, tex_id, shadow_id); + /* NOTE: The offset is irregular in respect to cubeface uvs. But it has + * a much more uniform behavior than biasing based on face derivatives. */ + depths.x = shadow_cube_radial_depth(cubevec + T * ofs, tex_id, shadow_id); + depths.y = shadow_cube_radial_depth(cubevec + B * ofs, tex_id, shadow_id); + depths.z = shadow_cube_radial_depth(cubevec - T * ofs, tex_id, shadow_id); + depths.w = shadow_cube_radial_depth(cubevec - B * ofs, tex_id, shadow_id); } + + float dx = depths.x - depths.z; + float dy = depths.y - depths.w; + + float s = min(d, min_v4(depths)); + + /* To avoid light leak from depth discontinuity and shadowmap aliasing. */ + float slope_bias = (abs(dx) + abs(dy)) * 0.5; + s -= slope_bias; + float delta = dist - s; float power = light_translucent_power_with_falloff(ld, N, l_vector); diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl index b1c78cae54f..6427f02ed25 100644 --- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl @@ -70,7 +70,6 @@ vec2 cubeFaceCoordEEVEE(vec3 P, float face, sampler2DArrayShadow tex) vec4 sample_cube(sampler2DArray tex, vec3 cubevec, float cube) { /* Manual Shadow Cube Layer indexing. */ - /* TODO Shadow Cube Array. */ float face = cubeFaceIndexEEVEE(cubevec); vec2 uv = cubeFaceCoordEEVEE(cubevec, face, tex); diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index 46193e255b5..b1eab3c73ae 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -81,7 +81,7 @@ BLI_INLINE int mesh_render_mat_len_get(Mesh *me) typedef struct MeshBufferCache { /* Every VBO below contains at least enough - * data for every loops in the mesh (except fdots). + * data for every loops in the mesh (except fdots and skin roots). * For some VBOs, it extends to (in this exact order) : * loops + loose_edges*2 + loose_verts */ struct { @@ -104,6 +104,7 @@ typedef struct MeshBufferCache { GPUVertBuf *fdots_uv; // GPUVertBuf *fdots_edit_data; /* inside fdots_nor for now. */ GPUVertBuf *fdots_edituv_data; + GPUVertBuf *skin_roots; /* Selection */ GPUVertBuf *vert_idx; /* extend */ GPUVertBuf *edge_idx; /* extend */ @@ -157,6 +158,7 @@ typedef enum DRWBatchFlag { MBC_WIRE_LOOPS = (1 << 24), MBC_WIRE_LOOPS_UVS = (1 << 25), MBC_SURF_PER_MAT = (1 << 26), + MBC_SKIN_ROOTS = (1 << 27), } DRWBatchFlag; #define MBC_EDITUV \ @@ -185,6 +187,7 @@ typedef struct MeshBatchCache { GPUBatch *edit_lnor; GPUBatch *edit_fdots; GPUBatch *edit_mesh_analysis; + GPUBatch *edit_skin_roots; /* Edit UVs */ GPUBatch *edituv_faces_stretch_area; GPUBatch *edituv_faces_stretch_angle; diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index 2ac97196b99..0479bdd4de7 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -3860,6 +3860,69 @@ static const MeshExtract extract_fdots_edituv_data = { /** \} */ /* ---------------------------------------------------------------------- */ +/** \name Extract Skin Modifier Roots + * \{ */ + +typedef struct SkinRootData { + float size; + float local_pos[3]; +} SkinRootData; + +static void *extract_skin_roots_init(const MeshRenderData *mr, void *buf) +{ + /* Exclusively for edit mode. */ + BLI_assert(mr->bm); + + static GPUVertFormat format = {0}; + if (format.attr_len == 0) { + GPU_vertformat_attr_add(&format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(&format, "local_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + } + GPUVertBuf *vbo = buf; + GPU_vertbuf_init_with_format(vbo, &format); + GPU_vertbuf_data_alloc(vbo, mr->bm->totvert); + + SkinRootData *vbo_data = (SkinRootData *)vbo->data; + + int root_len = 0; + int cd_ofs = CustomData_get_offset(&mr->bm->vdata, CD_MVERT_SKIN); + + BMIter iter; + BMVert *eve; + BM_ITER_MESH (eve, &iter, mr->bm, BM_VERTS_OF_MESH) { + const MVertSkin *vs = BM_ELEM_CD_GET_VOID_P(eve, cd_ofs); + if (vs->flag & MVERT_SKIN_ROOT) { + vbo_data->size = (vs->radius[0] + vs->radius[1]) * 0.5f; + copy_v3_v3(vbo_data->local_pos, eve->co); + vbo_data++; + root_len++; + } + } + + /* It's really unlikely that all verts will be roots. Resize to avoid loosing VRAM. */ + GPU_vertbuf_data_len_set(vbo, root_len); + + return NULL; +} + +static const MeshExtract extract_skin_roots = { + extract_skin_roots_init, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + false, +}; + +/** \} */ + +/* ---------------------------------------------------------------------- */ /** \name Extract Selection Index * \{ */ @@ -4358,6 +4421,7 @@ void mesh_buffer_cache_create_requested(MeshBatchCache *cache, EXTRACT(vbo, edge_idx); EXTRACT(vbo, vert_idx); EXTRACT(vbo, fdot_idx); + EXTRACT(vbo, skin_roots); EXTRACT(ibo, tris); EXTRACT(ibo, lines); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index cdc1791b153..8cb318bd0bb 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -142,6 +142,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_edit_edges(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_vnors(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_lnors(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_edit_skin_roots(struct Mesh *me); /* edit-mesh selection */ struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index b8b657354b2..49db8bd9765 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -879,6 +879,13 @@ GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(Mesh *me) return DRW_batch_request(&cache->batch.edit_fdots); } +GPUBatch *DRW_mesh_batch_cache_get_edit_skin_roots(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + mesh_batch_cache_add_request(cache, MBC_SKIN_ROOTS); + return DRW_batch_request(&cache->batch.edit_skin_roots); +} + /** \} */ /* ---------------------------------------------------------------------- */ @@ -1319,6 +1326,18 @@ void DRW_mesh_batch_cache_create_requested( DRW_vbo_request(cache->batch.edit_fdots, &mbufcache->vbo.fdots_pos); DRW_vbo_request(cache->batch.edit_fdots, &mbufcache->vbo.fdots_nor); } + if (DRW_batch_requested(cache->batch.edit_skin_roots, GPU_PRIM_LINES)) { + DRW_vbo_request(cache->batch.edit_skin_roots, &mbufcache->vbo.skin_roots); + /* HACK(fclem): This is a workaround the deferred batch init + * that prevent drawing using DRW_shgroup_call_instances_with_attribs. + * So we instead create the whole instancing batch here. + * Note that we use GPU_PRIM_LINES instead of expected GPU_PRIM_LINE_STRIP + * in order to mimic the old stipple pattern. */ + cache->batch.edit_skin_roots->inst = cache->batch.edit_skin_roots->verts[0]; + cache->batch.edit_skin_roots->verts[0] = NULL; + GPUBatch *circle = DRW_cache_screenspace_circle_get(); + GPU_batch_vertbuf_add(cache->batch.edit_skin_roots, circle->verts[0]); + } /* Selection */ if (DRW_batch_requested(cache->batch.edit_selection_verts, GPU_PRIM_POINTS)) { diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 988859c64a5..c04425ded3f 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -83,6 +83,7 @@ void DRW_globals_update(void) UI_GetThemeColor4fv(TH_VNORMAL, gb->colorVNormal); UI_GetThemeColor4fv(TH_LNORMAL, gb->colorLNormal); UI_GetThemeColor4fv(TH_FACE_DOT, gb->colorFaceDot); + UI_GetThemeColor4fv(TH_SKIN_ROOT, gb->colorSkinRoot); UI_GetThemeColor4fv(TH_BACK, gb->colorBackground); /* Custom median color to slightly affect the edit mesh colors. */ diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index 9899b6c0194..01c0946247a 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -73,6 +73,7 @@ typedef struct GlobalsUboStorage { float colorVNormal[4]; float colorLNormal[4]; float colorFaceDot[4]; + float colorSkinRoot[4]; float colorDeselect[4]; float colorOutline[4]; diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index 30fb6c9845c..623a4a52aed 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -55,6 +55,7 @@ extern char datatoc_edit_mesh_overlay_mesh_analysis_frag_glsl[]; extern char datatoc_edit_mesh_overlay_mesh_analysis_vert_glsl[]; extern char datatoc_edit_normals_vert_glsl[]; extern char datatoc_edit_normals_geom_glsl[]; +extern char datatoc_edit_mesh_skin_root_vert_glsl[]; extern char datatoc_common_globals_lib_glsl[]; extern char datatoc_common_view_lib_glsl[]; @@ -114,6 +115,7 @@ typedef struct EDIT_MESH_Shaders { GPUShader *overlay_edge_flat; GPUShader *overlay_face; GPUShader *overlay_facedot; + GPUShader *overlay_skin_root; GPUShader *overlay_mix; GPUShader *overlay_facefill; @@ -141,6 +143,7 @@ typedef struct EDIT_MESH_ComponentShadingGroupList { DRWShadingGroup *faces; DRWShadingGroup *faces_cage; DRWShadingGroup *facedots; + DRWShadingGroup *skin_roots; } EDIT_MESH_ComponentShadingGroupList; typedef struct EDIT_MESH_PrivateData { @@ -266,6 +269,12 @@ static void EDIT_MESH_engine_init(void *vedata) .frag = (const char *[]){lib, datatoc_edit_mesh_overlay_facefill_frag_glsl, NULL}, .defs = (const char *[]){sh_cfg_data->def, NULL}, }); + sh_data->overlay_skin_root = GPU_shader_create_from_arrays({ + .vert = (const char *[]){lib, datatoc_edit_mesh_skin_root_vert_glsl, NULL}, + .frag = (const char *[]){datatoc_gpu_shader_flat_color_frag_glsl, NULL}, + .defs = (const char *[]){sh_cfg_data->def, NULL}, + }); + MEM_freeN(lib); sh_data->overlay_mix = DRW_shader_create_fullscreen(datatoc_edit_mesh_overlay_mix_frag_glsl, @@ -341,6 +350,7 @@ static void edit_mesh_create_overlay_passes(float face_alpha, GPUShader *edge_sh = (select_vert) ? sh_data->overlay_edge : sh_data->overlay_edge_flat; GPUShader *face_sh = sh_data->overlay_face; GPUShader *facedot_sh = sh_data->overlay_facedot; + GPUShader *skin_root_sh = sh_data->overlay_skin_root; /* Faces */ passes->faces = DRW_pass_create("Edit Mesh Faces", DRW_STATE_WRITE_COLOR | statemod); @@ -388,6 +398,10 @@ static void edit_mesh_create_overlay_passes(float face_alpha, if (rv3d->rflag & RV3D_CLIPPING) { DRW_shgroup_state_enable(grp, DRW_STATE_CLIP_PLANES); } + + grp = shgrps->skin_roots = DRW_shgroup_create(skin_root_sh, passes->verts); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); } if (select_face) { grp = shgrps->facedots = DRW_shgroup_create(facedot_sh, passes->verts); @@ -632,21 +646,24 @@ static void EDIT_MESH_cache_init(void *vedata) static void edit_mesh_add_ob_to_pass(Scene *scene, Object *ob, + DRWShadingGroup *skin_roots_shgrp, DRWShadingGroup *vert_shgrp, DRWShadingGroup *edge_shgrp, DRWShadingGroup *face_shgrp, DRWShadingGroup *face_cage_shgrp, DRWShadingGroup *facedot_shgrp) { - struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter; + struct GPUBatch *geom_tris, *geom_verts, *geom_edges, *geom_fcenter, *skin_roots; ToolSettings *tsettings = scene->toolsettings; bool has_edit_mesh_cage = false; + bool has_skin_roots = false; /* TODO: Should be its own function. */ Mesh *me = (Mesh *)ob->data; BMEditMesh *embm = me->edit_mesh; if (embm) { has_edit_mesh_cage = embm->mesh_eval_cage && (embm->mesh_eval_cage != embm->mesh_eval_final); + has_skin_roots = CustomData_get_offset(&embm->bm->vdata, CD_MVERT_SKIN) != -1; } face_shgrp = (has_edit_mesh_cage) ? face_cage_shgrp : face_shgrp; @@ -659,6 +676,21 @@ static void edit_mesh_add_ob_to_pass(Scene *scene, if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) { geom_verts = DRW_mesh_batch_cache_get_edit_vertices(ob->data); DRW_shgroup_call_no_cull(vert_shgrp, geom_verts, ob); + + if (has_skin_roots) { + DRWShadingGroup *grp = DRW_shgroup_create_sub(skin_roots_shgrp); + /* We need to upload the matrix. But the ob can be temporary allocated so we cannot + * use direct reference to ob->obmat. */ + DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[0]", ob->obmat[0]); + DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[1]", ob->obmat[1]); + DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[2]", ob->obmat[2]); + DRW_shgroup_uniform_vec4_copy(grp, "editModelMat[3]", ob->obmat[3]); + + skin_roots = DRW_mesh_batch_cache_get_edit_skin_roots(ob->data); + /* NOTE(fclem) We cannot use ob here since it would offset the instance attribs with + * baseinstance offset. */ + DRW_shgroup_call(grp, skin_roots, NULL); + } } if (facedot_shgrp && (tsettings->selectmode & SCE_SELECT_FACE) != 0) { @@ -721,6 +753,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) if (g_data->do_zbufclip) { edit_mesh_add_ob_to_pass(scene, ob, + g_data->edit_shgrps.skin_roots, g_data->edit_shgrps.verts, g_data->edit_shgrps.edges, g_data->facefill_occluded_shgrp, @@ -730,6 +763,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) else if (do_in_front) { edit_mesh_add_ob_to_pass(scene, ob, + g_data->edit_in_front_shgrps.skin_roots, g_data->edit_in_front_shgrps.verts, g_data->edit_in_front_shgrps.edges, g_data->edit_in_front_shgrps.faces, @@ -739,6 +773,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob) else { edit_mesh_add_ob_to_pass(scene, ob, + g_data->edit_shgrps.skin_roots, g_data->edit_shgrps.verts, g_data->edit_shgrps.edges, g_data->edit_shgrps.faces, diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 21e1dff7128..11cef92c63c 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -3111,7 +3111,8 @@ static void DRW_shgroup_texture_space(OBJECT_ShadingGroupList *sgl, Object *ob, DRW_buffer_add_entry(sgl->texspace, color, &one, tmp); } -static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int theme_id) +static void DRW_shgroup_bounds( + OBJECT_ShadingGroupList *sgl, Object *ob, int theme_id, char boundtype, bool around_origin) { float color[4], center[3], size[3], tmp[4][4], final_mat[4][4], one = 1.0f; BoundBox bb_local; @@ -3137,10 +3138,16 @@ static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int the } UI_GetThemeColor4fv(theme_id, color); - BKE_boundbox_calc_center_aabb(bb, center); BKE_boundbox_calc_size_aabb(bb, size); - switch (ob->boundtype) { + if (around_origin) { + zero_v3(center); + } + else { + BKE_boundbox_calc_center_aabb(bb, center); + } + + switch (boundtype) { case OB_BOUND_BOX: size_to_mat4(tmp, size); copy_v3_v3(tmp[3], center); @@ -3193,6 +3200,27 @@ static void DRW_shgroup_bounds(OBJECT_ShadingGroupList *sgl, Object *ob, int the } } +static void DRW_shgroup_collision(OBJECT_ShadingGroupList *sgl, Object *ob, int theme_id) +{ + switch (ob->rigidbody_object->shape) { + case RB_SHAPE_BOX: + DRW_shgroup_bounds(sgl, ob, theme_id, OB_BOUND_BOX, true); + break; + case RB_SHAPE_SPHERE: + DRW_shgroup_bounds(sgl, ob, theme_id, OB_BOUND_SPHERE, true); + break; + case RB_SHAPE_CONE: + DRW_shgroup_bounds(sgl, ob, theme_id, OB_BOUND_CONE, true); + break; + case RB_SHAPE_CYLINDER: + DRW_shgroup_bounds(sgl, ob, theme_id, OB_BOUND_CYLINDER, true); + break; + case RB_SHAPE_CAPSULE: + DRW_shgroup_bounds(sgl, ob, theme_id, OB_BOUND_CAPSULE, true); + break; + } +} + static void OBJECT_cache_populate_particles(OBJECT_Shaders *sh_data, Object *ob, OBJECT_PassList *psl) @@ -3622,7 +3650,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) if (theme_id == TH_UNDEFINED) { theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } - DRW_shgroup_bounds(sgl, ob, theme_id); + DRW_shgroup_bounds(sgl, ob, theme_id, ob->boundtype, false); } /* Helpers for when we're transforming origins. */ @@ -3681,7 +3709,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) /* Don't draw bounding box again if draw type is bound box. */ if ((ob->dtx & OB_DRAWBOUNDOX) && (ob->dt != OB_BOUNDBOX) && !ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_EMPTY, OB_SPEAKER, OB_LIGHTPROBE)) { - DRW_shgroup_bounds(sgl, ob, theme_id); + DRW_shgroup_bounds(sgl, ob, theme_id, ob->boundtype, false); } if (ob->dtx & OB_AXIS) { @@ -3691,6 +3719,10 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) DRW_buffer_add_entry(sgl->empties.empty_axes, color, &axes_size, ob->obmat); } + if (ob->rigidbody_object) { + DRW_shgroup_collision(sgl, ob, theme_id); + } + if ((md = modifiers_findByType(ob, eModifierType_Smoke)) && (modifier_isEnabled(scene, md, eModifierMode_Realtime)) && (((SmokeModifierData *)md)->domain != NULL)) { diff --git a/source/blender/draw/modes/shaders/common_globals_lib.glsl b/source/blender/draw/modes/shaders/common_globals_lib.glsl index e559224eb9e..d147b193ccf 100644 --- a/source/blender/draw/modes/shaders/common_globals_lib.glsl +++ b/source/blender/draw/modes/shaders/common_globals_lib.glsl @@ -34,6 +34,7 @@ layout(std140) uniform globalsBlock vec4 colorVNormal; vec4 colorLNormal; vec4 colorFaceDot; + vec4 colorSkinRoot; vec4 colorDeselect; vec4 colorOutline; vec4 colorLightNoAlpha; diff --git a/source/blender/draw/modes/shaders/edit_mesh_skin_root_vert.glsl b/source/blender/draw/modes/shaders/edit_mesh_skin_root_vert.glsl new file mode 100644 index 00000000000..5187571b27b --- /dev/null +++ b/source/blender/draw/modes/shaders/edit_mesh_skin_root_vert.glsl @@ -0,0 +1,30 @@ +/* Need dedicated obmat since we use instancing attribs + * (we cannot let have baseinstance mess them). */ +uniform vec4 editModelMat[4]; +uniform vec3 screen_vecs[2]; + +/* ---- Instantiated Attrs ---- */ +in vec2 pos; + +/* ---- Per instance Attrs ---- */ +in float size; +in vec3 local_pos; + +flat out vec4 finalColor; + +void main() +{ + mat4 obmat = mat4(editModelMat[0], editModelMat[1], editModelMat[2], editModelMat[3]); + /* Could be optimized... but it is only for a handful of verts so not a priority. */ + mat3 imat = inverse(mat3(obmat)); + vec3 right = normalize(imat * vec3(screen_vecs[0])); + vec3 up = normalize(imat * vec3(screen_vecs[1])); + vec3 screen_pos = (right * pos.x + up * pos.y) * size; + vec4 pos_4d = obmat * vec4(local_pos + screen_pos, 1.0); + gl_Position = ViewProjectionMatrix * pos_4d; + finalColor = colorSkinRoot; + +#ifdef USE_WORLD_CLIP_PLANES + world_clip_planes_calc_clip_distance(pos_4d.xyz); +#endif +} |