Removing ParticleSystem->frand arrays to avoid memory corruption issues
authorLukas Tönne <lukas.toenne@gmail.com>
Fri, 7 Mar 2014 09:25:56 +0000 (10:25 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Fri, 7 Mar 2014 10:20:45 +0000 (11:20 +0100)
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).

source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/boids.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_particle_types.h
source/blender/render/intern/source/convertblender.c
source/creator/creator.c

index b6be72fadd3ef78fd0c311033b1b276ed155d2bb..d87b20907120fde796a106a832bd2d7335f9fcc5 100644 (file)
@@ -34,6 +34,8 @@
  *  \ingroup bke
  */
 
+#include "BLI_utildefines.h"
+
 #include "DNA_particle_types.h"
 #include "DNA_object_types.h"
 
@@ -70,9 +72,6 @@ struct EdgeHash;
 /* OpenMP: Can only advance one variable within loop definition. */
 #define LOOP_DYNAMIC_PARTICLES for (p = 0; p < psys->totpart; p++) if ((pa = psys->particles + p)->state.time > 0.0f)
 
-#define PSYS_FRAND_COUNT    1024
-#define PSYS_FRAND(seed)    psys->frand[(seed) % PSYS_FRAND_COUNT]
-
 /* fast but sure way to get the modifier*/
 #define PARTICLE_PSMD ParticleSystemModifierData * psmd = sim->psmd ? sim->psmd : psys_get_modifier(sim->ob, sim->psys)
 
@@ -247,6 +246,34 @@ typedef struct ParticleDrawData {
 
 #define PARTICLE_DRAW_DATA_UPDATED  1
 
+#define PSYS_FRAND_COUNT    1024
+unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT];
+unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT];
+float PSYS_FRAND_BASE[PSYS_FRAND_COUNT];
+
+void psys_init_rng(void);
+
+BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed)
+{
+       /* XXX far from ideal, this simply scrambles particle random numbers a bit
+        * to avoid obvious correlations.
+        * Can't use previous psys->frand arrays because these require initialization
+        * inside psys_check_enabled, which wreaks havok in multithreaded depgraph updates.
+        */
+       unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
+       unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
+       return PSYS_FRAND_BASE[(offset + seed * multiplier) % PSYS_FRAND_COUNT];
+}
+
+BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float vec[3])
+{
+       unsigned int offset = PSYS_FRAND_SEED_OFFSET[psys->seed % PSYS_FRAND_COUNT];
+       unsigned int multiplier = PSYS_FRAND_SEED_MULTIPLIER[psys->seed % PSYS_FRAND_COUNT];
+       vec[0] = PSYS_FRAND_BASE[(offset + (seed + 0) * multiplier) % PSYS_FRAND_COUNT];
+       vec[1] = PSYS_FRAND_BASE[(offset + (seed + 1) * multiplier) % PSYS_FRAND_COUNT];
+       vec[2] = PSYS_FRAND_BASE[(offset + (seed + 2) * multiplier) % PSYS_FRAND_COUNT];
+}
+
 /* ----------- functions needed outside particlesystem ---------------- */
 /* particle.c */
 int count_particles(struct ParticleSystem *psys);
index a8d64ea9fb637b5737ea2a4bd7ec4cf8c5a15338..157de3e2f1c80c4e28f2d6ccd803ab5cdecdd723 100644 (file)
@@ -970,8 +970,8 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa)
        bbd->wanted_speed = 0.0f;
 
        /* create random seed for every particle & frame */
-       rand = (int)(PSYS_FRAND(psys->seed + p) * 1000);
-       rand = (int)(PSYS_FRAND((int)bbd->cfra + rand) * 1000);
+       rand = (int)(psys_frand(psys, psys->seed + p) * 1000);
+       rand = (int)(psys_frand(psys, (int)bbd->cfra + rand) * 1000);
 
        set_boid_values(&val, bbd->part->boids, pa);
 
index c0336bf9bc765e72e646330e3edf6c049757bda6..06034f24f91032d9a1f991b867ccaec80e58aced 100644 (file)
@@ -1279,7 +1279,6 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
        psysn->pathcache = NULL;
        psysn->childcache = NULL;
        psysn->edit = NULL;
-       psysn->frand = NULL;
        psysn->pdd = NULL;
        psysn->effectors = NULL;
        psysn->tree = NULL;
index edf902e0eb5a4942e3876b9ffcdf256dbe7c1804..48db07d45ebf35296185e1697a4b70bfba61013c 100644 (file)
 
 #include "RE_render_ext.h"
 
+void psys_init_rng(void)
+{
+       int i;
+       BLI_srandom(5831); /* arbitrary */
+       for (i = 0; i < PSYS_FRAND_COUNT; ++i) {
+               PSYS_FRAND_BASE[i] = BLI_frand();
+               PSYS_FRAND_SEED_OFFSET[i] = (unsigned int)BLI_rand();
+               PSYS_FRAND_SEED_MULTIPLIER[i] = (unsigned int)BLI_rand();
+       }
+}
+
 static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
                                           ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
 static void do_child_modifiers(ParticleSimulationData *sim,
@@ -260,16 +271,6 @@ int psys_in_edit_mode(Scene *scene, ParticleSystem *psys)
 {
        return (scene->basact && (scene->basact->object->mode & OB_MODE_PARTICLE_EDIT) && psys == psys_get_current((scene->basact)->object) && (psys->edit || psys->pointcache->edit) && !psys->renderdata);
 }
-static void psys_create_frand(ParticleSystem *psys)
-{
-       int i;
-       float *rand = psys->frand = MEM_callocN(PSYS_FRAND_COUNT * sizeof(float), "particle randoms");
-
-       BLI_srandom(psys->seed);
-
-       for (i = 0; i < 1024; i++, rand++)
-               *rand = BLI_frand();
-}
 int psys_check_enabled(Object *ob, ParticleSystem *psys)
 {
        ParticleSystemModifierData *psmd;
@@ -285,14 +286,6 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
        else if (!(psmd->modifier.mode & eModifierMode_Realtime))
                return 0;
 
-       /* perhaps not the perfect place, but we have to be sure the rands are there before usage */
-       if (!psys->frand)
-               psys_create_frand(psys);
-       else if (psys->recalc & PSYS_RECALC_RESET) {
-               MEM_freeN(psys->frand);
-               psys_create_frand(psys);
-       }
-       
        return 1;
 }
 
@@ -579,9 +572,6 @@ void psys_free(Object *ob, ParticleSystem *psys)
 
                pdEndEffectors(&psys->effectors);
 
-               if (psys->frand)
-                       MEM_freeN(psys->frand);
-
                if (psys->pdd) {
                        psys_free_pdd(psys);
                        MEM_freeN(psys->pdd);
@@ -787,7 +777,7 @@ void psys_render_restore(Object *ob, ParticleSystem *psys)
                PARTICLE_P;
 
                LOOP_PARTICLES {
-                       if (PSYS_FRAND(p) > disp)
+                       if (psys_frand(psys, p) > disp)
                                pa->flag |= PARS_NO_DISP;
                        else
                                pa->flag &= ~PARS_NO_DISP;
@@ -2680,7 +2670,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
        /* get different child parameters from textures & vgroups */
        get_child_modifier_parameters(part, ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
 
-       if (ptex.exist < PSYS_FRAND(i + 24)) {
+       if (ptex.exist < psys_frand(psys, i + 24)) {
                child_keys->steps = -1;
                return;
        }
@@ -2996,7 +2986,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
        LOOP_SHOWN_PARTICLES {
                if (!psys->totchild) {
                        psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
-                       pa_length = ptex.length * (1.0f - part->randlength * PSYS_FRAND(psys->seed + p));
+                       pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p));
                        if (vg_length)
                                pa_length *= psys_particle_value_from_verts(psmd->dm, part->from, pa, vg_length);
                }
@@ -3832,8 +3822,8 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
        ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
        ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
 
-       ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26);
-       ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f;
+       ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
+       ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f;
 
        for (m = 0; m < MAX_MTEX; m++, mtexp++) {
                mtex = *mtexp;
@@ -3995,7 +3985,7 @@ float psys_get_child_time(ParticleSystem *psys, ChildParticle *cpa, float cfra,
                        w++;
                }
 
-               life = part->lifetime * (1.0f - part->randlife * PSYS_FRAND(cpa - psys->child + 25));
+               life = part->lifetime * (1.0f - part->randlife * psys_frand(psys, cpa - psys->child + 25));
        }
        else {
                ParticleData *pa = psys->particles + cpa->parent;
@@ -4024,7 +4014,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float UNUSED
        size *= part->childsize;
 
        if (part->childrandsize != 0.0f)
-               size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26);
+               size *= 1.0f - part->childrandsize * psys_frand(psys, cpa - psys->child + 26);
 
        return size;
 }
@@ -4036,7 +4026,7 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
        get_cpa_texture(ctx->dm, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS | PAMAP_CHILD, psys->cfra);
 
 
-       if (ptex->exist < PSYS_FRAND(i + 24))
+       if (ptex->exist < psys_frand(psys, i + 24))
                return;
 
        if (ctx->vg_length)
@@ -4091,11 +4081,17 @@ static void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *pte
        if (rough1 > 0.f)
                do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
 
-       if (rough2 > 0.f)
-               do_rough(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, rough2, part->rough2_size, part->rough2_thres, state);
+       if (rough2 > 0.f) {
+               float vec[3];
+               psys_frand_vec(sim->psys, i + 27, vec);
+               do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
+       }
 
-       if (rough_end > 0.f)
-               do_rough_end(sim->psys->frand + ((i + 27) % (PSYS_FRAND_COUNT - 3)), mat, t, rough_end, part->rough_end_shape, state);
+       if (rough_end > 0.f) {
+               float vec[3];
+               psys_frand_vec(sim->psys, i + 27, vec);
+               do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
+       }
 }
 /* get's hair (or keyed) particles state at the "path time" specified in state->time */
 void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, int vel)
@@ -4358,7 +4354,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
                                }
                        }
 
-                       state->time = (cfra - (part->sta + (part->end - part->sta) * PSYS_FRAND(p + 23))) / (part->lifetime * PSYS_FRAND(p + 24));
+                       state->time = (cfra - (part->sta + (part->end - part->sta) * psys_frand(psys, p + 23))) / (part->lifetime * psys_frand(psys, p + 24));
 
                        psys_get_particle_on_path(sim, p, state, 1);
                        return 1;
@@ -4567,7 +4563,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
                        float q_phase[4];
                        float phasefac = psys->part->phasefac;
                        if (psys->part->randphasefac != 0.0f)
-                               phasefac += psys->part->randphasefac * PSYS_FRAND((pa - psys->particles) + 20);
+                               phasefac += psys->part->randphasefac * psys_frand(psys, (pa - psys->particles) + 20);
                        axis_angle_to_quat(q_phase, vec, phasefac * (float)M_PI);
 
                        mul_qt_v3(q_phase, side);
index 4eaa2618e26346184ae30183684fc69f2776de07..3f4c53692e500729617074d8c8ccd505cfbc2e49 100644 (file)
@@ -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;
index 6c1aa01211865a242e365fcc0a1dbf3301ce2468..bf81e0b4e2189e865b4d417efa8ea482a3363125 100644 (file)
@@ -3848,7 +3848,6 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                psys->childcache = NULL;
                BLI_listbase_clear(&psys->pathcachebufs);
                BLI_listbase_clear(&psys->childcachebufs);
-               psys->frand = NULL;
                psys->pdd = NULL;
                psys->renderdata = NULL;
                
index b0eb8d20554e28c47600fb2d6c33ab35cd7c7d43..c1adbafe413519d606474b10ab53d3a3c674c215 100644 (file)
@@ -4649,8 +4649,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
                                        else
                                                pa_health = -1.0;
 
-                                       r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
-                                       r_length = PSYS_FRAND(a + 22);
+                                       r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+                                       r_length = psys_frand(psys, a + 22);
 
                                        if (part->draw_col > PART_DRAW_COL_MAT) {
                                                switch (part->draw_col) {
@@ -4677,8 +4677,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
 
                                        pa_health = -1.0;
 
-                                       r_tilt = 2.0f * (PSYS_FRAND(a + 21) - 0.5f);
-                                       r_length = PSYS_FRAND(a + 22);
+                                       r_tilt = 2.0f * (psys_frand(psys, a + 21) - 0.5f);
+                                       r_length = psys_frand(psys, a + 22);
                                }
 
                                drawn = 0;
index 170d1376908b4f8e7501f616990f42a47d1c0304..7b06f2a46db947e3079321ac84d80c8255db3dc3 100644 (file)
@@ -309,8 +309,6 @@ typedef struct ParticleSystem {
 
        struct ParticleDrawData *pdd;
 
-       float *frand;                                                   /* array of 1024 random floats for fast lookups */
-
        float dt_frac;                                                  /* current time step, as a fraction of a frame */
        float _pad;                                                             /* spare capacity */
 } ParticleSystem;
index a9e83e65455bcd302a543c179d9431f437b881b8..833acb68a7c36ca7b26ac63bc14ffc3de099d170 100644 (file)
@@ -1579,8 +1579,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 
                        pa_size = pa->size;
 
-                       r_tilt = 2.0f*(PSYS_FRAND(a) - 0.5f);
-                       r_length = PSYS_FRAND(a+1);
+                       r_tilt = 2.0f*(psys_frand(psys, a) - 0.5f);
+                       r_length = psys_frand(psys, a+1);
 
                        if (path_nbr) {
                                cache = psys->pathcache[a];
@@ -1604,8 +1604,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                        pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
                        pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
 
-                       r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
-                       r_length = PSYS_FRAND(a + 22);
+                       r_tilt = 2.0f*(psys_frand(psys, a + 21) - 0.5f);
+                       r_length = psys_frand(psys, a + 22);
 
                        num = cpa->num;
 
index 4aaa2ae32b19b025e0a1ab82d54667c0104cb8c5..6cf86c42eaffb2047a39557cfbebe135783af5fd 100644 (file)
 #include "BKE_report.h"
 #include "BKE_sound.h"
 #include "BKE_image.h"
+#include "BKE_particle.h"
 
 #include "IMB_imbuf.h"  /* for IMB_init */
 
@@ -1631,6 +1632,7 @@ int main(int argc, const char **argv)
 
        RE_engines_init();
        init_nodesystem();
+       psys_init_rng();
        /* end second init */