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
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-10-16 20:06:22 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-10-16 20:06:22 +0300
commitbb890d4f657544ea3e4e872056d236448f0d8938 (patch)
tree2e7c910376882904db6286cecc915c7badf060c8 /source
parent5da9ae9c0bb2241a26d867412669b55e7c0e7afd (diff)
parent131ac2ec82b9e810dd6e0153009a71276b6d6f13 (diff)
Merge branch 'blender-v2.81-release'
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl76
-rw-r--r--source/blender/draw/engines/eevee/shaders/lights_lib.glsl1
-rw-r--r--source/blender/draw/intern/draw_cache_extract.h5
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c64
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h1
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c19
-rw-r--r--source/blender/draw/intern/draw_common.c1
-rw-r--r--source/blender/draw/intern/draw_common.h1
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c37
-rw-r--r--source/blender/draw/modes/object_mode.c42
-rw-r--r--source/blender/draw/modes/shaders/common_globals_lib.glsl1
-rw-r--r--source/blender/draw/modes/shaders/edit_mesh_skin_root_vert.glsl30
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
+}