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
diff options
context:
space:
mode:
-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;
}