diff options
author | Jacques Lucke <jacques@blender.org> | 2020-03-10 12:37:17 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-03-10 12:37:17 +0300 |
commit | 4e6dc02f63c9d28c11028d3a3cd5c95c14803aea (patch) | |
tree | 0d308d35ef14398a63395b1402443d09a0ea983b /source | |
parent | 10c73f79fa18aa25b92f2eb9d19ac097541f22e7 (diff) |
simplify interface for a new solver
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/simulations/bparticles/forces.cpp | 15 | ||||
-rw-r--r-- | source/blender/simulations/bparticles/forces.hpp | 10 | ||||
-rw-r--r-- | source/blender/simulations/bparticles/integrator.cpp | 8 | ||||
-rw-r--r-- | source/blender/simulations/bparticles/node_frontend.cpp | 17 | ||||
-rw-r--r-- | source/blender/simulations/bparticles/simulate.cpp | 315 | ||||
-rw-r--r-- | source/blender/simulations/bparticles/simulate.hpp | 3 |
6 files changed, 38 insertions, 330 deletions
diff --git a/source/blender/simulations/bparticles/forces.cpp b/source/blender/simulations/bparticles/forces.cpp index 79a0f026008..ecc20cc20e7 100644 --- a/source/blender/simulations/bparticles/forces.cpp +++ b/source/blender/simulations/bparticles/forces.cpp @@ -8,16 +8,17 @@ Force::~Force() { } -void CustomForce::add_force(ForceInterface &interface) +void CustomForce::add_force(AttributesRef attributes, + IndexMask mask, + BufferCache &buffer_cache, + MutableArrayRef<float3> r_destination) { - MutableArrayRef<float3> dst = interface.combined_destination(); - - ParticleFunctionEvaluator inputs{m_inputs_fn, interface.mask(), interface.attributes()}; - inputs.context_builder().set_buffer_cache(interface.buffer_cache()); + ParticleFunctionEvaluator inputs{m_inputs_fn, mask, attributes}; + inputs.context_builder().set_buffer_cache(buffer_cache); inputs.compute(); - for (uint pindex : interface.mask()) { - dst[pindex] += inputs.get_single<float3>("Force", 0, pindex); + for (uint pindex : mask) { + r_destination[pindex] += inputs.get_single<float3>("Force", 0, pindex); } } diff --git a/source/blender/simulations/bparticles/forces.hpp b/source/blender/simulations/bparticles/forces.hpp index d2f3e9bc0b4..330271c2566 100644 --- a/source/blender/simulations/bparticles/forces.hpp +++ b/source/blender/simulations/bparticles/forces.hpp @@ -17,7 +17,10 @@ using BLI::float4x4; class Force { public: virtual ~Force() = 0; - virtual void add_force(ForceInterface &interface) = 0; + virtual void add_force(AttributesRef attributes, + IndexMask mask, + BufferCache &buffer_cache, + MutableArrayRef<float3> r_destination) = 0; }; class CustomForce : public Force { @@ -29,7 +32,10 @@ class CustomForce : public Force { { } - void add_force(ForceInterface &interface) override; + void add_force(AttributesRef attributes, + IndexMask mask, + BufferCache &buffer_cache, + MutableArrayRef<float3> r_destination) override; }; } // namespace BParticles diff --git a/source/blender/simulations/bparticles/integrator.cpp b/source/blender/simulations/bparticles/integrator.cpp index 3ab4fba5fc7..676e41e13ef 100644 --- a/source/blender/simulations/bparticles/integrator.cpp +++ b/source/blender/simulations/bparticles/integrator.cpp @@ -69,11 +69,11 @@ BLI_NOINLINE void EulerIntegrator::compute_combined_force(IntegratorInterface &i { r_force.fill({0, 0, 0}); - ForceInterface force_interface(interface.step_data(), interface.mask(), r_force); + // ForceInterface force_interface(interface.step_data(), interface.mask(), r_force); - for (Force *force : m_forces) { - force->add_force(force_interface); - } + // for (Force *force : m_forces) { + // force->add_force(force_interface); + // } } BLI_NOINLINE void EulerIntegrator::compute_offsets(IndexMask mask, diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp index 63aed77bdec..151cb9889cd 100644 --- a/source/blender/simulations/bparticles/node_frontend.cpp +++ b/source/blender/simulations/bparticles/node_frontend.cpp @@ -1098,8 +1098,7 @@ StringMap<ActionParserCallback, BLI::RawAllocator> action_parsers_map = static void collect_influences(FunctionTreeData &function_tree_data, WorldTransition &world_transition, Vector<std::string> &r_system_names, - InfluencesCollector &collector, - StringMap<Integrator *> &r_integrators) + InfluencesCollector &collector) { SCOPED_TIMER(__func__); @@ -1129,14 +1128,6 @@ static void collect_influences(FunctionTreeData &function_tree_data, (*callback)(builder); } } - - for (std::string &system_name : r_system_names) { - ArrayRef<Force *> forces = collector.m_forces.lookup_default(system_name); - EulerIntegrator &integrator = function_tree_data.construct<EulerIntegrator>("integrator", - forces); - - r_integrators.add_new(system_name, &integrator); - } } class NodeTreeStepSimulator : public StepSimulator { @@ -1167,10 +1158,8 @@ class NodeTreeStepSimulator : public StepSimulator { FunctionTreeData function_tree_data(*data_graph); Vector<std::string> system_names; - StringMap<Integrator *> integrators; InfluencesCollector influences_collector; - collect_influences( - function_tree_data, world_transition, system_names, influences_collector, integrators); + collect_influences(function_tree_data, world_transition, system_names, influences_collector); auto &containers = particles_state.particle_containers(); @@ -1188,7 +1177,7 @@ class NodeTreeStepSimulator : public StepSimulator { particles_state, name, system_attributes); ParticleSystemInfo type_info = { - integrators.lookup(name), + influences_collector.m_forces.lookup_default(name), influences_collector.m_events.lookup_default(name), influences_collector.m_offset_handlers.lookup_default(name), influences_collector.m_collision_objects.lookup_default(name), diff --git a/source/blender/simulations/bparticles/simulate.cpp b/source/blender/simulations/bparticles/simulate.cpp index 6538242901d..bf19b82cf6d 100644 --- a/source/blender/simulations/bparticles/simulate.cpp +++ b/source/blender/simulations/bparticles/simulate.cpp @@ -14,321 +14,32 @@ using BLI::ScopedVector; using BLI::VectorAdaptor; using FN::CPPType; -BLI_NOINLINE static void find_next_event_per_particle( - BlockStepData &step_data, - IndexMask mask, - ArrayRef<Event *> events, - MutableArrayRef<int> r_next_event_indices, - MutableArrayRef<float> r_time_factors_to_next_event, - ScopedVector<uint> &r_pindices_with_event) -{ - r_next_event_indices.fill_indices(mask, -1); - r_time_factors_to_next_event.fill_indices(mask, 1.0f); - - for (uint event_index : events.index_range()) { - Vector<uint> triggered_pindices; - Vector<float> triggered_time_factors; - - Event *event = events[event_index]; - EventFilterInterface interface( - step_data, mask, r_time_factors_to_next_event, triggered_pindices, triggered_time_factors); - event->filter(interface); - - for (uint i : triggered_pindices.index_range()) { - uint pindex = triggered_pindices[i]; - float time_factor = triggered_time_factors[i]; - BLI_assert(time_factor <= r_time_factors_to_next_event[pindex]); - - r_next_event_indices[pindex] = event_index; - r_time_factors_to_next_event[pindex] = time_factor; - } - } - - for (uint pindex : mask) { - if (r_next_event_indices[pindex] != -1) { - r_pindices_with_event.append(pindex); - } - } -} - -BLI_NOINLINE static void forward_particles_to_next_event_or_end( - BlockStepData &step_data, - ParticleAllocator &particle_allocator, - IndexMask mask, - ArrayRef<float> time_factors_to_next_event, - ArrayRef<OffsetHandler *> offset_handlers) -{ - OffsetHandlerInterface interface( - step_data, mask, time_factors_to_next_event, particle_allocator); - for (OffsetHandler *handler : offset_handlers) { - handler->execute(interface); - } - - auto attributes = step_data.attributes; - auto attribute_offsets = step_data.attribute_offsets; - for (uint attribute_index : attribute_offsets.info().indices()) { - StringRef name = attribute_offsets.info().name_of(attribute_index); - - /* Only vectors can be integrated for now. */ - auto values = attributes.get<float3>(name); - auto offsets = attribute_offsets.get<float3>(attribute_index); - - for (uint pindex : mask) { - float time_factor = time_factors_to_next_event[pindex]; - values[pindex] += time_factor * offsets[pindex]; - } - } -} - -BLI_NOINLINE static void update_remaining_attribute_offsets( - IndexMask mask, - ArrayRef<float> time_factors_to_next_event, - MutableAttributesRef attribute_offsets) -{ - for (uint attribute_index : attribute_offsets.info().indices()) { - /* Only vectors can be integrated for now. */ - auto offsets = attribute_offsets.get<float3>(attribute_index); - - for (uint pindex : mask) { - float factor = 1.0f - time_factors_to_next_event[pindex]; - offsets[pindex] *= factor; - } - } -} - -BLI_NOINLINE static void update_remaining_durations(IndexMask mask, - ArrayRef<float> time_factors_to_next_event, - MutableArrayRef<float> remaining_durations) -{ - for (uint pindex : mask) { - remaining_durations[pindex] *= (1.0f - time_factors_to_next_event[pindex]); - } -} - -BLI_NOINLINE static void find_pindices_per_event( - IndexMask mask, - ArrayRef<int> next_event_indices, - MutableArrayRef<Vector<uint>> r_particles_per_event) -{ - for (uint pindex : mask) { - int event_index = next_event_indices[pindex]; - BLI_assert(event_index >= 0); - r_particles_per_event[event_index].append(pindex); - } -} - -BLI_NOINLINE static void compute_current_time_per_particle(IndexMask mask, - ArrayRef<float> remaining_durations, - float end_time, - MutableArrayRef<float> r_current_times) -{ - for (uint pindex : mask) { - r_current_times[pindex] = end_time - remaining_durations[pindex]; - } -} - -BLI_NOINLINE static void find_unfinished_particles(IndexMask mask, - ArrayRef<float> time_factors_to_next_event, - ArrayRef<bool> kill_states, - VectorAdaptor<uint> &r_unfinished_pindices) -{ - for (uint pindex : mask) { - if (kill_states[pindex] == 0) { - float time_factor = time_factors_to_next_event[pindex]; - - if (time_factor < 1.0f) { - r_unfinished_pindices.append(pindex); - } - } - } -} - -BLI_NOINLINE static void execute_events(BlockStepData &step_data, - ParticleAllocator &particle_allocator, - ArrayRef<Vector<uint>> pindices_per_event, - ArrayRef<float> current_times, - ArrayRef<Event *> events) -{ - BLI::assert_same_size(events, pindices_per_event); - - for (uint event_index : events.index_range()) { - Event *event = events[event_index]; - ArrayRef<uint> pindices = pindices_per_event[event_index]; - - if (pindices.size() == 0) { - continue; - } - - EventExecuteInterface interface(step_data, pindices, current_times, particle_allocator); - event->execute(interface); - } -} - -BLI_NOINLINE static void simulate_to_next_event(BlockStepData &step_data, - ParticleAllocator &particle_allocator, - IndexMask mask, - ParticleSystemInfo &system_info, - VectorAdaptor<uint> &r_unfinished_pindices) -{ - uint amount = step_data.array_size(); - Array<int> next_event_indices(amount); - Array<float> time_factors_to_next_event(amount); - ScopedVector<uint> pindices_with_event; - - find_next_event_per_particle(step_data, - mask, - system_info.events, - next_event_indices, - time_factors_to_next_event, - pindices_with_event); - - forward_particles_to_next_event_or_end(step_data, - particle_allocator, - mask, - time_factors_to_next_event, - system_info.offset_handlers); - - update_remaining_attribute_offsets( - pindices_with_event, time_factors_to_next_event, step_data.attribute_offsets); - - update_remaining_durations( - pindices_with_event, time_factors_to_next_event, step_data.remaining_durations); - - Vector<Vector<uint>> particles_per_event(system_info.events.size()); - find_pindices_per_event(pindices_with_event, next_event_indices, particles_per_event); - - Array<float> current_times(amount); - compute_current_time_per_particle( - pindices_with_event, step_data.remaining_durations, step_data.step_end_time, current_times); - - execute_events( - step_data, particle_allocator, particles_per_event, current_times, system_info.events); - - find_unfinished_particles(pindices_with_event, - time_factors_to_next_event, - step_data.attributes.get<bool>("Dead"), - r_unfinished_pindices); -} - -BLI_NOINLINE static void simulate_with_max_n_events(BlockStepData &step_data, - ParticleAllocator &particle_allocator, - uint max_events, - ParticleSystemInfo &system_info, - ScopedVector<uint> &r_unfinished_pindices) -{ - Array<uint> pindices_A(step_data.array_size()); - Array<uint> pindices_B(step_data.array_size()); - - uint amount_left = step_data.attributes.size(); - - { - /* Handle first event separately to be able to use the static number range. */ - VectorAdaptor<uint> pindices_output(pindices_A.begin(), amount_left); - simulate_to_next_event(step_data, - particle_allocator, - IndexRange(amount_left).as_array_ref(), - system_info, - pindices_output); - amount_left = pindices_output.size(); - } - - for (uint iteration = 0; iteration < max_events - 1 && amount_left > 0; iteration++) { - VectorAdaptor<uint> pindices_input(pindices_A.begin(), amount_left, amount_left); - VectorAdaptor<uint> pindices_output(pindices_B.begin(), amount_left, 0); - - simulate_to_next_event( - step_data, particle_allocator, pindices_input, system_info, pindices_output); - amount_left = pindices_output.size(); - std::swap(pindices_A, pindices_B); - } - - for (uint i = 0; i < amount_left; i++) { - r_unfinished_pindices.append(pindices_A[i]); - } -} - -BLI_NOINLINE static void apply_remaining_offsets(BlockStepData &step_data, - ParticleAllocator &particle_allocator, - ArrayRef<OffsetHandler *> offset_handlers, - IndexMask mask) -{ - if (offset_handlers.size() > 0) { - Array<float> time_factors(step_data.array_size()); - time_factors.fill_indices(mask, 1.0f); - - OffsetHandlerInterface interface(step_data, mask, time_factors, particle_allocator); - for (OffsetHandler *handler : offset_handlers) { - handler->execute(interface); - } - } - - auto attributes = step_data.attributes; - auto attribute_offsets = step_data.attribute_offsets; - - for (uint attribute_index : attribute_offsets.info().indices()) { - StringRef name = attribute_offsets.info().name_of(attribute_index); - - /* Only vectors can be integrated for now. */ - auto values = attributes.get<float3>(name); - auto offsets = attribute_offsets.get<float3>(attribute_index); - - for (uint pindex : mask) { - values[pindex] += offsets[pindex]; - } - } -} - -BLI_NOINLINE static void simulate_particle_chunk(SimulationState &simulation_state, - ParticleAllocator &particle_allocator, +BLI_NOINLINE static void simulate_particle_chunk(SimulationState &UNUSED(simulation_state), + ParticleAllocator &UNUSED(particle_allocator), MutableAttributesRef attributes, ParticleSystemInfo &system_info, MutableArrayRef<float> remaining_durations, - float end_time) + float UNUSED(end_time)) { uint amount = attributes.size(); BLI_assert(amount == remaining_durations.size()); BufferCache buffer_cache; - Integrator &integrator = *system_info.integrator; - const AttributesInfo &offsets_info = integrator.offset_attributes_info(); - Vector<void *> offset_buffers; - for (const CPPType *type : offsets_info.types()) { - void *ptr = buffer_cache.allocate(type->size() * amount, type->alignment()); - offset_buffers.append(ptr); + Array<float3> forces(attributes.size(), {0, 0, 0}); + for (Force *force : system_info.forces) { + force->add_force(attributes, IndexRange(amount), buffer_cache, forces); } - MutableAttributesRef attribute_offsets(offsets_info, offset_buffers, amount); - BlockStepData step_data = {simulation_state, - buffer_cache, - attributes, - attribute_offsets, - remaining_durations, - end_time}; + MutableArrayRef<float3> velocities = attributes.get<float3>("Velocity"); + MutableArrayRef<float3> positions = attributes.get<float3>("Position"); - IntegratorInterface interface(step_data, IndexRange(amount).as_array_ref()); - integrator.integrate(interface); - - if (system_info.events.size() == 0) { - apply_remaining_offsets(step_data, - particle_allocator, - system_info.offset_handlers, - IndexRange(amount).as_array_ref()); - } - else { - ScopedVector<uint> unfinished_pindices; - simulate_with_max_n_events( - step_data, particle_allocator, 10, system_info, unfinished_pindices); - - /* Not sure yet, if this really should be done. */ - if (unfinished_pindices.size() > 0) { - apply_remaining_offsets( - step_data, particle_allocator, system_info.offset_handlers, unfinished_pindices); - } - } + for (uint pindex : IndexRange(amount)) { + float mass = 1.0f; + float duration = remaining_durations[pindex]; - for (void *buffer : offset_buffers) { - buffer_cache.deallocate(buffer); + velocities[pindex] += duration * forces[pindex] / mass; + positions[pindex] += duration * velocities[pindex]; } } diff --git a/source/blender/simulations/bparticles/simulate.hpp b/source/blender/simulations/bparticles/simulate.hpp index 3c7eae9a9e9..0a79e770308 100644 --- a/source/blender/simulations/bparticles/simulate.hpp +++ b/source/blender/simulations/bparticles/simulate.hpp @@ -5,13 +5,14 @@ #include "event_interface.hpp" #include "offset_handler_interface.hpp" #include "emitter_interface.hpp" +#include "forces.hpp" #include "DNA_object_types.h" namespace BParticles { struct ParticleSystemInfo { - Integrator *integrator; + ArrayRef<Force *> forces; ArrayRef<Event *> events; ArrayRef<OffsetHandler *> offset_handlers; ArrayRef<Object *> collision_objects; |