2018-06-21 19:45:39 +02:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup depsgraph
|
2018-06-21 19:45:39 +02:00
|
|
|
*
|
|
|
|
|
* Physics utilities for effectors and collision.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-01-31 12:56:40 +01:00
|
|
|
#include "intern/depsgraph_physics.h"
|
|
|
|
|
|
2018-06-21 19:45:39 +02:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_compiler_compat.h"
|
|
|
|
|
#include "BLI_ghash.h"
|
2018-06-25 16:04:56 +02:00
|
|
|
#include "BLI_listbase.h"
|
2018-06-21 19:45:39 +02:00
|
|
|
|
|
|
|
|
extern "C" {
|
2018-06-22 14:42:03 +02:00
|
|
|
#include "BKE_collision.h"
|
2018-06-21 19:45:39 +02:00
|
|
|
#include "BKE_effect.h"
|
2018-06-25 16:04:56 +02:00
|
|
|
#include "BKE_modifier.h"
|
2018-06-21 19:45:39 +02:00
|
|
|
} /* extern "C" */
|
|
|
|
|
|
2018-08-29 15:32:50 +02:00
|
|
|
#include "DNA_collection_types.h"
|
2018-06-25 14:21:15 +02:00
|
|
|
#include "DNA_object_types.h"
|
2018-06-25 16:04:56 +02:00
|
|
|
#include "DNA_object_force_types.h"
|
2018-06-21 19:45:39 +02:00
|
|
|
|
2018-06-25 16:04:56 +02:00
|
|
|
#include "DEG_depsgraph_build.h"
|
2018-06-21 19:45:39 +02:00
|
|
|
#include "DEG_depsgraph_physics.h"
|
2018-06-25 14:21:15 +02:00
|
|
|
#include "DEG_depsgraph_query.h"
|
2018-06-21 19:45:39 +02:00
|
|
|
|
|
|
|
|
#include "depsgraph.h"
|
|
|
|
|
|
2018-11-13 17:21:41 +01:00
|
|
|
/*************************** Evaluation Query API *****************************/
|
2018-06-25 16:04:56 +02:00
|
|
|
|
2018-11-13 17:21:41 +01:00
|
|
|
static ePhysicsRelationType modifier_to_relation_type(
|
|
|
|
|
unsigned int modifier_type)
|
2018-06-25 16:04:56 +02:00
|
|
|
{
|
|
|
|
|
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;
|
2018-06-26 08:35:35 +02:00
|
|
|
}
|
2018-06-25 16:04:56 +02:00
|
|
|
|
|
|
|
|
BLI_assert(!"Unknown collision modifier type");
|
|
|
|
|
return DEG_PHYSICS_RELATIONS_NUM;
|
|
|
|
|
}
|
2018-06-21 19:45:39 +02:00
|
|
|
|
|
|
|
|
ListBase *DEG_get_effector_relations(const Depsgraph *graph,
|
|
|
|
|
Collection *collection)
|
|
|
|
|
{
|
2018-11-13 17:21:41 +01:00
|
|
|
const DEG::Depsgraph *deg_graph =
|
|
|
|
|
reinterpret_cast<const DEG::Depsgraph *>(graph);
|
2018-06-25 16:04:56 +02:00
|
|
|
if (deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR] == NULL) {
|
2018-06-21 19:45:39 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-25 14:21:15 +02:00
|
|
|
ID *collection_orig = DEG_get_original_id(&collection->id);
|
2018-11-13 17:21:41 +01:00
|
|
|
return (ListBase *)BLI_ghash_lookup(
|
|
|
|
|
deg_graph->physics_relations[DEG_PHYSICS_EFFECTOR],
|
|
|
|
|
collection_orig);
|
2018-06-21 19:45:39 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-22 14:42:03 +02:00
|
|
|
ListBase *DEG_get_collision_relations(const Depsgraph *graph,
|
2018-06-25 16:04:56 +02:00
|
|
|
Collection *collection,
|
|
|
|
|
unsigned int modifier_type)
|
2018-06-22 14:42:03 +02:00
|
|
|
{
|
2018-11-13 17:21:41 +01:00
|
|
|
const DEG::Depsgraph *deg_graph =
|
|
|
|
|
reinterpret_cast<const DEG::Depsgraph *>(graph);
|
2018-06-25 16:04:56 +02:00
|
|
|
const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
|
|
|
|
|
if (deg_graph->physics_relations[type] == NULL) {
|
2018-06-22 14:42:03 +02:00
|
|
|
return NULL;
|
|
|
|
|
}
|
2018-06-25 14:21:15 +02:00
|
|
|
ID *collection_orig = DEG_get_original_id(&collection->id);
|
2018-11-13 17:21:41 +01:00
|
|
|
return (ListBase *)BLI_ghash_lookup(
|
|
|
|
|
deg_graph->physics_relations[type],
|
|
|
|
|
collection_orig);
|
2018-06-22 14:42:03 +02:00
|
|
|
}
|
|
|
|
|
|
2018-06-25 16:04:56 +02:00
|
|
|
/********************** Depsgraph Building API ************************/
|
|
|
|
|
|
|
|
|
|
void DEG_add_collision_relations(DepsNodeHandle *handle,
|
|
|
|
|
Object *object,
|
|
|
|
|
Collection *collection,
|
|
|
|
|
unsigned int modifier_type,
|
2018-11-13 17:21:41 +01:00
|
|
|
DEG_CollobjFilterFunction filter_function,
|
2018-06-25 16:04:56 +02:00
|
|
|
const char *name)
|
2018-06-22 14:42:03 +02:00
|
|
|
{
|
2018-06-25 16:04:56 +02:00
|
|
|
Depsgraph *depsgraph = DEG_get_graph_from_handle(handle);
|
|
|
|
|
DEG::Depsgraph *deg_graph = (DEG::Depsgraph *)depsgraph;
|
2019-01-31 12:56:40 +01:00
|
|
|
ListBase *relations = build_collision_relations(
|
2018-11-13 17:21:41 +01:00
|
|
|
deg_graph, collection, modifier_type);
|
2018-06-25 16:04:56 +02:00
|
|
|
LISTBASE_FOREACH (CollisionRelation *, relation, relations) {
|
|
|
|
|
Object *ob1 = relation->ob;
|
2018-11-13 17:21:41 +01:00
|
|
|
if (ob1 == object) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (filter_function == NULL ||
|
|
|
|
|
filter_function(
|
|
|
|
|
ob1,
|
|
|
|
|
modifiers_findByType(ob1, (ModifierType)modifier_type)))
|
|
|
|
|
{
|
2018-11-14 11:24:54 +01:00
|
|
|
DEG_add_object_pointcache_relation(
|
|
|
|
|
handle, ob1, DEG_OB_COMP_TRANSFORM, name);
|
|
|
|
|
DEG_add_object_pointcache_relation(
|
|
|
|
|
handle, ob1, DEG_OB_COMP_GEOMETRY, name);
|
2018-06-25 16:04:56 +02:00
|
|
|
}
|
2018-06-22 14:42:03 +02:00
|
|
|
}
|
2018-06-25 16:04:56 +02:00
|
|
|
}
|
2018-06-22 14:42:03 +02:00
|
|
|
|
2018-06-25 16:04:56 +02:00
|
|
|
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;
|
2018-11-13 17:21:41 +01:00
|
|
|
ListBase *relations =
|
2019-01-31 12:56:40 +01:00
|
|
|
build_effector_relations(deg_graph, effector_weights->group);
|
2018-06-25 16:04:56 +02:00
|
|
|
LISTBASE_FOREACH (EffectorRelation *, relation, relations) {
|
2018-11-13 17:21:41 +01:00
|
|
|
if (relation->ob == object) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (relation->pd->forcefield == skip_forcefield) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2019-01-22 15:17:34 +01:00
|
|
|
|
|
|
|
|
/* Relation to forcefield object, optionally including geometry.
|
|
|
|
|
* Use special point cache relations for automatic cache clearing. */
|
2018-11-14 11:24:54 +01:00
|
|
|
DEG_add_object_pointcache_relation(
|
2018-11-13 17:21:41 +01:00
|
|
|
handle, relation->ob, DEG_OB_COMP_TRANSFORM, name);
|
2019-01-22 15:17:34 +01:00
|
|
|
|
|
|
|
|
if (relation->psys ||
|
2019-01-11 13:13:55 +01:00
|
|
|
ELEM(relation->pd->shape, PFIELD_SHAPE_SURFACE, PFIELD_SHAPE_POINTS) ||
|
|
|
|
|
relation->pd->forcefield == PFIELD_GUIDE)
|
2019-01-22 15:17:34 +01:00
|
|
|
{
|
2018-11-13 19:31:44 +01:00
|
|
|
/* TODO(sergey): Consider going more granular with more dedicated
|
2018-11-14 11:24:54 +01:00
|
|
|
* particle system operation. */
|
|
|
|
|
DEG_add_object_pointcache_relation(
|
2018-11-13 17:21:41 +01:00
|
|
|
handle, relation->ob, DEG_OB_COMP_GEOMETRY, name);
|
|
|
|
|
}
|
2019-01-22 15:17:34 +01:00
|
|
|
|
|
|
|
|
/* Smoke flow relations. */
|
2018-11-13 17:21:41 +01:00
|
|
|
if (relation->pd->forcefield == PFIELD_SMOKEFLOW &&
|
|
|
|
|
relation->pd->f_source != NULL)
|
|
|
|
|
{
|
2018-11-14 11:24:54 +01:00
|
|
|
DEG_add_object_pointcache_relation(handle,
|
|
|
|
|
relation->pd->f_source,
|
|
|
|
|
DEG_OB_COMP_TRANSFORM,
|
|
|
|
|
"Smoke Force Domain");
|
|
|
|
|
DEG_add_object_pointcache_relation(handle,
|
|
|
|
|
relation->pd->f_source,
|
|
|
|
|
DEG_OB_COMP_GEOMETRY,
|
|
|
|
|
"Smoke Force Domain");
|
2018-11-13 17:21:41 +01:00
|
|
|
}
|
2019-01-22 15:17:34 +01:00
|
|
|
|
|
|
|
|
/* Absorption forces need collision relation. */
|
2018-11-13 17:21:41 +01:00
|
|
|
if (add_absorption && (relation->pd->flag & PFIELD_VISIBILITY)) {
|
|
|
|
|
DEG_add_collision_relations(handle,
|
|
|
|
|
object,
|
|
|
|
|
NULL,
|
|
|
|
|
eModifierType_Collision,
|
|
|
|
|
NULL,
|
|
|
|
|
"Force Absorption");
|
2018-06-25 16:04:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-06-22 14:42:03 +02:00
|
|
|
}
|
|
|
|
|
|
2018-11-13 17:21:41 +01:00
|
|
|
/******************************** Internal API ********************************/
|
2018-06-21 19:45:39 +02:00
|
|
|
|
|
|
|
|
namespace DEG
|
|
|
|
|
{
|
|
|
|
|
|
2019-01-31 12:56:40 +01:00
|
|
|
ListBase *build_effector_relations(Depsgraph *graph, Collection *collection)
|
2018-06-21 19:45:39 +02:00
|
|
|
{
|
2018-06-25 16:04:56 +02:00
|
|
|
GHash *hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR];
|
|
|
|
|
if (hash == NULL) {
|
2018-11-13 17:21:41 +01:00
|
|
|
graph->physics_relations[DEG_PHYSICS_EFFECTOR] =
|
|
|
|
|
BLI_ghash_ptr_new("Depsgraph physics relations hash");
|
2018-06-25 16:04:56 +02:00
|
|
|
hash = graph->physics_relations[DEG_PHYSICS_EFFECTOR];
|
2018-06-21 19:45:39 +02:00
|
|
|
}
|
2018-11-13 17:21:41 +01:00
|
|
|
ListBase *relations =
|
|
|
|
|
reinterpret_cast<ListBase*>(BLI_ghash_lookup(hash, collection));
|
2018-06-21 19:45:39 +02:00
|
|
|
if (relations == NULL) {
|
|
|
|
|
::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph);
|
2018-11-13 17:21:41 +01:00
|
|
|
relations = BKE_effector_relations_create(
|
|
|
|
|
depsgraph, graph->view_layer, collection);
|
2018-06-25 14:21:15 +02:00
|
|
|
BLI_ghash_insert(hash, &collection->id, relations);
|
2018-06-21 19:45:39 +02:00
|
|
|
}
|
|
|
|
|
return relations;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 12:56:40 +01:00
|
|
|
ListBase *build_collision_relations(Depsgraph *graph,
|
|
|
|
|
Collection *collection,
|
|
|
|
|
unsigned int modifier_type)
|
2018-06-22 14:42:03 +02:00
|
|
|
{
|
2018-06-25 16:04:56 +02:00
|
|
|
const ePhysicsRelationType type = modifier_to_relation_type(modifier_type);
|
|
|
|
|
GHash *hash = graph->physics_relations[type];
|
|
|
|
|
if (hash == NULL) {
|
2018-11-13 17:21:41 +01:00
|
|
|
graph->physics_relations[type] =
|
|
|
|
|
BLI_ghash_ptr_new("Depsgraph physics relations hash");
|
2018-06-25 16:04:56 +02:00
|
|
|
hash = graph->physics_relations[type];
|
2018-06-22 14:42:03 +02:00
|
|
|
}
|
2018-11-13 17:21:41 +01:00
|
|
|
ListBase *relations =
|
|
|
|
|
reinterpret_cast<ListBase*>(BLI_ghash_lookup(hash, collection));
|
2018-06-22 14:42:03 +02:00
|
|
|
if (relations == NULL) {
|
|
|
|
|
::Depsgraph *depsgraph = reinterpret_cast<::Depsgraph*>(graph);
|
2018-11-13 17:21:41 +01:00
|
|
|
relations = BKE_collision_relations_create(
|
|
|
|
|
depsgraph, collection, modifier_type);
|
2018-06-25 14:21:15 +02:00
|
|
|
BLI_ghash_insert(hash, &collection->id, relations);
|
2018-06-22 14:42:03 +02:00
|
|
|
}
|
|
|
|
|
return relations;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 17:21:41 +01:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
void free_effector_relations(void *value)
|
2018-06-21 19:45:39 +02:00
|
|
|
{
|
|
|
|
|
BKE_effector_relations_free(reinterpret_cast<ListBase*>(value));
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 17:21:41 +01:00
|
|
|
void free_collision_relations(void *value)
|
2018-06-22 14:42:03 +02:00
|
|
|
{
|
|
|
|
|
BKE_collision_relations_free(reinterpret_cast<ListBase*>(value));
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 17:21:41 +01:00
|
|
|
} // namespace
|
|
|
|
|
|
2019-01-31 12:56:40 +01:00
|
|
|
void clear_physics_relations(Depsgraph *graph)
|
2018-06-21 19:45:39 +02:00
|
|
|
{
|
2018-06-25 16:04:56 +02:00
|
|
|
for (int i = 0; i < DEG_PHYSICS_RELATIONS_NUM; i++) {
|
|
|
|
|
if (graph->physics_relations[i]) {
|
2019-01-31 12:56:40 +01:00
|
|
|
const ePhysicsRelationType type = (ePhysicsRelationType)i;
|
2018-06-25 16:04:56 +02:00
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case DEG_PHYSICS_EFFECTOR:
|
2018-11-13 17:21:41 +01:00
|
|
|
BLI_ghash_free(graph->physics_relations[i],
|
|
|
|
|
NULL,
|
|
|
|
|
free_effector_relations);
|
2018-06-25 16:04:56 +02:00
|
|
|
break;
|
|
|
|
|
case DEG_PHYSICS_COLLISION:
|
|
|
|
|
case DEG_PHYSICS_SMOKE_COLLISION:
|
|
|
|
|
case DEG_PHYSICS_DYNAMIC_BRUSH:
|
2018-11-13 17:21:41 +01:00
|
|
|
BLI_ghash_free(graph->physics_relations[i],
|
|
|
|
|
NULL,
|
|
|
|
|
free_collision_relations);
|
2018-06-25 16:04:56 +02:00
|
|
|
break;
|
|
|
|
|
case DEG_PHYSICS_RELATIONS_NUM:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
graph->physics_relations[i] = NULL;
|
|
|
|
|
}
|
2018-06-21 19:45:39 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|