Draw manager: Cleanup, early output

Do early output and reduce level of indentation.
This commit is contained in:
2018-03-29 10:33:02 +02:00
parent 05c76990c8
commit f42c6960d2

View File

@@ -176,85 +176,189 @@ static void ensure_seg_pt_count(ParticleSystem *psys, ParticleBatchCache *cache)
/* Gwn_Batch cache usage. */
static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, ModifierData *md, ParticleBatchCache *cache)
{
if (cache->pos == NULL || cache->segments == NULL) {
int curr_point = 0;
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
if (cache->pos != NULL && cache->segments != NULL) {
return;
}
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
int curr_point = 0;
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
static Gwn_VertFormat format = { 0 };
static struct { uint pos, tan, ind; } attr_id;
unsigned int *uv_id = NULL;
int uv_layers = 0;
MTFace **mtfaces = NULL;
float (**parent_uvs)[2] = NULL;
bool simple = psys->part->childtype == PART_CHILD_PARTICLES;
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
if (psmd) {
if (CustomData_has_layer(&psmd->dm_final->loopData, CD_MLOOPUV)) {
uv_layers = CustomData_number_of_layers(&psmd->dm_final->loopData, CD_MLOOPUV);
}
static Gwn_VertFormat format = { 0 };
static struct { uint pos, tan, ind; } attr_id;
unsigned int *uv_id = NULL;
int uv_layers = 0;
MTFace **mtfaces = NULL;
float (**parent_uvs)[2] = NULL;
bool simple = psys->part->childtype == PART_CHILD_PARTICLES;
if (psmd) {
if (CustomData_has_layer(&psmd->dm_final->loopData, CD_MLOOPUV)) {
uv_layers = CustomData_number_of_layers(&psmd->dm_final->loopData, CD_MLOOPUV);
}
}
GWN_vertformat_clear(&format);
/* initialize vertex format */
attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
attr_id.tan = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
attr_id.ind = GWN_vertformat_attr_add(&format, "ind", GWN_COMP_I32, 1, GWN_FETCH_INT);
if (psmd) {
uv_id = MEM_mallocN(sizeof(*uv_id) * uv_layers, "UV attrib format");
for (int i = 0; i < uv_layers; i++) {
const char *name = CustomData_get_layer_name(&psmd->dm_final->loopData, CD_MLOOPUV, i);
char uuid[32];
BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name));
uv_id[i] = GWN_vertformat_attr_add(&format, uuid, GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
}
}
cache->pos = GWN_vertbuf_create_with_format(&format);
GWN_vertbuf_data_alloc(cache->pos, cache->point_count);
Gwn_IndexBufBuilder elb;
GWN_indexbuf_init(&elb, GWN_PRIM_LINES, cache->segment_count, cache->point_count);
if (uv_layers) {
DM_ensure_tessface(psmd->dm_final);
mtfaces = MEM_mallocN(sizeof(*mtfaces) * uv_layers, "Faces UV layers");
for (int i = 0; i < uv_layers; i++) {
mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->dm_final->faceData, CD_MTFACE, i);
}
}
if (psys->pathcache && (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) {
if (simple) {
parent_uvs = MEM_callocN(sizeof(*parent_uvs) * psys->totpart, "Parent particle UVs");
}
GWN_vertformat_clear(&format);
for (int i = 0; i < psys->totpart; i++) {
ParticleCacheKey *path = psys->pathcache[i];
/* initialize vertex format */
attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
attr_id.tan = GWN_vertformat_attr_add(&format, "nor", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
attr_id.ind = GWN_vertformat_attr_add(&format, "ind", GWN_COMP_I32, 1, GWN_FETCH_INT);
if (path->segments > 0) {
float tangent[3];
int from = psmd ? psmd->psys->part->from : 0;
float (*uv)[2] = NULL;
if (psmd) {
uv_id = MEM_mallocN(sizeof(*uv_id) * uv_layers, "UV attrib format");
if (psmd) {
uv = MEM_callocN(sizeof(*uv) * uv_layers, "Particle UVs");
for (int i = 0; i < uv_layers; i++) {
const char *name = CustomData_get_layer_name(&psmd->dm_final->loopData, CD_MLOOPUV, i);
char uuid[32];
if (simple) {
parent_uvs[i] = uv;
}
}
BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name));
uv_id[i] = GWN_vertformat_attr_add(&format, uuid, GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
}
}
if (ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
ParticleData *particle = &psys->particles[i];
int num = particle->num_dmcache;
cache->pos = GWN_vertbuf_create_with_format(&format);
GWN_vertbuf_data_alloc(cache->pos, cache->point_count);
Gwn_IndexBufBuilder elb;
GWN_indexbuf_init(&elb, GWN_PRIM_LINES, cache->segment_count, cache->point_count);
if (uv_layers) {
DM_ensure_tessface(psmd->dm_final);
mtfaces = MEM_mallocN(sizeof(*mtfaces) * uv_layers, "Faces UV layers");
for (int i = 0; i < uv_layers; i++) {
mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->dm_final->faceData, CD_MTFACE, i);
}
}
if (psys->pathcache && (!psys->childcache || (psys->part->draw & PART_DRAW_PARENT))) {
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) {
float tangent[3];
int from = psmd ? psmd->psys->part->from : 0;
float (*uv)[2] = NULL;
if (psmd) {
uv = MEM_callocN(sizeof(*uv) * uv_layers, "Particle UVs");
if (simple) {
parent_uvs[i] = uv;
if (num == DMCACHE_NOTFOUND) {
if (particle->num < psmd->dm_final->getNumTessFaces(psmd->dm_final)) {
num = particle->num;
}
}
if (num != DMCACHE_NOTFOUND) {
MFace *mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
for (int j = 0; j < uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, uv[j]);
}
}
}
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) {
for (int k = 0; k < uv_layers; k++) {
GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]);
}
}
GWN_indexbuf_add_line_verts(&elb, curr_point, curr_point + 1);
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) {
for (int k = 0; k < uv_layers; k++) {
GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]);
}
if (!simple) {
MEM_freeN(uv);
}
}
curr_point++;
}
}
}
if (psys->childcache) {
int child_count = psys->totchild * psys->part->disp / 100;
if (simple && !parent_uvs) {
parent_uvs = MEM_callocN(sizeof(*parent_uvs) * psys->totpart, "Parent particle UVs");
}
for (int i = 0, x = psys->totpart; i < child_count; i++, x++) {
ParticleCacheKey *path = psys->childcache[i];
float tangent[3];
if (path->segments > 0) {
int from = psmd ? psmd->psys->part->from : 0;
float (*uv)[2] = NULL;
if (!simple) {
if (psmd) {
uv = MEM_callocN(sizeof(*uv) * uv_layers, "Particle UVs");
}
if (ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
ParticleData *particle = &psys->particles[i];
ChildParticle *particle = &psys->child[i];
int num = particle->num;
if (num != DMCACHE_NOTFOUND) {
MFace *mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
for (int j = 0; j < uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, uv[j]);
}
}
}
}
else if (!parent_uvs[psys->child[i].parent]) {
if (psmd) {
parent_uvs[psys->child[i].parent] = MEM_callocN(sizeof(*uv) * uv_layers, "Particle UVs");
}
if (ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
ParticleData *particle = &psys->particles[psys->child[i].parent];
int num = particle->num_dmcache;
if (num == DMCACHE_NOTFOUND) {
@@ -267,140 +371,21 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
MFace *mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
for (int j = 0; j < uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, uv[j]);
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, parent_uvs[psys->child[i].parent][j]);
}
}
}
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) {
for (int k = 0; k < uv_layers; k++) {
GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]);
}
}
GWN_indexbuf_add_line_verts(&elb, curr_point, curr_point + 1);
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) {
for (int k = 0; k < uv_layers; k++) {
GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point, uv[k]);
}
if (!simple) {
MEM_freeN(uv);
}
}
curr_point++;
}
}
}
if (psys->childcache) {
int child_count = psys->totchild * psys->part->disp / 100;
if (simple && !parent_uvs) {
parent_uvs = MEM_callocN(sizeof(*parent_uvs) * psys->totpart, "Parent particle UVs");
}
for (int i = 0, x = psys->totpart; i < child_count; i++, x++) {
ParticleCacheKey *path = psys->childcache[i];
float tangent[3];
if (path->segments > 0) {
int from = psmd ? psmd->psys->part->from : 0;
float (*uv)[2] = NULL;
if (!simple) {
if (psmd) {
uv = MEM_callocN(sizeof(*uv) * uv_layers, "Particle UVs");
}
if (ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
ChildParticle *particle = &psys->child[i];
int num = particle->num;
if (num != DMCACHE_NOTFOUND) {
MFace *mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
for (int j = 0; j < uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, uv[j]);
}
}
}
for (int j = 0; j < path->segments; j++) {
if (j == 0) {
sub_v3_v3v3(tangent, path[j + 1].co, path[j].co);
}
else if (!parent_uvs[psys->child[i].parent]) {
if (psmd) {
parent_uvs[psys->child[i].parent] = MEM_callocN(sizeof(*uv) * uv_layers, "Particle UVs");
}
if (ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME)) {
ParticleData *particle = &psys->particles[psys->child[i].parent];
int num = particle->num_dmcache;
if (num == DMCACHE_NOTFOUND) {
if (particle->num < psmd->dm_final->getNumTessFaces(psmd->dm_final)) {
num = particle->num;
}
}
if (num != DMCACHE_NOTFOUND) {
MFace *mface = psmd->dm_final->getTessFaceData(psmd->dm_final, num, CD_MFACE);
for (int j = 0; j < uv_layers; j++) {
psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, parent_uvs[psys->child[i].parent][j]);
}
}
}
else {
sub_v3_v3v3(tangent, path[j + 1].co, path[j - 1].co);
}
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, &x);
if (psmd) {
for (int k = 0; k < uv_layers; k++) {
GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point,
simple ? parent_uvs[psys->child[i].parent][k] : uv[k]);
}
}
GWN_indexbuf_add_line_verts(&elb, curr_point, curr_point + 1);
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.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, &x);
@@ -409,88 +394,107 @@ static void particle_batch_cache_ensure_pos_and_seg(ParticleSystem *psys, Modifi
GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point,
simple ? parent_uvs[psys->child[i].parent][k] : uv[k]);
}
if (!simple) {
MEM_freeN(uv);
}
}
GWN_indexbuf_add_line_verts(&elb, curr_point, curr_point + 1);
curr_point++;
}
}
}
if (parent_uvs) {
for (int i = 0; i < psys->totpart; i++) {
MEM_SAFE_FREE(parent_uvs[i]);
}
sub_v3_v3v3(tangent, path[path->segments].co, path[path->segments - 1].co);
MEM_freeN(parent_uvs);
}
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, &x);
if (uv_layers) {
MEM_freeN(mtfaces);
}
if (psmd) {
for (int k = 0; k < uv_layers; k++) {
GWN_vertbuf_attr_set(cache->pos, uv_id[k], curr_point,
simple ? parent_uvs[psys->child[i].parent][k] : uv[k]);
}
if (psmd) {
MEM_freeN(uv_id);
}
cache->segments = GWN_indexbuf_build(&elb);
}
}
static void particle_batch_cache_ensure_pos(ParticleSystem *psys, ParticleBatchCache *cache)
{
if (cache->pos == NULL) {
static Gwn_VertFormat format = { 0 };
static unsigned pos_id, rot_id, val_id;
int i, curr_point;
ParticleData *pa;
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
if (format.attrib_ct == 0) {
/* initialize vertex format */
pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
rot_id = GWN_vertformat_attr_add(&format, "rot", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
val_id = GWN_vertformat_attr_add(&format, "val", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
}
cache->pos = GWN_vertbuf_create_with_format(&format);
GWN_vertbuf_data_alloc(cache->pos, psys->totpart);
for (curr_point = 0, i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) {
if (pa->state.time >= pa->time && pa->state.time < pa->dietime &&
!(pa->flag & (PARS_NO_DISP | PARS_UNEXIST)))
{
float val;
GWN_vertbuf_attr_set(cache->pos, pos_id, curr_point, pa->state.co);
GWN_vertbuf_attr_set(cache->pos, rot_id, curr_point, pa->state.rot);
switch (psys->part->draw_col) {
case PART_DRAW_COL_VEL:
val = len_v3(pa->state.vel) / psys->part->color_vec_max;
break;
case PART_DRAW_COL_ACC:
val = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * psys->part->color_vec_max);
break;
default:
val = -1.0f;
break;
if (!simple) {
MEM_freeN(uv);
}
}
GWN_vertbuf_attr_set(cache->pos, val_id, curr_point, &val);
curr_point++;
}
}
}
if (curr_point != psys->totpart) {
GWN_vertbuf_data_resize(cache->pos, curr_point);
if (parent_uvs) {
for (int i = 0; i < psys->totpart; i++) {
MEM_SAFE_FREE(parent_uvs[i]);
}
MEM_freeN(parent_uvs);
}
if (uv_layers) {
MEM_freeN(mtfaces);
}
if (psmd) {
MEM_freeN(uv_id);
}
cache->segments = GWN_indexbuf_build(&elb);
}
static void particle_batch_cache_ensure_pos(ParticleSystem *psys, ParticleBatchCache *cache)
{
if (cache->pos != NULL) {
return;
}
static Gwn_VertFormat format = { 0 };
static unsigned pos_id, rot_id, val_id;
int i, curr_point;
ParticleData *pa;
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
if (format.attrib_ct == 0) {
/* initialize vertex format */
pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
rot_id = GWN_vertformat_attr_add(&format, "rot", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
val_id = GWN_vertformat_attr_add(&format, "val", GWN_COMP_F32, 1, GWN_FETCH_FLOAT);
}
cache->pos = GWN_vertbuf_create_with_format(&format);
GWN_vertbuf_data_alloc(cache->pos, psys->totpart);
for (curr_point = 0, i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) {
if (pa->state.time >= pa->time && pa->state.time < pa->dietime &&
!(pa->flag & (PARS_NO_DISP | PARS_UNEXIST)))
{
float val;
GWN_vertbuf_attr_set(cache->pos, pos_id, curr_point, pa->state.co);
GWN_vertbuf_attr_set(cache->pos, rot_id, curr_point, pa->state.rot);
switch (psys->part->draw_col) {
case PART_DRAW_COL_VEL:
val = len_v3(pa->state.vel) / psys->part->color_vec_max;
break;
case PART_DRAW_COL_ACC:
val = len_v3v3(pa->state.vel, pa->prev_state.vel) / ((pa->state.time - pa->prev_state.time) * psys->part->color_vec_max);
break;
default:
val = -1.0f;
break;
}
GWN_vertbuf_attr_set(cache->pos, val_id, curr_point, &val);
curr_point++;
}
}
if (curr_point != psys->totpart) {
GWN_vertbuf_data_resize(cache->pos, curr_point);
}
}