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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-06-21 20:45:39 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-06-22 18:57:22 +0300
commitcc4dc2dce26c724e27598e4a1878e00fdf30dcf2 (patch)
tree0ccf3d58e17666a24f9b0b6325666d0453b55645 /source/blender
parent79615c5adb46ffaa84d17b548074cec83d1071bb (diff)
Depsgraph: cache effector relations, for performance and stability.
To find all effectors in the scene, we need to loop over all objects. Doing this during depsgraph evaluation caused crashes because not all objects are guaranteed to be evaluated yet. To fix this, we now cache the relations as part of the dependency graph build. As a bonus this also makes evaluation faster for big scenes, since looping over all objects for each particle system is slow. Fixes T55156.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_effect.h38
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/cloth.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c6
-rw-r--r--source/blender/blenkernel/intern/effect.c259
-rw-r--r--source/blender/blenkernel/intern/particle.c4
-rw-r--r--source/blender/blenkernel/intern/particle_system.c30
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c6
-rw-r--r--source/blender/blenkernel/intern/smoke.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c52
-rw-r--r--source/blender/depsgraph/CMakeLists.txt2
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_physics.h51
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc61
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc5
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h4
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc28
-rw-r--r--source/blender/depsgraph/intern/depsgraph_intern.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_physics.cc94
-rw-r--r--source/blender/physics/intern/BPH_mass_spring.cpp2
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++) {