[Bf-blender-cvs] [ccc8d664fca] functions: initial Spawn Action node
Jacques Lucke
noreply at git.blender.org
Tue Dec 17 13:54:06 CET 2019
Commit: ccc8d664fca0e4d5318b1a6a14445d74650811c9
Author: Jacques Lucke
Date: Tue Dec 17 13:28:38 2019 +0100
Branches: functions
https://developer.blender.org/rBccc8d664fca0e4d5318b1a6a14445d74650811c9
initial Spawn Action node
===================================================================
M source/blender/simulations/bparticles/action_interface.hpp
M source/blender/simulations/bparticles/actions.cpp
M source/blender/simulations/bparticles/actions.hpp
M source/blender/simulations/bparticles/emitters.cpp
M source/blender/simulations/bparticles/node_frontend.cpp
===================================================================
diff --git a/source/blender/simulations/bparticles/action_interface.hpp b/source/blender/simulations/bparticles/action_interface.hpp
index 7fdfc23e916..693044e663b 100644
--- a/source/blender/simulations/bparticles/action_interface.hpp
+++ b/source/blender/simulations/bparticles/action_interface.hpp
@@ -17,34 +17,6 @@ class ActionContext {
virtual ~ActionContext();
};
-class SourceParticleActionContext : public ActionContext {
- private:
- ArrayRef<uint> m_all_source_indices;
- ArrayRef<uint> m_current_source_indices;
- ActionContext *m_source_context;
-
- public:
- SourceParticleActionContext(ArrayRef<uint> source_indices, ActionContext *source_context)
- : m_all_source_indices(source_indices), m_source_context(source_context)
- {
- }
-
- void update(IndexRange slice)
- {
- m_current_source_indices = m_all_source_indices.slice(slice.start(), slice.size());
- }
-
- ArrayRef<uint> source_indices()
- {
- return m_current_source_indices;
- }
-
- ActionContext *source_context()
- {
- return m_source_context;
- }
-};
-
class ActionInterface {
private:
ParticleAllocator &m_particle_allocator;
@@ -94,8 +66,7 @@ class Action {
ActionContext *action_context = nullptr);
void execute_for_subset(ArrayRef<uint> pindices, ActionInterface &action_interface);
void execute_for_new_particles(AttributesRefGroup &new_particles,
- ActionInterface &action_interface,
- SourceParticleActionContext *action_context);
+ ActionInterface &action_interface);
void execute_for_new_particles(AttributesRefGroup &new_particles,
OffsetHandlerInterface &offset_handler_interface);
};
@@ -219,8 +190,7 @@ inline void Action::execute_for_subset(ArrayRef<uint> pindices, ActionInterface
}
inline void Action::execute_for_new_particles(AttributesRefGroup &new_particles,
- ActionInterface &action_interface,
- SourceParticleActionContext *action_context)
+ ActionInterface &action_interface)
{
AttributesInfo info;
std::array<void *, 0> buffers;
@@ -228,20 +198,21 @@ inline void Action::execute_for_new_particles(AttributesRefGroup &new_particles,
uint offset = 0;
for (AttributesRef attributes : new_particles) {
uint range_size = attributes.size();
- action_context->update(IndexRange(offset, range_size));
offset += range_size;
AttributesRef offsets(info, buffers, range_size);
LargeScopedArray<float> durations(range_size);
durations.fill(0);
+ EmptyActionContext empty_context;
+
ActionInterface new_interface(action_interface.particle_allocator(),
IndexRange(range_size).as_array_ref(),
attributes,
offsets,
attributes.get<float>("Birth Time"),
durations,
- *action_context);
+ empty_context);
this->execute(new_interface);
}
}
diff --git a/source/blender/simulations/bparticles/actions.cpp b/source/blender/simulations/bparticles/actions.cpp
index fa3a5b6f4b6..84cc606ca00 100644
--- a/source/blender/simulations/bparticles/actions.cpp
+++ b/source/blender/simulations/bparticles/actions.cpp
@@ -128,7 +128,6 @@ void ExplodeAction::execute(ActionInterface &interface)
Vector<float3> new_positions;
Vector<float3> new_velocities;
Vector<float> new_birth_times;
- Vector<uint> source_particles;
auto inputs = m_inputs_fn->compute(interface);
@@ -136,7 +135,6 @@ void ExplodeAction::execute(ActionInterface &interface)
uint parts_amount = std::max(0, inputs->get<int>("Amount", 0, pindex));
float speed = inputs->get<float>("Speed", 1, pindex);
- source_particles.append_n_times(pindex, parts_amount);
new_positions.append_n_times(positions[pindex], parts_amount);
new_birth_times.append_n_times(interface.current_times()[pindex], parts_amount);
@@ -153,9 +151,7 @@ void ExplodeAction::execute(ActionInterface &interface)
new_particles.fill<float>("Size", 0.1f);
new_particles.set<float>("Birth Time", new_birth_times);
- SourceParticleActionContext source_context(source_particles, &interface.context());
-
- m_on_birth_action.execute_for_new_particles(new_particles, interface, &source_context);
+ m_on_birth_action.execute_for_new_particles(new_particles, interface);
}
}
@@ -217,4 +213,162 @@ void SetAttributeAction::execute(ActionInterface &interface)
}
}
+using FN::MFDataType;
+using FN::MFParamType;
+
+void SpawnParticlesAction::execute(ActionInterface &interface)
+{
+ FN::MFMask mask(interface.pindices());
+ uint min_array_size = mask.min_array_size();
+ FN::MFParamsBuilder params_builder{m_spawn_function, min_array_size};
+
+ for (uint param_index : m_spawn_function.param_indices()) {
+ MFParamType param_type = m_spawn_function.param_type(param_index);
+ MFDataType data_type = param_type.data_type();
+ BLI_assert(param_type.is_output());
+ switch (param_type.data_type().category()) {
+ case MFDataType::Single: {
+ const FN::CPPType &type = data_type.single__cpp_type();
+ void *buffer = MEM_malloc_arrayN(min_array_size, type.size(), __func__);
+ FN::GenericMutableArrayRef array{type, buffer, min_array_size};
+ params_builder.add_single_output(array);
+ break;
+ }
+ case MFDataType::Vector: {
+ const FN::CPPType &base_type = data_type.vector__cpp_base_type();
+ FN::GenericVectorArray *vector_array = new FN::GenericVectorArray(base_type,
+ min_array_size);
+ params_builder.add_vector_output(*vector_array);
+ break;
+ }
+ }
+ }
+
+ FN::ParticleAttributesContext attributes_context = {interface.attributes()};
+
+ FN::MFContextBuilder context_builder;
+ context_builder.add_global_context(m_id_data_cache);
+ context_builder.add_global_context(m_id_handle_lookup);
+ context_builder.add_element_context(attributes_context, IndexRange(min_array_size));
+
+ m_spawn_function.call(mask, params_builder, context_builder);
+
+ LargeScopedArray<int> particle_counts(min_array_size, -1);
+
+ for (uint param_index : m_spawn_function.param_indices()) {
+ MFParamType param_type = m_spawn_function.param_type(param_index);
+ if (param_type.is_vector_output()) {
+ FN::GenericVectorArray &vector_array = params_builder.computed_vector_array(param_index);
+ for (uint i : interface.pindices()) {
+ FN::GenericArrayRef array = vector_array[i];
+ particle_counts[i] = std::max<int>(particle_counts[i], array.size());
+ }
+ }
+ }
+
+ for (uint i : interface.pindices()) {
+ if (particle_counts[i] == -1) {
+ particle_counts[i] = 1;
+ }
+ }
+
+ uint total_spawn_amount = 0;
+ for (uint i : interface.pindices()) {
+ total_spawn_amount += particle_counts[i];
+ }
+
+ StringMap<GenericMutableArrayRef> attribute_arrays;
+
+ Vector<float> new_birth_times;
+ for (uint i : interface.pindices()) {
+ new_birth_times.append_n_times(interface.current_times()[i], particle_counts[i]);
+ }
+ attribute_arrays.add_new("Birth Time", new_birth_times.as_mutable_ref());
+
+ for (uint param_index : m_spawn_function.param_indices()) {
+ MFParamType param_type = m_spawn_function.param_type(param_index);
+ MFDataType data_type = param_type.data_type();
+ StringRef attribute_name = m_attribute_names[param_index];
+
+ switch (data_type.category()) {
+ case MFDataType::Single: {
+ const FN::CPPType &type = data_type.single__cpp_type();
+ void *buffer = MEM_malloc_arrayN(total_spawn_amount, type.size(), __func__);
+ GenericMutableArrayRef array(type, buffer, total_spawn_amount);
+ GenericMutableArrayRef computed_array = params_builder.computed_array(param_index);
+
+ uint current = 0;
+ for (uint i : interface.pindices()) {
+ uint amount = particle_counts[i];
+ array.slice(current, amount).fill__uninitialized(computed_array[i]);
+ current += amount;
+ }
+
+ attribute_arrays.add(attribute_name, array);
+
+ computed_array.destruct_indices(interface.pindices());
+ MEM_freeN(computed_array.buffer());
+ break;
+ }
+ case MFDataType::Vector: {
+ const FN::CPPType &base_type = data_type.vector__cpp_base_type();
+ void *buffer = MEM_malloc_arrayN(total_spawn_amount, base_type.size(), __func__);
+ GenericMutableArrayRef array(base_type, buffer, total_spawn_amount);
+ FN::GenericVectorArray &computed_vector_array = params_builder.computed_vector_array(
+ param_index);
+
+ uint current = 0;
+ for (uint pindex : interface.pindices()) {
+ uint amount = particle_counts[pindex];
+ GenericMutableArrayRef array_slice = array.slice(current, amount);
+ GenericArrayRef computed_array = computed_vector_array[pindex];
+
+ if (computed_array.size() == 0) {
+ const void *default_buffer = interface.attributes().info().default_of(attribute_name);
+ array_slice.fill__uninitialized(default_buffer);
+ }
+ else if (computed_array.size() == amount) {
+ base_type.copy_to_uninitialized_n(
+ computed_array.buffer(), array_slice.buffer(), amount);
+ }
+ else {
+ for (uint i : IndexRange(amount)) {
+ base_type.copy_to_uninitialized(computed_array[i % computed_array.size()],
+ array_slice[i]);
+ }
+ }
+
+ current += amount;
+ }
+
+ attribute_arrays.add(attribute_name, array);
+
+ delete &computed_vector_array;
+ break;
+ }
+ }
+ }
+
+ for (StringRef system_name : m_systems_to_emit) {
+ auto new_particles = interface.parti
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list