Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastián Barschkis <sebbas@sebbas.org>2019-12-16 17:51:43 +0300
committerSebastián Barschkis <sebbas@sebbas.org>2019-12-16 18:39:04 +0300
commitceba74dcd7bb43c667ac8e8e18ed80f02d8ba8e6 (patch)
tree3a79c23c3a039fa991f2d450cd1bdf248d13b286 /source/blender/blenkernel/intern/particle_system.c
parent7bd3d2be080720a5b40b6898e6588e937497201f (diff)
Mantaflow [Part 8]: Customization for particle system
The particle system needs some tweaks so that it can be used for particles created in Mantaflow (i.e. to read both FLIP and secondary particles from Mantaflow). Reviewed By: sergey Maniphest Tasks: T59995 Differential Revision: https://developer.blender.org/D3857
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r--source/blender/blenkernel/intern/particle_system.c507
1 files changed, 310 insertions, 197 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 5985d498606..26bfcdacc78 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -85,14 +85,11 @@
#include "RE_shader_ext.h"
-/* fluid sim particle import */
-#ifdef WITH_MOD_FLUID
-# include "DNA_object_fluidsim_types.h"
-# include "LBM_fluidsim.h"
-# include <zlib.h>
-# include <string.h>
-
-#endif // WITH_MOD_FLUID
+/* FLUID sim particle import */
+#ifdef WITH_FLUID
+# include "DNA_fluid_types.h"
+# include "manta_fluid_API.h"
+#endif // WITH_FLUID
static ThreadRWMutex psys_bvhtree_rwlock = BLI_RWLOCK_INITIALIZER;
@@ -594,8 +591,6 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat
}
pa->time = 0.f;
break;
- case PART_FLUID:
- break;
}
}
@@ -4143,7 +4138,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_
}
static void particles_fluid_step(ParticleSimulationData *sim,
- int UNUSED(cfra),
+ int cfra,
const bool use_render_params)
{
ParticleSystem *psys = sim->psys;
@@ -4153,80 +4148,223 @@ static void particles_fluid_step(ParticleSimulationData *sim,
psys->totpart = 0;
}
- /* fluid sim particle import handling, actual loading of particles from file */
-#ifdef WITH_MOD_FLUID
+#ifdef WITH_FLUID
{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(
- sim->ob, eModifierType_Fluidsim);
+ Object *ob = sim->ob;
+ FluidModifierData *mmd = (FluidModifierData *)modifiers_findByType(ob, eModifierType_Fluid);
+
+ if (mmd && mmd->domain && mmd->domain->fluid) {
+ FluidDomainSettings *mds = mmd->domain;
- if (fluidmd && fluidmd->fss) {
- FluidsimSettings *fss = fluidmd->fss;
ParticleSettings *part = psys->part;
ParticleData *pa = NULL;
- char filename[256];
- char debugStrBuffer[256];
- int curFrame = sim->scene->r.cfra - 1; // warning - sync with derived mesh fsmesh loading
- int p, j, totpart;
- int readMask, activeParts = 0, fileParts = 0;
- gzFile gzf;
-
- // XXX if (ob==G.obedit) // off...
- // return;
-
- // ok, start loading
- BLI_join_dirfile(
- filename, sizeof(filename), fss->surfdataPath, OB_FLUIDSIM_SURF_PARTICLES_FNAME);
- BLI_path_abs(filename, modifier_path_relbase_from_global(sim->ob));
-
- BLI_path_frame(filename, curFrame, 0); // fixed #frame-no
-
- gzf = BLI_gzopen(filename, "rb");
- if (!gzf) {
+ int p, totpart, tottypepart = 0;
+ int flagActivePart, activeParts = 0;
+ float posX, posY, posZ, velX, velY, velZ;
+ float resX, resY, resZ;
+ int upres = 1;
+ char debugStrBuffer[256];
+ float tmp[3] = {0}, tmp2[3] = {0};
+
+ /* Helper variables for scaling. */
+ float min[3], max[3], size[3], cell_size_scaled[3], max_size;
+
+ /* Sanity check: parts also enabled in fluid domain? */
+ if ((part->type & PART_FLUID_FLIP &&
+ (mds->particle_type & FLUID_DOMAIN_PARTICLE_FLIP) == 0) ||
+ (part->type & PART_FLUID_SPRAY &&
+ (mds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) == 0) ||
+ (part->type & PART_FLUID_BUBBLE &&
+ (mds->particle_type & FLUID_DOMAIN_PARTICLE_BUBBLE) == 0) ||
+ (part->type & PART_FLUID_FOAM &&
+ (mds->particle_type & FLUID_DOMAIN_PARTICLE_FOAM) == 0) ||
+ (part->type & PART_FLUID_TRACER &&
+ (mds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER) == 0)) {
BLI_snprintf(debugStrBuffer,
sizeof(debugStrBuffer),
- "readFsPartData::error - Unable to open file for reading '%s'\n",
- filename);
- // XXX bad level call elbeemDebugOut(debugStrBuffer);
+ "particles_fluid_step::error - found particle system that is not enabled in "
+ "fluid domain\n");
return;
}
- gzread(gzf, &totpart, sizeof(totpart));
- totpart = (use_render_params) ? totpart : (part->disp * totpart) / 100;
+ /* Count particle amount. tottypepart is only important for snd particles. */
+ if (part->type & PART_FLUID_FLIP) {
+ tottypepart = totpart = manta_liquid_get_num_flip_particles(mds->fluid);
+ }
+ if (part->type &
+ (PART_FLUID_SPRAY | PART_FLUID_BUBBLE | PART_FLUID_FOAM | PART_FLUID_TRACER)) {
+ totpart = manta_liquid_get_num_snd_particles(mds->fluid);
+
+ /* tottypepart is the amount of particles of a snd particle type. */
+ for (p = 0; p < totpart; p++) {
+ flagActivePart = manta_liquid_get_snd_particle_flag_at(mds->fluid, p);
+ if ((part->type & PART_FLUID_SPRAY) && (flagActivePart & PARTICLE_TYPE_SPRAY))
+ tottypepart++;
+ if ((part->type & PART_FLUID_BUBBLE) && (flagActivePart & PARTICLE_TYPE_BUBBLE))
+ tottypepart++;
+ if ((part->type & PART_FLUID_FOAM) && (flagActivePart & PARTICLE_TYPE_FOAM))
+ tottypepart++;
+ if ((part->type & PART_FLUID_TRACER) && (flagActivePart & PARTICLE_TYPE_TRACER))
+ tottypepart++;
+ }
+ }
+ /* Sanity check: no particles present. */
+ if (!totpart || !tottypepart)
+ return;
+
+ /* How many particles to display? */
+ tottypepart = (use_render_params) ? tottypepart : (part->disp * tottypepart) / 100;
- part->totpart = totpart;
+ part->totpart = tottypepart;
part->sta = part->end = 1.0f;
part->lifetime = sim->scene->r.efra + 1;
- /* allocate particles */
+ /* Allocate particles. */
realloc_particles(sim, part->totpart);
- // set up reading mask
- readMask = fss->typeFlags;
+ /* Set some randomness when choosing which particles to display. */
+ sim->rng = BLI_rng_new_srandom(31415926 + (int)cfra + psys->seed);
+ double r, dispProb = (double)part->disp / 100.0;
- for (p = 0, pa = psys->particles; p < totpart; p++, pa++) {
- int ptype = 0;
+ /* Loop over *all* particles. Will break out of loop before tottypepart amount exceeded. */
+ for (p = 0, pa = psys->particles; p < totpart; p++) {
- gzread(gzf, &ptype, sizeof(ptype));
- if (ptype & readMask) {
- activeParts++;
+ /* Apply some randomness and determine which particles to skip. */
+ r = BLI_rng_get_double(sim->rng);
+ if (r > dispProb)
+ continue;
- gzread(gzf, &(pa->size), sizeof(float));
+ /* flag, res, upres, pos, vel for FLIP and snd particles have different getters. */
+ if (part->type & PART_FLUID_FLIP) {
+ flagActivePart = manta_liquid_get_flip_particle_flag_at(mds->fluid, p);
- pa->size /= 10.0f;
+ resX = (float)manta_get_res_x(mds->fluid);
+ resY = (float)manta_get_res_y(mds->fluid);
+ resZ = (float)manta_get_res_z(mds->fluid);
- for (j = 0; j < 3; j++) {
- float wrf;
- gzread(gzf, &wrf, sizeof(wrf));
- pa->state.co[j] = wrf;
- // fprintf(stderr,"Rj%d ",j);
- }
- for (j = 0; j < 3; j++) {
- float wrf;
- gzread(gzf, &wrf, sizeof(wrf));
- pa->state.vel[j] = wrf;
- }
+ upres = 1;
+
+ posX = manta_liquid_get_flip_particle_position_x_at(mds->fluid, p);
+ posY = manta_liquid_get_flip_particle_position_y_at(mds->fluid, p);
+ posZ = manta_liquid_get_flip_particle_position_z_at(mds->fluid, p);
+
+ velX = manta_liquid_get_flip_particle_velocity_x_at(mds->fluid, p);
+ velY = manta_liquid_get_flip_particle_velocity_y_at(mds->fluid, p);
+ velZ = manta_liquid_get_flip_particle_velocity_z_at(mds->fluid, p);
+ }
+ else if (part->type &
+ (PART_FLUID_SPRAY | PART_FLUID_BUBBLE | PART_FLUID_FOAM | PART_FLUID_TRACER)) {
+ flagActivePart = manta_liquid_get_snd_particle_flag_at(mds->fluid, p);
+
+ resX = (float)manta_liquid_get_particle_res_x(mds->fluid);
+ resY = (float)manta_liquid_get_particle_res_y(mds->fluid);
+ resZ = (float)manta_liquid_get_particle_res_z(mds->fluid);
+
+ upres = manta_liquid_get_particle_upres(mds->fluid);
+
+ posX = manta_liquid_get_snd_particle_position_x_at(mds->fluid, p);
+ posY = manta_liquid_get_snd_particle_position_y_at(mds->fluid, p);
+ posZ = manta_liquid_get_snd_particle_position_z_at(mds->fluid, p);
+ velX = manta_liquid_get_snd_particle_velocity_x_at(mds->fluid, p);
+ velY = manta_liquid_get_snd_particle_velocity_y_at(mds->fluid, p);
+ velZ = manta_liquid_get_snd_particle_velocity_z_at(mds->fluid, p);
+ }
+ else {
+ BLI_snprintf(debugStrBuffer,
+ sizeof(debugStrBuffer),
+ "particles_fluid_step::error - unknown particle system type\n");
+ return;
+ }
+# if 0
+ /* Debugging: Print type of particle system and current particles. */
+ printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
+# endif
+
+ /* Type of particle must matche current particle system type (only important for snd
+ * particles). */
+ if ((flagActivePart & PARTICLE_TYPE_SPRAY) && (part->type & PART_FLUID_SPRAY) == 0)
+ continue;
+ if ((flagActivePart & PARTICLE_TYPE_BUBBLE) && (part->type & PART_FLUID_BUBBLE) == 0)
+ continue;
+ if ((flagActivePart & PARTICLE_TYPE_FOAM) && (part->type & PART_FLUID_FOAM) == 0)
+ continue;
+ if ((flagActivePart & PARTICLE_TYPE_TRACER) && (part->type & PART_FLUID_TRACER) == 0)
+ continue;
+# if 0
+ /* Debugging: Print type of particle system and current particles. */
+ printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
+# endif
+ /* Particle system has allocated tottypeparts particles - so break early before exceeded.
+ */
+ if (activeParts >= tottypepart)
+ break;
+
+ /* Only show active particles, i.e. filter out dead particles that just Mantaflow needs.
+ * Mantaflow convention: PARTICLE_TYPE_DELETE == inactive particle. */
+ if ((flagActivePart & PARTICLE_TYPE_DELETE) == 0) {
+ activeParts++;
+
+ /* Use particle system settings for particle size. */
+ pa->size = part->size;
+ if (part->randsize > 0.0f)
+ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
+
+ /* Get size (dimension) but considering scaling */
+ copy_v3_v3(cell_size_scaled, mds->cell_size);
+ mul_v3_v3(cell_size_scaled, ob->scale);
+ madd_v3fl_v3fl_v3fl_v3i(min, mds->p0, cell_size_scaled, mds->res_min);
+ madd_v3fl_v3fl_v3fl_v3i(max, mds->p0, cell_size_scaled, mds->res_max);
+ sub_v3_v3v3(size, max, min);
+
+ /* Biggest dimension will be used for upscaling. */
+ max_size = MAX3(size[0] / (float)upres, size[1] / (float)upres, size[2] / (float)upres);
+
+ /* Set particle position. */
+ float posParticle[3] = {posX, posY, posZ};
+ copy_v3_v3(pa->state.co, posParticle);
+
+ /* Normalize to unit cube around 0. */
+ float resDomain[3] = {resX, resY, resZ};
+ mul_v3_fl(resDomain, 0.5f);
+ sub_v3_v3(pa->state.co, resDomain);
+ mul_v3_fl(pa->state.co, mds->dx);
+
+ /* Match domain dimension / size. */
+ float scaleAbs[3] = {
+ 1. / fabsf(ob->scale[0]), 1. / fabsf(ob->scale[1]), 1. / fabsf(ob->scale[2])};
+ mul_v3_fl(scaleAbs, max_size);
+ mul_v3_v3(pa->state.co, scaleAbs);
+ ;
+
+ /* Match domain scale. */
+ mul_m4_v3(ob->obmat, pa->state.co);
+
+ /* Add origin offset to particle position. */
+ zero_v3(tmp);
+ zero_v3(tmp2);
+ sub_v3_v3v3(tmp2, mds->p1, mds->p0);
+ mul_v3_fl(tmp2, 0.5f);
+ add_v3_v3v3(tmp, tmp, mds->p1);
+ sub_v3_v3(tmp, tmp2);
+ mul_v3_v3(tmp, ob->scale);
+ add_v3_v3(pa->state.co, tmp);
+# if 0
+ /* Debugging: Print particle coordinates. */
+ printf("pa->state.co[0]: %f, pa->state.co[1]: %f, pa->state.co[2]: %f\n",
+ pa->state.co[0], pa->state.co[1], pa->state.co[2]);
+# endif
+ /* Set particle velocity. */
+ float velParticle[3] = {velX, velY, velZ};
+ copy_v3_v3(pa->state.vel, velParticle);
+ mul_v3_fl(pa->state.vel, mds->dx);
+# if 0
+ /* Debugging: Print particle velocity. */
+ printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n",
+ pa->state.vel[0], pa->state.vel[1], pa->state.vel[2]);
+# endif
+ /* Set default angular velocity and particle rotation. */
zero_v3(pa->state.ave);
unit_qt(pa->state.rot);
@@ -4234,46 +4372,25 @@ static void particles_fluid_step(ParticleSimulationData *sim,
pa->dietime = sim->scene->r.efra + 1;
pa->lifetime = sim->scene->r.efra;
pa->alive = PARS_ALIVE;
-# if 0
- if (a < 25) {
- fprintf(stderr,
- "FSPARTICLE debug set %s, a%d = %f,%f,%f, life=%f\n",
- filename,
- a,
- pa->co[0],
- pa->co[1],
- pa->co[2],
- pa->lifetime);
- }
-# endif
- }
- else {
- // skip...
- for (j = 0; j < 2 * 3 + 1; j++) {
- float wrf;
- gzread(gzf, &wrf, sizeof(wrf));
- }
+
+ /* Increasing particle settings pointer only for active particles. */
+ pa++;
}
- fileParts++;
}
- gzclose(gzf);
+# if 0
+ /* Debugging: Print number of active particles. */
+ printf("active parts: %d\n", activeParts);
+# endif
+ totpart = psys->totpart = part->totpart = activeParts;
- totpart = psys->totpart = activeParts;
- BLI_snprintf(debugStrBuffer,
- sizeof(debugStrBuffer),
- "readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d\n",
- psys->totpart,
- activeParts,
- fileParts,
- readMask);
- // bad level call
- // XXX elbeemDebugOut(debugStrBuffer);
+ BLI_rng_free(sim->rng);
+ sim->rng = NULL;
- } // fluid sim particles done
+ } /* Fluid sim particles done. */
}
#else
UNUSED_VARS(use_render_params);
-#endif // WITH_MOD_FLUID
+#endif // WITH_FLUID
}
static int emit_particles(ParticleSimulationData *sim, PTCacheID *pid, float UNUSED(cfra))
@@ -4654,128 +4771,124 @@ void particle_system_update(struct Depsgraph *depsgraph,
/* setup necessary physics type dependent additional data if it doesn't yet exist */
psys_prepare_physics(&sim);
- switch (part->type) {
- case PART_HAIR: {
- /* nothing to do so bail out early */
- if (psys->totpart == 0 && part->totpart == 0) {
- psys_free_path_cache(psys, NULL);
- free_hair(ob, psys, 0);
- psys->flag |= PSYS_HAIR_DONE;
- }
- /* (re-)create hair */
- else if (hair_needs_recalc(psys)) {
- float hcfra = 0.0f;
- int i, recalc = psys->recalc;
+ if (part->type & PART_HAIR) {
+ /* nothing to do so bail out early */
+ if (psys->totpart == 0 && part->totpart == 0) {
+ psys_free_path_cache(psys, NULL);
+ free_hair(ob, psys, 0);
+ psys->flag |= PSYS_HAIR_DONE;
+ }
+ /* (re-)create hair */
+ else if (hair_needs_recalc(psys)) {
+ float hcfra = 0.0f;
+ int i, recalc = psys->recalc;
- free_hair(ob, psys, 0);
+ free_hair(ob, psys, 0);
- if (psys_orig->edit && psys_orig->free_edit) {
- psys_orig->free_edit(psys_orig->edit);
- psys_orig->edit = NULL;
- psys_orig->free_edit = NULL;
- }
-
- /* first step is negative so particles get killed and reset */
- psys->cfra = 1.0f;
+ if (psys_orig->edit && psys_orig->free_edit) {
+ psys_orig->free_edit(psys_orig->edit);
+ psys_orig->edit = NULL;
+ psys_orig->free_edit = NULL;
+ }
- ParticleSettings *part_local = part;
- if ((part->flag & PART_HAIR_REGROW) == 0) {
- part_local = particle_settings_localize(part);
- psys->part = part_local;
- }
+ /* first step is negative so particles get killed and reset */
+ psys->cfra = 1.0f;
- for (i = 0; i <= part->hair_step; i++) {
- hcfra = 100.0f * (float)i / (float)psys->part->hair_step;
- if ((part->flag & PART_HAIR_REGROW) == 0) {
- BKE_animsys_evaluate_animdata(
- scene, &part_local->id, part_local->adt, hcfra, ADT_RECALC_ANIM, false);
- }
- system_step(&sim, hcfra, use_render_params);
- psys->cfra = hcfra;
- psys->recalc = 0;
- save_hair(&sim, hcfra);
- }
+ ParticleSettings *part_local = part;
+ if ((part->flag & PART_HAIR_REGROW) == 0) {
+ part_local = particle_settings_localize(part);
+ psys->part = part_local;
+ }
- if (part_local != part) {
- particle_settings_free_local(part_local);
- psys->part = part;
+ for (i = 0; i <= part->hair_step; i++) {
+ hcfra = 100.0f * (float)i / (float)psys->part->hair_step;
+ if ((part->flag & PART_HAIR_REGROW) == 0) {
+ BKE_animsys_evaluate_animdata(
+ scene, &part_local->id, part_local->adt, hcfra, ADT_RECALC_ANIM, false);
}
-
- psys->flag |= PSYS_HAIR_DONE;
- psys->recalc = recalc;
- }
- else if (psys->flag & PSYS_EDITED) {
- psys->flag |= PSYS_HAIR_DONE;
+ system_step(&sim, hcfra, use_render_params);
+ psys->cfra = hcfra;
+ psys->recalc = 0;
+ save_hair(&sim, hcfra);
}
- if (psys->flag & PSYS_HAIR_DONE) {
- hair_step(&sim, cfra, use_render_params);
+ if (part_local != part) {
+ particle_settings_free_local(part_local);
+ psys->part = part;
}
- break;
+
+ psys->flag |= PSYS_HAIR_DONE;
+ psys->recalc = recalc;
}
- case PART_FLUID: {
- particles_fluid_step(&sim, (int)cfra, use_render_params);
- break;
+ else if (psys->flag & PSYS_EDITED) {
+ psys->flag |= PSYS_HAIR_DONE;
}
- default: {
- switch (part->phystype) {
- case PART_PHYS_NO:
- case PART_PHYS_KEYED: {
- PARTICLE_P;
- float disp = psys_get_current_display_percentage(psys, use_render_params);
- bool free_unexisting = false;
-
- /* Particles without dynamics haven't been reset yet because they don't use pointcache */
- if (psys->recalc & ID_RECALC_PSYS_RESET) {
- psys_reset(psys, PSYS_RESET_ALL);
- }
- if (emit_particles(&sim, NULL, cfra) || (psys->recalc & ID_RECALC_PSYS_RESET)) {
- free_keyed_keys(psys);
- distribute_particles(&sim, part->from);
- initialize_all_particles(&sim);
- free_unexisting = true;
+ if (psys->flag & PSYS_HAIR_DONE) {
+ hair_step(&sim, cfra, use_render_params);
+ }
+ }
+ else if (part->type & (PART_FLUID_FLIP | PART_FLUID_BUBBLE | PART_FLUID_BUBBLE |
+ PART_FLUID_FOAM | PART_FLUID_TRACER)) {
+ particles_fluid_step(&sim, (int)cfra, use_render_params);
+ }
+ else {
+ switch (part->phystype) {
+ case PART_PHYS_NO:
+ case PART_PHYS_KEYED: {
+ PARTICLE_P;
+ float disp = psys_get_current_display_percentage(psys, use_render_params);
+ bool free_unexisting = false;
+
+ /* Particles without dynamics haven't been reset yet because they don't use pointcache */
+ if (psys->recalc & ID_RECALC_PSYS_RESET) {
+ psys_reset(psys, PSYS_RESET_ALL);
+ }
- /* flag for possible explode modifiers after this system */
- sim.psmd->flag |= eParticleSystemFlag_Pars;
- }
+ if (emit_particles(&sim, NULL, cfra) || (psys->recalc & ID_RECALC_PSYS_RESET)) {
+ free_keyed_keys(psys);
+ distribute_particles(&sim, part->from);
+ initialize_all_particles(&sim);
+ free_unexisting = true;
- LOOP_EXISTING_PARTICLES
- {
- pa->size = part->size;
- if (part->randsize > 0.0f) {
- pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
- }
-
- reset_particle(&sim, pa, 0.0, cfra);
-
- if (psys_frand(psys, p) > disp) {
- pa->flag |= PARS_NO_DISP;
- }
- else {
- pa->flag &= ~PARS_NO_DISP;
- }
- }
+ /* flag for possible explode modifiers after this system */
+ sim.psmd->flag |= eParticleSystemFlag_Pars;
+ }
- /* free unexisting after resetting particles */
- if (free_unexisting) {
- free_unexisting_particles(&sim);
+ LOOP_EXISTING_PARTICLES
+ {
+ pa->size = part->size;
+ if (part->randsize > 0.0f) {
+ pa->size *= 1.0f - part->randsize * psys_frand(psys, p + 1);
}
- if (part->phystype == PART_PHYS_KEYED) {
- psys_count_keyed_targets(&sim);
- set_keyed_keys(&sim);
- psys_update_path_cache(&sim, (int)cfra, use_render_params);
+ reset_particle(&sim, pa, 0.0, cfra);
+
+ if (psys_frand(psys, p) > disp) {
+ pa->flag |= PARS_NO_DISP;
+ }
+ else {
+ pa->flag &= ~PARS_NO_DISP;
}
- break;
}
- default: {
- /* the main dynamic particle system step */
- system_step(&sim, cfra, use_render_params);
- break;
+
+ /* free unexisting after resetting particles */
+ if (free_unexisting) {
+ free_unexisting_particles(&sim);
}
+
+ if (part->phystype == PART_PHYS_KEYED) {
+ psys_count_keyed_targets(&sim);
+ set_keyed_keys(&sim);
+ psys_update_path_cache(&sim, (int)cfra, use_render_params);
+ }
+ break;
+ }
+ default: {
+ /* the main dynamic particle system step */
+ system_step(&sim, cfra, use_render_params);
+ break;
}
- break;
}
}