diff options
Diffstat (limited to 'source/blender')
19 files changed, 432 insertions, 228 deletions
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index 379ab3e81b5..a0af34d59e6 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -45,6 +45,7 @@ struct ParticleSimulationData; struct ParticleData; struct ParticleKey; struct Depsgraph; +struct ViewLayer; struct EffectorWeights *BKE_add_effector_weights(struct Collection *collection); struct PartDeflect *object_add_collision_fields(int type); @@ -111,13 +112,36 @@ typedef struct EffectorCache { int flag; } EffectorCache; -void free_partdeflect(struct PartDeflect *pd); -struct ListBase *pdInitEffectors( - struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, - struct EffectorWeights *weights, bool for_simulation); -void pdEndEffectors(struct ListBase **effectors); -void pdPrecalculateEffectors(struct Depsgraph *depsgraph, struct ListBase *effectors); -void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse); +typedef struct EffectorRelation { + struct EffectorRelation *next, *prev; + + struct Object *ob; + struct ParticleSystem *psys; + struct PartDeflect *pd; +} EffectorRelation; + +void free_partdeflect(struct PartDeflect *pd); + +struct ListBase *BKE_effector_relations_create( + struct Depsgraph *depsgraph, + struct ViewLayer *view_layer, + struct Collection *collection); +void BKE_effector_relations_free(struct ListBase *lb); + +struct ListBase *BKE_effectors_create( + struct Depsgraph *depsgraph, + struct Scene *scene, + struct Object *ob_src, + struct ParticleSystem *psys_src, + struct EffectorWeights *weights); +void BKE_effectors_apply( + struct ListBase *effectors, + struct ListBase *colliders, + struct EffectorWeights *weights, + struct EffectedPoint *point, + float *force, + float *impulse); +void BKE_effectors_free(struct ListBase *lb); void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point); void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point); diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 8fdaf183b06..f47d09d7dc2 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -1265,7 +1265,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* account for effectors */ pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint); - pdDoEffectors(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL); + BKE_effectors_apply(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL); if (ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) { float length = normalize_v3(force); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index f8ea7e8b1d1..bfe59e5366d 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -375,7 +375,7 @@ static int do_step_cloth(struct Depsgraph *depsgraph, Scene *scene, Object *ob, mul_m4_v3(ob->obmat, verts->xconst); } - effectors = pdInitEffectors(depsgraph, scene, ob, NULL, clmd->sim_parms->effector_weights, true); + effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, clmd->sim_parms->effector_weights); if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH ) cloth_update_verts ( ob, clmd, result ); @@ -395,7 +395,7 @@ static int do_step_cloth(struct Depsgraph *depsgraph, Scene *scene, Object *ob, // TIMEIT_END(cloth_step) - pdEndEffectors(&effectors); + BKE_effectors_free(effectors); // printf ( "%f\n", ( float ) tval() ); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 2b3ef91678f..173dc8050a1 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -4886,7 +4886,7 @@ static void dynamic_paint_prepare_effect_cb( EffectedPoint epoint; pd_point_from_loc(scene, realCoord[bData->s_pos[index]].v, vel, index, &epoint); epoint.vel_to_sec = 1.0f; - pdDoEffectors(effectors, NULL, surface->effector_weights, &epoint, forc, NULL); + BKE_effectors_apply(effectors, NULL, surface->effector_weights, &epoint, forc, NULL); } /* if global gravity is enabled, add it too */ @@ -4926,7 +4926,7 @@ static int dynamicPaint_prepareEffectStep( /* Init force data if required */ if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) { - ListBase *effectors = pdInitEffectors(depsgraph, scene, ob, NULL, surface->effector_weights, true); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, surface->effector_weights); /* allocate memory for force data (dir vector + strength) */ *force = MEM_mallocN(sData->total_points * 4 * sizeof(float), "PaintEffectForces"); @@ -4950,7 +4950,7 @@ static int dynamicPaint_prepareEffectStep( } average_force /= sData->total_points; } - pdEndEffectors(&effectors); + BKE_effectors_free(effectors); } /* Get number of required steps using average point distance diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index c155fbc1d97..adf5b5da35e 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -74,6 +74,7 @@ #include "BKE_smoke.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_physics.h" #include "DEG_depsgraph_query.h" #include "RE_render_ext.h" @@ -135,9 +136,8 @@ PartDeflect *object_add_collision_fields(int type) return pd; } -/* ***************** PARTICLES ***************** */ +/************************ PARTICLES ***************************/ -/* -------------------------- Effectors ------------------ */ void free_partdeflect(PartDeflect *pd) { if (!pd) @@ -149,114 +149,7 @@ void free_partdeflect(PartDeflect *pd) MEM_freeN(pd); } -static EffectorCache *new_effector_cache(struct Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd) -{ - EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache"); - eff->depsgraph = depsgraph; - eff->scene = scene; - eff->ob = ob; - eff->psys = psys; - eff->pd = pd; - eff->frame = -1; - return eff; -} -static void add_object_to_effectors(ListBase **effectors, struct Depsgraph *depsgraph, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation) -{ - EffectorCache *eff = NULL; - - if ( ob == ob_src ) - return; - - if (for_simulation) { - if (weights->weight[ob->pd->forcefield] == 0.0f ) - return; - - if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal ) - return; - } - - if (*effectors == NULL) - *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); - - eff = new_effector_cache(depsgraph, scene, ob, NULL, ob->pd); - - /* make sure imat is up to date */ - invert_m4_m4(ob->imat, ob->obmat); - - BLI_addtail(*effectors, eff); -} -static void add_particles_to_effectors(ListBase **effectors, struct Depsgraph *depsgraph, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation) -{ - ParticleSettings *part= psys->part; - const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER); - - if ( !psys_check_enabled(ob, psys, for_render) ) - return; - - if ( psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0) - return; - - if ( part->pd && part->pd->forcefield && (!for_simulation || weights->weight[part->pd->forcefield] != 0.0f)) { - if (*effectors == NULL) - *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); - - BLI_addtail(*effectors, new_effector_cache(depsgraph, scene, ob, psys, part->pd)); - } - - if (part->pd2 && part->pd2->forcefield && (!for_simulation || weights->weight[part->pd2->forcefield] != 0.0f)) { - if (*effectors == NULL) - *effectors = MEM_callocN(sizeof(ListBase), "effectors list"); - - BLI_addtail(*effectors, new_effector_cache(depsgraph, scene, ob, psys, part->pd2)); - } -} - -/* returns ListBase handle with objects taking part in the effecting */ -ListBase *pdInitEffectors( - struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, ParticleSystem *psys_src, - EffectorWeights *weights, bool for_simulation) -{ - /* For dependency building, we get objects from the scene. - * For simulation, we get objects from the depsgraph. */ - Base *base = BKE_collection_or_layer_objects((for_simulation) ? depsgraph : NULL, scene, NULL, weights->group); - ListBase *effectors = NULL; - - for (; base; base = base->next) { - if (base->object->pd && base->object->pd->forcefield) { - add_object_to_effectors(&effectors, depsgraph, scene, weights, base->object, ob_src, for_simulation); - } - - if (base->object->particlesystem.first) { - ParticleSystem *psys= base->object->particlesystem.first; - - for (; psys; psys=psys->next) { - add_particles_to_effectors(&effectors, depsgraph, scene, weights, base->object, psys, psys_src, for_simulation); - } - } - } - - if (for_simulation) { - pdPrecalculateEffectors(depsgraph, effectors); - } - - return effectors; -} - -void pdEndEffectors(ListBase **effectors) -{ - if (*effectors) { - EffectorCache *eff = (*effectors)->first; - - for (; eff; eff=eff->next) { - if (eff->guide_data) - MEM_freeN(eff->guide_data); - } - - BLI_freelistN(*effectors); - MEM_freeN(*effectors); - *effectors = NULL; - } -} +/******************** EFFECTOR RELATIONS ***********************/ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *eff) { @@ -299,12 +192,144 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef } } -void pdPrecalculateEffectors(struct Depsgraph *depsgraph, ListBase *effectors) +static void add_effector_relation(ListBase *relations, Object *ob, ParticleSystem *psys, PartDeflect *pd) { - if (effectors) { - EffectorCache *eff = effectors->first; - for (; eff; eff=eff->next) - precalculate_effector(depsgraph, eff); + EffectorRelation *relation = MEM_callocN(sizeof(EffectorRelation), "EffectorRelation"); + relation->ob = ob; + relation->psys = psys; + relation->pd = pd; + + BLI_addtail(relations, relation); +} + +static void add_effector_evaluation(ListBase **effectors, Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd) +{ + if (*effectors == NULL) { + *effectors = MEM_callocN(sizeof(ListBase), "effector effectors"); + } + + EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache"); + eff->depsgraph = depsgraph; + eff->scene = scene; + eff->ob = ob; + eff->psys = psys; + eff->pd = pd; + eff->frame = -1; + BLI_addtail(*effectors, eff); + + precalculate_effector(depsgraph, eff); +} + +/* Create list of effector relations in the collection or entire scene. + * This is used by the depsgraph to build relations, as well as faster + * lookup of effectors during evaluation. */ +ListBase *BKE_effector_relations_create( + Depsgraph *depsgraph, + ViewLayer *view_layer, + Collection *collection) +{ + const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER); + Base *base = BKE_collection_or_layer_objects(NULL, NULL, view_layer, collection); + ListBase *relations = MEM_callocN(sizeof(ListBase), "effector relations"); + + for (; base; base = base->next) { + Object *ob = base->object; + + if (ob->pd && ob->pd->forcefield) { + add_effector_relation(relations, ob, NULL, ob->pd); + } + + for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) { + ParticleSettings *part = psys->part; + + if (psys_check_enabled(ob, psys, for_render)) { + if (part->pd && part->pd->forcefield) { + add_effector_relation(relations, ob, psys, part->pd); + } + if (part->pd2 && part->pd2->forcefield) { + add_effector_relation(relations, ob, psys, part->pd2); + } + } + } + } + + return relations; +} + +void BKE_effector_relations_free(ListBase *lb) +{ + if (lb) { + BLI_freelistN(lb); + MEM_freeN(lb); + } +} + +/* Create effective list of effectors from relations built beforehand. */ +ListBase *BKE_effectors_create( + Depsgraph *depsgraph, + Scene *scene, + Object *ob_src, + ParticleSystem *psys_src, + EffectorWeights *weights) +{ + ListBase *relations = DEG_get_effector_relations(depsgraph, weights->group); + ListBase *effectors = NULL; + + if (!relations) { + return NULL; + } + + for (EffectorRelation *relation = relations->first; relation; relation = relation->next) { + /* Get evaluated object. */ + Object *ob = (Object*)DEG_get_evaluated_id(depsgraph, &relation->ob->id); + + if (relation->psys) { + /* Get evaluated particle system. */ + ParticleSystem *psys = BLI_findstring(&ob->particlesystem, + relation->psys->name, offsetof(ParticleSystem, name)); + ParticleSettings *part = psys->part; + + if (psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0) { + continue; + } + + PartDeflect *pd = (relation->pd == relation->psys->part->pd) ? part->pd : part->pd2; + if (weights->weight[pd->forcefield] == 0.0f) { + continue; + } + + add_effector_evaluation(&effectors, depsgraph, scene, ob, psys, pd); + } + else { + /* Object effector. */ + if (ob == ob_src) { + continue; + } + else if (weights->weight[ob->pd->forcefield] == 0.0f) { + continue; + } + else if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal) { + continue; + } + + add_effector_evaluation(&effectors, depsgraph, scene, ob, NULL, ob->pd); + } + } + + return effectors; +} + +void BKE_effectors_free(ListBase *lb) +{ + if (lb) { + for (EffectorCache *eff = lb->first; eff; eff = eff->next) { + if (eff->guide_data) { + MEM_freeN(eff->guide_data); + } + } + + BLI_freelistN(lb); + MEM_freeN(lb); } } @@ -963,7 +988,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected } } -/* -------- pdDoEffectors() -------- +/* -------- BKE_effectors_apply() -------- * generic force/speed system, now used for particles and softbodies * scene = scene where it runs in, for time and stuff * lb = listbase with objects that take part in effecting @@ -976,7 +1001,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected * flags = only used for softbody wind now * guide = old speed of particle */ -void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse) +void BKE_effectors_apply(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse) { /* * Modifies the force on a particle according to its diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 494878bcc8e..278a8ab9720 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -641,7 +641,7 @@ void psys_free(Object *ob, ParticleSystem *psys) if (psys->fluid_springs) MEM_freeN(psys->fluid_springs); - pdEndEffectors(&psys->effectors); + BKE_effectors_free(psys->effectors); if (psys->pdd) { psys_free_pdd(psys); @@ -1842,7 +1842,7 @@ static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheK copy_qt_qt(eff_key.rot, (ca - 1)->rot); pd_point_from_particle(sim, sim->psys->particles + i, &eff_key, &epoint); - pdDoEffectors(sim->psys->effectors, sim->colliders, sim->psys->part->effector_weights, &epoint, force, NULL); + BKE_effectors_apply(sim->psys->effectors, sim->colliders, sim->psys->part->effector_weights, &epoint, force, NULL); mul_v3_fl(force, effector * powf((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / (float)steps); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 1c50e85668d..d6a29531482 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -93,6 +93,7 @@ #include "BKE_bvhutils.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_physics.h" #include "DEG_depsgraph_query.h" #include "PIL_time.h" @@ -1307,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->depsgraph, 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); } @@ -2066,7 +2068,7 @@ static void basic_force_cb(void *efdata_v, ParticleKey *state, float *force, flo /* 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); @@ -2957,18 +2959,20 @@ 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 */ - 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; + 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; } - FOREACH_SCENE_OBJECT_END; if (!skip) { psys_cache_paths(sim, cfra, use_render_params); diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 2374670b212..ffabdb2e77d 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1278,7 +1278,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod ListBase *effectors; /* get effectors present in the group specified by effector_weights */ - effectors = pdInitEffectors(depsgraph, scene, ob, NULL, effector_weights, true); + effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, effector_weights); if (effectors) { float eff_force[3] = {0.0f, 0.0f, 0.0f}; float eff_loc[3], eff_vel[3]; @@ -1293,7 +1293,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod /* calculate net force of effectors, and apply to sim object * - we use 'central force' since apply force requires a "relative position" which we don't have... */ - pdDoEffectors(effectors, NULL, effector_weights, &epoint, eff_force, NULL); + BKE_effectors_apply(effectors, NULL, effector_weights, &epoint, eff_force, NULL); if (G.f & G_DEBUG) printf("\tapplying force (%f,%f,%f) to '%s'\n", eff_force[0], eff_force[1], eff_force[2], ob->id.name + 2); /* activate object in case it is deactivated */ @@ -1305,7 +1305,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBod printf("\tno forces to apply to '%s'\n", ob->id.name + 2); /* cleanup */ - pdEndEffectors(&effectors); + BKE_effectors_free(effectors); } /* NOTE: passive objects don't need to be updated since they don't move */ diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 6bdce647bd9..5ba9b7ce4dc 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -2512,7 +2512,7 @@ static void update_effectors_task_cb( mul_m4_v3(sds->obmat, voxelCenter); pd_point_from_loc(data->scene, voxelCenter, vel, index, &epoint); - pdDoEffectors(data->effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + BKE_effectors_apply(data->effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); /* convert retvel to local space */ mag = len_v3(retvel); @@ -2533,7 +2533,7 @@ static void update_effectors(struct Depsgraph *depsgraph, Scene *scene, Object * ListBase *effectors; /* make sure smoke flow influence is 0.0f */ sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; - effectors = pdInitEffectors(depsgraph, scene, ob, NULL, sds->effector_weights, true); + effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, sds->effector_weights); if (effectors) { // precalculate wind forces @@ -2560,7 +2560,7 @@ static void update_effectors(struct Depsgraph *depsgraph, Scene *scene, Object * &settings); } - pdEndEffectors(&effectors); + BKE_effectors_free(effectors); } static void step( diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 31644cc2392..c552bfeb0dc 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -139,7 +139,7 @@ typedef struct SB_thread_context { float timenow; int ifirst; int ilast; - ListBase *do_effector; + ListBase *effectors; int do_deflector; float fieldfactor; float windfactor; @@ -1444,7 +1444,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl return deflected; } -static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, int ifirst, int ilast, struct ListBase *do_effector) +static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, int ifirst, int ilast, struct ListBase *effectors) { SoftBody *sb = ob->soft; int a; @@ -1478,14 +1478,14 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, float vel[3], sp[3], pr[3], force[3]; float f, windfactor = 0.25f; /*see if we have wind*/ - if (do_effector) { + if (effectors) { EffectedPoint epoint; float speed[3] = {0.0f, 0.0f, 0.0f}; float pos[3]; mid_v3_v3v3(pos, sb->bpoint[bs->v1].pos, sb->bpoint[bs->v2].pos); mid_v3_v3v3(vel, sb->bpoint[bs->v1].vec, sb->bpoint[bs->v2].vec); pd_point_from_soft(scene, pos, vel, -1, &epoint); - pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); + BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, speed); mul_v3_fl(speed, windfactor); add_v3_v3(vel, speed); @@ -1521,29 +1521,27 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, static void scan_for_ext_spring_forces(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float timenow) { SoftBody *sb = ob->soft; - ListBase *do_effector = NULL; - do_effector = pdInitEffectors(depsgraph, scene, ob, NULL, sb->effector_weights, true); - _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector); - pdEndEffectors(&do_effector); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, sb->effector_weights); + _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, effectors); + BKE_effectors_free(effectors); } static void *exec_scan_for_ext_spring_forces(void *data) { SB_thread_context *pctx = (SB_thread_context*)data; - _scan_for_ext_spring_forces(pctx->scene, pctx->ob, pctx->timenow, pctx->ifirst, pctx->ilast, pctx->do_effector); + _scan_for_ext_spring_forces(pctx->scene, pctx->ob, pctx->timenow, pctx->ifirst, pctx->ilast, pctx->effectors); return NULL; } static void sb_sfesf_threads_run(struct Depsgraph *depsgraph, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void))) { - ListBase *do_effector = NULL; ListBase threads; SB_thread_context *sb_threads; int i, totthread, left, dec; int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */ - do_effector= pdInitEffectors(depsgraph, scene, ob, NULL, ob->soft->effector_weights, true); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, ob->soft->effector_weights); /* figure the number of threads while preventing pretty pointless threading overhead */ totthread= BKE_scene_num_threads(scene); @@ -1568,7 +1566,7 @@ static void sb_sfesf_threads_run(struct Depsgraph *depsgraph, Scene *scene, stru } else sb_threads[i].ifirst = 0; - sb_threads[i].do_effector = do_effector; + sb_threads[i].effectors = effectors; sb_threads[i].do_deflector = false;// not used here sb_threads[i].fieldfactor = 0.0f;// not used here sb_threads[i].windfactor = 0.0f;// not used here @@ -1588,7 +1586,7 @@ static void sb_sfesf_threads_run(struct Depsgraph *depsgraph, Scene *scene, stru /* clean up */ MEM_freeN(sb_threads); - pdEndEffectors(&do_effector); + BKE_effectors_free(effectors); } @@ -1941,7 +1939,7 @@ static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, floa /* since this is definitely the most CPU consuming task here .. try to spread it */ /* core function _softbody_calc_forces_slice_in_a_thread */ /* result is int to be able to flag user break */ -static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *UNUSED(ptr_to_break_func(void)), ListBase *do_effector, int do_deflector, float fieldfactor, float windfactor) +static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, float forcetime, float timenow, int ifirst, int ilast, int *UNUSED(ptr_to_break_func(void)), ListBase *effectors, int do_deflector, float fieldfactor, float windfactor) { float iks; int bb, do_selfcollision, do_springcollision, do_aero; @@ -2060,14 +2058,14 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo } /* particle field & vortex */ - if (do_effector) { + if (effectors) { EffectedPoint epoint; float kd; float force[3] = {0.0f, 0.0f, 0.0f}; float speed[3] = {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); - pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); + BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, speed); /* apply forcefield*/ mul_v3_fl(force, fieldfactor* eval_sb_fric_force_scale); @@ -2142,11 +2140,11 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo static void *exec_softbody_calc_forces(void *data) { SB_thread_context *pctx = (SB_thread_context*)data; - _softbody_calc_forces_slice_in_a_thread(pctx->scene, pctx->ob, pctx->forcetime, pctx->timenow, pctx->ifirst, pctx->ilast, NULL, pctx->do_effector, pctx->do_deflector, pctx->fieldfactor, pctx->windfactor); + _softbody_calc_forces_slice_in_a_thread(pctx->scene, pctx->ob, pctx->forcetime, pctx->timenow, pctx->ifirst, pctx->ilast, NULL, pctx->effectors, pctx->do_deflector, pctx->fieldfactor, pctx->windfactor); return NULL; } -static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float timenow, int totpoint, int *UNUSED(ptr_to_break_func(void)), struct ListBase *do_effector, int do_deflector, float fieldfactor, float windfactor) +static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float timenow, int totpoint, int *UNUSED(ptr_to_break_func(void)), struct ListBase *effectors, int do_deflector, float fieldfactor, float windfactor) { ListBase threads; SB_thread_context *sb_threads; @@ -2178,7 +2176,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t } else sb_threads[i].ifirst = 0; - sb_threads[i].do_effector = do_effector; + sb_threads[i].effectors = effectors; sb_threads[i].do_deflector = do_deflector; sb_threads[i].fieldfactor = fieldfactor; sb_threads[i].windfactor = windfactor; @@ -2208,7 +2206,6 @@ static void softbody_calc_forcesEx(struct Depsgraph *depsgraph, Scene *scene, Ob */ SoftBody *sb= ob->soft; /* is supposed to be there */ /*BodyPoint *bproot;*/ /* UNUSED */ - ListBase *do_effector = NULL; /* float gravity; */ /* UNUSED */ /* float iks; */ float fieldfactor = -1.0f, windfactor = 0.25; @@ -2229,20 +2226,20 @@ static void softbody_calc_forcesEx(struct Depsgraph *depsgraph, Scene *scene, Ob sb_sfesf_threads_run(depsgraph, scene, ob, timenow, sb->totspring, NULL); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(depsgraph, scene, ob, NULL, sb->effector_weights, true); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, sb->effector_weights); if (do_deflector) { float defforce[3]; do_deflector = sb_detect_aabb_collisionCached(defforce, ob->lay, ob, timenow); } - sb_cf_threads_run(scene, ob, forcetime, timenow, sb->totpoint, NULL, do_effector, do_deflector, fieldfactor, windfactor); + sb_cf_threads_run(scene, ob, forcetime, timenow, sb->totpoint, NULL, effectors, do_deflector, fieldfactor, windfactor); /* finally add forces caused by face collision */ if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob, timenow); /* finish matrix and solve */ - pdEndEffectors(&do_effector); + BKE_effectors_free(effectors); } @@ -2269,7 +2266,6 @@ static void softbody_calc_forces(struct Depsgraph *depsgraph, Scene *scene, Obje BodyPoint *bp; /* BodyPoint *bproot; */ /* UNUSED */ BodySpring *bs; - ListBase *do_effector = NULL; float iks, ks, kd, gravity[3] = {0.0f, 0.0f, 0.0f}; float fieldfactor = -1.0f, windfactor = 0.25f; float tune = sb->ballstiff; @@ -2291,7 +2287,7 @@ static void softbody_calc_forces(struct Depsgraph *depsgraph, Scene *scene, Obje if (do_springcollision || do_aero) scan_for_ext_spring_forces(depsgraph, scene, ob, timenow); /* after spring scan because it uses Effoctors too */ - do_effector= pdInitEffectors(depsgraph, scene, ob, NULL, ob->soft->effector_weights, true); + ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, ob->soft->effector_weights); if (do_deflector) { float defforce[3]; @@ -2394,13 +2390,13 @@ static void softbody_calc_forces(struct Depsgraph *depsgraph, Scene *scene, Obje /* particle field & vortex */ - if (do_effector) { + if (effectors) { EffectedPoint epoint; float force[3] = {0.0f, 0.0f, 0.0f}; float speed[3] = {0.0f, 0.0f, 0.0f}; float eval_sb_fric_force_scale = sb_fric_force_scale(ob); /* just for calling function once */ pd_point_from_soft(scene, bp->pos, bp->vec, sb->bpoint-bp, &epoint); - pdDoEffectors(do_effector, NULL, sb->effector_weights, &epoint, force, speed); + BKE_effectors_apply(effectors, NULL, sb->effector_weights, &epoint, force, speed); /* apply forcefield*/ mul_v3_fl(force, fieldfactor* eval_sb_fric_force_scale); @@ -2492,7 +2488,7 @@ static void softbody_calc_forces(struct Depsgraph *depsgraph, Scene *scene, Obje /* finally add forces caused by face collision */ if (ob->softflag & OB_SB_FACECOLL) scan_for_ext_face_forces(ob, timenow); - pdEndEffectors(&do_effector); + BKE_effectors_free(effectors); } } diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 8f6eee244f7..0673a3177b7 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -67,6 +67,7 @@ set(SRC intern/depsgraph_build.cc intern/depsgraph_debug.cc intern/depsgraph_eval.cc + intern/depsgraph_physics.cc intern/depsgraph_query.cc intern/depsgraph_query_foreach.cc intern/depsgraph_query_iter.cc @@ -76,6 +77,7 @@ set(SRC DEG_depsgraph.h DEG_depsgraph_build.h DEG_depsgraph_debug.h + DEG_depsgraph_physics.h DEG_depsgraph_query.h intern/builder/deg_builder.h diff --git a/source/blender/depsgraph/DEG_depsgraph_physics.h b/source/blender/depsgraph/DEG_depsgraph_physics.h new file mode 100644 index 00000000000..6bffe0c2358 --- /dev/null +++ b/source/blender/depsgraph/DEG_depsgraph_physics.h @@ -0,0 +1,51 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/DEG_depsgraph_physics.h + * \ingroup depsgraph + * + * Physics utilities for effectors and collision. + */ + +#ifndef __DEG_DEPSGRAPH_PHYSICS_H__ +#define __DEG_DEPSGRAPH_PHYSICS_H__ + +#include "DEG_depsgraph.h" + +struct Colllection; +struct Depsgraph; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Get effector relations from collection or entire scene during evaluation, + * these are created during depsgraph relations building. */ +struct ListBase *DEG_get_effector_relations(const struct Depsgraph *depsgraph, + struct Collection *collection); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __DEG_DEPSGRAPH_PHYSICS_H__ */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index d36e7eceb88..c9b9cf38cc5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -333,52 +333,49 @@ void DepsgraphRelationBuilder::add_forcefield_relations( bool add_absorption, const char *name) { - ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph_); - ListBase *effectors = pdInitEffectors(depsgraph, scene, object, psys, eff, false); - if (effectors == NULL) { - return; - } - LISTBASE_FOREACH (EffectorCache *, eff, effectors) { - if (eff->ob != object) { - ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM); + ListBase *relations = deg_build_effector_relations(graph_, eff->group); + + LISTBASE_FOREACH (EffectorRelation *, relation, relations) { + if (relation->ob != object) { + ComponentKey eff_key(&relation->ob->id, DEG_NODE_TYPE_TRANSFORM); add_relation(eff_key, key, name); + + if (relation->pd->forcefield == PFIELD_SMOKEFLOW && relation->pd->f_source) { + ComponentKey trf_key(&relation->pd->f_source->id, + DEG_NODE_TYPE_TRANSFORM); + add_relation(trf_key, key, "Smoke Force Domain"); + ComponentKey eff_key(&relation->pd->f_source->id, + DEG_NODE_TYPE_GEOMETRY); + add_relation(eff_key, key, "Smoke Force Domain"); + } + if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) { + add_collision_relations(key, + scene, + object, + NULL, + true, + "Force Absorption"); + } } - if (eff->psys != NULL) { - if (eff->ob != object) { - ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES); + if (relation->psys) { + if (relation->ob != object) { + ComponentKey eff_key(&relation->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES); add_relation(eff_key, key, name); /* TODO: remove this when/if EVAL_PARTICLES is sufficient * for up to date particles. */ - ComponentKey mod_key(&eff->ob->id, DEG_NODE_TYPE_GEOMETRY); + ComponentKey mod_key(&relation->ob->id, DEG_NODE_TYPE_GEOMETRY); add_relation(mod_key, key, name); } - else if (eff->psys != psys) { - OperationKey eff_key(&eff->ob->id, + else if (relation->psys != psys) { + OperationKey eff_key(&relation->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, - eff->psys->name); + relation->psys->name); add_relation(eff_key, key, name); } } - if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) { - ComponentKey trf_key(&eff->pd->f_source->id, - DEG_NODE_TYPE_TRANSFORM); - add_relation(trf_key, key, "Smoke Force Domain"); - ComponentKey eff_key(&eff->pd->f_source->id, - DEG_NODE_TYPE_GEOMETRY); - add_relation(eff_key, key, "Smoke Force Domain"); - } - if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) { - add_collision_relations(key, - scene, - object, - NULL, - true, - "Force Absorption"); - } } - pdEndEffectors(&effectors); } Depsgraph *DepsgraphRelationBuilder::getGraph() diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 16427d3eb59..5b7cf3d5a16 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -93,7 +93,8 @@ Depsgraph::Depsgraph(Scene *scene, mode(mode), ctime(BKE_scene_frame_get(scene)), scene_cow(NULL), - is_active(false) + is_active(false), + effector_relations(NULL) { BLI_spin_init(&lock); id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); @@ -360,6 +361,8 @@ void Depsgraph::clear_id_nodes() /* Clear containers. */ BLI_ghash_clear(id_hash, NULL, NULL); id_nodes.clear(); + /* Clear physics relation caches. */ + deg_clear_physics_relations(this); } /* Add new relationship between two nodes. */ diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index a69be39c50b..a27af42e7b9 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -226,6 +226,10 @@ struct Depsgraph { /* NITE: Corresponds to G_DEBUG_DEPSGRAPH_* flags. */ int debug_flags; string debug_name; + + /* Cached list of effectors for collections and the scene created + * along with relations, for fast lookup during evaluation. */ + GHash *effector_relations; }; } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 9c03e8c4ca3..da64478404b 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -357,31 +357,30 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, const char *name) { Depsgraph *depsgraph = DEG_get_graph_from_handle(handle); - ListBase *effectors = pdInitEffectors(depsgraph, scene, object, NULL, effector_weights, false); - if (effectors == NULL) { - return; - } - for (EffectorCache *eff = (EffectorCache*)effectors->first; eff; eff = eff->next) { - if (eff->ob != object && eff->pd->forcefield != skip_forcefield) { - DEG_add_object_relation(handle, eff->ob, DEG_OB_COMP_TRANSFORM, name); - if (eff->psys) { - DEG_add_object_relation(handle, eff->ob, DEG_OB_COMP_EVAL_PARTICLES, name); + DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph; + ListBase *relations = deg_build_effector_relations(deg_graph, effector_weights->group); + + LISTBASE_FOREACH (EffectorRelation *, relation, relations) { + if (relation->ob != object && relation->pd->forcefield != skip_forcefield) { + DEG_add_object_relation(handle, relation->ob, DEG_OB_COMP_TRANSFORM, name); + if (relation->psys) { + DEG_add_object_relation(handle, relation->ob, DEG_OB_COMP_EVAL_PARTICLES, name); /* TODO: remove this when/if EVAL_PARTICLES is sufficient * for up to date particles. */ - DEG_add_object_relation(handle, eff->ob, DEG_OB_COMP_GEOMETRY, name); + DEG_add_object_relation(handle, relation->ob, DEG_OB_COMP_GEOMETRY, name); } - if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) { + if (relation->pd->forcefield == PFIELD_SMOKEFLOW && relation->pd->f_source) { DEG_add_object_relation(handle, - eff->pd->f_source, + relation->pd->f_source, DEG_OB_COMP_TRANSFORM, "Smoke Force Domain"); DEG_add_object_relation(handle, - eff->pd->f_source, + relation->pd->f_source, DEG_OB_COMP_GEOMETRY, "Smoke Force Domain"); } - if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) { + if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) { DEG_add_collision_relations(handle, scene, object, @@ -393,5 +392,4 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, } } } - pdEndEffectors(&effectors); } diff --git a/source/blender/depsgraph/intern/depsgraph_intern.h b/source/blender/depsgraph/intern/depsgraph_intern.h index 526cecde457..cd5508a4088 100644 --- a/source/blender/depsgraph/intern/depsgraph_intern.h +++ b/source/blender/depsgraph/intern/depsgraph_intern.h @@ -50,6 +50,7 @@ extern "C" { struct DEGEditorUpdateContext; struct Collection; +struct ListBase; struct Main; struct Scene; @@ -139,4 +140,9 @@ bool deg_terminal_do_color(void); string deg_color_for_pointer(const void *pointer); string deg_color_end(void); +/* Physics Utilities -------------------------------------------------- */ + +struct ListBase *deg_build_effector_relations(Depsgraph *graph, struct Collection *collection); +void deg_clear_physics_relations(Depsgraph *graph); + } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_physics.cc b/source/blender/depsgraph/intern/depsgraph_physics.cc new file mode 100644 index 00000000000..d26ba845dd5 --- /dev/null +++ b/source/blender/depsgraph/intern/depsgraph_physics.cc @@ -0,0 +1,94 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018 Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/depsgraph_physics.cc + * \ingroup depsgraph + * + * Physics utilities for effectors and collision. + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_compiler_compat.h" +#include "BLI_ghash.h" + +extern "C" { +#include "BKE_effect.h" +} /* extern "C" */ + +#include "DNA_group_types.h" + +#include "DEG_depsgraph_physics.h" + +#include "depsgraph.h" +#include "depsgraph_intern.h" + +/************************ Public API *************************/ + +ListBase *DEG_get_effector_relations(const Depsgraph *graph, + Collection *collection) +{ + const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); + if (deg_graph->effector_relations == NULL) { + return NULL; + } + + return (ListBase*)BLI_ghash_lookup(deg_graph->effector_relations, collection); +} + +/*********************** Internal API ************************/ + +namespace DEG +{ + +ListBase *deg_build_effector_relations(Depsgraph *graph, + Collection *collection) +{ + if (graph->effector_relations == NULL) { + graph->effector_relations = BLI_ghash_ptr_new("Depsgraph effector relations hash"); + } + + ListBase *relations = reinterpret_cast<ListBase*>(BLI_ghash_lookup(graph->effector_relations, collection)); + if (relations == NULL) { + ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph); + relations = BKE_effector_relations_create(depsgraph, graph->view_layer, collection); + BLI_ghash_insert(graph->effector_relations, collection, relations); + } + + return relations; +} + +static void free_effector_relations(void *value) +{ + BKE_effector_relations_free(reinterpret_cast<ListBase*>(value)); +} + +void deg_clear_physics_relations(Depsgraph *graph) +{ + if (graph->effector_relations) { + BLI_ghash_free(graph->effector_relations, NULL, free_effector_relations); + graph->effector_relations = NULL; + } +} + +} diff --git a/source/blender/physics/intern/BPH_mass_spring.cpp b/source/blender/physics/intern/BPH_mass_spring.cpp index 738673b0b37..1ce6407161e 100644 --- a/source/blender/physics/intern/BPH_mass_spring.cpp +++ b/source/blender/physics/intern/BPH_mass_spring.cpp @@ -488,7 +488,7 @@ static void cloth_calc_force(Scene *scene, ClothModifierData *clmd, float UNUSED BPH_mass_spring_get_motion_state(data, i, x, v); pd_point_from_loc(scene, x, v, i, &epoint); - pdDoEffectors(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL); + BKE_effectors_apply(effectors, NULL, clmd->sim_parms->effector_weights, &epoint, winvec[i], NULL); } for (i = 0; i < cloth->tri_num; i++) { |