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
path: root/source
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-06-08 16:41:41 +0300
committerJacques Lucke <jacques@blender.org>2020-06-08 16:49:17 +0300
commit6f96dfabe5cbf6966282decd2307ade9aacdeaee (patch)
tree01529fbad8453faf81a62877d03373eaf0b77b57 /source
parentbf4198cdaf7d4fa1a5f91526fb6bbe84d2fa2a37 (diff)
Simulations: initial simulation state and cache
The current particle state is stored in a `CustomData` instance and the cache is stored in `PointCache`. The current state exists on the copy-on-write copies of the simulation, while the cache only exists in the original data block. This patch implements a temporary trivial particle simulation that does not use the node system yet. It is used for testing and will be replaced soon. `PointCache` still has some limitations that need to be overcome using separate refactorings. For example, we need to be able to store the number of particles in the point cache. Also we need to change which attributes are stored for a particle system more dynamically than is currently possible afaik. Reviewers: brecht Differential Revision: https://developer.blender.org/D7836
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h4
-rw-r--r--source/blender/blenkernel/intern/pointcache.c99
-rw-r--r--source/blender/blenkernel/intern/pointcloud.c1
-rw-r--r--source/blender/blenkernel/intern/simulation.cc135
-rw-r--r--source/blender/blenloader/intern/readfile.c13
-rw-r--r--source/blender/blenloader/intern/writefile.c24
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc14
-rw-r--r--source/blender/editors/space_action/action_draw.c2
-rw-r--r--source/blender/makesdna/DNA_simulation_types.h40
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c14
-rw-r--r--source/blender/modifiers/intern/MOD_simulation.cc41
11 files changed, 380 insertions, 7 deletions
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 164783f4d14..2dd364f3c48 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -64,6 +64,7 @@ extern "C" {
#define PTCACHE_TYPE_SMOKE_HIGHRES 4
#define PTCACHE_TYPE_DYNAMICPAINT 5
#define PTCACHE_TYPE_RIGIDBODY 6
+#define PTCACHE_TYPE_SIM_PARTICLES 7
/* high bits reserved for flags that need to be stored in file */
#define PTCACHE_TYPEFLAG_COMPRESS (1 << 16)
@@ -84,10 +85,12 @@ struct ListBase;
struct Main;
struct Object;
struct ParticleKey;
+struct ParticleSimulationState;
struct ParticleSystem;
struct PointCache;
struct RigidBodyWorld;
struct Scene;
+struct Simulation;
struct SoftBody;
struct ViewLayer;
@@ -292,6 +295,7 @@ void BKE_ptcache_id_from_dynamicpaint(PTCacheID *pid,
struct Object *ob,
struct DynamicPaintSurface *surface);
void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, struct Object *ob, struct RigidBodyWorld *rbw);
+void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, struct ParticleSimulationState *state);
PTCacheID BKE_ptcache_id_find(struct Object *ob, struct Scene *scene, struct PointCache *cache);
void BKE_ptcache_ids_from_object(struct ListBase *lb,
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 5ee61667eca..17c41d992ed 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -41,6 +41,7 @@
#include "DNA_particle_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
+#include "DNA_simulation_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -1828,6 +1829,87 @@ void BKE_ptcache_id_from_rigidbody(PTCacheID *pid, Object *ob, RigidBodyWorld *r
pid->file_type = PTCACHE_FILE_PTCACHE;
}
+static int ptcache_sim_particle_totpoint(void *state_v, int UNUSED(cfra))
+{
+ ParticleSimulationState *state = (ParticleSimulationState *)state_v;
+ return state->tot_particles;
+}
+
+static void ptcache_sim_particle_error(void *UNUSED(state_v), const char *UNUSED(message))
+{
+}
+
+static int ptcache_sim_particle_write(int index, void *state_v, void **data, int UNUSED(cfra))
+{
+ ParticleSimulationState *state = (ParticleSimulationState *)state_v;
+
+ const float *positions = (const float *)CustomData_get_layer_named(
+ &state->attributes, CD_LOCATION, "Position");
+
+ PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, positions + (index * 3));
+
+ return 1;
+}
+static void ptcache_sim_particle_read(
+ int index, void *state_v, void **data, float UNUSED(cfra), float *UNUSED(old_data))
+{
+ ParticleSimulationState *state = (ParticleSimulationState *)state_v;
+
+ BLI_assert(index < state->tot_particles);
+ float *positions = (float *)CustomData_get_layer_named(
+ &state->attributes, CD_LOCATION, "Position");
+
+ PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, positions + (index * 3));
+}
+
+void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, ParticleSimulationState *state)
+{
+ memset(pid, 0, sizeof(PTCacheID));
+
+ ParticleSimulationState *state_orig;
+ if (state->head.orig_state != NULL) {
+ state_orig = (ParticleSimulationState *)state->head.orig_state;
+ }
+ else {
+ state_orig = state;
+ }
+
+ pid->calldata = state;
+ pid->type = PTCACHE_TYPE_SIM_PARTICLES;
+ pid->cache = state_orig->point_cache;
+ pid->cache_ptr = &state_orig->point_cache;
+ pid->ptcaches = &state_orig->ptcaches;
+ pid->totpoint = ptcache_sim_particle_totpoint;
+ pid->totwrite = ptcache_sim_particle_totpoint;
+ pid->error = ptcache_sim_particle_error;
+
+ pid->write_point = ptcache_sim_particle_write;
+ pid->read_point = ptcache_sim_particle_read;
+ pid->interpolate_point = NULL;
+
+ pid->write_stream = NULL;
+ pid->read_stream = NULL;
+
+ pid->write_openvdb_stream = NULL;
+ pid->read_openvdb_stream = NULL;
+
+ pid->write_extra_data = NULL;
+ pid->read_extra_data = NULL;
+ pid->interpolate_extra_data = NULL;
+
+ pid->write_header = NULL;
+ pid->read_header = NULL;
+
+ pid->data_types = 1 << BPHYS_DATA_LOCATION;
+ pid->info_types = 0;
+
+ pid->stack_index = 0;
+
+ pid->default_step = 1;
+ pid->max_step = 1;
+ pid->file_type = PTCACHE_FILE_PTCACHE;
+}
+
/**
* \param ob: Optional, may be NULL.
* \param scene: Optional may be NULL.
@@ -1926,6 +2008,23 @@ static bool foreach_object_modifier_ptcache(Object *object,
}
}
}
+ else if (md->type == eModifierType_Simulation) {
+ SimulationModifierData *smd = (SimulationModifierData *)md;
+ if (smd->simulation) {
+ LISTBASE_FOREACH (SimulationState *, state, &smd->simulation->states) {
+ switch ((eSimulationStateType)state->type) {
+ case SIM_STATE_TYPE_PARTICLES: {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+ BKE_ptcache_id_from_sim_particles(&pid, particle_state);
+ if (!callback(&pid, callback_user_data)) {
+ return false;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
}
return true;
}
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c
index e03888dcad7..df5d93beccb 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.c
@@ -192,6 +192,7 @@ void BKE_pointcloud_update_customdata_pointers(PointCloud *pointcloud)
PointCloud *BKE_pointcloud_new_for_eval(const PointCloud *pointcloud_src, int totpoint)
{
PointCloud *pointcloud_dst = BKE_id_new_nomain(ID_PT, NULL);
+ CustomData_free(&pointcloud_dst->pdata, pointcloud_dst->totpoint);
STRNCPY(pointcloud_dst->id.name, pointcloud_src->id.name);
pointcloud_dst->mat = MEM_dupallocN(pointcloud_src->mat);
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index d5ba345928b..20386869ca9 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -27,7 +27,9 @@
#include "DNA_scene_types.h"
#include "DNA_simulation_types.h"
+#include "BLI_array_ref.hh"
#include "BLI_compiler_compat.h"
+#include "BLI_float3.hh"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -35,12 +37,14 @@
#include "BKE_anim_data.h"
#include "BKE_animsys.h"
+#include "BKE_customdata.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_pointcache.h"
#include "BKE_simulation.h"
#include "NOD_simulation.h"
@@ -50,6 +54,10 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+using BLI::ArrayRef;
+using BLI::float3;
+using BLI::MutableArrayRef;
+
static void simulation_init_data(ID *id)
{
Simulation *simulation = (Simulation *)id;
@@ -59,6 +67,14 @@ static void simulation_init_data(ID *id)
bNodeTree *ntree = ntreeAddTree(nullptr, "Simulation Nodetree", ntreeType_Simulation->idname);
simulation->nodetree = ntree;
+
+ /* Add a default particle simulation state for now. */
+ ParticleSimulationState *state = (ParticleSimulationState *)MEM_callocN(
+ sizeof(ParticleSimulationState), __func__);
+ CustomData_reset(&state->attributes);
+
+ state->point_cache = BKE_ptcache_add(&state->ptcaches);
+ BLI_addtail(&simulation->states, state);
}
static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
@@ -75,6 +91,21 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
(ID **)&simulation_dst->nodetree,
flag_private_id_data);
}
+
+ BLI_listbase_clear(&simulation_dst->states);
+
+ LISTBASE_FOREACH (const SimulationState *, state_src, &simulation_src->states) {
+ switch ((eSimulationStateType)state_src->type) {
+ case SIM_STATE_TYPE_PARTICLES: {
+ ParticleSimulationState *particle_state_dst = (ParticleSimulationState *)MEM_callocN(
+ sizeof(ParticleSimulationState), __func__);
+ CustomData_reset(&particle_state_dst->attributes);
+
+ BLI_addtail(&simulation_dst->states, particle_state_dst);
+ break;
+ }
+ }
+ }
}
static void simulation_free_data(ID *id)
@@ -88,6 +119,18 @@ static void simulation_free_data(ID *id)
MEM_freeN(simulation->nodetree);
simulation->nodetree = nullptr;
}
+
+ LISTBASE_FOREACH_MUTABLE (SimulationState *, state, &simulation->states) {
+ switch ((eSimulationStateType)state->type) {
+ case SIM_STATE_TYPE_PARTICLES: {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+ CustomData_free(&particle_state->attributes, particle_state->tot_particles);
+ BKE_ptcache_free_list(&particle_state->ptcaches);
+ break;
+ }
+ }
+ MEM_freeN(state);
+ }
}
static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -125,8 +168,94 @@ void *BKE_simulation_add(Main *bmain, const char *name)
return simulation;
}
-void BKE_simulation_data_update(Depsgraph *UNUSED(depsgraph),
- Scene *UNUSED(scene),
- Simulation *UNUSED(simulation))
+static MutableArrayRef<float3> get_particle_positions(ParticleSimulationState *state)
{
+ return MutableArrayRef<float3>(
+ (float3 *)CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position"),
+ state->tot_particles);
+}
+
+static void ensure_attributes_exist(ParticleSimulationState *state)
+{
+ if (CustomData_get_layer_named(&state->attributes, CD_LOCATION, "Position") == nullptr) {
+ CustomData_add_layer_named(
+ &state->attributes, CD_LOCATION, CD_CALLOC, nullptr, state->tot_particles, "Position");
+ }
+}
+
+static void copy_particle_state_to_cow(ParticleSimulationState *state_orig,
+ ParticleSimulationState *state_cow)
+{
+ ensure_attributes_exist(state_cow);
+ CustomData_free(&state_cow->attributes, state_cow->tot_particles);
+ CustomData_copy(&state_orig->attributes,
+ &state_cow->attributes,
+ CD_MASK_ALL,
+ CD_DUPLICATE,
+ state_orig->tot_particles);
+ state_cow->current_frame = state_orig->current_frame;
+ state_cow->tot_particles = state_orig->tot_particles;
+}
+
+void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation)
+{
+ int current_frame = scene->r.cfra;
+
+ ParticleSimulationState *state_cow = (ParticleSimulationState *)simulation->states.first;
+ ParticleSimulationState *state_orig = (ParticleSimulationState *)state_cow->head.orig_state;
+
+ if (current_frame == state_cow->current_frame) {
+ return;
+ }
+
+ /* Number of particles should be stored in the cache, but for now assume it is constant. */
+ state_cow->tot_particles = state_orig->tot_particles;
+ CustomData_realloc(&state_cow->attributes, state_orig->tot_particles);
+ ensure_attributes_exist(state_cow);
+
+ PTCacheID pid_cow;
+ BKE_ptcache_id_from_sim_particles(&pid_cow, state_cow);
+ BKE_ptcache_id_time(&pid_cow, scene, current_frame, nullptr, nullptr, nullptr);
+
+ /* If successfull, this will read the state directly into the cow state. */
+ int cache_result = BKE_ptcache_read(&pid_cow, current_frame, true);
+ if (cache_result == PTCACHE_READ_EXACT) {
+ state_cow->current_frame = current_frame;
+ return;
+ }
+
+ /* Below we modify the original state/cache. Only the active depsgraph is allowed to do that. */
+ if (!DEG_is_active(depsgraph)) {
+ return;
+ }
+
+ PTCacheID pid_orig;
+ BKE_ptcache_id_from_sim_particles(&pid_orig, state_orig);
+ BKE_ptcache_id_time(&pid_orig, scene, current_frame, nullptr, nullptr, nullptr);
+
+ if (current_frame == 1) {
+ state_orig->tot_particles = 100;
+ state_orig->current_frame = 1;
+ CustomData_realloc(&state_orig->attributes, state_orig->tot_particles);
+ ensure_attributes_exist(state_orig);
+
+ MutableArrayRef<float3> positions = get_particle_positions(state_orig);
+ for (uint i : positions.index_range()) {
+ positions[i] = {i / 10.0f, 0, 0};
+ }
+
+ BKE_ptcache_write(&pid_orig, current_frame);
+ copy_particle_state_to_cow(state_orig, state_cow);
+ }
+ else if (current_frame == state_orig->current_frame + 1) {
+ state_orig->current_frame = current_frame;
+ ensure_attributes_exist(state_orig);
+ MutableArrayRef<float3> positions = get_particle_positions(state_orig);
+ for (float3 &position : positions) {
+ position.z += 0.1f;
+ }
+
+ BKE_ptcache_write(&pid_orig, current_frame);
+ copy_particle_state_to_cow(state_orig, state_cow);
+ }
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index f7f18d98e73..1e09f01fa57 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9105,6 +9105,19 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati
{
BLO_read_data_address(reader, &simulation->adt);
direct_link_animdata(reader, simulation->adt);
+
+ BLO_read_list(reader, &simulation->states);
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ switch ((eSimulationStateType)state->type) {
+ case SIM_STATE_TYPE_PARTICLES: {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+ direct_link_customdata(reader, &particle_state->attributes, particle_state->tot_particles);
+ direct_link_pointcache_list(
+ reader, &particle_state->ptcaches, &particle_state->point_cache, 0);
+ break;
+ };
+ }
+ }
}
/** \} */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 205184e6e7c..3fa36c6995e 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3915,6 +3915,30 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const
BLO_write_struct(writer, bNodeTree, simulation->nodetree);
write_nodetree_nolib(writer, simulation->nodetree);
}
+
+ LISTBASE_FOREACH (SimulationState *, state, &simulation->states) {
+ switch ((eSimulationStateType)state->type) {
+ case SIM_STATE_TYPE_PARTICLES: {
+ ParticleSimulationState *particle_state = (ParticleSimulationState *)state;
+ BLO_write_struct(writer, ParticleSimulationState, particle_state);
+
+ CustomDataLayer *layers = NULL;
+ CustomDataLayer layers_buff[CD_TEMP_CHUNK_SIZE];
+ CustomData_file_write_prepare(
+ &particle_state->attributes, &layers, layers_buff, ARRAY_SIZE(layers_buff));
+
+ write_customdata(writer,
+ &simulation->id,
+ particle_state->tot_particles,
+ &particle_state->attributes,
+ layers,
+ CD_MASK_ALL);
+
+ write_pointcaches(writer, &particle_state->ptcaches);
+ break;
+ }
+ }
+ }
}
}
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 2f2e05d410e..70a6875f1c0 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -63,6 +63,7 @@
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_simulation_types.h"
#include "DNA_sound_types.h"
#include "DRW_engine.h"
@@ -709,6 +710,13 @@ void update_modifiers_orig_pointers(const Object *object_orig, Object *object_co
&object_orig->modifiers, &object_cow->modifiers, &ModifierData::orig_modifier_data);
}
+void update_simulation_states_orig_pointers(const Simulation *simulation_orig,
+ Simulation *simulation_cow)
+{
+ update_list_orig_pointers(
+ &simulation_orig->states, &simulation_cow->states, &SimulationState::orig_state);
+}
+
void update_nla_strips_orig_pointers(const ListBase *strips_orig, ListBase *strips_cow)
{
NlaStrip *strip_orig = reinterpret_cast<NlaStrip *>(strips_orig->first);
@@ -808,6 +816,12 @@ void update_id_after_copy(const Depsgraph *depsgraph,
update_scene_orig_pointers(scene_orig, scene_cow);
break;
}
+ case ID_SIM: {
+ Simulation *simulation_cow = (Simulation *)id_cow;
+ const Simulation *simulation_orig = (const Simulation *)id_orig;
+ update_simulation_states_orig_pointers(simulation_orig, simulation_cow);
+ break;
+ }
default:
break;
}
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 52287b07b28..ada4243ab4e 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -360,6 +360,7 @@ static bool timeline_cache_is_hidden_by_setting(SpaceAction *saction, PTCacheID
}
break;
case PTCACHE_TYPE_PARTICLES:
+ case PTCACHE_TYPE_SIM_PARTICLES:
if ((saction->cache_display & TIME_CACHE_PARTICLES) == 0) {
return true;
}
@@ -399,6 +400,7 @@ static void timeline_cache_color_get(PTCacheID *pid, float color[4])
color[3] = 0.1;
break;
case PTCACHE_TYPE_PARTICLES:
+ case PTCACHE_TYPE_SIM_PARTICLES:
color[0] = 1.0;
color[1] = 0.1;
color[2] = 0.02;
diff --git a/source/blender/makesdna/DNA_simulation_types.h b/source/blender/makesdna/DNA_simulation_types.h
index 113c301bb9e..93ba9c425f0 100644
--- a/source/blender/makesdna/DNA_simulation_types.h
+++ b/source/blender/makesdna/DNA_simulation_types.h
@@ -22,6 +22,7 @@
#define __DNA_SIMULATION_TYPES_H__
#include "DNA_ID.h"
+#include "DNA_customdata_types.h"
typedef struct Simulation {
ID id;
@@ -30,12 +31,49 @@ typedef struct Simulation {
struct bNodeTree *nodetree;
int flag;
- int _pad1[1];
+ int _pad;
+
+ /** List containing SimulationState objects. */
+ struct ListBase states;
} Simulation;
+typedef struct SimulationState {
+ struct SimulationState *next;
+ struct SimulationState *prev;
+
+ /** This is only initialized on cow copies of the simulation. It points to the state on the
+ * original data block. That is where the cache is stored. */
+ struct SimulationState *orig_state;
+
+ /** eSimulationStateType */
+ int type;
+ int _pad;
+
+ char name[64];
+} SimulationState;
+
+typedef struct ParticleSimulationState {
+ SimulationState head;
+
+ /** Contains the state of the particles at time current_frame. */
+ float current_frame;
+ int tot_particles;
+ struct CustomData attributes;
+
+ /** Caches the state of the particles over time. The cache only exists on the original data
+ * block, not on cow copies. */
+ struct PointCache *point_cache;
+ struct ListBase ptcaches;
+} ParticleSimulationState;
+
/* Simulation.flag */
enum {
SIM_DS_EXPAND = (1 << 0),
};
+/* SimulationCache.type */
+typedef enum eSimulationStateType {
+ SIM_STATE_TYPE_PARTICLES = 0,
+} eSimulationStateType;
+
#endif /* __DNA_SIMULATION_TYPES_H__ */
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index b8dad8cf5c1..a0026797c68 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -29,6 +29,7 @@
#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_simulation_types.h"
#include "MEM_guardedalloc.h"
@@ -1631,6 +1632,17 @@ static void rna_ParticleInstanceModifier_particle_system_set(PointerRNA *ptr,
CLAMP_MIN(psmd->psys, 1);
}
+# ifdef WITH_NEW_SIMULATION_TYPE
+static void rna_SimulationModifier_simulation_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ SimulationModifierData *smd = ptr->data;
+ if (smd->simulation != NULL) {
+ DEG_id_tag_update(&smd->simulation->id, ID_RECALC_ALL);
+ }
+ rna_Modifier_dependency_update(bmain, scene, ptr);
+}
+# endif
+
#else
/* NOTE: *MUST* return subdivision_type property. */
@@ -6794,7 +6806,7 @@ static void rna_def_modifier_simulation(BlenderRNA *brna)
prop = RNA_def_property(srna, "simulation", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Simulation", "Simulation to access");
RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ RNA_def_property_update(prop, 0, "rna_SimulationModifier_simulation_update");
# endif
prop = RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_simulation.cc b/source/blender/modifiers/intern/MOD_simulation.cc
index f126d1af959..5ccf945b5a6 100644
--- a/source/blender/modifiers/intern/MOD_simulation.cc
+++ b/source/blender/modifiers/intern/MOD_simulation.cc
@@ -21,11 +21,14 @@
* \ingroup modifiers
*/
+#include <cstring>
#include <iostream>
#include <string>
#include "MEM_guardedalloc.h"
+#include "BLI_float3.hh"
+#include "BLI_listbase.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
@@ -41,6 +44,8 @@
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_pointcloud.h"
+#include "BKE_simulation.h"
/* SpaceType struct has a member called 'new' which obviously conflicts with C++
* so temporarily redefining the new keyword to make it compile. */
@@ -59,6 +64,8 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
+using BLI::float3;
+
static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
{
SimulationModifierData *smd = (SimulationModifierData *)md;
@@ -81,12 +88,42 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
return smd->simulation == nullptr;
}
+static const ParticleSimulationState *find_particle_state(SimulationModifierData *smd)
+{
+ if (smd->simulation == nullptr) {
+ return nullptr;
+ }
+ LISTBASE_FOREACH (const SimulationState *, state, &smd->simulation->states) {
+ if (state->type == SIM_STATE_TYPE_PARTICLES) {
+ return (ParticleSimulationState *)state;
+ }
+ }
+ return nullptr;
+}
+
static PointCloud *modifyPointCloud(ModifierData *md,
const ModifierEvalContext *UNUSED(ctx),
- PointCloud *pointcloud)
+ PointCloud *input_pointcloud)
{
SimulationModifierData *smd = (SimulationModifierData *)md;
- UNUSED_VARS(smd);
+ const ParticleSimulationState *state = find_particle_state(smd);
+ if (state == nullptr) {
+ return input_pointcloud;
+ }
+
+ PointCloud *pointcloud = BKE_pointcloud_new_for_eval(input_pointcloud, state->tot_particles);
+ if (state->tot_particles == 0) {
+ return pointcloud;
+ }
+
+ const float3 *positions = (const float3 *)CustomData_get_layer_named(
+ &state->attributes, CD_LOCATION, "Position");
+ memcpy(pointcloud->co, positions, sizeof(float3) * state->tot_particles);
+
+ for (int i = 0; i < state->tot_particles; i++) {
+ pointcloud->radius[i] = 0.05f;
+ }
+
return pointcloud;
}