diff options
Diffstat (limited to 'source/blender/depsgraph')
18 files changed, 483 insertions, 163 deletions
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_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h index 202e8ef3cf0..30fefb7d4e4 100644 --- a/source/blender/depsgraph/DEG_depsgraph_build.h +++ b/source/blender/depsgraph/DEG_depsgraph_build.h @@ -153,25 +153,6 @@ void DEG_add_object_cache_relation(struct DepsNodeHandle *handle, struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle); 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, - 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, - int skip_forcefield, - const char *name); - /* ************************************************ */ #ifdef __cplusplus diff --git a/source/blender/depsgraph/DEG_depsgraph_physics.h b/source/blender/depsgraph/DEG_depsgraph_physics.h new file mode 100644 index 00000000000..fd35a7fb2c0 --- /dev/null +++ b/source/blender/depsgraph/DEG_depsgraph_physics.h @@ -0,0 +1,85 @@ +/* + * ***** 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; +struct DepsNodeHandle; +struct EffectorWeights; +struct ListBase; +struct Object; + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum ePhysicsRelationType { + DEG_PHYSICS_EFFECTOR = 0, + DEG_PHYSICS_COLLISION = 1, + DEG_PHYSICS_SMOKE_COLLISION = 2, + DEG_PHYSICS_DYNAMIC_BRUSH = 3, + DEG_PHYSICS_RELATIONS_NUM = 4 +} ePhysicsRelationType; + +/* 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, + unsigned int modifier_type); + + +/* Build collision/effector relations for depsgraph. */ +typedef bool (*DEG_CollobjFilterFunction)(struct Object *obj, + struct ModifierData *md); + +void DEG_add_collision_relations(struct DepsNodeHandle *handle, + struct Object *object, + struct Collection *collection, + unsigned int modifier_type, + DEG_CollobjFilterFunction fn, + const char *name); +void DEG_add_forcefield_relations(struct DepsNodeHandle *handle, + struct Object *object, + struct EffectorWeights *eff, + bool add_absorption, + int skip_forcefield, + const char *name); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __DEG_DEPSGRAPH_PHYSICS_H__ */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc index 1b2dcd8fcf8..b6256e9ceb0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder.cc @@ -58,7 +58,7 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) foreach (IDDepsNode *id_node, graph->id_nodes) { ID *id = id_node->id_orig; id_node->finalize_build(graph); - int flag = DEG_TAG_TRANSFORM | DEG_TAG_GEOMETRY; + int flag = 0; if ((id->recalc & ID_RECALC_ALL)) { AnimData *adt = BKE_animdata_from_id(id); if (adt != NULL && (adt->recalc & ADT_RECALC_ANIM) != 0) { @@ -68,7 +68,9 @@ void deg_graph_build_finalize(Main *bmain, Depsgraph *graph) if (!deg_copy_on_write_is_expanded(id_node->id_cow)) { flag |= DEG_TAG_COPY_ON_WRITE; } - DEG_id_tag_update_ex(bmain, id_node->id_orig, flag); + if (flag != 0) { + DEG_id_tag_update_ex(bmain, id_node->id_orig, flag); + } } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index d4a115cfb8b..cfb2f1bc8d6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -65,6 +65,7 @@ extern "C" { #include "DNA_lightprobe_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" +#include "DNA_speaker_types.h" #include "DNA_texture_types.h" #include "DNA_world_types.h" @@ -431,6 +432,9 @@ void DepsgraphNodeBuilder::build_id(ID *id) { case ID_LT: build_object_data_geometry_datablock(id); break; + case ID_SPK: + build_speaker((Speaker *)id); + break; default: fprintf(stderr, "Unhandled ID %s\n", id->name); BLI_assert(!"Should never happen"); @@ -458,6 +462,15 @@ void DepsgraphNodeBuilder::build_collection( add_id_node(&collection->id); /* Build collection objects. */ LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { + if (allow_restrict_flags) { + const int restrict_flag = ( + (graph_->mode == DAG_EVAL_VIEWPORT) ? + OB_RESTRICT_VIEW : + OB_RESTRICT_RENDER); + if (cob->ob->restrictflag & restrict_flag) { + continue; + } + } build_object(-1, cob->ob, DEG_ID_LINKED_INDIRECTLY); } /* Build child collections. */ @@ -530,9 +543,12 @@ void DepsgraphNodeBuilder::build_object(int base_index, build_gpencil(object->gpd); } /* Proxy object to copy from. */ - if (object->proxy_from) { + if (object->proxy_from != NULL) { build_object(-1, object->proxy_from, DEG_ID_LINKED_INDIRECTLY); } + if (object->proxy_group != NULL) { + build_object(-1, object->proxy_group, DEG_ID_LINKED_INDIRECTLY); + } /* Object dupligroup. */ if (object->dup_group != NULL) { build_collection(DEG_COLLECTION_OWNER_OBJECT, object->dup_group); @@ -604,6 +620,9 @@ void DepsgraphNodeBuilder::build_object_data(Object *object) case OB_LIGHTPROBE: build_object_data_lightprobe(object); break; + case OB_SPEAKER: + build_object_data_speaker(object); + break; default: { ID *obdata = (ID *)object->data; @@ -637,6 +656,16 @@ void DepsgraphNodeBuilder::build_object_data_lightprobe(Object *object) DEG_OPCODE_LIGHT_PROBE_EVAL); } +void DepsgraphNodeBuilder::build_object_data_speaker(Object *object) +{ + Speaker *speaker = (Speaker *)object->data; + build_speaker(speaker); + add_operation_node(&object->id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_SPEAKER_EVAL); +} + void DepsgraphNodeBuilder::build_object_transform(Object *object) { OperationDepsNode *op_node; @@ -1453,6 +1482,19 @@ void DepsgraphNodeBuilder::build_lightprobe(LightProbe *probe) build_animdata(&probe->id); } +void DepsgraphNodeBuilder::build_speaker(Speaker *speaker) +{ + if (built_map_.checkIsBuiltAndTag(speaker)) { + return; + } + /* Placeholder so we can add relations and tag ID node for update. */ + add_operation_node(&speaker->id, + DEG_NODE_TYPE_PARAMETERS, + NULL, + DEG_OPCODE_SPEAKER_EVAL); + build_animdata(&speaker->id); +} + /* **** ID traversal callbacks functions **** */ void DepsgraphNodeBuilder::modifier_walk(void *user_data, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 72aa5dbe003..487b834bd07 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -62,6 +62,7 @@ struct Probe; struct bPoseChannel; struct bConstraint; struct Scene; +struct Speaker; struct Tex; struct World; @@ -175,6 +176,7 @@ struct DepsgraphNodeBuilder { void build_object_data_geometry_datablock(ID *obdata); void build_object_data_lamp(Object *object); void build_object_data_lightprobe(Object *object); + void build_object_data_speaker(Object *object); void build_object_transform(Object *object); void build_object_constraints(Object *object); void build_pose_constraints(Object *object, bPoseChannel *pchan, int pchan_index); @@ -209,6 +211,7 @@ struct DepsgraphNodeBuilder { void build_mask(Mask *mask); void build_movieclip(MovieClip *clip); void build_lightprobe(LightProbe *probe); + void build_speaker(Speaker *speaker); protected: struct SavedEntryTag { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc index e2526272570..f1db05b7220 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc @@ -105,7 +105,7 @@ void DepsgraphNodeBuilder::build_view_layer( */ int base_index = 0; const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? - BASE_VISIBLE_VIEWPORT : BASE_VISIBLE_RENDER; + BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER; LISTBASE_FOREACH(Base *, base, &view_layer->object_bases) { /* object itself */ if (base->flag & base_flag) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 861f2dff1d6..e39bf8aaa98 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_object_types.h" #include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" +#include "DNA_speaker_types.h" #include "DNA_texture_types.h" #include "DNA_world_types.h" #include "DNA_object_force_types.h" @@ -297,87 +298,72 @@ 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, eModifierType_Collision); - 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, bool add_absorption, const char *name) { - ListBase *effectors = pdInitEffectors(NULL, 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, + object, + NULL, + "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() @@ -442,6 +428,9 @@ void DepsgraphRelationBuilder::build_id(ID *id) case ID_LT: build_object_data_geometry_datablock(id); break; + case ID_SPK: + build_speaker((Speaker *)id); + break; default: fprintf(stderr, "Unhandled ID %s\n", id->name); BLI_assert(!"Should never happen"); @@ -464,11 +453,19 @@ void DepsgraphRelationBuilder::build_collection( } } const bool group_done = built_map_.checkIsBuiltAndTag(collection); - OperationKey object_local_transform_key(object != NULL ? &object->id : NULL, + OperationKey object_transform_final_key(object != NULL ? &object->id : NULL, DEG_NODE_TYPE_TRANSFORM, - DEG_OPCODE_TRANSFORM_LOCAL); + DEG_OPCODE_TRANSFORM_FINAL); if (!group_done) { LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { + if (allow_restrict_flags) { + const int restrict_flag = (graph_->mode == DAG_EVAL_VIEWPORT) + ? OB_RESTRICT_VIEW + : OB_RESTRICT_RENDER; + if (cob->ob->restrictflag & restrict_flag) { + continue; + } + } build_object(NULL, cob->ob); } LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { @@ -479,7 +476,7 @@ void DepsgraphRelationBuilder::build_collection( FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN(collection, ob, graph_->mode) { ComponentKey dupli_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM); - add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); + add_relation(dupli_transform_key, object_transform_final_key, "Dupligroup"); } FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END; } @@ -597,7 +594,13 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object) ComponentKey proxy_transform_key(&object->id, DEG_NODE_TYPE_TRANSFORM); add_relation(ob_transform_key, proxy_transform_key, "Proxy Transform"); } - + if (object->proxy_group != NULL) { + build_object(NULL, object->proxy_group); + OperationKey proxy_group_ubereval_key(&object->proxy_group->id, + DEG_NODE_TYPE_TRANSFORM, + DEG_OPCODE_TRANSFORM_OBJECT_UBEREVAL); + add_relation(proxy_group_ubereval_key, final_transform_key, "Proxy Group Transform"); + } /* Object dupligroup. */ if (object->dup_group != NULL) { build_collection(DEG_COLLECTION_OWNER_OBJECT, object, object->dup_group); @@ -657,6 +660,9 @@ void DepsgraphRelationBuilder::build_object_data(Object *object) case OB_LIGHTPROBE: build_object_data_lightprobe(object); break; + case OB_SPEAKER: + build_object_data_speaker(object); + break; } Key *key = BKE_key_from_object(object); if (key != NULL) { @@ -698,6 +704,19 @@ void DepsgraphRelationBuilder::build_object_data_lightprobe(Object *object) add_relation(probe_key, object_key, "LightProbe Update"); } +void DepsgraphRelationBuilder::build_object_data_speaker(Object *object) +{ + Speaker *speaker = (Speaker *)object->data; + build_speaker(speaker); + OperationKey probe_key(&speaker->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_SPEAKER_EVAL); + OperationKey object_key(&object->id, + DEG_NODE_TYPE_PARAMETERS, + DEG_OPCODE_SPEAKER_EVAL); + add_relation(probe_key, object_key, "Speaker Update"); +} + void DepsgraphRelationBuilder::build_object_parent(Object *object) { /* XXX: for now, need to use the component key (not just direct to the parent op), @@ -1563,10 +1582,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) && @@ -1574,15 +1591,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, @@ -2119,6 +2133,14 @@ void DepsgraphRelationBuilder::build_lightprobe(LightProbe *probe) build_animdata(&probe->id); } +void DepsgraphRelationBuilder::build_speaker(Speaker *speaker) +{ + if (built_map_.checkIsBuiltAndTag(speaker)) { + return; + } + build_animdata(&speaker->id); +} + void DepsgraphRelationBuilder::build_copy_on_write_relations() { foreach (IDDepsNode *id_node, graph_->id_nodes) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 3d3a73b6551..9996e420663 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -75,6 +75,7 @@ struct bConstraint; struct ParticleSystem; struct ParticleSettings; struct Scene; +struct Speaker; struct ViewLayer; struct Tex; struct World; @@ -212,6 +213,7 @@ struct DepsgraphRelationBuilder void build_object_data_geometry_datablock(ID *obdata); void build_object_data_lamp(Object *object); void build_object_data_lightprobe(Object *object); + void build_object_data_speaker(Object *object); void build_object_parent(Object *object); void build_constraints(ID *id, eDepsNode_Type component_type, @@ -263,19 +265,17 @@ struct DepsgraphRelationBuilder void build_mask(Mask *mask); void build_movieclip(MovieClip *clip); void build_lightprobe(LightProbe *probe); + void build_speaker(Speaker *speaker); void build_nested_datablock(ID *owner, ID *id); void build_nested_nodetree(ID *owner, bNodeTree *ntree); 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/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc index b940fc3035e..f069c63f138 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc @@ -95,7 +95,7 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la * do NULL-pointer check of the base, so it's fine to pass original one. */ const int base_flag = (graph_->mode == DAG_EVAL_VIEWPORT) ? - BASE_VISIBLE_VIEWPORT : BASE_VISIBLE_RENDER; + BASE_ENABLED_VIEWPORT : BASE_ENABLED_RENDER; LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) { if (base->flag & base_flag) { build_object(base, base->object); diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 16427d3eb59..ddc6e44ee1b 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -100,6 +100,7 @@ Depsgraph::Depsgraph(Scene *scene, entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags"); debug_flags = G.debug; memset(id_type_updated, 0, sizeof(id_type_updated)); + memset(physics_relations, 0, sizeof(physics_relations)); } Depsgraph::~Depsgraph() @@ -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..804fd1b36c2 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -45,6 +45,7 @@ #include "BLI_threads.h" /* for SpinLock */ #include "DEG_depsgraph.h" +#include "DEG_depsgraph_physics.h" #include "intern/depsgraph_types.h" @@ -226,6 +227,10 @@ struct Depsgraph { /* NITE: Corresponds to G_DEBUG_DEPSGRAPH_* flags. */ int debug_flags; string debug_name; + + /* Cached list of colliders/effectors for collections and the scene + * created along with relations, for fast lookup during evaluation. */ + GHash *physics_relations[DEG_PHYSICS_RELATIONS_NUM]; }; } // namespace DEG diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index c39f6222a13..fccb5808711 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -43,12 +43,8 @@ extern "C" { #include "DNA_cachefile_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_object_force_types.h" #include "BKE_main.h" -#include "BKE_collision.h" -#include "BKE_effect.h" -#include "BKE_modifier.h" #include "BKE_scene.h" } /* extern "C" */ @@ -322,75 +318,3 @@ 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); - - 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 *object, - EffectorWeights *effector_weights, - bool add_absorption, - int skip_forcefield, - const char *name) -{ - ListBase *effectors = pdInitEffectors(NULL, 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); - /* 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, - object, - NULL, - eModifierType_Collision, - NULL, - true, - "Force Absorption"); - } - } - } - pdEndEffectors(&effectors); -} diff --git a/source/blender/depsgraph/intern/depsgraph_intern.h b/source/blender/depsgraph/intern/depsgraph_intern.h index 526cecde457..aa67226c47e 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,10 @@ 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); +struct ListBase *deg_build_collision_relations(Depsgraph *graph, struct Collection *collection, unsigned int modifier_type); +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..e542e0c48ae --- /dev/null +++ b/source/blender/depsgraph/intern/depsgraph_physics.cc @@ -0,0 +1,242 @@ +/* + * ***** 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" +#include "BLI_listbase.h" + +extern "C" { +#include "BKE_collision.h" +#include "BKE_effect.h" +#include "BKE_modifier.h" +} /* extern "C" */ + +#include "DNA_group_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force_types.h" + +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_physics.h" +#include "DEG_depsgraph_query.h" + +#include "depsgraph.h" +#include "depsgraph_intern.h" + +/*********************** Evaluation Query API *************************/ + +static ePhysicsRelationType modifier_to_relation_type(unsigned int modifier_type) +{ + switch (modifier_type) { + case eModifierType_Collision: + return DEG_PHYSICS_COLLISION; + case eModifierType_Smoke: + return DEG_PHYSICS_SMOKE_COLLISION; + case eModifierType_DynamicPaint: + return DEG_PHYSICS_DYNAMIC_BRUSH; + } + + BLI_assert(!"Unknown collision modifier type"); + return DEG_PHYSICS_RELATIONS_NUM; +} + +ListBase *DEG_get_effector_relations(const Depsgraph *graph, + Collection *collection) +{ + const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); + if (deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR] == NULL) { + return NULL; + } + + ID *collection_orig = DEG_get_original_id(&collection->id); + return (ListBase *)BLI_ghash_lookup(deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR], collection_orig); +} + +ListBase *DEG_get_collision_relations(const Depsgraph *graph, + Collection *collection, + unsigned int modifier_type) +{ + const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(graph); + const ePhysicsRelationType type = modifier_to_relation_type(modifier_type); + if (deg_graph->physics_relations[type] == NULL) { + return NULL; + } + + ID *collection_orig = DEG_get_original_id(&collection->id); + return (ListBase *)BLI_ghash_lookup(deg_graph->physics_relations[type], collection_orig); +} + +/********************** Depsgraph Building API ************************/ + +void DEG_add_collision_relations(DepsNodeHandle *handle, + Object *object, + Collection *collection, + unsigned int modifier_type, + DEG_CollobjFilterFunction fn, + const char *name) +{ + Depsgraph *depsgraph = DEG_get_graph_from_handle(handle); + DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph; + ListBase *relations = deg_build_collision_relations(deg_graph, collection, modifier_type); + + 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); + } + } + } +} + +void DEG_add_forcefield_relations(DepsNodeHandle *handle, + Object *object, + EffectorWeights *effector_weights, + bool add_absorption, + int skip_forcefield, + const char *name) +{ + Depsgraph *depsgraph = DEG_get_graph_from_handle(handle); + 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, relation->ob, DEG_OB_COMP_GEOMETRY, name); + } + if (relation->pd->forcefield == PFIELD_SMOKEFLOW && relation->pd->f_source) { + DEG_add_object_relation(handle, + relation->pd->f_source, + DEG_OB_COMP_TRANSFORM, + "Smoke Force Domain"); + DEG_add_object_relation(handle, + relation->pd->f_source, + DEG_OB_COMP_GEOMETRY, + "Smoke Force Domain"); + } + if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) { + DEG_add_collision_relations(handle, + object, + NULL, + eModifierType_Collision, + NULL, + "Force Absorption"); + } + } + } +} + +/**************************** Internal API ****************************/ + +namespace DEG +{ + +ListBase *deg_build_effector_relations(Depsgraph *graph, + Collection *collection) +{ + GHash *hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR]; + if (hash == NULL) { + graph->physics_relations[DEG_PHYSICS_EFFECTOR] = BLI_ghash_ptr_new("Depsgraph physics relations hash"); + hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR]; + } + + ListBase *relations = reinterpret_cast<ListBase*>(BLI_ghash_lookup(hash, collection)); + if (relations == NULL) { + ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph); + relations = BKE_effector_relations_create(depsgraph, graph->view_layer, collection); + BLI_ghash_insert(hash, &collection->id, relations); + } + + return relations; +} + +ListBase *deg_build_collision_relations(Depsgraph *graph, + Collection *collection, + unsigned int modifier_type) +{ + const ePhysicsRelationType type = modifier_to_relation_type(modifier_type); + GHash *hash = graph->physics_relations[type]; + if (hash == NULL) { + graph->physics_relations[type] = BLI_ghash_ptr_new("Depsgraph physics relations hash"); + hash = graph->physics_relations[type]; + } + + ListBase *relations = reinterpret_cast<ListBase*>(BLI_ghash_lookup(hash, collection)); + if (relations == NULL) { + ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph); + relations = BKE_collision_relations_create(depsgraph, collection, modifier_type); + BLI_ghash_insert(hash, &collection->id, 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) +{ + for (int i = 0; i < DEG_PHYSICS_RELATIONS_NUM; i++) { + if (graph->physics_relations[i]) { + ePhysicsRelationType type = (ePhysicsRelationType)i; + + switch (type) { + case DEG_PHYSICS_EFFECTOR: + BLI_ghash_free(graph->physics_relations[i], NULL, free_effector_relations); + break; + case DEG_PHYSICS_COLLISION: + case DEG_PHYSICS_SMOKE_COLLISION: + case DEG_PHYSICS_DYNAMIC_BRUSH: + BLI_ghash_free(graph->physics_relations[i], NULL, free_collision_relations); + break; + case DEG_PHYSICS_RELATIONS_NUM: + break; + } + + graph->physics_relations[i] = NULL; + } + } +} + +} diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc index 1dd6f8b6a0b..a9492b48a1b 100644 --- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc +++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc @@ -139,7 +139,7 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter) temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROMDUPLI; /* Duplicated elements shouldn't care whether their original collection is visible or not. */ - temp_dupli_object->base_flag |= BASE_VISIBLED; + temp_dupli_object->base_flag |= BASE_VISIBLE; if (BKE_object_is_visible(temp_dupli_object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) { continue; diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc index 9b1733bae8e..6d7f86581d9 100644 --- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc +++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc @@ -141,6 +141,7 @@ const char *operationCodeAsString(eDepsOperation_Code opcode) STRINGIFY_OPCODE(GEOMETRY_SHAPEKEY); /* Object data. */ STRINGIFY_OPCODE(LIGHT_PROBE_EVAL); + STRINGIFY_OPCODE(SPEAKER_EVAL); /* Pose. */ STRINGIFY_OPCODE(POSE_INIT); STRINGIFY_OPCODE(POSE_INIT_IK); diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h index c6eb0d57bac..6577e742266 100644 --- a/source/blender/depsgraph/intern/depsgraph_types.h +++ b/source/blender/depsgraph/intern/depsgraph_types.h @@ -211,6 +211,7 @@ typedef enum eDepsOperation_Code { /* Object data. ------------------------------------- */ DEG_OPCODE_LIGHT_PROBE_EVAL, + DEG_OPCODE_SPEAKER_EVAL, /* Pose. -------------------------------------------- */ /* Init pose, clear flags, etc. */ |