diff options
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 279 |
1 files changed, 159 insertions, 120 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index fd63285ea85..d6a29531482 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -74,10 +74,13 @@ #include "BKE_collision.h" #include "BKE_colortools.h" #include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_main.h" #include "BKE_particle.h" +#include "BKE_collection.h" #include "BKE_DerivedMesh.h" #include "BKE_object.h" #include "BKE_material.h" @@ -88,12 +91,14 @@ #include "BKE_modifier.h" #include "BKE_scene.h" #include "BKE_bvhutils.h" -#include "BKE_depsgraph.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_physics.h" +#include "DEG_depsgraph_query.h" #include "PIL_time.h" #include "RE_shader_ext.h" -#include "DEG_depsgraph.h" /* fluid sim particle import */ #ifdef WITH_MOD_FLUID @@ -121,11 +126,11 @@ static int particles_are_dynamic(ParticleSystem *psys) return ELEM(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID); } -float psys_get_current_display_percentage(ParticleSystem *psys) +float psys_get_current_display_percentage(ParticleSystem *psys, const bool use_render_params) { ParticleSettings *part=psys->part; - if ((psys->renderdata && !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */ + if ((use_render_params && !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */ (part->child_nbr && part->childtype) || /* display percentage applies to children */ (psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */ { @@ -285,31 +290,31 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart) } } -int psys_get_child_number(Scene *scene, ParticleSystem *psys) +int psys_get_child_number(Scene *scene, ParticleSystem *psys, const bool use_render_params) { int nbr; if (!psys->part->childtype) return 0; - if (psys->renderdata) + if (use_render_params) nbr= psys->part->ren_child_nbr; else nbr= psys->part->child_nbr; - return get_render_child_particle_number(&scene->r, nbr, psys->renderdata != NULL); + return get_render_child_particle_number(&scene->r, nbr, use_render_params); } -int psys_get_tot_child(Scene *scene, ParticleSystem *psys) +int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render_params) { - return psys->totpart*psys_get_child_number(scene, psys); + return psys->totpart*psys_get_child_number(scene, psys, use_render_params); } /************************************************/ /* Distribution */ /************************************************/ -void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deformed, ParticleSystem *psys) +void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_original, ParticleSystem *psys) { /* use for building derived mesh mapping info: * @@ -322,13 +327,13 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform PARTICLE_P; /* CACHE LOCATIONS */ - if (!dm_final->deformedOnly) { + if (!mesh_final->runtime.deformed_only) { /* Will use later to speed up subsurf/derivedmesh */ LinkNode *node, *nodedmelem, **nodearray; int totdmelem, totelem, i, *origindex, *origindex_poly = NULL; if (psys->part->from == PART_FROM_VERT) { - totdmelem= dm_final->getNumVerts(dm_final); + totdmelem = mesh_final->totvert; if (use_modifier_stack) { totelem= totdmelem; @@ -336,11 +341,11 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform } else { totelem= me->totvert; - origindex= dm_final->getVertDataArray(dm_final, CD_ORIGINDEX); + origindex = CustomData_get_layer(&mesh_final->vdata, CD_ORIGINDEX); } } else { /* FROM_FACE/FROM_VOLUME */ - totdmelem= dm_final->getNumTessFaces(dm_final); + totdmelem= mesh_final->totface; if (use_modifier_stack) { totelem= totdmelem; @@ -348,11 +353,11 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform origindex_poly= NULL; } else { - totelem = dm_deformed->getNumTessFaces(dm_deformed); - origindex = dm_final->getTessFaceDataArray(dm_final, CD_ORIGINDEX); + totelem = mesh_original->totface; + origindex = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX); /* for face lookups we need the poly origindex too */ - origindex_poly= dm_final->getPolyDataArray(dm_final, CD_ORIGINDEX); + origindex_poly = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX); if (origindex_poly == NULL) { origindex= NULL; } @@ -412,7 +417,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm_final, DerivedMesh *dm_deform pa->num_dmcache = DMCACHE_NOTFOUND; } else { /* FROM_FACE/FROM_VOLUME */ - pa->num_dmcache = psys_particle_dm_face_lookup(dm_final, dm_deformed, pa->num, pa->fuv, nodearray); + pa->num_dmcache = psys_particle_dm_face_lookup(mesh_final, mesh_original, pa->num, pa->fuv, nodearray); } } } @@ -436,7 +441,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData { memset(ctx, 0, sizeof(ParticleThreadContext)); ctx->sim = *sim; - ctx->dm = ctx->sim.psmd->dm_final; + ctx->mesh = ctx->sim.psmd->mesh_final; ctx->ma = give_current_material(sim->ob, sim->psys->part->omat); } @@ -511,7 +516,6 @@ void psys_thread_context_free(ParticleThreadContext *ctx) if (ctx->jitoff) MEM_freeN(ctx->jitoff); if (ctx->weight) MEM_freeN(ctx->weight); if (ctx->index) MEM_freeN(ctx->index); - if (ctx->skip) MEM_freeN(ctx->skip); if (ctx->seams) MEM_freeN(ctx->seams); //if (ctx->vertpart) MEM_freeN(ctx->vertpart); BLI_kdtree_free(ctx->tree); @@ -702,9 +706,9 @@ void psys_get_birth_coords(ParticleSimulationData *sim, ParticleData *pa, Partic /* get birth location from object */ if (use_tangents) - psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0); + psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0); else - psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0); + psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0); /* get possible textural influence */ psys_get_texture(sim, pa, &ptex, PAMAP_IVEL, cfra); @@ -988,14 +992,14 @@ void psys_get_birth_coords(ParticleSimulationData *sim, ParticleData *pa, Partic } /* recursively evaluate emitter parent anim at cfra */ -static void evaluate_emitter_anim(Scene *scene, Object *ob, float cfra) +static void evaluate_emitter_anim(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float cfra) { if (ob->parent) - evaluate_emitter_anim(scene, ob->parent, cfra); + evaluate_emitter_anim(depsgraph, scene, ob->parent, cfra); /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */ - BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM); - BKE_object_where_is_calc_time(scene, ob, cfra); + BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM); + BKE_object_where_is_calc_time(depsgraph, scene, ob, cfra); } /* sets particle to the emitter surface with initial velocity & rotation */ @@ -1009,7 +1013,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, /* get precise emitter matrix if particle is born */ if (part->type != PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) { - evaluate_emitter_anim(sim->scene, sim->ob, pa->time); + evaluate_emitter_anim(sim->depsgraph, sim->scene, sim->ob, pa->time); psys->flag |= PSYS_OB_ANIM_RESTORE; } @@ -1143,7 +1147,8 @@ static void set_keyed_keys(ParticleSimulationData *sim) int totpart = psys->totpart, k, totkeys = psys->totkeyed; int keyed_flag = 0; - ksim.scene= sim->scene; + ksim.depsgraph = sim->depsgraph; + ksim.scene = sim->scene; /* no proper targets so let's clear and bail out */ if (psys->totkeyed==0) { @@ -1303,9 +1308,10 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra) static void psys_update_effectors(ParticleSimulationData *sim) { - pdEndEffectors(&sim->psys->effectors); - sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, - sim->psys->part->effector_weights, true); + BKE_effectors_free(sim->psys->effectors); + sim->psys->effectors = BKE_effectors_create(sim->depsgraph, + sim->scene, sim->ob, sim->psys, + sim->psys->part->effector_weights); precalc_guides(sim, sim->psys->effectors); } @@ -2057,11 +2063,12 @@ static void basic_force_cb(void *efdata_v, ParticleKey *state, float *force, flo ParticleSettings *part = sim->psys->part; ParticleData *pa = efdata->pa; EffectedPoint epoint; + RNG *rng = sim->rng; /* add effectors */ pd_point_from_particle(efdata->sim, efdata->pa, state, &epoint); if (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR) - pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse); + BKE_effectors_apply(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse); mul_v3_fl(force, efdata->ptex.field); mul_v3_fl(impulse, efdata->ptex.field); @@ -2072,9 +2079,9 @@ static void basic_force_cb(void *efdata_v, ParticleKey *state, float *force, flo /* brownian force */ if (part->brownfac != 0.0f) { - force[0] += (BLI_frand()-0.5f) * part->brownfac; - force[1] += (BLI_frand()-0.5f) * part->brownfac; - force[2] += (BLI_frand()-0.5f) * part->brownfac; + force[0] += (BLI_rng_get_float(rng)-0.5f) * part->brownfac; + force[1] += (BLI_rng_get_float(rng)-0.5f) * part->brownfac; + force[2] += (BLI_rng_get_float(rng)-0.5f) * part->brownfac; } if (part->flag & PART_ROT_DYN && epoint.ave) @@ -2125,7 +2132,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa tkey.time=pa->state.time; if (part->type != PART_HAIR) { - if (do_guides(sim->psys->part, sim->psys->effectors, &tkey, p, time)) { + if (do_guides(sim->depsgraph, sim->psys->part, sim->psys->effectors, &tkey, p, time)) { copy_v3_v3(pa->state.co,tkey.co); /* guides don't produce valid velocity */ sub_v3_v3v3(pa->state.vel, tkey.co, pa->prev_state.co); @@ -2645,16 +2652,17 @@ static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRay return hit->index >= 0; } -static int collision_response(ParticleData *pa, ParticleCollision *col, BVHTreeRayHit *hit, int kill, int dynamic_rotation) +static int collision_response(ParticleSimulationData *sim, ParticleData *pa, ParticleCollision *col, BVHTreeRayHit *hit, int kill, int dynamic_rotation) { ParticleCollisionElement *pce = &col->pce; PartDeflect *pd = col->hit->pd; + RNG *rng = sim->rng; float co[3]; /* point of collision */ float x = hit->dist/col->original_ray_length; /* location factor of collision between this iteration */ float f = col->f + x * (1.0f - col->f); /* time factor of collision between timestep */ float dt1 = (f - col->f) * col->total_time; /* time since previous collision (in seconds) */ float dt2 = (1.0f - f) * col->total_time; /* time left after collision (in seconds) */ - int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0; /* did particle pass through the collision surface? */ + int through = (BLI_rng_get_float(rng) < pd->pdef_perm) ? 1 : 0; /* did particle pass through the collision surface? */ /* calculate exact collision location */ interp_v3_v3v3(co, col->co1, col->co2, x); @@ -2679,8 +2687,8 @@ static int collision_response(ParticleData *pa, ParticleCollision *col, BVHTreeR float v0_tan[3];/* tangential component of v0 */ float vc_tan[3];/* tangential component of collision surface velocity */ float v0_dot, vc_dot; - float damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_frand() - 0.5f); - float frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_frand() - 0.5f); + float damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_rng_get_float(rng) - 0.5f); + float frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_rng_get_float(rng) - 0.5f); float distance, nor[3], dot; CLAMP(damp,0.0f, 1.0f); @@ -2890,7 +2898,7 @@ static void collision_check(ParticleSimulationData *sim, int p, float dfra, floa if (collision_count == PARTICLE_COLLISION_MAX_COLLISIONS) collision_fail(pa, &col); - else if (collision_response(pa, &col, &hit, part->flag & PART_DIE_ON_COL, part->flag & PART_ROT_DYN)==0) + else if (collision_response(sim, pa, &col, &hit, part->flag & PART_DIE_ON_COL, part->flag & PART_ROT_DYN)==0) return; } else @@ -2906,10 +2914,9 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; ParticleEditSettings *pset = &sim->scene->toolsettings->particle; - Base *base; int distr=0, alloc=0, skip=0; - if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET) + if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys, use_render_params)) || psys->recalc&PSYS_RECALC_RESET) alloc=1; if (alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT))) @@ -2919,7 +2926,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons if (alloc) realloc_particles(sim, sim->psys->totpart); - if (psys_get_tot_child(sim->scene, psys)) { + if (psys_get_tot_child(sim->scene, psys, use_render_params)) { /* don't generate children while computing the hair keys */ if (!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) { distribute_particles(sim, PART_FROM_CHILD); @@ -2936,12 +2943,13 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons skip = 1; /* only hair, keyed and baked stuff can have paths */ else if (part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR))) skip = 1; /* particle visualization must be set as path */ - else if (!psys->renderdata) { + else { if (part->draw_as != PART_DRAW_REND) skip = 1; /* draw visualization */ else if (psys->pointcache->flag & PTCACHE_BAKING) skip = 1; /* no need to cache paths while baking dynamics */ - else if (psys_in_edit_mode(sim->scene, psys)) { + + else if (psys_in_edit_mode(sim->depsgraph, psys)) { if ((pset->flag & PE_DRAW_PART)==0) skip = 1; else if (part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0) @@ -2951,15 +2959,19 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons /* particle instance modifier with "path" option need cached paths even if particle system doesn't */ - for (base = sim->scene->base.first; base; base= base->next) { - ModifierData *md = modifiers_findByType(base->object, eModifierType_ParticleInstance); - if (md) { - ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; - if (pimd->flag & eParticleInstanceFlag_Path && pimd->ob == sim->ob && pimd->psys == (psys - (ParticleSystem*)sim->ob->particlesystem.first)) { - skip = 0; - break; + if (skip) { + FOREACH_SCENE_OBJECT_BEGIN(sim->scene, ob) + { + ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleInstance); + if (md) { + ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; + if (pimd->flag & eParticleInstanceFlag_Path && pimd->ob == sim->ob && pimd->psys == (psys - (ParticleSystem*)sim->ob->particlesystem.first)) { + skip = 0; + break; + } } } + FOREACH_SCENE_OBJECT_END; } if (!skip) { @@ -3019,11 +3031,11 @@ static MDeformVert *hair_set_pinning(MDeformVert *dvert, float weight) return dvert; } -static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int totedge, DerivedMesh **r_dm, ClothHairData **r_hairdata) +static void hair_create_input_mesh(ParticleSimulationData *sim, int totpoint, int totedge, Mesh **r_mesh, ClothHairData **r_hairdata) { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; - DerivedMesh *dm; + Mesh *mesh; ClothHairData *hairdata; MVert *mvert; MEdge *medge; @@ -3035,14 +3047,15 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int float max_length; float hair_radius; - dm = *r_dm; - if (!dm) { - *r_dm = dm = CDDM_new(totpoint, totedge, 0, 0, 0); - DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL); + mesh = *r_mesh; + if (!mesh) { + *r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0); + CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, mesh->totvert); + BKE_mesh_update_customdata_pointers(mesh, false); } - mvert = CDDM_get_verts(dm); - medge = CDDM_get_edges(dm); - dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT); + mvert = mesh->mvert; + medge = mesh->medge; + dvert = mesh->dvert; hairdata = *r_hairdata; if (!hairdata) { @@ -3077,7 +3090,7 @@ static void hair_create_input_dm(ParticleSimulationData *sim, int totpoint, int pa->hair_index = hair_index; use_hair = psys_hair_use_simulation(pa, max_length); - psys_mat_hair_to_object(sim->ob, sim->psmd->dm_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); normalize_m4(root_mat); @@ -3174,26 +3187,26 @@ static void do_hair_dynamics(ParticleSimulationData *sim) } realloc_roots = false; /* whether hair root info array has to be reallocated */ - if (psys->hair_in_dm) { - DerivedMesh *dm = psys->hair_in_dm; - if (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm)) { - dm->release(dm); - psys->hair_in_dm = NULL; + if (psys->hair_in_mesh) { + Mesh *mesh = psys->hair_in_mesh; + if (totpoint != mesh->totvert || totedge != mesh->totedge) { + BKE_id_free(NULL, mesh); + psys->hair_in_mesh = NULL; realloc_roots = true; } } - if (!psys->hair_in_dm || !psys->clmd->hairdata || realloc_roots) { + if (!psys->hair_in_mesh || !psys->clmd->hairdata || realloc_roots) { if (psys->clmd->hairdata) { MEM_freeN(psys->clmd->hairdata); psys->clmd->hairdata = NULL; } } - hair_create_input_dm(sim, totpoint, totedge, &psys->hair_in_dm, &psys->clmd->hairdata); + hair_create_input_mesh(sim, totpoint, totedge, &psys->hair_in_mesh, &psys->clmd->hairdata); - if (psys->hair_out_dm) - psys->hair_out_dm->release(psys->hair_out_dm); + if (psys->hair_out_mesh) + BKE_id_free(NULL, psys->hair_out_mesh); psys->clmd->point_cache = psys->pointcache; /* for hair sim we replace the internal cloth effector weights temporarily @@ -3202,13 +3215,16 @@ static void do_hair_dynamics(ParticleSimulationData *sim) clmd_effweights = psys->clmd->sim_parms->effector_weights; psys->clmd->sim_parms->effector_weights = psys->part->effector_weights; - deformedVerts = MEM_mallocN(sizeof(*deformedVerts) * psys->hair_in_dm->getNumVerts(psys->hair_in_dm), "do_hair_dynamics vertexCos"); - psys->hair_out_dm = CDDM_copy(psys->hair_in_dm); - psys->hair_out_dm->getVertCos(psys->hair_out_dm, deformedVerts); - - clothModifier_do(psys->clmd, sim->scene, sim->ob, psys->hair_in_dm, deformedVerts); - - CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts); + BKE_id_copy_ex( + NULL, &psys->hair_in_mesh->id, (ID **)&psys->hair_out_mesh, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG | + LIB_ID_COPY_NO_PREVIEW, + false); + deformedVerts = BKE_mesh_vertexCos_get(psys->hair_out_mesh, NULL); + clothModifier_do(psys->clmd, sim->depsgraph, sim->scene, sim->ob, psys->hair_in_mesh, deformedVerts); + BKE_mesh_apply_vert_coords(psys->hair_out_mesh, deformedVerts); MEM_freeN(deformedVerts); @@ -3220,7 +3236,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; PARTICLE_P; - float disp = psys_get_current_display_percentage(psys); + float disp = psys_get_current_display_percentage(psys, use_render_params); LOOP_PARTICLES { pa->size = part->size; @@ -3235,7 +3251,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re if (psys->recalc & PSYS_RECALC_RESET) { /* need this for changing subsurf levels */ - psys_calc_dmcache(sim->ob, sim->psmd->dm_final, sim->psmd->dm_deformed, psys); + psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_original, psys); if (psys->clmd) cloth_free_modifier(psys->clmd); @@ -3282,7 +3298,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) if (pa->totkey) { sub_v3_v3(key->co, root->co); - psys_vec_rot_to_face(sim->psmd->dm_final, pa, key->co); + psys_vec_rot_to_face(sim->psmd->mesh_final, pa, key->co); } key->time = pa->state.time; @@ -3492,7 +3508,6 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) { ParticleSystem *psys = sim->psys; ParticleSettings *part=psys->part; - RNG *rng; BoidBrainData bbd; ParticleTexture ptex; PARTICLE_P; @@ -3519,9 +3534,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) return; } - BLI_srandom(31415926 + (int)cfra + psys->seed); /* for now do both, boids us 'rng' */ - rng = BLI_rng_new_srandom(31415926 + (int)cfra + psys->seed); + sim->rng = BLI_rng_new_srandom(31415926 + (int)cfra + psys->seed); psys_update_effectors(sim); @@ -3538,7 +3552,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) bbd.cfra = cfra; bbd.dfra = dfra; bbd.timestep = timestep; - bbd.rng = rng; + bbd.rng = sim->rng; psys_update_particle_tree(psys, cfra); @@ -3734,15 +3748,17 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) } free_collider_cache(&sim->colliders); - BLI_rng_free(rng); + BLI_rng_free(sim->rng); + sim->rng = NULL; } -static void update_children(ParticleSimulationData *sim) + +static void update_children(ParticleSimulationData *sim, const bool use_render_params) { if ((sim->psys->part->type == PART_HAIR) && (sim->psys->flag & PSYS_HAIR_DONE)==0) /* don't generate children while growing hair - waste of time */ psys_free_children(sim->psys); else if (sim->psys->part->childtype) { - if (sim->psys->totchild != psys_get_tot_child(sim->scene, sim->psys)) + if (sim->psys->totchild != psys_get_tot_child(sim->scene, sim->psys, use_render_params)) distribute_particles(sim, PART_FROM_CHILD); else { /* Children are up to date, nothing to do. */ @@ -3752,7 +3768,7 @@ static void update_children(ParticleSimulationData *sim) psys_free_children(sim->psys); } /* updates cached particles' alive & other flags etc..*/ -static void cached_step(ParticleSimulationData *sim, float cfra) +static void cached_step(ParticleSimulationData *sim, float cfra, const bool use_render_params) { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; @@ -3762,7 +3778,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra) psys_update_effectors(sim); - disp= psys_get_current_display_percentage(psys); + disp= psys_get_current_display_percentage(psys, use_render_params); LOOP_PARTICLES { psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra); @@ -3985,8 +4001,8 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ int cache_result = BKE_ptcache_read(pid, cache_cfra, true); if (ELEM(cache_result, PTCACHE_READ_EXACT, PTCACHE_READ_INTERPOLATED)) { - cached_step(sim, cfra); - update_children(sim); + cached_step(sim, cfra, use_render_params); + update_children(sim, use_render_params); psys_update_path_cache(sim, cfra, use_render_params); BKE_ptcache_validate(cache, (int)cache_cfra); @@ -4003,7 +4019,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ } else if (cache_result == PTCACHE_READ_OLD) { psys->cfra = (float)cache->simframe; - cached_step(sim, psys->cfra); + cached_step(sim, psys->cfra, use_render_params); } /* if on second frame, write cache for first frame */ @@ -4015,7 +4031,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ /* 3. do dynamics */ /* set particles to be not calculated TODO: can't work with pointcache */ - disp= psys_get_current_display_percentage(psys); + disp= psys_get_current_display_percentage(psys, use_render_params); LOOP_PARTICLES { if (psys_frand(psys, p) > disp) @@ -4071,7 +4087,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ BKE_ptcache_write(pid, (int)cache_cfra); } - update_children(sim); + update_children(sim, use_render_params); /* cleanup */ if (psys->lattice_deform_data) { @@ -4195,11 +4211,13 @@ static int hair_needs_recalc(ParticleSystem *psys) /* main particle update call, checks that things are ok on the large scale and * then advances in to actual particle calculations depending on particle type */ -void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params) +void particle_system_update(struct Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params) { ParticleSimulationData sim= {0}; ParticleSettings *part = psys->part; + ParticleSystem *psys_orig = psys_orig_get(psys); float cfra; + ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); /* drawdata is outdated after ANY change */ if (psys->pdd) psys->pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED; @@ -4207,12 +4225,13 @@ void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSyste if (!psys_check_enabled(ob, psys, use_render_params)) return; - cfra= BKE_scene_frame_get(scene); + cfra = DEG_get_ctime(depsgraph); - sim.scene= scene; - sim.ob= ob; - sim.psys= psys; - sim.psmd= psys_get_modifier(ob, psys); + sim.depsgraph = depsgraph; + sim.scene = scene; + sim.ob = ob; + sim.psys = psys; + sim.psmd = psmd; /* system was already updated from modifier stack */ if (sim.psmd->flag & eParticleSystemFlag_psys_updated) { @@ -4222,22 +4241,19 @@ void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSyste return; } - if (!sim.psmd->dm_final) + if (!sim.psmd->mesh_final) return; if (part->from != PART_FROM_VERT) { - DM_ensure_tessface(sim.psmd->dm_final); + BKE_mesh_tessface_ensure(sim.psmd->mesh_final); } /* execute drivers only, as animation has already been done */ - BKE_animsys_evaluate_animdata(scene, &part->id, part->adt, cfra, ADT_RECALC_DRIVERS); + BKE_animsys_evaluate_animdata(depsgraph, scene, &part->id, part->adt, cfra, ADT_RECALC_DRIVERS); /* to verify if we need to restore object afterwards */ psys->flag &= ~PSYS_OB_ANIM_RESTORE; - if (psys->recalc & PSYS_RECALC_TYPE) - psys_changed_type(sim.ob, sim.psys); - if (psys->recalc & PSYS_RECALC_RESET) psys->totunexist = 0; @@ -4260,10 +4276,10 @@ void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSyste free_hair(ob, psys, 0); - if (psys->edit && psys->free_edit) { - psys->free_edit(psys->edit); - psys->edit = NULL; - psys->free_edit = NULL; + 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 */ @@ -4272,7 +4288,7 @@ void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSyste 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->id, part->adt, hcfra, ADT_RECALC_ANIM); + BKE_animsys_evaluate_animdata(depsgraph, scene, &part->id, part->adt, hcfra, ADT_RECALC_ANIM); system_step(&sim, hcfra, use_render_params); psys->cfra = hcfra; psys->recalc = 0; @@ -4291,7 +4307,7 @@ void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSyste } case PART_FLUID: { - particles_fluid_step(bmain, &sim, (int)cfra, use_render_params); + particles_fluid_step(G.main /* Yuck :/ */, &sim, (int)cfra, use_render_params); break; } default: @@ -4301,7 +4317,7 @@ void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSyste case PART_PHYS_KEYED: { PARTICLE_P; - float disp = psys_get_current_display_percentage(psys); + 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 */ @@ -4355,16 +4371,33 @@ void particle_system_update(Main *bmain, Scene *scene, Object *ob, ParticleSyste /* make sure emitter is left at correct time (particle emission can change this) */ if (psys->flag & PSYS_OB_ANIM_RESTORE) { - evaluate_emitter_anim(scene, ob, cfra); + evaluate_emitter_anim(depsgraph, scene, ob, cfra); psys->flag &= ~PSYS_OB_ANIM_RESTORE; } + if (psys_orig->edit) { + psys_orig->edit->flags |= PT_CACHE_EDIT_UPDATE_PARTICLE_FROM_EVAL; + } + + if (DEG_is_active(depsgraph)) { + if (psys_orig != psys) { + if (psys_orig->edit != NULL && + psys_orig->edit->psys == psys_orig) + { + psys_orig->edit->psys_eval = psys; + psys_orig->edit->psmd_eval = psmd; + } + psys_orig->flag = psys->flag; + } + } + psys->cfra = cfra; psys->recalc = 0; /* save matrix for duplicators, at rendertime the actual dupliobject's matrix is used so don't update! */ - if (psys->renderdata==0) - invert_m4_m4(psys->imat, ob->obmat); + invert_m4_m4(psys->imat, ob->obmat); + + BKE_particle_batch_cache_dirty(psys, BKE_PARTICLE_BATCH_DIRTY_ALL); } /* ID looper */ @@ -4395,10 +4428,16 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func, /* **** Depsgraph evaluation **** */ -void BKE_particle_system_eval_init(EvaluationContext *UNUSED(eval_ctx), +void BKE_particle_system_eval_init(struct Depsgraph *depsgraph, Scene *scene, Object *ob) { - DEG_debug_print_eval(__func__, ob->id.name, ob); + DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob); + for (ParticleSystem *psys = ob->particlesystem.first; + psys != NULL; + psys = psys->next) + { + psys->recalc |= (psys->part->id.recalc & DEG_TAG_PSYS_ALL); + } BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH); } |