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:
-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++) {