diff options
Diffstat (limited to 'source/blender/simulation/intern/simulation_solver.cc')
-rw-r--r-- | source/blender/simulation/intern/simulation_solver.cc | 98 |
1 files changed, 59 insertions, 39 deletions
diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc index 5ab706dbb4b..a035a40f72f 100644 --- a/source/blender/simulation/intern/simulation_solver.cc +++ b/source/blender/simulation/intern/simulation_solver.cc @@ -34,7 +34,11 @@ ParticleEmitter::~ParticleEmitter() { } -static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type) +ParticleAction::~ParticleAction() +{ +} + +static CustomDataType cpp_to_custom_data_type(const CPPType &type) { if (type.is<float3>()) { return CD_PROP_FLOAT3; @@ -49,18 +53,18 @@ static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type) return CD_PROP_FLOAT; } -static const fn::CPPType &custom_to_cpp_data_type(CustomDataType type) +static const CPPType &custom_to_cpp_data_type(CustomDataType type) { switch (type) { case CD_PROP_FLOAT3: - return fn::CPPType::get<float3>(); + return CPPType::get<float3>(); case CD_PROP_FLOAT: - return fn::CPPType::get<float>(); + return CPPType::get<float>(); case CD_PROP_INT32: - return fn::CPPType::get<int32_t>(); + return CPPType::get<int32_t>(); default: BLI_assert(false); - return fn::CPPType::get<float>(); + return CPPType::get<float>(); } } @@ -68,33 +72,33 @@ class CustomDataAttributesRef { private: Array<void *> buffers_; int64_t size_; - const fn::AttributesInfo &info_; + const AttributesInfo &info_; public: - CustomDataAttributesRef(CustomData &custom_data, int64_t size, const fn::AttributesInfo &info) + CustomDataAttributesRef(CustomData &custom_data, int64_t size, const AttributesInfo &info) : buffers_(info.size(), nullptr), size_(size), info_(info) { for (int attribute_index : info.index_range()) { StringRefNull name = info.name_of(attribute_index); - const fn::CPPType &cpp_type = info.type_of(attribute_index); + const CPPType &cpp_type = info.type_of(attribute_index); CustomDataType custom_type = cpp_to_custom_data_type(cpp_type); void *data = CustomData_get_layer_named(&custom_data, custom_type, name.c_str()); buffers_[attribute_index] = data; } } - operator fn::MutableAttributesRef() + operator MutableAttributesRef() { - return fn::MutableAttributesRef(info_, buffers_, size_); + return MutableAttributesRef(info_, buffers_, size_); } - operator fn::AttributesRef() const + operator AttributesRef() const { - return fn::AttributesRef(info_, buffers_, size_); + return AttributesRef(info_, buffers_, size_); } }; -static void ensure_attributes_exist(ParticleSimulationState *state, const fn::AttributesInfo &info) +static void ensure_attributes_exist(ParticleSimulationState *state, const AttributesInfo &info) { bool found_layer_to_remove; do { @@ -102,7 +106,7 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At for (int layer_index = 0; layer_index < state->attributes.totlayer; layer_index++) { CustomDataLayer *layer = &state->attributes.layers[layer_index]; BLI_assert(layer->name != nullptr); - const fn::CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer->type); + const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer->type); StringRefNull name = layer->name; if (!info.has_attribute(name, cpp_type)) { found_layer_to_remove = true; @@ -114,7 +118,7 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At for (int attribute_index : info.index_range()) { StringRefNull attribute_name = info.name_of(attribute_index); - const fn::CPPType &cpp_type = info.type_of(attribute_index); + const CPPType &cpp_type = info.type_of(attribute_index); CustomDataType custom_type = cpp_to_custom_data_type(cpp_type); if (CustomData_get_layer_named(&state->attributes, custom_type, attribute_name.c_str()) == nullptr) { @@ -131,13 +135,13 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_context, ParticleSimulationState &state, - fn::MutableAttributesRef attributes, + MutableAttributesRef attributes, MutableSpan<float> remaining_durations, float end_time) { int particle_amount = attributes.size(); Array<float3> force_vectors{particle_amount, {0, 0, 0}}; - Span<const ParticleForce *> forces = solve_context.influences().particle_forces.lookup_as( + Span<const ParticleForce *> forces = solve_context.influences.particle_forces.lookup_as( state.head.name); ParticleChunkContext particle_chunk_context{IndexMask(particle_amount), attributes}; @@ -166,23 +170,23 @@ BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_c BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context, ParticleSimulationState &state, - const fn::AttributesInfo &attributes_info) + const AttributesInfo &attributes_info) { CustomDataAttributesRef custom_data_attributes{ state.attributes, state.tot_particles, attributes_info}; - fn::MutableAttributesRef attributes = custom_data_attributes; + MutableAttributesRef attributes = custom_data_attributes; - Array<float> remaining_durations(state.tot_particles, solve_context.solve_interval().duration()); + Array<float> remaining_durations(state.tot_particles, solve_context.solve_interval.duration()); simulate_particle_chunk( - solve_context, state, attributes, remaining_durations, solve_context.solve_interval().end()); + solve_context, state, attributes, remaining_durations, solve_context.solve_interval.end()); } BLI_NOINLINE static void run_emitters(SimulationSolveContext &solve_context, ParticleAllocators &particle_allocators) { - for (const ParticleEmitter *emitter : solve_context.influences().particle_emitters) { + for (const ParticleEmitter *emitter : solve_context.influences.particle_emitters) { ParticleEmitterContext emitter_context{ - solve_context, particle_allocators, solve_context.solve_interval()}; + solve_context, particle_allocators, solve_context.solve_interval}; emitter->emit(emitter_context); } } @@ -192,10 +196,10 @@ BLI_NOINLINE static int count_particles_after_time_step(ParticleSimulationState { CustomDataAttributesRef custom_data_attributes{ state.attributes, state.tot_particles, allocator.attributes_info()}; - fn::MutableAttributesRef attributes = custom_data_attributes; + MutableAttributesRef attributes = custom_data_attributes; int new_particle_amount = attributes.get<int>("Dead").count(0); - for (fn::MutableAttributesRef emitted_attributes : allocator.get_allocations()) { + for (MutableAttributesRef emitted_attributes : allocator.get_allocations()) { new_particle_amount += emitted_attributes.get<int>("Dead").count(0); } @@ -210,7 +214,7 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta CustomDataAttributesRef custom_data_attributes{ state.attributes, state.tot_particles, allocator.attributes_info()}; - Vector<fn::MutableAttributesRef> particle_sources; + Vector<MutableAttributesRef> particle_sources; particle_sources.append(custom_data_attributes); particle_sources.extend(allocator.get_allocations()); @@ -222,16 +226,16 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta dead_layer = &layer; continue; } - const fn::CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type); - fn::GMutableSpan new_buffer{ + const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type); + GMutableSpan new_buffer{ cpp_type, MEM_mallocN_aligned(new_particle_amount * cpp_type.size(), cpp_type.alignment(), AT), new_particle_amount}; int current = 0; - for (fn::MutableAttributesRef attributes : particle_sources) { + for (MutableAttributesRef attributes : particle_sources) { Span<int> dead_states = attributes.get<int>("Dead"); - fn::GSpan source_buffer = attributes.get(name); + GSpan source_buffer = attributes.get(name); BLI_assert(source_buffer.type() == cpp_type); for (int i : attributes.index_range()) { if (dead_states[i] == 0) { @@ -286,24 +290,26 @@ void solve_simulation_time_step(Simulation &simulation, Span<ParticleSimulationState *> particle_simulation_states = state_map.lookup<ParticleSimulationState>(); - Map<std::string, std::unique_ptr<fn::AttributesInfo>> attribute_infos; + Map<std::string, std::unique_ptr<AttributesInfo>> attribute_infos; Map<std::string, std::unique_ptr<ParticleAllocator>> particle_allocators_map; for (ParticleSimulationState *state : particle_simulation_states) { - const fn::AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as( + const AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as( state->head.name); - auto info = std::make_unique<fn::AttributesInfo>(builder); + auto info = std::make_unique<AttributesInfo>(builder); ensure_attributes_exist(state, *info); + uint32_t hash_seed = DefaultHash<StringRef>{}(state->head.name); particle_allocators_map.add_new( - state->head.name, std::make_unique<ParticleAllocator>(*info, state->next_particle_id)); + state->head.name, + std::make_unique<ParticleAllocator>(*info, state->next_particle_id, hash_seed)); attribute_infos.add_new(state->head.name, std::move(info)); } ParticleAllocators particle_allocators{particle_allocators_map}; for (ParticleSimulationState *state : particle_simulation_states) { - const fn::AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name); + const AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name); simulate_existing_particles(solve_context, *state, attributes_info); } @@ -312,10 +318,24 @@ void solve_simulation_time_step(Simulation &simulation, for (ParticleSimulationState *state : particle_simulation_states) { ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name); - for (fn::MutableAttributesRef attributes : allocator.get_allocations()) { + for (MutableAttributesRef attributes : allocator.get_allocations()) { + Span<const ParticleAction *> actions = influences.particle_birth_actions.lookup_as( + state->head.name); + for (const ParticleAction *action : actions) { + MutableParticleChunkContext chunk_context{IndexRange(attributes.size()), attributes}; + ParticleActionContext action_context{solve_context, chunk_context}; + action->execute(action_context); + } + } + } + + for (ParticleSimulationState *state : particle_simulation_states) { + ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name); + + for (MutableAttributesRef attributes : allocator.get_allocations()) { Array<float> remaining_durations(attributes.size()); Span<float> birth_times = attributes.get<float>("Birth Time"); - const float end_time = solve_context.solve_interval().end(); + const float end_time = solve_context.solve_interval.end(); for (int i : attributes.index_range()) { remaining_durations[i] = end_time - birth_times[i]; } @@ -325,7 +345,7 @@ void solve_simulation_time_step(Simulation &simulation, remove_dead_and_add_new_particles(*state, allocator); } - simulation.current_simulation_time = solve_context.solve_interval().end(); + simulation.current_simulation_time = solve_context.solve_interval.end(); } } // namespace blender::sim |