diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-06-20 12:07:36 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-06-20 12:12:33 +0300 |
commit | 61b49de449404ecb51902113e7b568ed49f9c3aa (patch) | |
tree | fcf6ce490999383a6af00a5ffde7bc3d665cb5f2 /source/blender | |
parent | 2e553f77b85dc1673f0358e7cd183e8e67a00f2b (diff) |
Fix once more time particle distribution.
rB046adde64f16 was actually pretty useless (and broken), since issue ends up not being
in binary search code, but in generation of the 'summed weights' array used to distribute
particles over mesh items - looks like very small weights could lead to null accumulated
weights, wich was breaking binary search.
Fixed simply by adding a minimal, non-zero weight for mesh items to be allowed to emit particles.
Hopefully we are done with this distribution mess!
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/particle_distribute.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 7830e4eb650..c814713f3f4 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -408,10 +408,10 @@ static int distribute_binary_search(float *sum, int n, float value) return mid; if (sum[mid] > value) { - high = mid; + high = mid - 1; } else { - low = mid; + low = mid + 1; } } @@ -1007,22 +1007,24 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti MEM_freeN(vweight); } +#define MIN_WEIGHT 1e-7f /* Weights too small cause issues e.g. with binary search... */ + /* Calculate total weight of all elements */ int totmapped = 0; totweight = 0.0f; for (i = 0; i < totelem; i++) { - if (element_weight[i] != 0.0f) { + if (element_weight[i] > MIN_WEIGHT) { totmapped++; + totweight += element_weight[i]; } - totweight += element_weight[i]; } - if (totweight == 0.0f) { + if (totmapped == 0) { /* We are not allowed to distribute particles anywhere... */ return 0; } - inv_totweight = (totweight > 0.f ? 1.f/totweight : 0.f); + inv_totweight = 1.0f / totweight; /* Calculate cumulative weights. * We remove all null-weighted elements from element_sum, and create a new mapping @@ -1034,20 +1036,23 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti int *element_map = MEM_mallocN(sizeof(*element_map) * totmapped, __func__); int i_mapped = 0; - for (i = 0; i < totelem && element_weight[i] == 0.0f; i++); + for (i = 0; i < totelem && element_weight[i] <= MIN_WEIGHT; i++); element_sum[i_mapped] = element_weight[i] * inv_totweight; element_map[i_mapped] = i; i_mapped++; for (i++; i < totelem; i++) { - if (element_weight[i] != 0.0f) { + if (element_weight[i] > MIN_WEIGHT) { element_sum[i_mapped] = element_sum[i_mapped - 1] + element_weight[i] * inv_totweight; + BLI_assert(element_sum[i_mapped] > element_sum[i_mapped - 1]); element_map[i_mapped] = i; i_mapped++; } } BLI_assert(i_mapped == totmapped); - + +#undef MIN_WEIGHT + /* Finally assign elements to particles */ if ((part->flag & PART_TRAND) || (part->simplify_flag & PART_SIMPLIFY_ENABLE)) { for (p = 0; p < totpart; p++) { |