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:
Diffstat (limited to 'source/blender/blenkernel/intern/particle_system.c')
-rw-r--r--source/blender/blenkernel/intern/particle_system.c129
1 files changed, 81 insertions, 48 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 94c1dd0c7c3..ab307ebdbe8 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -77,6 +77,7 @@
#include "BKE_library_query.h"
#include "BKE_particle.h"
+#include "BKE_collection.h"
#include "BKE_DerivedMesh.h"
#include "BKE_object.h"
#include "BKE_material.h"
@@ -87,12 +88,16 @@
#include "BKE_modifier.h"
#include "BKE_scene.h"
#include "BKE_bvhutils.h"
-#include "BKE_depsgraph.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "PIL_time.h"
#include "RE_shader_ext.h"
-#include "DEG_depsgraph.h"
+
+/* FIXME: BAD LEVEL CALL. */
+#include "../../editors/include/ED_particle.h"
/* fluid sim particle import */
#ifdef WITH_MOD_FLUID
@@ -120,11 +125,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 */
{
@@ -284,24 +289,24 @@ 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);
}
/************************************************/
@@ -510,7 +515,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);
@@ -701,9 +705,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);
@@ -987,14 +991,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_object_where_is_calc_time(depsgraph, scene, ob, cfra);
}
/* sets particle to the emitter surface with initial velocity & rotation */
@@ -1008,7 +1012,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;
}
@@ -1142,7 +1146,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,7 +1308,7 @@ 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->effectors = pdInitEffectors(sim->depsgraph, sim->scene, sim->ob, sim->psys,
sim->psys->part->effector_weights, true);
precalc_guides(sim, sim->psys->effectors);
}
@@ -2124,7 +2129,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);
@@ -2905,10 +2910,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)))
@@ -2918,7 +2922,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);
@@ -2935,23 +2939,27 @@ 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;
+#if 0 /* TODO(mai): something is very wrong with these conditionals, they dont make sense and the cache isnt updating */
else if (part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */
+#endif
}
}
/* 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);
+ 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)) {
@@ -2960,6 +2968,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
}
}
}
+ FOREACH_SCENE_OBJECT_END;
if (!skip) {
psys_cache_paths(sim, cfra, use_render_params);
@@ -3205,7 +3214,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
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);
+ clothModifier_do(psys->clmd, sim->depsgraph, sim->scene, sim->ob, psys->hair_in_dm, deformedVerts);
CDDM_apply_vert_coords(psys->hair_out_dm, deformedVerts);
@@ -3219,7 +3228,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;
@@ -3735,13 +3744,13 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
free_collider_cache(&sim->colliders);
BLI_rng_free(rng);
}
-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. */
@@ -3751,7 +3760,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;
@@ -3761,7 +3770,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);
@@ -3983,8 +3992,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);
@@ -4001,7 +4010,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 */
@@ -4013,7 +4022,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)
@@ -4069,7 +4078,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) {
@@ -4205,7 +4214,7 @@ 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(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;
@@ -4219,10 +4228,11 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, cons
cfra= BKE_scene_frame_get(scene);
- 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 = psys_get_modifier(ob, psys);
/* system was already updated from modifier stack */
if (sim.psmd->flag & eParticleSystemFlag_psys_updated) {
@@ -4311,7 +4321,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, cons
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 */
@@ -4365,7 +4375,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, cons
/* 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;
}
@@ -4373,8 +4383,25 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys, cons
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);
+
+ if (ob->mode & OB_MODE_PARTICLE_EDIT && ob == OBACT(DEG_get_evaluated_view_layer(depsgraph))) {
+ PTCacheEdit *edit = PE_create_current(depsgraph, scene, ob);
+
+ if (edit && edit->psys == psys) {
+ if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED) {
+ PE_update_object(depsgraph, scene, ob, 0);
+ }
+
+ /* create path and child path cache if it doesn't exist already */
+ if (edit->pathcache == NULL) {
+ psys_cache_edit_paths(depsgraph, scene, ob, edit, DEG_get_ctime(depsgraph), DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+
+ }
+ }
+ }
+
+ BKE_particle_batch_cache_dirty(psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
}
/* ID looper */
@@ -4405,10 +4432,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);
}