Blender  V3.3
depsgraph_physics.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2018 Blender Foundation. All rights reserved. */
3 
11 
12 #include "MEM_guardedalloc.h"
13 
14 #include "BLI_compiler_compat.h"
15 #include "BLI_listbase.h"
16 
17 #include "BKE_collision.h"
18 #include "BKE_effect.h"
19 #include "BKE_modifier.h"
20 
21 #include "DNA_collection_types.h"
22 #include "DNA_object_force_types.h"
23 #include "DNA_object_types.h"
24 
25 #include "DEG_depsgraph_build.h"
26 #include "DEG_depsgraph_physics.h"
27 #include "DEG_depsgraph_query.h"
28 
29 #include "depsgraph.h"
30 
31 namespace deg = blender::deg;
32 
33 /*************************** Evaluation Query API *****************************/
34 
35 static ePhysicsRelationType modifier_to_relation_type(unsigned int modifier_type)
36 {
37  switch (modifier_type) {
39  return DEG_PHYSICS_COLLISION;
44  }
45 
46  BLI_assert_msg(0, "Unknown collision modifier type");
48 }
49 /* Get ID from an ID type object, in a safe manner. This means that object can be nullptr,
50  * in which case the function returns nullptr.
51  */
52 template<class T> static ID *object_id_safe(T *object)
53 {
54  if (object == nullptr) {
55  return nullptr;
56  }
57  return &object->id;
58 }
59 
61 {
62  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
64  if (hash == nullptr) {
65  return nullptr;
66  }
67  /* NOTE: nullptr is a valid lookup key here as it means that the relation is not bound to a
68  * specific collection. */
69  ID *collection_orig = DEG_get_original_id(object_id_safe(collection));
70  return hash->lookup_default(collection_orig, nullptr);
71 }
72 
74  Collection *collection,
75  unsigned int modifier_type)
76 {
77  const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
80  if (hash == nullptr) {
81  return nullptr;
82  }
83  /* NOTE: nullptr is a valid lookup key here as it means that the relation is not bound to a
84  * specific collection. */
85  ID *collection_orig = DEG_get_original_id(object_id_safe(collection));
86  return hash->lookup_default(collection_orig, nullptr);
87 }
88 
89 /********************** Depsgraph Building API ************************/
90 
91 void DEG_add_collision_relations(DepsNodeHandle *handle,
92  Object *object,
93  Collection *collection,
94  unsigned int modifier_type,
95  DEG_CollobjFilterFunction filter_function,
96  const char *name)
97 {
99  deg::Depsgraph *deg_graph = (deg::Depsgraph *)depsgraph;
100  ListBase *relations = build_collision_relations(deg_graph, collection, modifier_type);
101  LISTBASE_FOREACH (CollisionRelation *, relation, relations) {
102  Object *ob1 = relation->ob;
103  if (ob1 == object) {
104  continue;
105  }
106  if (filter_function == nullptr ||
107  filter_function(ob1, BKE_modifiers_findby_type(ob1, (ModifierType)modifier_type))) {
110  }
111  }
112 }
113 
114 void DEG_add_forcefield_relations(DepsNodeHandle *handle,
115  Object *object,
116  EffectorWeights *effector_weights,
117  bool add_absorption,
118  int skip_forcefield,
119  const char *name)
120 {
122  deg::Depsgraph *deg_graph = (deg::Depsgraph *)depsgraph;
123  ListBase *relations = build_effector_relations(deg_graph, effector_weights->group);
124  LISTBASE_FOREACH (EffectorRelation *, relation, relations) {
125  if (relation->ob == object) {
126  continue;
127  }
128  if (relation->pd->forcefield == skip_forcefield) {
129  continue;
130  }
131 
132  /* Relation to forcefield object, optionally including geometry.
133  * Use special point cache relations for automatic cache clearing. */
134  DEG_add_object_pointcache_relation(handle, relation->ob, DEG_OB_COMP_TRANSFORM, name);
135 
136  if (relation->psys || ELEM(relation->pd->shape, PFIELD_SHAPE_SURFACE, PFIELD_SHAPE_POINTS) ||
137  relation->pd->forcefield == PFIELD_GUIDE) {
138  /* TODO(sergey): Consider going more granular with more dedicated
139  * particle system operation. */
140  DEG_add_object_pointcache_relation(handle, relation->ob, DEG_OB_COMP_GEOMETRY, name);
141  }
142 
143  /* Smoke flow relations. */
144  if (relation->pd->forcefield == PFIELD_FLUIDFLOW && relation->pd->f_source != nullptr) {
146  handle, relation->pd->f_source, DEG_OB_COMP_TRANSFORM, "Fluid Force Domain");
148  handle, relation->pd->f_source, DEG_OB_COMP_GEOMETRY, "Fluid Force Domain");
149  }
150 
151  /* Absorption forces need collision relation. */
152  if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
154  handle, object, nullptr, eModifierType_Collision, nullptr, "Force Absorption");
155  }
156  }
157 }
158 
159 /******************************** Internal API ********************************/
160 
161 namespace blender::deg {
162 
164 {
166  if (hash == nullptr) {
169  }
170  /* If collection is nullptr still use it as a key.
171  * In this case the BKE_effector_relations_create() will create relates for all bases in the
172  * view layer.
173  */
174  ID *collection_id = object_id_safe(collection);
175  return hash->lookup_or_add_cb(collection_id, [&]() {
176  ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph);
178  });
179 }
180 
182  Collection *collection,
183  unsigned int modifier_type)
184 {
185  const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
187  if (hash == nullptr) {
190  }
191  /* If collection is nullptr still use it as a key.
192  * In this case the BKE_collision_relations_create() will create relates for all bases in the
193  * view layer.
194  */
195  ID *collection_id = object_id_safe(collection);
196  return hash->lookup_or_add_cb(collection_id, [&]() {
197  ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph *>(graph);
198  return BKE_collision_relations_create(depsgraph, collection, modifier_type);
199  });
200 }
201 
203 {
204  for (int i = 0; i < DEG_PHYSICS_RELATIONS_NUM; i++) {
206  if (hash) {
208 
209  switch (type) {
211  for (ListBase *list : hash->values()) {
213  }
214  break;
218  for (ListBase *list : hash->values()) {
220  }
221  break;
223  break;
224  }
225  delete hash;
226  graph->physics_relations[i] = nullptr;
227  }
228  }
229 }
230 
231 } // namespace blender::deg
struct ListBase * BKE_collision_relations_create(struct Depsgraph *depsgraph, struct Collection *collection, unsigned int modifier_type)
Definition: collision.c:1247
void BKE_collision_relations_free(struct ListBase *relations)
Definition: collision.c:1267
struct ListBase * BKE_effector_relations_create(struct Depsgraph *depsgraph, struct ViewLayer *view_layer, struct Collection *collection)
Definition: effect.c:209
void BKE_effector_relations_free(struct ListBase *lb)
Definition: effect.c:247
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ DEG_OB_COMP_GEOMETRY
@ DEG_OB_COMP_TRANSFORM
void DEG_add_object_pointcache_relation(struct DepsNodeHandle *node_handle, struct Object *object, eDepsObjectComponentType component, const char *description)
struct Depsgraph * DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle)
ePhysicsRelationType
@ DEG_PHYSICS_DYNAMIC_BRUSH
@ DEG_PHYSICS_SMOKE_COLLISION
@ DEG_PHYSICS_COLLISION
@ DEG_PHYSICS_RELATIONS_NUM
@ DEG_PHYSICS_EFFECTOR
bool(* DEG_CollobjFilterFunction)(struct Object *obj, struct ModifierData *md)
struct ID * DEG_get_original_id(struct ID *id)
Object groups, one object can be in many groups at once.
ModifierType
@ eModifierType_Fluid
@ eModifierType_Collision
@ eModifierType_DynamicPaint
#define PFIELD_SHAPE_SURFACE
#define PFIELD_VISIBILITY
@ PFIELD_FLUIDFLOW
@ PFIELD_GUIDE
#define PFIELD_SHAPE_POINTS
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
Depsgraph * graph
const Depsgraph * depsgraph
ListBase * DEG_get_collision_relations(const Depsgraph *graph, Collection *collection, unsigned int modifier_type)
static ID * object_id_safe(T *object)
void DEG_add_collision_relations(DepsNodeHandle *handle, Object *object, Collection *collection, unsigned int modifier_type, DEG_CollobjFilterFunction filter_function, const char *name)
void DEG_add_forcefield_relations(DepsNodeHandle *handle, Object *object, EffectorWeights *effector_weights, bool add_absorption, int skip_forcefield, const char *name)
static ePhysicsRelationType modifier_to_relation_type(unsigned int modifier_type)
ListBase * DEG_get_effector_relations(const Depsgraph *graph, Collection *collection)
#define T
ListBase * build_collision_relations(Depsgraph *graph, Collection *collection, unsigned int modifier_type)
ListBase * build_effector_relations(Depsgraph *graph, Collection *collection)
void clear_physics_relations(Depsgraph *graph)
#define hash
Definition: noise.c:153
struct Collection * group
Definition: DNA_ID.h:368
Map< const ID *, ListBase * > * physics_relations[DEG_PHYSICS_RELATIONS_NUM]
Definition: depsgraph.h:165
ViewLayer * view_layer
Definition: depsgraph.h:129