diff options
-rw-r--r-- | source/blender/blenkernel/intern/object_update.c | 9 | ||||
-rw-r--r-- | source/blender/draw/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 7 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_particles.c | 93 | ||||
-rw-r--r-- | source/blender/draw/modes/particle_mode.c | 52 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/particle_strand_vert.glsl (renamed from source/blender/draw/modes/shaders/particle_vert.glsl) | 0 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 2 |
9 files changed, 145 insertions, 26 deletions
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 68cc0ed9ec1..c1cc6bf0bdc 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -465,4 +465,13 @@ void BKE_object_eval_flush_base_flags(Depsgraph *depsgraph, object->base_flag |= BASE_FROM_SET; object->base_flag &= ~(BASE_SELECTED | BASE_SELECTABLED); } + + if (object->mode == OB_MODE_PARTICLE_EDIT) { + for (ParticleSystem *psys = object->particlesystem.first; + psys != NULL; + psys = psys->next) + { + BKE_particle_batch_cache_dirty(psys, BKE_PARTICLE_BATCH_DIRTY_ALL); + } + } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2207dfe5c34..5a753ffe159 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -278,7 +278,7 @@ data_to_c_simple(modes/shaders/paint_wire_frag.glsl SRC) data_to_c_simple(modes/shaders/paint_wire_vert.glsl SRC) data_to_c_simple(modes/shaders/paint_vert_frag.glsl SRC) data_to_c_simple(modes/shaders/particle_strand_frag.glsl SRC) -data_to_c_simple(modes/shaders/particle_vert.glsl SRC) +data_to_c_simple(modes/shaders/particle_strand_vert.glsl SRC) list(APPEND INC ) diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 15f4aa319bd..95193bebaea 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -2886,11 +2886,16 @@ Gwn_Batch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys) return DRW_particles_batch_cache_get_dots(object, psys); } -Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit* edit) +Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit *edit) { return DRW_particles_batch_cache_get_edit_strands(edit); } +Gwn_Batch *DRW_cache_particles_get_edit_points(struct PTCacheEdit *edit) +{ + return DRW_particles_batch_cache_get_edit_points(edit); +} + Gwn_Batch *DRW_cache_particles_get_prim(int type) { switch (type) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 82cfe77d613..e726e25431f 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -169,7 +169,8 @@ struct Gwn_Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob); /* Particles */ struct Gwn_Batch *DRW_cache_particles_get_hair(struct ParticleSystem *psys, struct ModifierData *md); struct Gwn_Batch *DRW_cache_particles_get_dots(struct Object *object, struct ParticleSystem *psys); -struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit* edit); +struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct PTCacheEdit *edit); +struct Gwn_Batch *DRW_cache_particles_get_edit_points(struct PTCacheEdit *edit); struct Gwn_Batch *DRW_cache_particles_get_prim(int type); /* Metaball */ diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index b537f1f0151..84c7825c6f9 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -125,6 +125,7 @@ void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me); /* Particles */ struct Gwn_Batch *DRW_particles_batch_cache_get_hair(struct ParticleSystem *psys, struct ModifierData *md); struct Gwn_Batch *DRW_particles_batch_cache_get_dots(struct Object *object, struct ParticleSystem *psys); -struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct PTCacheEdit* edit); +struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct PTCacheEdit *edit); +struct Gwn_Batch *DRW_particles_batch_cache_get_edit_points(struct PTCacheEdit *edit); #endif /* __DRAW_CACHE_IMPL_H__ */ diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 0cc3c001ef2..065628f3f68 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -59,15 +59,22 @@ static void particle_batch_cache_clear(ParticleSystem *psys); /* Particle Gwn_Batch Cache */ typedef struct ParticleBatchCache { + /* Object mode strands for hair and points for particle, + * strands for paths when in edit mode. + */ Gwn_VertBuf *pos; Gwn_IndexBuf *indices; - Gwn_Batch *hairs; int elems_count; int point_count; - /* settings to determine if cache is invalid */ + /* Control points when in edit mode. */ + Gwn_VertBuf *edit_pos; + Gwn_Batch *edit_points; + int edit_point_count; + + /* Settings to determine if cache is invalid. */ bool is_dirty; } ParticleBatchCache; @@ -143,9 +150,11 @@ static void particle_batch_cache_clear(ParticleSystem *psys) } GWN_BATCH_DISCARD_SAFE(cache->hairs); - GWN_VERTBUF_DISCARD_SAFE(cache->pos); GWN_INDEXBUF_DISCARD_SAFE(cache->indices); + + GWN_BATCH_DISCARD_SAFE(cache->edit_points); + GWN_VERTBUF_DISCARD_SAFE(cache->edit_pos); } void DRW_particle_batch_cache_free(ParticleSystem *psys) @@ -173,7 +182,7 @@ static void ensure_seg_pt_count(ParticleSystem *psys, ParticleBatchCache *cache) cache->elems_count = 0; cache->point_count = 0; - PTCacheEdit* edit = PE_get_current_from_psys(psys); + PTCacheEdit *edit = PE_get_current_from_psys(psys); if (edit != NULL && edit->pathcache != NULL) { count_cache_segment_keys(edit->pathcache, psys->totpart, cache); } else { @@ -436,7 +445,7 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, } } - PTCacheEdit* edit = PE_get_current_from_psys(psys); + PTCacheEdit *edit = PE_get_current_from_psys(psys); if (edit != NULL && edit->pathcache != NULL) { curr_point = particle_batch_cache_fill_segments( psys, psmd, edit->pathcache, PARTICLE_SOURCE_PARENT, @@ -578,7 +587,7 @@ Gwn_Batch *DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *ps return cache->hairs; } -Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(PTCacheEdit* edit) +Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(PTCacheEdit *edit) { ParticleSystem *psys = edit->psys; ParticleBatchCache *cache = particle_batch_cache_get(psys); @@ -590,3 +599,75 @@ Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(PTCacheEdit* edit) cache->hairs = GWN_batch_create(GWN_PRIM_LINE_STRIP, cache->pos, cache->indices); return cache->hairs; } + +static void ensure_edit_points_count(const PTCacheEdit *edit, + ParticleBatchCache *cache) +{ + if (cache->edit_pos != NULL) { + return; + } + cache->edit_point_count = 0; + for (int point_index = 0; point_index < edit->totpoint; point_index++) { + const PTCacheEditPoint *point = &edit->points[point_index]; + cache->edit_point_count += point->totkey; + } +} + +static void particle_batch_cache_ensure_edit_pos(PTCacheEdit *edit, + ParticleBatchCache *cache) +{ + if (cache->edit_pos != NULL) { + return; + } + + static Gwn_VertFormat format = { 0 }; + static unsigned pos_id, color_id; + + GWN_VERTBUF_DISCARD_SAFE(cache->edit_pos); + + if (format.attrib_ct == 0) { + /* initialize vertex format */ + pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + color_id = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + } + + cache->edit_pos = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(cache->edit_pos, cache->edit_point_count); + + /* Convert theme colors from uchar[3] to float[4]. */ + float selected_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + float normal_color[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + rgb_uchar_to_float(selected_color, edit->sel_col); + rgb_uchar_to_float(normal_color, edit->nosel_col); + + int global_key_index = 0; + for (int point_index = 0; point_index < edit->totpoint; point_index++) { + const PTCacheEditPoint *point = &edit->points[point_index]; + for (int key_index = 0; key_index < point->totkey; key_index++) { + PTCacheEditKey *key = &point->keys[key_index]; + GWN_vertbuf_attr_set(cache->edit_pos, pos_id, global_key_index, key->world_co); + if (key->flag & PEK_SELECT) { + GWN_vertbuf_attr_set(cache->edit_pos, color_id, global_key_index, selected_color); + } + else { + GWN_vertbuf_attr_set(cache->edit_pos, color_id, global_key_index, normal_color); + } + global_key_index++; + } + } +} + +Gwn_Batch *DRW_particles_batch_cache_get_edit_points(PTCacheEdit *edit) +{ + ParticleSystem *psys = edit->psys; + ParticleBatchCache *cache = particle_batch_cache_get(psys); + if (cache->edit_points != NULL) { + return cache->edit_points; + } + ensure_edit_points_count(edit, cache); + particle_batch_cache_ensure_edit_pos(edit, cache); + cache->edit_points = GWN_batch_create(GWN_PRIM_POINTS, + cache->edit_pos, + NULL); + return cache->edit_points; +} diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index eff7d9ca33b..52d72da0151 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -46,7 +46,7 @@ #include "draw_cache_impl.h" -extern char datatoc_particle_vert_glsl[]; +extern char datatoc_particle_strand_vert_glsl[]; extern char datatoc_particle_strand_frag_glsl[]; /* *********** LISTS *********** */ @@ -79,23 +79,29 @@ typedef struct PARTICLE_Data { /* *********** STATIC *********** */ static struct { - struct GPUShader *hair_shader; + struct GPUShader *strands_shader; + struct GPUShader *points_shader; } e_data = {NULL}; /* Engine data */ typedef struct PARTICLE_PrivateData { - DRWShadingGroup *psys_edit_group; + DRWShadingGroup *strands_group; + DRWShadingGroup *points_group; } PARTICLE_PrivateData; /* Transient data */ /* *********** FUNCTIONS *********** */ static void particle_engine_init(void *UNUSED(vedata)) { - if (!e_data.hair_shader) { - e_data.hair_shader = DRW_shader_create( - datatoc_particle_vert_glsl, + if (!e_data.strands_shader) { + e_data.strands_shader = DRW_shader_create( + datatoc_particle_strand_vert_glsl, NULL, datatoc_particle_strand_frag_glsl, - "#define MAX_MATERIAL 1\n" ); + ""); + } + if (!e_data.points_shader) { + e_data.points_shader = GPU_shader_get_builtin_shader( + GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR); } } @@ -114,17 +120,31 @@ static void particle_cache_init(void *vedata) (DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | - DRW_STATE_WIRE)); - - stl->g_data->psys_edit_group = DRW_shgroup_create( - e_data.hair_shader, psl->psys_edit_pass); + DRW_STATE_WIRE | + DRW_STATE_POINT)); + + stl->g_data->strands_group = DRW_shgroup_create( + e_data.strands_shader, psl->psys_edit_pass); + stl->g_data->points_group = DRW_shgroup_create( + e_data.points_shader, psl->psys_edit_pass); + + static float size = 5.0f; + DRW_shgroup_uniform_float(stl->g_data->points_group, "size", &size, 1); + static float outline_width = 1.0f; + DRW_shgroup_uniform_float(stl->g_data->points_group, "outlineWidth", &outline_width, 1); } -static void particle_edit_cache_populate(void *vedata, PTCacheEdit* edit) +static void particle_edit_cache_populate(void *vedata, PTCacheEdit *edit) { PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl; - struct Gwn_Batch *edit_strands = DRW_cache_particles_get_edit_strands(edit); - DRW_shgroup_call_add(stl->g_data->psys_edit_group, edit_strands, NULL); + { + struct Gwn_Batch *strands = DRW_cache_particles_get_edit_strands(edit); + DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL); + } + { + struct Gwn_Batch *points = DRW_cache_particles_get_edit_points(edit); + DRW_shgroup_call_add(stl->g_data->points_group, points, NULL); + } } static void particle_cache_populate(void *vedata, Object *object) @@ -136,7 +156,7 @@ static void particle_cache_populate(void *vedata, Object *object) if (!psys_check_enabled(object, psys, false)) { continue; } - PTCacheEdit* edit = PE_get_current_from_psys(psys); + PTCacheEdit *edit = PE_get_current_from_psys(psys); if (edit == NULL) { continue; } @@ -161,7 +181,7 @@ static void particle_draw_scene(void *vedata) static void particle_engine_free(void) { - DRW_SHADER_FREE_SAFE(e_data.hair_shader); + DRW_SHADER_FREE_SAFE(e_data.strands_shader); } static const DrawEngineDataSize particle_data_size = diff --git a/source/blender/draw/modes/shaders/particle_vert.glsl b/source/blender/draw/modes/shaders/particle_strand_vert.glsl index d4c35d14182..d4c35d14182 100644 --- a/source/blender/draw/modes/shaders/particle_vert.glsl +++ b/source/blender/draw/modes/shaders/particle_strand_vert.glsl diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index fe749fd096e..2874b748f7e 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -1181,6 +1181,8 @@ static void PE_update_selection(Depsgraph *depsgraph, Scene *scene, Object *ob, /* disable update flag */ LOOP_POINTS point->flag &= ~PEP_EDIT_RECALC; + + DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE); } void update_world_cos(Object *ob, PTCacheEdit *edit) |