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_collision.h4
-rw-r--r--source/blender/blenkernel/BKE_effect.h2
-rw-r--r--source/blender/blenkernel/depsgraph_private.h10
-rw-r--r--source/blender/blenkernel/intern/collision.c18
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c101
-rw-r--r--source/blender/blenkernel/intern/effect.c31
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc82
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h5
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc53
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c8
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c9
-rw-r--r--source/blender/makesrna/intern/rna_particle.c8
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c30
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c32
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c207
-rw-r--r--source/blender/modifiers/intern/MOD_softbody.c33
17 files changed, 320 insertions, 321 deletions
diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h
index d5b4a584ec6..8fedcd4ab06 100644
--- a/source/blender/blenkernel/BKE_collision.h
+++ b/source/blender/blenkernel/BKE_collision.h
@@ -146,6 +146,10 @@ void collision_get_collider_velocity(float vel_old[3], float vel_new[3], struct
/////////////////////////////////////////////////
// used in effect.c
/////////////////////////////////////////////////
+
+/* explicit control over layer mask and dupli recursion */
+struct Object **get_collisionobjects_ext(struct Scene *scene, struct Object *self, struct Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli);
+
struct Object **get_collisionobjects(struct Scene *scene, struct Object *self, struct Group *group, unsigned int *numcollobj, unsigned int modifier_type);
typedef struct ColliderCache {
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index f8fee444d91..b934ec7166d 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -110,7 +110,7 @@ typedef struct EffectorCache {
} EffectorCache;
void free_partdeflect(struct PartDeflect *pd);
-struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool precalc);
+struct ListBase *pdInitEffectors(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 ListBase *effectors);
void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
index 7b3199efb41..69ca75836d9 100644
--- a/source/blender/blenkernel/depsgraph_private.h
+++ b/source/blender/blenkernel/depsgraph_private.h
@@ -34,6 +34,11 @@
#include "DNA_constraint_types.h"
#include "BKE_constraint.h"
+struct Scene;
+struct Group;
+struct EffectorWeights;
+struct ModifierData;
+
/* **** DAG relation types *** */
/* scene link to object */
@@ -152,6 +157,11 @@ DagNode *dag_get_node(DagForest *forest, void *fob);
DagNode *dag_get_sub_node(DagForest *forest, void *fob);
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name);
+typedef bool (*DagCollobjFilterFunction)(struct Object *obj, struct ModifierData *md);
+
+void dag_add_collision_relations(DagForest *dag, struct Scene *scene, Object *ob, DagNode *node, struct Group *group, int layer, unsigned int modifier_type, DagCollobjFilterFunction fn, bool dupli, const char *name);
+void dag_add_forcefield_relations(DagForest *dag, struct Scene *scene, Object *ob, DagNode *node, struct EffectorWeights *eff, bool add_absorption, int skip_forcefield, const char *name);
+
void graph_print_queue(DagNodeQueue *nqueue);
void graph_print_queue_dist(DagNodeQueue *nqueue);
void graph_print_adj_list(DagForest *dag);
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 8cac856b560..35a7aafdbde 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -503,12 +503,13 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
// return all collision objects in scene
// collision object will exclude self
-Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned int *numcollobj, unsigned int modifier_type)
+Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
{
Base *base;
Object **objs;
GroupObject *go;
unsigned int numobj= 0, maxobj= 100;
+ int level = dupli ? 0 : 1;
objs= MEM_callocN(sizeof(Object *)*maxobj, "CollisionObjectsArray");
@@ -516,16 +517,14 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned
if (group) {
/* use specified group */
for (go= group->gobject.first; go; go= go->next)
- add_collision_object(&objs, &numobj, &maxobj, go->ob, self, 0, modifier_type);
+ add_collision_object(&objs, &numobj, &maxobj, go->ob, self, level, modifier_type);
}
else {
Scene *sce_iter;
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {
- /* Need to check for active layers, too.
- Otherwise this check fails if the objects are not on the same layer - DG */
- if ((base->lay & self->lay) || (base->lay & scene->lay))
- add_collision_object(&objs, &numobj, &maxobj, base->object, self, 0, modifier_type);
+ if ( base->lay & layer )
+ add_collision_object(&objs, &numobj, &maxobj, base->object, self, level, modifier_type);
}
}
@@ -535,6 +534,13 @@ Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned
return objs;
}
+Object **get_collisionobjects(Scene *scene, Object *self, Group *group, unsigned int *numcollobj, unsigned int modifier_type)
+{
+ /* Need to check for active layers, too.
+ Otherwise this check fails if the objects are not on the same layer - DG */
+ return get_collisionobjects_ext(scene, self, group, self->lay | scene->lay, numcollobj, modifier_type, true);
+}
+
static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self, int level)
{
CollisionModifierData *cmd= NULL;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 45a23c39910..5f8332dcf0c 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -59,11 +59,14 @@
#include "DNA_windowmanager_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_mask_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_rigidbody_types.h"
#include "BKE_anim.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_collision.h"
#include "BKE_effect.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
@@ -450,49 +453,51 @@ static void dag_add_lamp_driver_relations(DagForest *dag, DagNode *node, Lamp *l
la->id.tag &= ~LIB_TAG_DOIT;
}
-static void check_and_create_collision_relation(DagForest *dag, Object *ob, DagNode *node, Object *ob1, int skip_forcefield, bool no_collision)
+static void create_collision_relation(DagForest *dag, DagNode *node, Object *ob1, const char *name)
{
- DagNode *node2;
- if (ob1->pd && (ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) {
- if ((skip_forcefield && ob1->pd->forcefield == skip_forcefield) || (no_collision && ob1->pd->forcefield == 0))
- return;
- node2 = dag_get_node(dag, ob1);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision");
+ DagNode *node2 = dag_get_node(dag, ob1);
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, name);
+}
+
+void dag_add_collision_relations(DagForest *dag, Scene *scene, Object *ob, DagNode *node, Group *group, int layer, unsigned int modifier_type, DagCollobjFilterFunction fn, bool dupli, const char *name)
+{
+ unsigned int numcollobj;
+ Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, modifier_type, dupli);
+
+ for (unsigned int i = 0; i < numcollobj; i++) {
+ Object *ob1 = collobjs[i];
+
+ if (!fn || fn(ob1, modifiers_findByType(ob1, modifier_type))) {
+ create_collision_relation(dag, node, ob1, name);
+ }
}
+
+ if (collobjs)
+ MEM_freeN(collobjs);
}
-static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield, bool no_collision)
+void dag_add_forcefield_relations(DagForest *dag, Scene *scene, Object *ob, DagNode *node, EffectorWeights *effector_weights, bool add_absorption, int skip_forcefield, const char *name)
{
- Base *base;
- ParticleSystem *particle_system;
+ ListBase *effectors = pdInitEffectors(scene, ob, NULL, effector_weights, false);
- for (particle_system = ob->particlesystem.first;
- particle_system;
- particle_system = particle_system->next)
- {
- EffectorWeights *effector_weights = particle_system->part->effector_weights;
- if (effector_weights->group) {
- GroupObject *group_object;
+ if (effectors) {
+ for (EffectorCache *eff = effectors->first; eff; eff = eff->next) {
+ if (eff->ob != ob && eff->pd->forcefield != skip_forcefield) {
+ create_collision_relation(dag, node, eff->ob, name);
- for (group_object = effector_weights->group->gobject.first;
- group_object;
- group_object = group_object->next)
- {
- if ((group_object->ob->lay & ob->lay)) {
- check_and_create_collision_relation(dag, ob, node, group_object->ob, skip_forcefield, no_collision);
+ if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
+ create_collision_relation(dag, node, eff->pd->f_source, "Smoke Force Domain");
+ }
+
+ if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
+ /* Actual code uses get_collider_cache */
+ dag_add_collision_relations(dag, scene, ob, node, NULL, eff->ob->lay, eModifierType_Collision, NULL, true, "Force Absorption");
}
}
}
}
- /* would be nice to have a list of colliders here
- * so for now walk all objects in scene check 'same layer rule' */
- for (base = scene->base.first; base; base = base->next) {
- if ((base->lay & ob->lay)) {
- Object *ob1 = base->object;
- check_and_create_collision_relation(dag, ob, node, ob1, skip_forcefield, no_collision);
- }
- }
+ pdEndEffectors(&effectors);
}
static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Scene *scene, Object *ob, int mask)
@@ -643,23 +648,13 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc
}
}
- /* softbody collision */
+ /* rigidbody force fields */
if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) {
- if (ob->particlesystem.first ||
- modifiers_isModifierEnabled(ob, eModifierType_Softbody) ||
- modifiers_isModifierEnabled(ob, eModifierType_Cloth) ||
- modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint))
- {
- dag_add_collision_field_relation(dag, scene, ob, node, 0, false); /* TODO: use effectorweight->group */
- }
- else if (modifiers_isModifierEnabled(ob, eModifierType_Smoke)) {
- dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW, false);
- }
- else if (ob->rigidbody_object) {
- dag_add_collision_field_relation(dag, scene, ob, node, 0, true);
+ if (ob->rigidbody_object && scene->rigidbody_world) {
+ dag_add_forcefield_relations(dag, scene, ob, node, scene->rigidbody_world->effector_weights, true, 0, "Force Field");
}
}
-
+
/* object data drivers */
if (ob->data) {
AnimData *adt = BKE_animdata_from_id((ID *)ob->data);
@@ -763,8 +758,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc
BoidRule *rule = NULL;
BoidState *state = NULL;
ParticleSettings *part = psys->part;
- ListBase *effectors = NULL;
- EffectorCache *eff;
if (part->adt) {
dag_add_driver_relation(part->adt, dag, node, 1);
@@ -803,18 +796,12 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Main *bmain, Sc
}
}
- effectors = pdInitEffectors(scene, ob, psys, part->effector_weights, false);
-
- if (effectors) {
- for (eff = effectors->first; eff; eff = eff->next) {
- if (eff->psys) {
- node2 = dag_get_node(dag, eff->ob);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Field");
- }
- }
+ if (part->type != PART_HAIR) {
+ /* Actual code uses get_collider_cache */
+ dag_add_collision_relations(dag, scene, ob, node, part->collision_group, ob->lay, eModifierType_Collision, NULL, true, "Particle Collision");
}
- pdEndEffectors(&effectors);
+ dag_add_forcefield_relations(dag, scene, ob, node, part->effector_weights, part->type == PART_HAIR, 0, "Particle Force Field");
if (part->boids) {
for (state = part->boids->states.first; state; state = state->next) {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 5090e46f1fc..7e6897a2858 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -155,15 +155,20 @@ static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSyste
eff->frame = -1;
return eff;
}
-static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src)
+static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
{
EffectorCache *eff = NULL;
- if ( ob == ob_src || weights->weight[ob->pd->forcefield] == 0.0f )
+ if ( ob == ob_src )
return;
- if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal )
- 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");
@@ -175,7 +180,7 @@ static void add_object_to_effectors(ListBase **effectors, Scene *scene, Effector
BLI_addtail(*effectors, eff);
}
-static void add_particles_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src)
+static void add_particles_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
{
ParticleSettings *part= psys->part;
@@ -185,14 +190,14 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
if ( psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0)
return;
- if ( part->pd && part->pd->forcefield && weights->weight[part->pd->forcefield] != 0.0f) {
+ 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(scene, ob, psys, part->pd));
}
- if (part->pd2 && part->pd2->forcefield && weights->weight[part->pd2->forcefield] != 0.0f) {
+ 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");
@@ -202,7 +207,7 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
/* returns ListBase handle with objects taking part in the effecting */
ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
- EffectorWeights *weights, bool precalc)
+ EffectorWeights *weights, bool for_simulation)
{
Base *base;
unsigned int layer= ob_src->lay;
@@ -214,13 +219,13 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
for (go= weights->group->gobject.first; go; go= go->next) {
if ( (go->ob->lay & layer) ) {
if ( go->ob->pd && go->ob->pd->forcefield )
- add_object_to_effectors(&effectors, scene, weights, go->ob, ob_src);
+ add_object_to_effectors(&effectors, scene, weights, go->ob, ob_src, for_simulation);
if ( go->ob->particlesystem.first ) {
ParticleSystem *psys= go->ob->particlesystem.first;
for ( ; psys; psys=psys->next )
- add_particles_to_effectors(&effectors, scene, weights, go->ob, psys, psys_src);
+ add_particles_to_effectors(&effectors, scene, weights, go->ob, psys, psys_src, for_simulation);
}
}
}
@@ -229,19 +234,19 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
for (base = scene->base.first; base; base= base->next) {
if ( (base->lay & layer) ) {
if ( base->object->pd && base->object->pd->forcefield )
- add_object_to_effectors(&effectors, scene, weights, base->object, ob_src);
+ add_object_to_effectors(&effectors, 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, scene, weights, base->object, psys, psys_src);
+ add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src, for_simulation);
}
}
}
}
- if (precalc)
+ if (for_simulation)
pdPrecalculateEffectors(effectors);
return effectors;
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index 0209e94debe..0945da439ef 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -42,6 +42,8 @@ struct Depsgraph;
struct Main;
struct Scene;
+struct Group;
+struct EffectorWeights;
#ifdef __cplusplus
extern "C" {
@@ -112,6 +114,12 @@ void DEG_add_object_cache_relation(struct DepsNodeHandle *handle, struct CacheFi
/* TODO(sergey): Remove once all geometry update is granular. */
void DEG_add_special_eval_flag(struct Depsgraph *graph, struct ID *id, short flag);
+/* Utility functions for physics modifiers */
+typedef bool (*DEG_CollobjFilterFunction)(struct Object *obj, struct ModifierData *md);
+
+void DEG_add_collision_relations(struct DepsNodeHandle *handle, struct Scene *scene, Object *ob, struct Group *group, int layer, unsigned int modifier_type, DEG_CollobjFilterFunction fn, bool dupli, const char *name);
+void DEG_add_forcefield_relations(struct DepsNodeHandle *handle, struct Scene *scene, Object *ob, struct EffectorWeights *eff, bool add_absorption, int skip_forcefield, const char *name);
+
/* ************************************************ */
#ifdef __cplusplus
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 9ab28331249..2148a3501d8 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -65,6 +65,7 @@ extern "C" {
#include "DNA_scene_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
+#include "DNA_object_force.h"
#include "BKE_action.h"
#include "BKE_armature.h"
@@ -72,6 +73,7 @@ extern "C" {
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_effect.h"
+#include "BKE_collision.h"
#include "BKE_fcurve.h"
#include "BKE_group.h"
#include "BKE_key.h"
@@ -243,6 +245,69 @@ void DepsgraphRelationBuilder::add_operation_relation(
}
}
+void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name)
+{
+ unsigned int numcollobj;
+ Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, eModifierType_Collision, dupli);
+
+ for (unsigned int i = 0; i < numcollobj; i++)
+ {
+ Object *ob1 = collobjs[i];
+
+ ComponentKey trf_key(&ob1->id, DEPSNODE_TYPE_TRANSFORM);
+ add_relation(trf_key, key, DEPSREL_TYPE_STANDARD, name);
+
+ ComponentKey coll_key(&ob1->id, DEPSNODE_TYPE_GEOMETRY);
+ add_relation(coll_key, key, DEPSREL_TYPE_STANDARD, name);
+ }
+
+ if (collobjs)
+ MEM_freeN(collobjs);
+}
+
+void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name)
+{
+ ListBase *effectors = pdInitEffectors(scene, ob, psys, eff, false);
+
+ if (effectors) {
+ for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) {
+ if (eff->ob != ob) {
+ ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_TRANSFORM);
+ add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+ }
+
+ if (eff->psys) {
+ if (eff->ob != ob) {
+ ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES);
+ add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+
+ /* TODO: remove this when/if EVAL_PARTICLES is sufficient for up to date particles */
+ ComponentKey mod_key(&eff->ob->id, DEPSNODE_TYPE_GEOMETRY);
+ add_relation(mod_key, key, DEPSREL_TYPE_STANDARD, name);
+ }
+ else if (eff->psys != psys) {
+ OperationKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, eff->psys->name);
+ add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+ }
+ }
+
+ if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
+ ComponentKey trf_key(&eff->pd->f_source->id, DEPSNODE_TYPE_TRANSFORM);
+ add_relation(trf_key, key, DEPSREL_TYPE_STANDARD, "Smoke Force Domain");
+
+ ComponentKey eff_key(&eff->pd->f_source->id, DEPSNODE_TYPE_GEOMETRY);
+ add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, "Smoke Force Domain");
+ }
+
+ if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
+ add_collision_relations(key, scene, ob, NULL, eff->ob->lay, true, "Force Absorption");
+ }
+ }
+ }
+
+ pdEndEffectors(&effectors);
+}
+
/* **** Functions to build relations between entities **** */
void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene)
@@ -1137,20 +1202,13 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
}
#endif
- /* effectors */
- ListBase *effectors = pdInitEffectors(scene, ob, psys, part->effector_weights, false);
-
- if (effectors) {
- for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) {
- if (eff->psys) {
- // XXX: DAG_RL_DATA_DATA | DAG_RL_OB_DATA
- ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_GEOMETRY); // xxx: particles instead?
- add_relation(eff_key, psys_key, DEPSREL_TYPE_STANDARD, "Particle Field");
- }
- }
+ /* collisions */
+ if (part->type != PART_HAIR) {
+ add_collision_relations(psys_key, scene, ob, part->collision_group, ob->lay, true, "Particle Collision");
}
- pdEndEffectors(&effectors);
+ /* effectors */
+ add_forcefield_relations(psys_key, scene, ob, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field");
/* boids */
if (part->boids) {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index ce6d2c961fd..46e65d464a4 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -63,6 +63,8 @@ struct bConstraint;
struct Scene;
struct Tex;
struct World;
+struct EffectorWeights;
+struct ParticleSystem;
struct PropertyRNA;
@@ -244,6 +246,9 @@ struct DepsgraphRelationBuilder
void build_compositor(Scene *scene);
void build_gpencil(ID *owner, bGPdata *gpd);
+ void add_collision_relations(const OperationKey &key, Scene *scene, Object *ob, Group *group, int layer, bool dupli, const char *name);
+ void add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name);
+
template <typename KeyType>
OperationDepsNode *find_operation_node(const KeyType &key);
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index ae830da1252..7a3b19e82c6 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -36,11 +36,15 @@ extern "C" {
#include "DNA_cachefile_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_object_force.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BKE_main.h"
+#include "BKE_collision.h"
+#include "BKE_effect.h"
+#include "BKE_modifier.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_debug.h"
@@ -304,3 +308,52 @@ void DEG_scene_graph_free(Scene *scene)
scene->depsgraph = NULL;
}
}
+
+void DEG_add_collision_relations(DepsNodeHandle *handle, Scene *scene, Object *ob, Group *group, int layer, unsigned int modifier_type, DEG_CollobjFilterFunction fn, bool dupli, const char *name)
+{
+ unsigned int numcollobj;
+ Object **collobjs = get_collisionobjects_ext(scene, ob, group, layer, &numcollobj, modifier_type, dupli);
+
+ for (unsigned int i = 0; i < numcollobj; i++) {
+ Object *ob1 = collobjs[i];
+
+ if (!fn || fn(ob1, modifiers_findByType(ob1, (ModifierType)modifier_type))) {
+ DEG_add_object_relation(handle, ob1, DEG_OB_COMP_TRANSFORM, name);
+ DEG_add_object_relation(handle, ob1, DEG_OB_COMP_GEOMETRY, name);
+ }
+ }
+
+ if (collobjs)
+ MEM_freeN(collobjs);
+}
+
+void DEG_add_forcefield_relations(DepsNodeHandle *handle, Scene *scene, Object *ob, EffectorWeights *effector_weights, bool add_absorption, int skip_forcefield, const char *name)
+{
+ ListBase *effectors = pdInitEffectors(scene, ob, NULL, effector_weights, false);
+
+ if (effectors) {
+ for (EffectorCache *eff = (EffectorCache*)effectors->first; eff; eff = eff->next) {
+ if (eff->ob != ob && 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);
+
+ /* 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);
+ }
+
+ if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
+ DEG_add_object_relation(handle, eff->pd->f_source, DEG_OB_COMP_TRANSFORM, "Smoke Force Domain");
+ DEG_add_object_relation(handle, eff->pd->f_source, DEG_OB_COMP_GEOMETRY, "Smoke Force Domain");
+ }
+
+ if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
+ DEG_add_collision_relations(handle, scene, ob, NULL, eff->ob->lay, eModifierType_Collision, NULL, true, "Force Absorption");
+ }
+ }
+ }
+ }
+
+ pdEndEffectors(&effectors);
+}
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 91cae32d054..d8bcbc2cc72 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -56,6 +56,12 @@ static void rna_cloth_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
}
+static void rna_cloth_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ DAG_relations_tag_update(bmain);
+ rna_cloth_update(bmain, scene, ptr);
+}
+
static void rna_cloth_pinning_changed(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Object *ob = (Object *)ptr->id.data;
@@ -729,7 +735,7 @@ static void rna_def_cloth_collision_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group");
- RNA_def_property_update(prop, 0, "rna_cloth_update");
+ RNA_def_property_update(prop, 0, "rna_cloth_dependency_update");
prop = RNA_def_property(srna, "vertex_group_self_collisions", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_CollSettings_selfcol_vgroup_get", "rna_CollSettings_selfcol_vgroup_length",
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index f05813043ca..1d89f7535c4 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -730,6 +730,11 @@ static void rna_softbody_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Point
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
}
+static void rna_softbody_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ DAG_relations_tag_update(bmain);
+ rna_softbody_update(bmain, scene, ptr);
+}
static EnumPropertyItem *rna_Effector_shape_itemf(bContext *UNUSED(C), PointerRNA *ptr,
PropertyRNA *UNUSED(prop), bool *UNUSED(r_free))
@@ -1378,7 +1383,7 @@ static void rna_def_field(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_absorption", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_VISIBILITY);
RNA_def_property_ui_text(prop, "Absorption", "Force gets absorbed by collision objects");
- RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+ RNA_def_property_update(prop, 0, "rna_FieldSettings_dependency_update");
prop = RNA_def_property(srna, "use_multiple_springs", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_MULTIPLE_SPRINGS);
@@ -1855,7 +1860,7 @@ static void rna_def_softbody(BlenderRNA *brna)
prop = RNA_def_property(srna, "collision_group", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group");
- RNA_def_property_update(prop, 0, "rna_softbody_update");
+ RNA_def_property_update(prop, 0, "rna_softbody_dependency_update");
prop = RNA_def_property(srna, "effector_weights", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "effector_weights");
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index eabf41cb332..5e3fa4b467d 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -630,6 +630,12 @@ static void rna_Particle_reset(Main *bmain, Scene *scene, PointerRNA *ptr)
particle_recalc(bmain, scene, ptr, PSYS_RECALC_RESET);
}
+static void rna_Particle_reset_dependency(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ DAG_relations_tag_update(bmain);
+ rna_Particle_reset(bmain, scene, ptr);
+}
+
static void rna_Particle_change_type(Main *bmain, Scene *scene, PointerRNA *ptr)
{
particle_recalc(bmain, scene, ptr, PSYS_RECALC_RESET | PSYS_RECALC_TYPE);
@@ -2744,7 +2750,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "collision_group", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Collision Group", "Limit colliders to this Group");
- RNA_def_property_update(prop, 0, "rna_Particle_reset");
+ RNA_def_property_update(prop, 0, "rna_Particle_reset_dependency");
/* global physical properties */
prop = RNA_def_property(srna, "drag_factor", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 6cc2f097be8..d15a6fcb1c8 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -123,19 +123,11 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
{
ClothModifierData *clmd = (ClothModifierData *) md;
- Base *base;
-
if (clmd) {
- for (base = scene->base.first; base; base = base->next) {
- Object *ob1 = base->object;
- if (ob1 != ob) {
- CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
- if (coll_clmd) {
- DagNode *curNode = dag_get_node(forest, ob1);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Cloth Collision");
- }
- }
- }
+ /* Actual code uses get_collisionobjects */
+ dag_add_collision_relations(forest, scene, ob, obNode, clmd->coll_parms->group, ob->lay|scene->lay, eModifierType_Collision, NULL, true, "Cloth Collision");
+
+ dag_add_forcefield_relations(forest, scene, ob, obNode, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
}
}
@@ -147,16 +139,10 @@ static void updateDepsgraph(ModifierData *md,
{
ClothModifierData *clmd = (ClothModifierData *)md;
if (clmd != NULL) {
- Base *base;
- for (base = scene->base.first; base; base = base->next) {
- Object *ob1 = base->object;
- if (ob1 != ob) {
- CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
- if (coll_clmd) {
- DEG_add_object_relation(node, ob1, DEG_OB_COMP_TRANSFORM, "Cloth Modifier");
- }
- }
- }
+ /* Actual code uses get_collisionobjects */
+ DEG_add_collision_relations(node, scene, ob, clmd->coll_parms->group, ob->lay|scene->lay, eModifierType_Collision, NULL, true, "Cloth Collision");
+
+ DEG_add_forcefield_relations(node, scene, ob, clmd->sim_parms->effector_weights, true, 0, "Cloth Field");
}
}
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index edf959f42c6..bde20e56748 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -114,6 +114,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
return dm;
}
+static bool is_brush_cb(Object *UNUSED(ob), ModifierData *pmd)
+{
+ return ((DynamicPaintModifierData*)pmd)->brush != NULL;
+}
+
static void updateDepgraph(ModifierData *md, DagForest *forest,
struct Main *UNUSED(bmain),
struct Scene *scene,
@@ -124,16 +129,13 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
/* add relation from canvases to all brush objects */
if (pmd && pmd->canvas) {
- Base *base = scene->base.first;
-
- for (; base; base = base->next) {
- DynamicPaintModifierData *pmd2 =
- (DynamicPaintModifierData *)modifiers_findByType(base->object, eModifierType_DynamicPaint);
-
- if (pmd2 && pmd2->brush && ob != base->object) {
- DagNode *brushNode = dag_get_node(forest, base->object);
- dag_add_relation(forest, brushNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Dynamic Paint Brush");
+ for (DynamicPaintSurface *surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
+ if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
+ dag_add_forcefield_relations(forest, scene, ob, obNode, surface->effector_weights, true, 0, "Dynamic Paint Field");
}
+
+ /* Actual code uses custom loop over group/scene without layer checks in dynamicPaint_doStep */
+ dag_add_collision_relations(forest, scene, ob, obNode, surface->brush_group, -1, eModifierType_DynamicPaint, is_brush_cb, false, "Dynamic Paint Brush");
}
}
}
@@ -147,13 +149,13 @@ static void updateDepsgraph(ModifierData *md,
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
/* Add relation from canvases to all brush objects. */
if (pmd->canvas != NULL) {
- Base *base = scene->base.first;
- for (; base; base = base->next) {
- DynamicPaintModifierData *pmd2 =
- (DynamicPaintModifierData *)modifiers_findByType(base->object, eModifierType_DynamicPaint);
- if (pmd2 && pmd2->brush && ob != base->object) {
- DEG_add_object_relation(node, base->object, DEG_OB_COMP_TRANSFORM, "Dynamic Paint Brush");
+ for (DynamicPaintSurface *surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
+ if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
+ DEG_add_forcefield_relations(node, scene, ob, surface->effector_weights, true, 0, "Dynamic Paint Field");
}
+
+ /* Actual code uses custom loop over group/scene without layer checks in dynamicPaint_doStep */
+ DEG_add_collision_relations(node, scene, ob, surface->brush_group, -1, eModifierType_DynamicPaint, is_brush_cb, false, "Dynamic Paint Brush");
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index 237d4cc6718..f04d7432a8f 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -117,219 +117,48 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
-static void update_depsgraph_flow_coll_object(DagForest *forest,
- DagNode *obNode,
- Object *object2)
+static bool is_flow_cb(Object *UNUSED(ob), ModifierData *md)
{
- SmokeModifierData *smd;
- if ((object2->id.tag & LIB_TAG_DOIT) == 0) {
- return;
- }
- object2->id.tag &= ~LIB_TAG_DOIT;
- smd = (SmokeModifierData *)modifiers_findByType(object2, eModifierType_Smoke);
- if (smd && (((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) ||
- ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll)))
- {
- DagNode *curNode = dag_get_node(forest, object2);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Smoke Flow/Coll");
- }
- if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) {
- GroupObject *go;
- for (go = object2->dup_group->gobject.first;
- go != NULL;
- go = go->next)
- {
- if (go->ob == NULL) {
- continue;
- }
- update_depsgraph_flow_coll_object(forest, obNode, go->ob);
- }
- }
+ SmokeModifierData *smd = (SmokeModifierData *) md;
+ return (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow;
}
-static void update_depsgraph_field_source_object(DagForest *forest,
- DagNode *obNode,
- Object *object,
- Object *object2)
+static bool is_coll_cb(Object *UNUSED(ob), ModifierData *md)
{
- if ((object2->id.tag & LIB_TAG_DOIT) == 0) {
- return;
- }
- object2->id.tag &= ~LIB_TAG_DOIT;
- if (object2->pd && object2->pd->forcefield == PFIELD_SMOKEFLOW && object2->pd->f_source == object) {
- DagNode *node2 = dag_get_node(forest, object2);
- dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object");
- }
- if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) {
- GroupObject *go;
- for (go = object2->dup_group->gobject.first;
- go != NULL;
- go = go->next)
- {
- if (go->ob == NULL) {
- continue;
- }
- update_depsgraph_field_source_object(forest, obNode, object, go->ob);
- }
- }
+ SmokeModifierData *smd = (SmokeModifierData *) md;
+ return (smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll;
}
static void updateDepgraph(ModifierData *md, DagForest *forest,
- struct Main *bmain,
+ struct Main *UNUSED(bmain),
struct Scene *scene, struct Object *ob,
DagNode *obNode)
{
SmokeModifierData *smd = (SmokeModifierData *) md;
- Base *base;
if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
- if (smd->domain->fluid_group || smd->domain->coll_group) {
- GroupObject *go = NULL;
-
- if (smd->domain->fluid_group)
- for (go = smd->domain->fluid_group->gobject.first; go; go = go->next) {
- if (go->ob) {
- SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke);
-
- /* check for initialized smoke object */
- if (smd2 && (smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) {
- DagNode *curNode = dag_get_node(forest, go->ob);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Smoke Flow");
- }
- }
- }
-
- if (smd->domain->coll_group)
- for (go = smd->domain->coll_group->gobject.first; go; go = go->next) {
- if (go->ob) {
- SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke);
-
- /* check for initialized smoke object */
- if (smd2 && (smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) {
- DagNode *curNode = dag_get_node(forest, go->ob);
- dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Smoke Coll");
- }
- }
- }
- }
- else {
- BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true);
- base = scene->base.first;
- for (; base; base = base->next) {
- update_depsgraph_flow_coll_object(forest, obNode, base->object);
- }
- }
- /* add relation to all "smoke flow" force fields */
- base = scene->base.first;
- BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true);
- for (; base; base = base->next) {
- update_depsgraph_field_source_object(forest, obNode, ob, base->object);
- }
- }
-}
+ /* Actual code uses get_collisionobjects */
+ dag_add_collision_relations(forest, scene, ob, obNode, smd->domain->fluid_group, ob->lay|scene->lay, eModifierType_Smoke, is_flow_cb, true, "Smoke Flow");
+ dag_add_collision_relations(forest, scene, ob, obNode, smd->domain->coll_group, ob->lay|scene->lay, eModifierType_Smoke, is_coll_cb, true, "Smoke Coll");
-static void update_depsgraph_flow_coll_object_new(struct DepsNodeHandle *node,
- Object *object2)
-{
- SmokeModifierData *smd;
- if ((object2->id.tag & LIB_TAG_DOIT) == 0) {
- return;
- }
- object2->id.tag &= ~LIB_TAG_DOIT;
- smd = (SmokeModifierData *)modifiers_findByType(object2, eModifierType_Smoke);
- if (smd && (((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) ||
- ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll)))
- {
- DEG_add_object_relation(node, object2, DEG_OB_COMP_TRANSFORM, "Smoke Flow/Coll");
- DEG_add_object_relation(node, object2, DEG_OB_COMP_GEOMETRY, "Smoke Flow/Coll");
- }
- if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) {
- GroupObject *go;
- for (go = object2->dup_group->gobject.first;
- go != NULL;
- go = go->next)
- {
- if (go->ob == NULL) {
- continue;
- }
- update_depsgraph_flow_coll_object_new(node, go->ob);
- }
- }
-}
-
-static void update_depsgraph_field_source_object_new(struct DepsNodeHandle *node,
- Object *object,
- Object *object2)
-{
- if ((object2->id.tag & LIB_TAG_DOIT) == 0) {
- return;
- }
- object2->id.tag &= ~LIB_TAG_DOIT;
- if (object2->pd && object2->pd->forcefield == PFIELD_SMOKEFLOW && object2->pd->f_source == object) {
- DEG_add_object_relation(node, object2, DEG_OB_COMP_TRANSFORM, "Field Source Object");
- DEG_add_object_relation(node, object2, DEG_OB_COMP_GEOMETRY, "Field Source Object");
- }
- if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) {
- GroupObject *go;
- for (go = object2->dup_group->gobject.first;
- go != NULL;
- go = go->next)
- {
- if (go->ob == NULL) {
- continue;
- }
- update_depsgraph_field_source_object_new(node, object, go->ob);
- }
+ dag_add_forcefield_relations(forest, scene, ob, obNode, smd->domain->effector_weights, true, PFIELD_SMOKEFLOW, "Smoke Force Field");
}
}
static void updateDepsgraph(ModifierData *md,
- struct Main *bmain,
+ struct Main *UNUSED(bmain),
struct Scene *scene,
Object *ob,
struct DepsNodeHandle *node)
{
SmokeModifierData *smd = (SmokeModifierData *)md;
- Base *base;
+
if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) {
- if (smd->domain->fluid_group || smd->domain->coll_group) {
- GroupObject *go = NULL;
- if (smd->domain->fluid_group != NULL) {
- for (go = smd->domain->fluid_group->gobject.first; go; go = go->next) {
- if (go->ob != NULL) {
- SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke);
- /* Check for initialized smoke object. */
- if (smd2 && (smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) {
- DEG_add_object_relation(node, go->ob, DEG_OB_COMP_TRANSFORM, "Smoke Flow");
- }
- }
- }
- }
- if (smd->domain->coll_group != NULL) {
- for (go = smd->domain->coll_group->gobject.first; go; go = go->next) {
- if (go->ob != NULL) {
- SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke);
- /* Check for initialized smoke object. */
- if (smd2 && (smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) {
- DEG_add_object_relation(node, go->ob, DEG_OB_COMP_TRANSFORM, "Smoke Coll");
- }
- }
- }
- }
- }
- else {
- BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true);
- base = scene->base.first;
- for (; base; base = base->next) {
- update_depsgraph_flow_coll_object_new(node, base->object);
- }
- }
- /* add relation to all "smoke flow" force fields */
- base = scene->base.first;
- BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true);
- for (; base; base = base->next) {
- update_depsgraph_field_source_object_new(node, ob, base->object);
- }
+ /* Actual code uses get_collisionobjects */
+ DEG_add_collision_relations(node, scene, ob, smd->domain->fluid_group, ob->lay|scene->lay, eModifierType_Smoke, is_flow_cb, true, "Smoke Flow");
+ DEG_add_collision_relations(node, scene, ob, smd->domain->coll_group, ob->lay|scene->lay, eModifierType_Smoke, is_coll_cb, true, "Smoke Coll");
+
+ DEG_add_forcefield_relations(node, scene, ob, smd->domain->effector_weights, true, PFIELD_SMOKEFLOW, "Smoke Force Field");
}
}
diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c
index 98a1412d0c6..17adc7f1520 100644
--- a/source/blender/modifiers/intern/MOD_softbody.c
+++ b/source/blender/modifiers/intern/MOD_softbody.c
@@ -35,6 +35,7 @@
#include <stdio.h>
#include "DNA_scene_types.h"
+#include "DNA_object_force.h"
#include "BLI_utildefines.h"
@@ -42,6 +43,9 @@
#include "BKE_particle.h"
#include "BKE_softbody.h"
+#include "depsgraph_private.h"
+#include "DEG_depsgraph_build.h"
+
#include "MOD_modifiertypes.h"
static void deformVerts(ModifierData *md, Object *ob,
@@ -58,6 +62,31 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
+static void updateDepgraph(ModifierData *UNUSED(md), DagForest *forest,
+ struct Main *UNUSED(bmain),
+ Scene *scene, Object *ob, DagNode *obNode)
+{
+ if (ob->soft) {
+ /* Actual code uses ccd_build_deflector_hash */
+ dag_add_collision_relations(forest, scene, ob, obNode, ob->soft->collision_group, ob->lay, eModifierType_Collision, NULL, false, "Softbody Collision");
+
+ dag_add_forcefield_relations(forest, scene, ob, obNode, ob->soft->effector_weights, true, 0, "Softbody Field");
+ }
+}
+
+static void updateDepsgraph(ModifierData *UNUSED(md),
+ struct Main *UNUSED(bmain),
+ struct Scene *scene,
+ Object *ob,
+ struct DepsNodeHandle *node)
+{
+ if (ob->soft) {
+ /* Actual code uses ccd_build_deflector_hash */
+ DEG_add_collision_relations(node, scene, ob, ob->soft->collision_group, ob->lay, eModifierType_Collision, NULL, false, "Softbody Collision");
+
+ DEG_add_forcefield_relations(node, scene, ob, ob->soft->effector_weights, true, 0, "Softbody Field");
+ }
+}
ModifierTypeInfo modifierType_Softbody = {
/* name */ "Softbody",
@@ -80,8 +109,8 @@ ModifierTypeInfo modifierType_Softbody = {
/* requiredDataMask */ NULL,
/* freeData */ NULL,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
- /* updateDepsgraph */ NULL,
+ /* updateDepgraph */ updateDepgraph,
+ /* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
/* foreachObjectLink */ NULL,