diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-06-22 15:42:03 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-06-25 14:35:41 +0300 |
commit | a99dcab148ed209409f3b2479ada12d869ae84b6 (patch) | |
tree | 2b7fc55752cbe3538fc05c8f77fd86b18a0d6df7 /source/blender/depsgraph | |
parent | 5b3ff9f7d890554ae87e63095f24ac6d31a36d3c (diff) |
Depsgraph: cache collision relations, for performance and stability.
Same reasoning as effector relations in earlier commit.
Diffstat (limited to 'source/blender/depsgraph')
9 files changed, 111 insertions, 52 deletions
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h index 202e8ef3cf0..834d45a7e61 100644 --- a/source/blender/depsgraph/DEG_depsgraph_build.h +++ b/source/blender/depsgraph/DEG_depsgraph_build.h @@ -157,15 +157,12 @@ void DEG_add_special_eval_flag(struct Depsgraph *graph, struct ID *id, short fla typedef bool (*DEG_CollobjFilterFunction)(struct Object *obj, struct ModifierData *md); void DEG_add_collision_relations(struct DepsNodeHandle *handle, - struct Scene *scene, struct Object *object, struct Collection *collection, unsigned int modifier_type, DEG_CollobjFilterFunction fn, - bool dupli, const char *name); void DEG_add_forcefield_relations(struct DepsNodeHandle *handle, - struct Scene *scene, struct Object *object, struct EffectorWeights *eff, bool add_absorption, diff --git a/source/blender/depsgraph/DEG_depsgraph_physics.h b/source/blender/depsgraph/DEG_depsgraph_physics.h index 6bffe0c2358..c90f66838cc 100644 --- a/source/blender/depsgraph/DEG_depsgraph_physics.h +++ b/source/blender/depsgraph/DEG_depsgraph_physics.h @@ -34,15 +34,21 @@ struct Colllection; struct Depsgraph; +struct ListBase; #ifdef __cplusplus extern "C" { #endif -/* Get effector relations from collection or entire scene during evaluation, - * these are created during depsgraph relations building. */ +/* Get collision/effector relations from collection or entire scene. These + * created during depsgraph relations building and should only be accessed + * during evaluation. */ struct ListBase *DEG_get_effector_relations(const struct Depsgraph *depsgraph, struct Collection *collection); +struct ListBase *DEG_get_collision_relations(const struct Depsgraph *depsgraph, + struct Collection *collection); +struct ListBase *DEG_get_smoke_collision_relations(const struct Depsgraph *depsgraph, + struct Collection *collection); #ifdef __cplusplus } /* extern "C" */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 9714cf9d853..d87cb59e976 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -298,36 +298,25 @@ DepsRelation *DepsgraphRelationBuilder::add_operation_relation( void DepsgraphRelationBuilder::add_collision_relations( const OperationKey &key, - Scene *scene, Object *object, Collection *collection, - bool dupli, const char *name) { - unsigned int numcollobj; - Object **collobjs = get_collisionobjects_ext(scene, - object, - collection, - &numcollobj, - eModifierType_Collision, - dupli); - for (unsigned int i = 0; i < numcollobj; i++) { - Object *ob1 = collobjs[i]; + ListBase *relations = deg_build_collision_relations(graph_, collection); - ComponentKey trf_key(&ob1->id, DEG_NODE_TYPE_TRANSFORM); - add_relation(trf_key, key, name); + LISTBASE_FOREACH (CollisionRelation *, relation, relations) { + if (relation->ob != object) { + ComponentKey trf_key(&relation->ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(trf_key, key, name); - ComponentKey coll_key(&ob1->id, DEG_NODE_TYPE_GEOMETRY); - add_relation(coll_key, key, name); - } - if (collobjs != NULL) { - MEM_freeN(collobjs); + ComponentKey coll_key(&relation->ob->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(coll_key, key, name); + } } } void DepsgraphRelationBuilder::add_forcefield_relations( const OperationKey &key, - Scene *scene, Object *object, ParticleSystem *psys, EffectorWeights *eff, @@ -351,10 +340,8 @@ void DepsgraphRelationBuilder::add_forcefield_relations( } if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) { add_collision_relations(key, - scene, object, NULL, - true, "Force Absorption"); } } @@ -1586,10 +1573,8 @@ void DepsgraphRelationBuilder::build_particles(Object *object) /* Collisions */ if (part->type != PART_HAIR) { add_collision_relations(psys_key, - scene_, object, part->collision_group, - true, "Particle Collision"); } else if ((psys->flag & PSYS_HAIR_DYNAMICS) && @@ -1597,15 +1582,12 @@ void DepsgraphRelationBuilder::build_particles(Object *object) psys->clmd->coll_parms != NULL) { add_collision_relations(psys_key, - scene_, object, psys->clmd->coll_parms->group, - true, "Hair Collision"); } /* Effectors. */ add_forcefield_relations(psys_key, - scene_, object, psys, part->effector_weights, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 2b9ba3edffb..9996e420663 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -272,13 +272,10 @@ struct DepsgraphRelationBuilder void build_nested_shapekey(ID *owner, Key *key); void add_collision_relations(const OperationKey &key, - Scene *scene, Object *object, Collection *collection, - bool dupli, const char *name); void add_forcefield_relations(const OperationKey &key, - Scene *scene, Object *object, ParticleSystem *psys, EffectorWeights *eff, diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index bb340492a63..267cadb7993 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -94,7 +94,9 @@ Depsgraph::Depsgraph(Scene *scene, ctime(BKE_scene_frame_get(scene)), scene_cow(NULL), is_active(false), - effector_relations(NULL) + collision_relations(NULL), + smoke_collision_relations(NULL), + effector_relations(NULL) { BLI_spin_init(&lock); id_hash = BLI_ghash_ptr_new("Depsgraph id hash"); diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index a27af42e7b9..3517a6f6f34 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -227,8 +227,10 @@ struct Depsgraph { int debug_flags; string debug_name; - /* Cached list of effectors for collections and the scene created - * along with relations, for fast lookup during evaluation. */ + /* Cached list of colliders/effectors for collections and the scene + * created along with relations, for fast lookup during evaluation. */ + GHash *collision_relations; + GHash *smoke_collision_relations; GHash *effector_relations; }; diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index da64478404b..042cf801e6b 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -324,32 +324,35 @@ void DEG_relations_tag_update(Main *bmain) } void DEG_add_collision_relations(DepsNodeHandle *handle, - Scene *scene, Object *object, Collection *collection, unsigned int modifier_type, DEG_CollobjFilterFunction fn, - bool dupli, const char *name) { - unsigned int numcollobj; - Object **collobjs = get_collisionobjects_ext(scene, object, collection, &numcollobj, modifier_type, dupli); + Depsgraph *depsgraph = DEG_get_graph_from_handle(handle); + DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph; + ListBase *relations; - for (unsigned int i = 0; i < numcollobj; i++) { - Object *ob1 = collobjs[i]; + if (modifier_type == eModifierType_Smoke) { + relations = deg_build_smoke_collision_relations(deg_graph, collection); + } + else { + relations = deg_build_collision_relations(deg_graph, collection); + } - 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); + LISTBASE_FOREACH (CollisionRelation *, relation, relations) { + Object *ob1 = relation->ob; + if (ob1 != object) { + 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 *object, EffectorWeights *effector_weights, bool add_absorption, @@ -382,12 +385,10 @@ void DEG_add_forcefield_relations(DepsNodeHandle *handle, } if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) { DEG_add_collision_relations(handle, - scene, object, NULL, eModifierType_Collision, NULL, - true, "Force Absorption"); } } diff --git a/source/blender/depsgraph/intern/depsgraph_intern.h b/source/blender/depsgraph/intern/depsgraph_intern.h index cd5508a4088..55ecfacf126 100644 --- a/source/blender/depsgraph/intern/depsgraph_intern.h +++ b/source/blender/depsgraph/intern/depsgraph_intern.h @@ -143,6 +143,8 @@ string deg_color_end(void); /* Physics Utilities -------------------------------------------------- */ struct ListBase *deg_build_effector_relations(Depsgraph *graph, struct Collection *collection); +struct ListBase *deg_build_collision_relations(Depsgraph *graph, struct Collection *collection); +struct ListBase *deg_build_smoke_collision_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 index fb14c020f81..ba42ef96365 100644 --- a/source/blender/depsgraph/intern/depsgraph_physics.cc +++ b/source/blender/depsgraph/intern/depsgraph_physics.cc @@ -33,6 +33,7 @@ #include "BLI_ghash.h" extern "C" { +#include "BKE_collision.h" #include "BKE_effect.h" } /* extern "C" */ @@ -56,6 +57,28 @@ ListBase *DEG_get_effector_relations(const Depsgraph *graph, return (ListBase *)BLI_ghash_lookup(deg_graph->effector_relations, collection); } +ListBase *DEG_get_collision_relations(const Depsgraph *graph, + Collection *collection) +{ + const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); + if (deg_graph->collision_relations == NULL) { + return NULL; + } + + return (ListBase*)BLI_ghash_lookup(deg_graph->collision_relations, collection); +} + +ListBase *DEG_get_smoke_collision_relations(const Depsgraph *graph, + Collection *collection) +{ + const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); + if (deg_graph->smoke_collision_relations == NULL) { + return NULL; + } + + return (ListBase*)BLI_ghash_lookup(deg_graph->smoke_collision_relations, collection); +} + /*********************** Internal API ************************/ namespace DEG @@ -78,13 +101,60 @@ ListBase *deg_build_effector_relations(Depsgraph *graph, return relations; } +ListBase *deg_build_collision_relations(Depsgraph *graph, + Collection *collection) +{ + if (graph->collision_relations == NULL) { + graph->collision_relations = BLI_ghash_ptr_new("Depsgraph collision relations hash"); + } + + ListBase *relations = reinterpret_cast<ListBase*>(BLI_ghash_lookup(graph->collision_relations, collection)); + if (relations == NULL) { + ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph); + relations = BKE_collision_relations_create(depsgraph, collection, eModifierType_Collision); + BLI_ghash_insert(graph->collision_relations, collection, relations); + } + + return relations; +} + +ListBase *deg_build_smoke_collision_relations(Depsgraph *graph, + Collection *collection) +{ + if (graph->smoke_collision_relations == NULL) { + graph->smoke_collision_relations = BLI_ghash_ptr_new("Depsgraph smoke collision relations hash"); + } + + ListBase *relations = reinterpret_cast<ListBase*>(BLI_ghash_lookup(graph->smoke_collision_relations, collection)); + if (relations == NULL) { + ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph); + relations = BKE_collision_relations_create(depsgraph, collection, eModifierType_Smoke); + BLI_ghash_insert(graph->smoke_collision_relations, collection, relations); + } + + return relations; +} + static void free_effector_relations(void *value) { BKE_effector_relations_free(reinterpret_cast<ListBase*>(value)); } +static void free_collision_relations(void *value) +{ + BKE_collision_relations_free(reinterpret_cast<ListBase*>(value)); +} + void deg_clear_physics_relations(Depsgraph *graph) { + if (graph->collision_relations) { + BLI_ghash_free(graph->collision_relations, NULL, free_collision_relations); + graph->collision_relations = NULL; + } + if (graph->smoke_collision_relations) { + BLI_ghash_free(graph->smoke_collision_relations, NULL, free_collision_relations); + graph->smoke_collision_relations = NULL; + } if (graph->effector_relations) { BLI_ghash_free(graph->effector_relations, NULL, free_effector_relations); graph->effector_relations = NULL; |