MetaBall support for Workbench + EEVEE
Note: Metaballs only support the first material slot. Splicing it per material would create empty Batches. In order to overcome this we set the batch for other materials to NULL. We added extra checks in EEVEE and Workbench to not draw when the geom is NULL.
This commit is contained in:
parent
5aa8d981ec
commit
a67cc72232
Notes:
blender-bot
2024-04-11 14:26:06 +02:00
Referenced by issue #55436, Crash when tweaking shader values connected to Point Density node Referenced by issue #55440, Pose Mode Crash
|
@ -142,7 +142,7 @@ static void eevee_cache_populate(void *vedata, Object *ob)
|
|||
}
|
||||
|
||||
if (DRW_check_object_visible_within_active_context(ob)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
|
||||
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
|
||||
}
|
||||
else if (!USE_SCENE_LIGHT(draw_ctx->v3d)) {
|
||||
|
|
|
@ -1406,7 +1406,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
|
|||
const bool is_default_mode_shader = is_sculpt_mode;
|
||||
|
||||
/* First get materials for this mesh. */
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
|
||||
const int materials_len = MAX2(1, (is_sculpt_mode_draw ? 1 : ob->totcol));
|
||||
|
||||
struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len);
|
||||
|
@ -1484,6 +1484,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld
|
|||
&auto_layer_count);
|
||||
if (mat_geom) {
|
||||
for (int i = 0; i < materials_len; ++i) {
|
||||
if (mat_geom[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
EEVEE_ObjectEngineData *oedata = NULL;
|
||||
Material *ma = give_current_material(ob, i + 1);
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ void EEVEE_render_cache(
|
|||
}
|
||||
|
||||
if (DRW_check_object_visible_within_active_context(ob)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
|
||||
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
|
||||
}
|
||||
else if (ob->type == OB_LIGHTPROBE) {
|
||||
|
|
|
@ -655,12 +655,12 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
}
|
||||
|
||||
WORKBENCH_MaterialData *material;
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const bool is_active = (ob == draw_ctx->obact);
|
||||
const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
|
||||
bool is_drawn = false;
|
||||
if (!is_sculpt_mode && wpd->drawtype == OB_TEXTURE && ob->type == OB_MESH) {
|
||||
if (!is_sculpt_mode && wpd->drawtype == OB_TEXTURE && ELEM(ob->type, OB_MESH)) {
|
||||
const Mesh *me = ob->data;
|
||||
if (me->mloopuv) {
|
||||
const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
|
||||
|
@ -668,6 +668,10 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL;
|
||||
if (materials_len > 0 && geom_array) {
|
||||
for (int i = 0; i < materials_len; i++) {
|
||||
if (geom_array[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Material *mat = give_current_material(ob, i + 1);
|
||||
Image *image;
|
||||
ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
|
||||
|
@ -710,6 +714,10 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
ob, gpumat_array, materials_len, NULL, NULL, NULL);
|
||||
if (mat_geom) {
|
||||
for (int i = 0; i < materials_len; ++i) {
|
||||
if (mat_geom[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Material *mat = give_current_material(ob, i + 1);
|
||||
material = get_or_create_material_data(vedata, ob, mat, NULL, OB_SOLID);
|
||||
DRW_shgroup_call_object_add(material->shgrp, mat_geom[i], ob);
|
||||
|
|
|
@ -461,14 +461,14 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
|
||||
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const bool is_active = (ob == draw_ctx->obact);
|
||||
const bool is_sculpt_mode = is_active && (draw_ctx->object_mode & OB_MODE_SCULPT) != 0;
|
||||
bool is_drawn = false;
|
||||
|
||||
WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, NULL, NULL, OB_SOLID);
|
||||
if (!is_sculpt_mode && wpd->drawtype == OB_TEXTURE && ob->type == OB_MESH) {
|
||||
if (!is_sculpt_mode && wpd->drawtype == OB_TEXTURE && ELEM(ob->type, OB_MESH)) {
|
||||
const Mesh *me = ob->data;
|
||||
if (me->mloopuv) {
|
||||
const int materials_len = MAX2(1, (is_sculpt_mode ? 1 : ob->totcol));
|
||||
|
@ -476,6 +476,10 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
struct Gwn_Batch **geom_array = me->totcol ? DRW_cache_mesh_surface_texpaint_get(ob) : NULL;
|
||||
if (materials_len > 0 && geom_array) {
|
||||
for (int i = 0; i < materials_len; i++) {
|
||||
if(geom_array[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Material *mat = give_current_material(ob, i + 1);
|
||||
Image *image;
|
||||
ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
|
||||
|
@ -520,6 +524,10 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
|
|||
ob, gpumat_array, materials_len, NULL, NULL, NULL);
|
||||
if (mat_geom) {
|
||||
for (int i = 0; i < materials_len; ++i) {
|
||||
if(mat_geom[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Material *mat = give_current_material(ob, i + 1);
|
||||
material = get_or_create_material_data(vedata, ob, mat, NULL, OB_SOLID);
|
||||
DRW_shgroup_call_object_add(material->shgrp_object_outline, mat_geom[i], ob);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meta_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
|
@ -576,6 +577,8 @@ Gwn_Batch **DRW_cache_object_surface_material_get(
|
|||
return DRW_cache_surf_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||
case OB_FONT:
|
||||
return DRW_cache_text_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||
case OB_MBALL:
|
||||
return DRW_cache_mball_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2804,6 +2807,14 @@ Gwn_Batch *DRW_cache_mball_surface_get(Object *ob)
|
|||
return DRW_metaball_batch_cache_get_triangles_with_normals(ob);
|
||||
}
|
||||
|
||||
Gwn_Batch **DRW_cache_mball_surface_shaded_get(
|
||||
Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MBALL);
|
||||
MetaBall *mb = ob->data;
|
||||
return DRW_metaball_batch_cache_get_surface_shaded(ob, mb, gpumat_array, gpumat_array_len);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -187,5 +187,6 @@ struct Gwn_Batch *DRW_cache_particles_get_prim(int type);
|
|||
|
||||
/* Metaball */
|
||||
struct Gwn_Batch *DRW_cache_mball_surface_get(struct Object *ob);
|
||||
struct Gwn_Batch **DRW_cache_mball_surface_shaded_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
|
||||
|
||||
#endif /* __DRAW_CACHE_H__ */
|
||||
|
|
|
@ -73,6 +73,7 @@ struct Gwn_Batch **DRW_curve_batch_cache_get_surface_shaded(
|
|||
|
||||
/* Metaball */
|
||||
struct Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob);
|
||||
struct Gwn_Batch **DRW_metaball_batch_cache_get_surface_shaded(struct Object *ob, struct MetaBall *mb, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
|
||||
|
||||
/* Curve (Font) */
|
||||
struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu);
|
||||
|
|
|
@ -49,7 +49,9 @@ static void metaball_batch_cache_clear(MetaBall *mb);
|
|||
|
||||
typedef struct MetaBallBatchCache {
|
||||
Gwn_Batch *batch;
|
||||
Gwn_Batch **shaded_triangles;
|
||||
|
||||
int mat_len;
|
||||
/* settings to determine if cache is invalid */
|
||||
bool is_dirty;
|
||||
} MetaBallBatchCache;
|
||||
|
@ -75,6 +77,8 @@ static void metaball_batch_cache_init(MetaBall *mb)
|
|||
cache = mb->batch_cache = MEM_mallocN(sizeof(*cache), __func__);
|
||||
}
|
||||
cache->batch = NULL;
|
||||
cache->mat_len = 0;
|
||||
cache->shaded_triangles = NULL;
|
||||
cache->is_dirty = false;
|
||||
}
|
||||
|
||||
|
@ -110,6 +114,9 @@ static void metaball_batch_cache_clear(MetaBall *mb)
|
|||
}
|
||||
|
||||
GWN_BATCH_DISCARD_SAFE(cache->batch);
|
||||
/* Note: shaded_triangles[0] is already freed by cache->batch */
|
||||
MEM_SAFE_FREE(cache->shaded_triangles);
|
||||
cache->mat_len = 0;
|
||||
}
|
||||
|
||||
void DRW_mball_batch_cache_free(MetaBall *mb)
|
||||
|
@ -125,8 +132,9 @@ void DRW_mball_batch_cache_free(MetaBall *mb)
|
|||
|
||||
Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob)
|
||||
{
|
||||
if (!BKE_mball_is_basis(ob))
|
||||
if (!BKE_mball_is_basis(ob)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaBall *mb = ob->data;
|
||||
MetaBallBatchCache *cache = metaball_batch_cache_get(mb);
|
||||
|
@ -142,3 +150,22 @@ Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob)
|
|||
|
||||
return cache->batch;
|
||||
}
|
||||
|
||||
Gwn_Batch **DRW_metaball_batch_cache_get_surface_shaded(Object *ob, MetaBall *mb, struct GPUMaterial **UNUSED(gpumat_array), uint gpumat_array_len)
|
||||
{
|
||||
if (!BKE_mball_is_basis(ob)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MetaBallBatchCache *cache = metaball_batch_cache_get(mb);
|
||||
if (cache->shaded_triangles == NULL) {
|
||||
cache->mat_len = gpumat_array_len;
|
||||
cache->shaded_triangles = MEM_callocN(sizeof(*cache->shaded_triangles) * cache->mat_len, __func__);
|
||||
cache->shaded_triangles[0] = DRW_metaball_batch_cache_get_triangles_with_normals(ob);
|
||||
for (int i = 1; i < cache->mat_len; ++i) {
|
||||
cache->shaded_triangles[i] = NULL;
|
||||
}
|
||||
}
|
||||
return cache->shaded_triangles;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue