Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-06-22 15:42:03 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-06-25 14:35:41 +0300
commita99dcab148ed209409f3b2479ada12d869ae84b6 (patch)
tree2b7fc55752cbe3538fc05c8f77fd86b18a0d6df7 /source/blender/depsgraph
parent5b3ff9f7d890554ae87e63095f24ac6d31a36d3c (diff)
Depsgraph: cache collision relations, for performance and stability.
Same reasoning as effector relations in earlier commit.
Diffstat (limited to 'source/blender/depsgraph')
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h3
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_physics.h10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc34
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h3
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc4
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc31
-rw-r--r--source/blender/depsgraph/intern/depsgraph_intern.h2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_physics.cc70
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;