Depsgraph: Remove unused operation code
[blender.git] / source / blender / depsgraph / intern / depsgraph_physics.cc
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2018 Blender Foundation.
19  * All rights reserved.
20  *
21  * ***** END GPL LICENSE BLOCK *****
22  */
23
24 /** \file blender/depsgraph/intern/depsgraph_physics.cc
25  *  \ingroup depsgraph
26  *
27  * Physics utilities for effectors and collision.
28  */
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_compiler_compat.h"
33 #include "BLI_ghash.h"
34 #include "BLI_listbase.h"
35
36 extern "C" {
37 #include "BKE_collision.h"
38 #include "BKE_effect.h"
39 #include "BKE_modifier.h"
40 } /* extern "C" */
41
42 #include "DNA_collection_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_object_force_types.h"
45
46 #include "DEG_depsgraph_build.h"
47 #include "DEG_depsgraph_physics.h"
48 #include "DEG_depsgraph_query.h"
49
50 #include "depsgraph.h"
51 #include "depsgraph_intern.h"
52
53 /*************************** Evaluation Query API *****************************/
54
55 static ePhysicsRelationType modifier_to_relation_type(
56         unsigned int modifier_type)
57 {
58         switch (modifier_type) {
59                 case eModifierType_Collision:
60                         return DEG_PHYSICS_COLLISION;
61                 case eModifierType_Smoke:
62                         return DEG_PHYSICS_SMOKE_COLLISION;
63                 case eModifierType_DynamicPaint:
64                         return DEG_PHYSICS_DYNAMIC_BRUSH;
65         }
66
67         BLI_assert(!"Unknown collision modifier type");
68         return DEG_PHYSICS_RELATIONS_NUM;
69 }
70
71 ListBase *DEG_get_effector_relations(const Depsgraph *graph,
72                                      Collection *collection)
73 {
74         const DEG::Depsgraph *deg_graph =
75                 reinterpret_cast<const DEG::Depsgraph *>(graph);
76         if (deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR] == NULL) {
77                 return NULL;
78         }
79
80         ID *collection_orig = DEG_get_original_id(&collection->id);
81         return (ListBase *)BLI_ghash_lookup(
82                 deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR],
83                 collection_orig);
84 }
85
86 ListBase *DEG_get_collision_relations(const Depsgraph *graph,
87                                       Collection *collection,
88                                       unsigned int modifier_type)
89 {
90         const DEG::Depsgraph *deg_graph =
91                 reinterpret_cast<const DEG::Depsgraph *>(graph);
92         const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
93         if (deg_graph->physics_relations[type] == NULL) {
94                 return NULL;
95         }
96         ID *collection_orig = DEG_get_original_id(&collection->id);
97         return (ListBase *)BLI_ghash_lookup(
98                 deg_graph->physics_relations[type],
99                 collection_orig);
100 }
101
102 /********************** Depsgraph Building API ************************/
103
104 void DEG_add_collision_relations(DepsNodeHandle *handle,
105                                  Object *object,
106                                  Collection *collection,
107                                  unsigned int modifier_type,
108                                  DEG_CollobjFilterFunction filter_function,
109                                  const char *name)
110 {
111         Depsgraph *depsgraph = DEG_get_graph_from_handle(handle);
112         DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph;
113         ListBase *relations = deg_build_collision_relations(
114                 deg_graph, collection, modifier_type);
115         LISTBASE_FOREACH (CollisionRelation *, relation, relations) {
116                 Object *ob1 = relation->ob;
117                 if (ob1 == object) {
118                         continue;
119                 }
120                 if (filter_function == NULL ||
121                     filter_function(
122                             ob1,
123                             modifiers_findByType(ob1, (ModifierType)modifier_type)))
124                 {
125                         DEG_add_object_relation(handle, ob1, DEG_OB_COMP_TRANSFORM, name);
126                         DEG_add_object_relation(handle, ob1, DEG_OB_COMP_GEOMETRY, name);
127                 }
128         }
129 }
130
131 void DEG_add_forcefield_relations(DepsNodeHandle *handle,
132                                   Object *object,
133                                   EffectorWeights *effector_weights,
134                                   bool add_absorption,
135                                   int skip_forcefield,
136                                   const char *name)
137 {
138         Depsgraph *depsgraph = DEG_get_graph_from_handle(handle);
139         DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph;
140         ListBase *relations =
141                 deg_build_effector_relations(deg_graph, effector_weights->group);
142         LISTBASE_FOREACH (EffectorRelation *, relation, relations) {
143                 if (relation->ob == object) {
144                         continue;
145                 }
146                 if (relation->pd->forcefield == skip_forcefield) {
147                         continue;
148                 }
149                 DEG_add_object_relation(
150                         handle, relation->ob, DEG_OB_COMP_TRANSFORM, name);
151                 if (relation->psys) {
152                         /* TODO(sergey): Consider going more granular with more dedicated
153                          * particle system operation.
154                          */
155                         DEG_add_object_relation(
156                                 handle, relation->ob, DEG_OB_COMP_GEOMETRY, name);
157                 }
158                 if (relation->pd->forcefield == PFIELD_SMOKEFLOW &&
159                     relation->pd->f_source != NULL)
160                 {
161                         DEG_add_object_relation(handle,
162                                                 relation->pd->f_source,
163                                                 DEG_OB_COMP_TRANSFORM,
164                                                 "Smoke Force Domain");
165                         DEG_add_object_relation(handle,
166                                                 relation->pd->f_source,
167                                                 DEG_OB_COMP_GEOMETRY,
168                                                 "Smoke Force Domain");
169                 }
170                 if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
171                         DEG_add_collision_relations(handle,
172                                                     object,
173                                                     NULL,
174                                                     eModifierType_Collision,
175                                                     NULL,
176                                                     "Force Absorption");
177                 }
178         }
179 }
180
181 /******************************** Internal API ********************************/
182
183 namespace DEG
184 {
185
186 ListBase *deg_build_effector_relations(Depsgraph *graph,
187                                        Collection *collection)
188 {
189         GHash *hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR];
190         if (hash == NULL) {
191                 graph->physics_relations[DEG_PHYSICS_EFFECTOR] =
192                         BLI_ghash_ptr_new("Depsgraph physics relations hash");
193                 hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR];
194         }
195         ListBase *relations =
196                 reinterpret_cast<ListBase*>(BLI_ghash_lookup(hash, collection));
197         if (relations == NULL) {
198                 ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph);
199                 relations = BKE_effector_relations_create(
200                         depsgraph, graph->view_layer, collection);
201                 BLI_ghash_insert(hash, &collection->id, relations);
202         }
203         return relations;
204 }
205
206 ListBase *deg_build_collision_relations(Depsgraph *graph,
207                                         Collection *collection,
208                                         unsigned int modifier_type)
209 {
210         const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
211         GHash *hash = graph->physics_relations[type];
212         if (hash == NULL) {
213                 graph->physics_relations[type] =
214                         BLI_ghash_ptr_new("Depsgraph physics relations hash");
215                 hash = graph->physics_relations[type];
216         }
217         ListBase *relations =
218                 reinterpret_cast<ListBase*>(BLI_ghash_lookup(hash, collection));
219         if (relations == NULL) {
220                 ::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph);
221                 relations = BKE_collision_relations_create(
222                         depsgraph, collection, modifier_type);
223                 BLI_ghash_insert(hash, &collection->id, relations);
224         }
225         return relations;
226 }
227
228 namespace {
229
230 void free_effector_relations(void *value)
231 {
232         BKE_effector_relations_free(reinterpret_cast<ListBase*>(value));
233 }
234
235 void free_collision_relations(void *value)
236 {
237         BKE_collision_relations_free(reinterpret_cast<ListBase*>(value));
238 }
239
240 }  // namespace
241
242 void deg_clear_physics_relations(Depsgraph *graph)
243 {
244         for (int i = 0; i < DEG_PHYSICS_RELATIONS_NUM; i++) {
245                 if (graph->physics_relations[i]) {
246                         ePhysicsRelationType type = (ePhysicsRelationType)i;
247
248                         switch (type) {
249                                 case DEG_PHYSICS_EFFECTOR:
250                                         BLI_ghash_free(graph->physics_relations[i],
251                                                        NULL,
252                                                        free_effector_relations);
253                                         break;
254                                 case DEG_PHYSICS_COLLISION:
255                                 case DEG_PHYSICS_SMOKE_COLLISION:
256                                 case DEG_PHYSICS_DYNAMIC_BRUSH:
257                                         BLI_ghash_free(graph->physics_relations[i],
258                                                        NULL,
259                                                        free_collision_relations);
260                                         break;
261                                 case DEG_PHYSICS_RELATIONS_NUM:
262                                         break;
263                         }
264                         graph->physics_relations[i] = NULL;
265                 }
266         }
267 }
268
269 }