diff options
Diffstat (limited to 'source/blender/blenkernel/intern/depsgraph.c')
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 101 |
1 files changed, 44 insertions, 57 deletions
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) { |