diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-08 16:02:11 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-09 11:34:45 +0300 |
commit | 17d13e4107bfff29b2d98f23ea41faae86cca805 (patch) | |
tree | b85ae0924a890aa680b9b0f729b720fe8288b89c /source/blender/draw/intern/draw_cache_impl_particles.c | |
parent | 81e6aa16004dc0f04a0d2161119a192b99bf669a (diff) |
Draw manager: Move parent particle cache fill into an own function
Should make it fairly simple to make it re-usable by children particles.
Diffstat (limited to 'source/blender/draw/intern/draw_cache_impl_particles.c')
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_particles.c | 132 |
1 files changed, 80 insertions, 52 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 5734b84e154..ff5fb989b17 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -70,6 +70,12 @@ typedef struct ParticleBatchCache { /* Gwn_Batch cache management. */ +typedef struct HairAttributeID { + uint pos; + uint tan; + uint ind; +} HairAttributeID; + static bool particle_batch_cache_valid(ParticleSystem *psys) { ParticleBatchCache *cache = psys->batch_cache; @@ -272,7 +278,75 @@ static void particle_calculate_uvs(ParticleSystem *psys, } } -/* Gwn_Batch cache usage. */ +/* Will return last filled index. */ +static int particle_batch_cache_fill_segments(ParticleSystem *psys, + ParticleSystemModifierData *psmd, + ParticleCacheKey **path_cache, + const int start_index, + const int num_path_keys, + const int num_uv_layers, + /*const*/ MTFace **mtfaces, + unsigned int *uv_id, + float (**r_parent_uvs)[2], + Gwn_IndexBufBuilder *elb, + HairAttributeID *attr_id, + ParticleBatchCache *cache) +{ + const bool is_simple = (psys->part->childtype == PART_CHILD_PARTICLES); + int curr_point = start_index; + for (int i = 0; i < num_path_keys; i++) { + ParticleCacheKey *path = path_cache[i]; + if (path->segments <= 0) { + continue; + } + float tangent[3]; + float (*uv)[2] = NULL; + particle_calculate_uvs( + psys, psmd, + is_simple, num_uv_layers, + i, -1, + mtfaces, + r_parent_uvs, &uv); + for (int j = 0; j < path->segments; j++) { + if (j == 0) { + sub_v3_v3v3(tangent, path[j + 1].co, path[j].co); + } + else { + sub_v3_v3v3(tangent, path[j + 1].co, path[j - 1].co); + } + GWN_vertbuf_attr_set(cache->pos, attr_id->pos, curr_point, path[j].co); + GWN_vertbuf_attr_set(cache->pos, attr_id->tan, curr_point, tangent); + GWN_vertbuf_attr_set(cache->pos, attr_id->ind, curr_point, &i); + if (psmd != NULL) { + for (int k = 0; k < num_uv_layers; k++) { + GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]); + } + } + GWN_indexbuf_add_generic_vert(elb, curr_point); + curr_point++; + } + sub_v3_v3v3(tangent, path[path->segments].co, path[path->segments - 1].co); + + GWN_vertbuf_attr_set(cache->pos, attr_id->pos, curr_point, path[path->segments].co); + GWN_vertbuf_attr_set(cache->pos, attr_id->tan, curr_point, tangent); + GWN_vertbuf_attr_set(cache->pos, attr_id->ind, curr_point, &i); + + if (psmd != NULL) { + for (int k = 0; k < num_uv_layers; k++) { + GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]); + } + if (!is_simple) { + MEM_freeN(uv); + } + } + /* Finish the segment and add restart primitive. */ + GWN_indexbuf_add_generic_vert(elb, curr_point); + GWN_indexbuf_add_primitive_restart(elb); + curr_point++; + } + return curr_point; +} + static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, ModifierData *md, ParticleBatchCache *cache) { if (cache->pos != NULL && cache->indices != NULL) { @@ -286,7 +360,7 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi GWN_INDEXBUF_DISCARD_SAFE(cache->indices); static Gwn_VertFormat format = { 0 }; - static struct { uint pos, tan, ind; } attr_id; + static HairAttributeID attr_id; unsigned int *uv_id = NULL; int num_uv_layers = 0; MTFace **mtfaces = NULL; @@ -336,56 +410,10 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi if (simple) { parent_uvs = MEM_callocN(sizeof(*parent_uvs) * psys->totpart, "Parent particle UVs"); } - for (int i = 0; i < psys->totpart; i++) { - ParticleCacheKey *path = psys->pathcache[i]; - if (path->segments <= 0) { - continue; - } - float tangent[3]; - float (*uv)[2] = NULL; - particle_calculate_uvs( - psys, psmd, - simple, num_uv_layers, - i, -1, - mtfaces, - parent_uvs, &uv); - for (int j = 0; j < path->segments; j++) { - if (j == 0) { - sub_v3_v3v3(tangent, path[j + 1].co, path[j].co); - } - else { - sub_v3_v3v3(tangent, path[j + 1].co, path[j - 1].co); - } - GWN_vertbuf_attr_set(cache->pos, attr_id.pos, curr_point, path[j].co); - GWN_vertbuf_attr_set(cache->pos, attr_id.tan, curr_point, tangent); - GWN_vertbuf_attr_set(cache->pos, attr_id.ind, curr_point, &i); - if (psmd != NULL) { - for (int k = 0; k < num_uv_layers; k++) { - GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]); - } - } - GWN_indexbuf_add_generic_vert(&elb, curr_point); - curr_point++; - } - sub_v3_v3v3(tangent, path[path->segments].co, path[path->segments - 1].co); - - GWN_vertbuf_attr_set(cache->pos, attr_id.pos, curr_point, path[path->segments].co); - GWN_vertbuf_attr_set(cache->pos, attr_id.tan, curr_point, tangent); - GWN_vertbuf_attr_set(cache->pos, attr_id.ind, curr_point, &i); - - if (psmd != NULL) { - for (int k = 0; k < num_uv_layers; k++) { - GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]); - } - if (!simple) { - MEM_freeN(uv); - } - } - /* Finish the segment and add restart primitive. */ - GWN_indexbuf_add_generic_vert(&elb, curr_point); - GWN_indexbuf_add_primitive_restart(&elb); - curr_point++; - } + particle_batch_cache_fill_segments( + psys, psmd, psys->pathcache, 0, psys->totpart, + num_uv_layers, mtfaces, uv_id, parent_uvs, + &elb, &attr_id, cache); } if (psys->childcache) { |