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:
authorJacques Lucke <jacques@blender.org>2020-07-28 13:03:02 +0300
committerJacques Lucke <jacques@blender.org>2020-07-28 13:10:37 +0300
commit3b9e16a4f7b8deca23ba8d2a02ef9182eb9d6bb4 (patch)
tree210485641412e442d0d6fee197b022b04b7fdeda /source/blender/simulation
parentc8e45c3fe96ebbb4c75df568cc72a05421921a7e (diff)
Particles: initial support for the Time input node
Diffstat (limited to 'source/blender/simulation')
-rw-r--r--source/blender/simulation/intern/particle_function.cc6
-rw-r--r--source/blender/simulation/intern/particle_function.hh7
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.cc95
3 files changed, 97 insertions, 11 deletions
diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc
index d1e9019a85a..035e6d50e21 100644
--- a/source/blender/simulation/intern/particle_function.cc
+++ b/source/blender/simulation/intern/particle_function.cc
@@ -116,8 +116,9 @@ void ParticleFunctionEvaluator::compute_globals()
fn::MFParamsBuilder params(*particle_fn_.global_fn_, mask_.min_array_size());
/* Add input parameters. */
+ ParticleFunctionInputContext input_context{solve_context_, particles_};
for (const ParticleFunctionInput *input : particle_fn_.global_inputs_) {
- input->add_input(particles_.attributes, params, resources_);
+ input->add_input(input_context, params, resources_);
}
/* Add output parameters. */
@@ -143,8 +144,9 @@ void ParticleFunctionEvaluator::compute_per_particle()
fn::MFParamsBuilder params(*particle_fn_.per_particle_fn_, mask_.min_array_size());
/* Add input parameters. */
+ ParticleFunctionInputContext input_context{solve_context_, particles_};
for (const ParticleFunctionInput *input : particle_fn_.per_particle_inputs_) {
- input->add_input(particles_.attributes, params, resources_);
+ input->add_input(input_context, params, resources_);
}
/* Add output parameters. */
diff --git a/source/blender/simulation/intern/particle_function.hh b/source/blender/simulation/intern/particle_function.hh
index abe0aae8522..c9b35640b47 100644
--- a/source/blender/simulation/intern/particle_function.hh
+++ b/source/blender/simulation/intern/particle_function.hh
@@ -26,10 +26,15 @@
namespace blender::sim {
+struct ParticleFunctionInputContext {
+ const SimulationSolveContext &solve_context;
+ const ParticleChunkContext &particles;
+};
+
class ParticleFunctionInput {
public:
virtual ~ParticleFunctionInput() = default;
- virtual void add_input(fn::AttributesRef attributes,
+ virtual void add_input(ParticleFunctionInputContext &context,
fn::MFParamsBuilder &params,
ResourceCollector &resources) const = 0;
};
diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc
index 40a29c95d25..4d339f9e323 100644
--- a/source/blender/simulation/intern/simulation_collect_influences.cc
+++ b/source/blender/simulation/intern/simulation_collect_influences.cc
@@ -28,12 +28,15 @@
#include "BLI_hash.h"
#include "BLI_rand.hh"
+#include "BLI_set.hh"
namespace blender::sim {
using fn::GVSpan;
using fn::MFContextBuilder;
using fn::MFDataType;
+using fn::MFDummyNode;
+using fn::MFFunctionNode;
using fn::MFInputSocket;
using fn::MFNetwork;
using fn::MFNetworkEvaluator;
@@ -53,6 +56,8 @@ using nodes::NodeTreeRefMap;
struct DummyDataSources {
Map<const MFOutputSocket *, std::string> particle_attributes;
+ Set<const MFOutputSocket *> simulation_time;
+ Set<const MFOutputSocket *> scene_time;
};
extern "C" {
@@ -226,6 +231,47 @@ static void prepare_particle_attribute_nodes(CollectContext &context)
}
}
+static void prepare_time_input_nodes(CollectContext &context)
+{
+ Span<const DNode *> time_input_dnodes = nodes_by_type(context, "SimulationNodeTime");
+ Vector<const DNode *> simulation_time_inputs;
+ Vector<const DNode *> scene_time_inputs;
+ for (const DNode *dnode : time_input_dnodes) {
+ NodeSimInputTimeType type = (NodeSimInputTimeType)dnode->node_ref().bnode()->custom1;
+ switch (type) {
+ case NODE_SIM_INPUT_SIMULATION_TIME: {
+ simulation_time_inputs.append(dnode);
+ break;
+ }
+ case NODE_SIM_INPUT_SCENE_TIME: {
+ scene_time_inputs.append(dnode);
+ break;
+ }
+ }
+ }
+
+ if (simulation_time_inputs.size() > 0) {
+ MFOutputSocket &new_socket = context.network.add_input("Simulation Time",
+ MFDataType::ForSingle<float>());
+ for (const DNode *dnode : simulation_time_inputs) {
+ MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+ context.network.relink(old_socket, new_socket);
+ context.network.remove(old_socket.node());
+ }
+ context.data_sources.simulation_time.add(&new_socket);
+ }
+ if (scene_time_inputs.size() > 0) {
+ MFOutputSocket &new_socket = context.network.add_input("Scene Time",
+ MFDataType::ForSingle<float>());
+ for (const DNode *dnode : scene_time_inputs) {
+ MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+ context.network.relink(old_socket, new_socket);
+ context.network.remove(old_socket.node());
+ }
+ context.data_sources.scene_time.add(&new_socket);
+ }
+}
+
class ParticleAttributeInput : public ParticleFunctionInput {
private:
std::string attribute_name_;
@@ -237,11 +283,12 @@ class ParticleAttributeInput : public ParticleFunctionInput {
{
}
- void add_input(AttributesRef attributes,
+ void add_input(ParticleFunctionInputContext &context,
MFParamsBuilder &params,
ResourceCollector &UNUSED(resources)) const override
{
- std::optional<GSpan> span = attributes.try_get(attribute_name_, attribute_type_);
+ std::optional<GSpan> span = context.particles.attributes.try_get(attribute_name_,
+ attribute_type_);
if (span.has_value()) {
params.add_readonly_single_input(*span);
}
@@ -251,6 +298,29 @@ class ParticleAttributeInput : public ParticleFunctionInput {
}
};
+class SceneTimeInput : public ParticleFunctionInput {
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
+ ResourceCollector &resources) const override
+ {
+ const float time = DEG_get_ctime(&context.solve_context.depsgraph);
+ float *time_ptr = &resources.construct<float>(AT, time);
+ params.add_readonly_single_input(time_ptr);
+ }
+};
+
+class SimulationTimeInput : public ParticleFunctionInput {
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
+ ResourceCollector &resources) const override
+ {
+ /* TODO: Vary this per particle. */
+ const float time = context.solve_context.solve_interval.stop();
+ float *time_ptr = &resources.construct<float>(AT, time);
+ params.add_readonly_single_input(time_ptr);
+ }
+};
+
static const ParticleFunction *create_particle_function_for_inputs(
CollectContext &context, Span<const MFInputSocket *> sockets_to_compute)
{
@@ -264,13 +334,21 @@ static const ParticleFunction *create_particle_function_for_inputs(
Vector<const ParticleFunctionInput *> per_particle_inputs;
for (const MFOutputSocket *socket : dummy_deps) {
- const std::string *attribute_name = context.data_sources.particle_attributes.lookup_ptr(
- socket);
- if (attribute_name == nullptr) {
- return nullptr;
+ if (context.data_sources.particle_attributes.contains(socket)) {
+ const std::string *attribute_name = context.data_sources.particle_attributes.lookup_ptr(
+ socket);
+ if (attribute_name == nullptr) {
+ return nullptr;
+ }
+ per_particle_inputs.append(&context.resources.construct<ParticleAttributeInput>(
+ AT, *attribute_name, socket->data_type().single_type()));
+ }
+ else if (context.data_sources.scene_time.contains(socket)) {
+ per_particle_inputs.append(&context.resources.construct<SceneTimeInput>(AT));
+ }
+ else if (context.data_sources.simulation_time.contains(socket)) {
+ per_particle_inputs.append(&context.resources.construct<SimulationTimeInput>(AT));
}
- per_particle_inputs.append(&context.resources.construct<ParticleAttributeInput>(
- AT, *attribute_name, socket->data_type().single_type()));
}
const MultiFunction &per_particle_fn = context.resources.construct<MFNetworkEvaluator>(
@@ -689,6 +767,7 @@ void collect_simulation_influences(Simulation &simulation,
initialize_particle_attribute_builders(context);
prepare_particle_attribute_nodes(context);
+ prepare_time_input_nodes(context);
collect_forces(context);
collect_emitters(context);