diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2014-03-07 13:25:56 +0400 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2014-03-07 14:20:45 +0400 |
commit | 08444518e62b4c7154c1428c33adab842774aa30 (patch) | |
tree | 17a55f7dae3b1b877e3f6a2d3c0a6d6cdd213c46 /source/blender/blenkernel/intern/particle_system.c | |
parent | 98abc80dcf52e6711d20f7e5738e5a8797567f24 (diff) |
Removing ParticleSystem->frand arrays to avoid memory corruption issues
in threaded depgraph updates and effector list construction.
Gathering effectors during depgraph updates will call the
psys_check_enabled function. This in turn contained a DNA alloc call
for the psys->frand RNG arrays, which is really bad because data must be
immutable during these effector constructions.
To avoid such allocs the frand array is now global for all particle
systems. To avoid correlation of pseudo-random numbers the psys->seed
value is complemented with random offset and multiplier for the actual
float array. This is not ideal, but work sufficiently well (given that
random numbers were already really limited and show repetition quite
easily for particle counts > PSYS_FRAND_COUNT).
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 4eaa2618e26..3f4c53692e5 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -660,9 +660,9 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys) if (pa->flag & PARS_UNEXIST) continue; - pa->fuv[0] += rfac * (PSYS_FRAND(p + 31) - 0.5f); - pa->fuv[1] += rfac * (PSYS_FRAND(p + 32) - 0.5f); - pa->fuv[2] += rfac * (PSYS_FRAND(p + 33) - 0.5f); + pa->fuv[0] += rfac * (psys_frand(psys, p + 31) - 0.5f); + pa->fuv[1] += rfac * (psys_frand(psys, p + 32) - 0.5f); + pa->fuv[2] += rfac * (psys_frand(psys, p + 33) - 0.5f); } } } @@ -1549,7 +1549,7 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat if (part->type != PART_FLUID) { psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f); - if (ptex.exist < PSYS_FRAND(p+125)) + if (ptex.exist < psys_frand(psys, p+125)) pa->flag |= PARS_UNEXIST; pa->time = (part->type == PART_HAIR) ? 0.f : part->sta + (part->end - part->sta)*ptex.time; @@ -1714,9 +1714,9 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P /* -velocity (boids need this even if there's no random velocity) */ if (part->randfac != 0.0f || (part->phystype==PART_PHYS_BOIDS && pa->boid)) { - r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f); - r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f); - r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f); + r_vel[0] = 2.0f * (psys_frand(psys, p + 10) - 0.5f); + r_vel[1] = 2.0f * (psys_frand(psys, p + 11) - 0.5f); + r_vel[2] = 2.0f * (psys_frand(psys, p + 12) - 0.5f); mul_mat3_m4_v3(ob->obmat, r_vel); normalize_v3(r_vel); @@ -1724,9 +1724,9 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P /* -angular velocity */ if (part->avemode==PART_AVE_RAND) { - r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f); - r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f); - r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f); + r_ave[0] = 2.0f * (psys_frand(psys, p + 13) - 0.5f); + r_ave[1] = 2.0f * (psys_frand(psys, p + 14) - 0.5f); + r_ave[2] = 2.0f * (psys_frand(psys, p + 15) - 0.5f); mul_mat3_m4_v3(ob->obmat,r_ave); normalize_v3(r_ave); @@ -1734,10 +1734,10 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P /* -rotation */ if (part->randrotfac != 0.0f) { - r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f); - r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f); - r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f); - r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f); + r_rot[0] = 2.0f * (psys_frand(psys, p + 16) - 0.5f); + r_rot[1] = 2.0f * (psys_frand(psys, p + 17) - 0.5f); + r_rot[2] = 2.0f * (psys_frand(psys, p + 18) - 0.5f); + r_rot[3] = 2.0f * (psys_frand(psys, p + 19) - 0.5f); normalize_qt(r_rot); mat4_to_quat(rot,ob->obmat); @@ -1940,7 +1940,7 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P /* rotation phase */ phasefac = part->phasefac; if (part->randphasefac != 0.0f) - phasefac += part->randphasefac * PSYS_FRAND(p + 20); + phasefac += part->randphasefac * psys_frand(psys, p + 20); axis_angle_to_quat( q_phase,x_vec, phasefac*(float)M_PI); /* combine base rotation & phase */ @@ -2019,7 +2019,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, /* initialize the lifetime, in case the texture coordinates * are from Particles/Strands, which would cause undefined values */ - pa->lifetime = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(p + 21)); + pa->lifetime = part->lifetime * (1.0f - part->randlife * psys_frand(psys, p + 21)); pa->dietime = pa->time + pa->lifetime; /* get possible textural influence */ @@ -2028,7 +2028,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, pa->lifetime = part->lifetime * ptex.life; if (part->randlife != 0.0f) - pa->lifetime *= 1.0f - part->randlife * PSYS_FRAND(p + 21); + pa->lifetime *= 1.0f - part->randlife * psys_frand(psys, p + 21); } pa->dietime = pa->time + pa->lifetime; @@ -4093,9 +4093,9 @@ static void hair_step(ParticleSimulationData *sim, float cfra) LOOP_PARTICLES { pa->size = part->size; if (part->randsize > 0.0f) - pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); + pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1); - if (PSYS_FRAND(p) > disp) + if (psys_frand(psys, p) > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -4254,7 +4254,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra); pa->size = part->size*ptex.size; if (part->randsize > 0.0f) - pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); + pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1); reset_particle(sim, pa, dtime, cfra); } @@ -4312,7 +4312,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) pa->size = part->size*ptex.size; if (part->randsize > 0.0f) - pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); + pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1); birthtime = pa->time; dietime = pa->dietime; @@ -4498,7 +4498,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra) psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra); pa->size = part->size*ptex.size; if (part->randsize > 0.0f) - pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); + pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1); psys->lattice_deform_data = psys_create_lattice_deform_data(sim); @@ -4520,7 +4520,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra) psys->lattice_deform_data = NULL; } - if (PSYS_FRAND(p) > disp) + if (psys_frand(psys, p) > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -4744,7 +4744,7 @@ static void system_step(ParticleSimulationData *sim, float cfra) disp= psys_get_current_display_percentage(psys); LOOP_PARTICLES { - if (PSYS_FRAND(p) > disp) + if (psys_frand(psys, p) > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; @@ -5055,11 +5055,11 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys) LOOP_EXISTING_PARTICLES { pa->size = part->size; if (part->randsize > 0.0f) - pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); + pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1); reset_particle(&sim, pa, 0.0, cfra); - if (PSYS_FRAND(p) > disp) + if (psys_frand(psys, p) > disp) pa->flag |= PARS_NO_DISP; else pa->flag &= ~PARS_NO_DISP; |