Draw manager: Initial implementation of key points visualization

Does all points all the time, ignoring the setting in viewport header.
This is to be addressed by the next commit.
This commit is contained in:
Sergey Sharybin 2018-05-09 14:08:44 +02:00
parent 033c2c7131
commit 5cea8bf435
9 changed files with 144 additions and 25 deletions

View File

@ -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);
}
}
}

View File

@ -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
)

View File

@ -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) {

View File

@ -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 */

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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));
DRW_STATE_WIRE |
DRW_STATE_POINT));
stl->g_data->psys_edit_group = DRW_shgroup_create(
e_data.hair_shader, psl->psys_edit_pass);
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 =

View File

@ -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)