diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_pointcache.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_simulation.h | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pointcache.c | 87 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/simulation.cc | 277 |
4 files changed, 226 insertions, 158 deletions
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index a9abe2d0f6d..dc99ec7f56f 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -86,12 +86,10 @@ struct ListBase; struct Main; struct Object; struct ParticleKey; -struct ParticleSimulationState; struct ParticleSystem; struct PointCache; struct RigidBodyWorld; struct Scene; -struct Simulation; struct SoftBody; struct ViewLayer; @@ -296,9 +294,6 @@ 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_orig, - struct ParticleSimulationState *state_cow); 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/BKE_simulation.h b/source/blender/blenkernel/BKE_simulation.h index 36f4122f4dc..5aa71b6381d 100644 --- a/source/blender/blenkernel/BKE_simulation.h +++ b/source/blender/blenkernel/BKE_simulation.h @@ -34,13 +34,26 @@ void BKE_simulation_data_update(struct Depsgraph *depsgraph, struct Simulation *simulation); SimulationState *BKE_simulation_state_add(Simulation *simulation, - eSimulationStateType type, + const char *type, const char *name); void BKE_simulation_state_remove(Simulation *simulation, SimulationState *state); void BKE_simulation_state_remove_all(Simulation *simulation); +void BKE_simulation_state_reset(Simulation *simulation, SimulationState *state); +void BKE_simulation_state_reset_all(Simulation *simulation); +SimulationState *BKE_simulation_state_try_find_by_name(Simulation *simulation, const char *name); +SimulationState *BKE_simulation_state_try_find_by_name_and_type(Simulation *simulation, + const char *name, + const char *type); +void BKE_simulation_state_copy_data(const SimulationState *src_state, SimulationState *dst_state); #ifdef __cplusplus } #endif +#ifdef __cplusplus + +template<typename StateType> const char *BKE_simulation_get_state_type_name(); + +#endif + #endif /* __BKE_SIMULATION_H__ */ diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index aa93c6cb854..4b09f7542c7 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1885,81 +1885,6 @@ 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_PROP_FLOAT3, "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), const 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_PROP_FLOAT3, "Position"); - - PTCACHE_DATA_TO(data, BPHYS_DATA_LOCATION, 0, positions + (index * 3)); -} - -void BKE_ptcache_id_from_sim_particles(PTCacheID *pid, - ParticleSimulationState *state_orig, - ParticleSimulationState *state_cow) -{ - memset(pid, 0, sizeof(PTCacheID)); - - pid->calldata = state_cow; - 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. @@ -2059,17 +1984,7 @@ 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: { - /* TODO(jacques) */ - break; - } - } - } - } + /* TODO(jacques) */ } } return true; diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc index 1f11869e21c..95340e4e29c 100644 --- a/source/blender/blenkernel/intern/simulation.cc +++ b/source/blender/blenkernel/intern/simulation.cc @@ -51,6 +51,7 @@ #include "NOD_node_tree_multi_function.hh" #include "NOD_simulation.h" +#include "BLI_map.hh" #include "BLT_translation.h" #include "FN_attributes_ref.hh" @@ -62,6 +63,22 @@ #include "SIM_simulation_update.hh" +using StateInitFunction = void (*)(SimulationState *state); +using StateResetFunction = void (*)(SimulationState *state); +using StateRemoveFunction = void (*)(SimulationState *state); +using StateCopyFunction = void (*)(const SimulationState *src, SimulationState *dst); + +struct SimulationStateType { + const char *name; + int size; + StateInitFunction init; + StateResetFunction reset; + StateRemoveFunction remove; + StateCopyFunction copy; +}; + +static const SimulationStateType *try_get_state_type(blender::StringRefNull type_name); + static void simulation_init_data(ID *id) { Simulation *simulation = (Simulation *)id; @@ -76,7 +93,7 @@ static void simulation_init_data(ID *id) static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag) { Simulation *simulation_dst = (Simulation *)id_dst; - Simulation *simulation_src = (Simulation *)id_src; + const Simulation *simulation_src = (const Simulation *)id_src; /* We always need allocation of our private ID data. */ const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE; @@ -89,76 +106,16 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons } BLI_listbase_clear(&simulation_dst->states); + LISTBASE_FOREACH (const SimulationState *, state_src, &simulation_src->states) { + SimulationState *state_dst = BKE_simulation_state_add( + simulation_dst, state_src->type, state_src->name); + BKE_simulation_state_copy_data(state_src, state_dst); + } BLI_duplicatelist(&simulation_dst->persistent_data_handles, &simulation_src->persistent_data_handles); } -static void free_simulation_state_head(SimulationState *state) -{ - MEM_freeN(state->name); -} - -static void free_particle_simulation_state(ParticleSimulationState *state) -{ - free_simulation_state_head(&state->head); - CustomData_free(&state->attributes, state->tot_particles); - BKE_ptcache_free_list(&state->ptcaches); - MEM_freeN(state); -} - -SimulationState *BKE_simulation_state_add(Simulation *simulation, - eSimulationStateType type, - const char *name) -{ - BLI_assert(simulation != nullptr); - BLI_assert(name != nullptr); - - bool is_cow_simulation = DEG_is_evaluated_id(&simulation->id); - - switch (type) { - case SIM_STATE_TYPE_PARTICLES: { - ParticleSimulationState *state = (ParticleSimulationState *)MEM_callocN(sizeof(*state), AT); - state->head.type = SIM_STATE_TYPE_PARTICLES; - state->head.name = BLI_strdup(name); - CustomData_reset(&state->attributes); - - if (!is_cow_simulation) { - state->point_cache = BKE_ptcache_add(&state->ptcaches); - } - - BLI_addtail(&simulation->states, state); - return &state->head; - } - } - - BLI_assert(false); - return nullptr; -} - -void BKE_simulation_state_remove(Simulation *simulation, SimulationState *state) -{ - BLI_assert(simulation != nullptr); - BLI_assert(state != nullptr); - BLI_assert(BLI_findindex(&simulation->states, state) >= 0); - - BLI_remlink(&simulation->states, state); - switch ((eSimulationStateType)state->type) { - case SIM_STATE_TYPE_PARTICLES: { - free_particle_simulation_state((ParticleSimulationState *)state); - break; - } - } -} - -void BKE_simulation_state_remove_all(Simulation *simulation) -{ - BLI_assert(simulation != nullptr); - while (!BLI_listbase_is_empty(&simulation->states)) { - BKE_simulation_state_remove(simulation, (SimulationState *)simulation->states.first); - } -} - static void simulation_free_data(ID *id) { Simulation *simulation = (Simulation *)id; @@ -215,7 +172,195 @@ void *BKE_simulation_add(Main *bmain, const char *name) return simulation; } +SimulationState *BKE_simulation_state_add(Simulation *simulation, + const char *type, + const char *name) +{ + BLI_assert(simulation != nullptr); + BLI_assert(name != nullptr); + + const SimulationStateType *state_type = try_get_state_type(type); + BLI_assert(state_type != nullptr); + + SimulationState *state = (SimulationState *)MEM_callocN(state_type->size, AT); + state->type = BLI_strdup(type); + state->name = BLI_strdup(name); + + state_type->init(state); + BLI_addtail(&simulation->states, state); + return state; +} + +void BKE_simulation_state_remove(Simulation *simulation, SimulationState *state) +{ + BLI_assert(simulation != nullptr); + BLI_assert(state != nullptr); + BLI_assert(BLI_findindex(&simulation->states, state) >= 0); + + BLI_remlink(&simulation->states, state); + const SimulationStateType *state_type = try_get_state_type(state->type); + BLI_assert(state_type != nullptr); + state_type->remove(state); + MEM_freeN(state->name); + MEM_freeN(state->type); + MEM_freeN(state); +} + +void BKE_simulation_state_remove_all(Simulation *simulation) +{ + BLI_assert(simulation != nullptr); + + while (!BLI_listbase_is_empty(&simulation->states)) { + BKE_simulation_state_remove(simulation, (SimulationState *)simulation->states.first); + } +} + +void BKE_simulation_state_reset(Simulation *UNUSED(simulation), SimulationState *state) +{ + BLI_assert(state != nullptr); + + const SimulationStateType *state_type = try_get_state_type(state->type); + BLI_assert(state_type != nullptr); + state_type->reset(state); +} + +void BKE_simulation_state_reset_all(Simulation *simulation) +{ + BLI_assert(simulation != nullptr); + + LISTBASE_FOREACH (SimulationState *, state, &simulation->states) { + BKE_simulation_state_reset(simulation, state); + } +} + +void BKE_simulation_state_copy_data(const SimulationState *src_state, SimulationState *dst_state) +{ + BLI_assert(src_state != nullptr); + BLI_assert(dst_state != nullptr); + BLI_assert(STREQ(src_state->type, dst_state->type)); + + const SimulationStateType *state_type = try_get_state_type(src_state->type); + BLI_assert(state_type != nullptr); + state_type->copy(src_state, dst_state); +} + +SimulationState *BKE_simulation_state_try_find_by_name(Simulation *simulation, const char *name) +{ + if (simulation == nullptr) { + return nullptr; + } + if (name == nullptr) { + return nullptr; + } + + LISTBASE_FOREACH (SimulationState *, state, &simulation->states) { + if (STREQ(state->name, name)) { + return state; + } + } + return nullptr; +} + +SimulationState *BKE_simulation_state_try_find_by_name_and_type(Simulation *simulation, + const char *name, + const char *type) +{ + if (type == nullptr) { + return nullptr; + } + + SimulationState *state = BKE_simulation_state_try_find_by_name(simulation, name); + if (state == nullptr) { + return nullptr; + } + if (STREQ(state->type, type)) { + return state; + } + return nullptr; +} + void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *simulation) { blender::sim::update_simulation_in_depsgraph(depsgraph, scene, simulation); } + +using StateTypeMap = blender::Map<std::string, std::unique_ptr<SimulationStateType>>; + +template<typename T> +static void add_state_type(StateTypeMap &map, + const char *name, + void (*init)(T *state), + void (*reset)(T *state), + void (*remove)(T *state), + void (*copy)(const T *src, T *dst)) +{ + SimulationStateType state_type{ + name, + (int)sizeof(T), + (StateInitFunction)init, + (StateResetFunction)reset, + (StateRemoveFunction)remove, + (StateCopyFunction)copy, + }; + map.add_new(name, std::make_unique<SimulationStateType>(state_type)); +} + +static StateTypeMap init_state_types() +{ + StateTypeMap map; + add_state_type<ParticleSimulationState>( + map, + SIM_TYPE_NAME_PARTICLE_SIMULATION, + [](ParticleSimulationState *state) { CustomData_reset(&state->attributes); }, + [](ParticleSimulationState *state) { + CustomData_free(&state->attributes, state->tot_particles); + state->tot_particles = 0; + state->next_particle_id = 0; + }, + [](ParticleSimulationState *state) { + CustomData_free(&state->attributes, state->tot_particles); + }, + [](const ParticleSimulationState *src, ParticleSimulationState *dst) { + CustomData_free(&dst->attributes, dst->tot_particles); + dst->tot_particles = src->tot_particles; + dst->next_particle_id = src->next_particle_id; + CustomData_copy( + &src->attributes, &dst->attributes, CD_MASK_ALL, CD_DUPLICATE, src->tot_particles); + }); + + add_state_type<ParticleMeshEmitterSimulationState>( + map, + SIM_TYPE_NAME_PARTICLE_MESH_EMITTER, + [](ParticleMeshEmitterSimulationState *UNUSED(state)) {}, + [](ParticleMeshEmitterSimulationState *state) { state->last_birth_time = 0.0f; }, + [](ParticleMeshEmitterSimulationState *UNUSED(state)) {}, + [](const ParticleMeshEmitterSimulationState *src, ParticleMeshEmitterSimulationState *dst) { + dst->last_birth_time = src->last_birth_time; + }); + return map; +} + +static StateTypeMap &get_state_types() +{ + static StateTypeMap state_type_map = init_state_types(); + return state_type_map; +} + +static const SimulationStateType *try_get_state_type(blender::StringRefNull type_name) +{ + std::unique_ptr<SimulationStateType> *type = get_state_types().lookup_ptr_as(type_name); + if (type == nullptr) { + return nullptr; + } + return type->get(); +} + +template<> const char *BKE_simulation_get_state_type_name<ParticleSimulationState>() +{ + return SIM_TYPE_NAME_PARTICLE_SIMULATION; +} + +template<> const char *BKE_simulation_get_state_type_name<ParticleMeshEmitterSimulationState>() +{ + return SIM_TYPE_NAME_PARTICLE_MESH_EMITTER; +} |