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-21 18:20:05 +0300
committerJacques Lucke <jacques@blender.org>2020-07-21 18:35:09 +0300
commit8369adabc0ec7a1fce248b688bf20860ae0434bb (patch)
treeaf767efe8c6765c5876391a5eb96923fc8d6ac68 /source/blender/nodes
parent6c7e62ef9be564fbee279c7467c9b6adaf51b6c8 (diff)
Particles: initial object socket and emitter node support
Object sockets work now, but only the new Object Transforms and the Particle Mesh Emitter node use it. The emitter does not actually use the mesh surface yet. Instead, new particles are just emitted around the origin of the object. Internally, handles to object data blocks are passed around in the network, instead of raw object pointers. Using handles has a couple of benefits: * The caller of the function has control over which handles can be resolved and therefore limit access to specific data. The set of data blocks that is accessed by a node tree should be known statically. This is necessary for a proper integration with the dependency graph. * When the pointer to an object changes (e.g. after restarting Blender), all handles are still valid. * When an object is deleted, the handle is invalidated without causing crashes. * The handle is just an integer that can be stored per particle and can be cached easily. The mapping between handles and their corresponding data blocks is stored in the Simulation data block.
Diffstat (limited to 'source/blender/nodes')
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_function.h1
-rw-r--r--source/blender/nodes/NOD_node_tree_multi_function.hh7
-rw-r--r--source/blender/nodes/NOD_static_types.h2
-rw-r--r--source/blender/nodes/function/nodes/node_fn_object_transforms.cc88
-rw-r--r--source/blender/nodes/intern/node_socket.cc56
6 files changed, 153 insertions, 2 deletions
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index b3cb8163f2a..80720f5206a 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -135,6 +135,7 @@ set(SRC
function/nodes/node_fn_combine_strings.cc
function/nodes/node_fn_float_compare.cc
function/nodes/node_fn_group_instance_id.cc
+ function/nodes/node_fn_object_transforms.cc
function/nodes/node_fn_switch.cc
function/node_function_util.cc
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index 377ae8bfb84..4c05da694f7 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -26,6 +26,7 @@ void register_node_type_fn_float_compare(void);
void register_node_type_fn_switch(void);
void register_node_type_fn_group_instance_id(void);
void register_node_type_fn_combine_strings(void);
+void register_node_type_fn_object_transforms(void);
#ifdef __cplusplus
}
diff --git a/source/blender/nodes/NOD_node_tree_multi_function.hh b/source/blender/nodes/NOD_node_tree_multi_function.hh
index 79c2b3c7ce8..81b467eca3a 100644
--- a/source/blender/nodes/NOD_node_tree_multi_function.hh
+++ b/source/blender/nodes/NOD_node_tree_multi_function.hh
@@ -288,7 +288,12 @@ class SocketMFNetworkBuilder : public MFNetworkBuilderBase {
*/
template<typename T> void set_constant_value(T value)
{
- const fn::MultiFunction &fn = this->construct_fn<fn::CustomMF_Constant<T>>(std::move(value));
+ this->construct_generator_fn<fn::CustomMF_Constant<T>>(std::move(value));
+ }
+
+ template<typename T, typename... Args> void construct_generator_fn(Args &&... args)
+ {
+ const fn::MultiFunction &fn = this->construct_fn<T>(std::forward<Args>(args)...);
this->set_generator_fn(fn);
}
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 91aa11566d3..31ce3f81450 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -276,6 +276,8 @@ DefNode(FunctionNode, FN_NODE_FLOAT_COMPARE, def_float_compare, "FLOAT_COMPARE",
DefNode(FunctionNode, FN_NODE_SWITCH, def_fn_switch, "SWITCH", Switch, "Switch", "")
DefNode(FunctionNode, FN_NODE_GROUP_INSTANCE_ID, 0, "GROUP_INSTANCE_ID", GroupInstanceID, "Group Instance ID", "")
DefNode(FunctionNode, FN_NODE_COMBINE_STRINGS, 0, "COMBINE_STRINGS", CombineStrings, "Combine Strings", "")
+DefNode(FunctionNode, FN_NODE_OBJECT_TRANSFORMS, 0, "OBJECT_TRANSFORMS", ObjectTransforms, "Object Transforms", "")
+
/* undefine macros */
diff --git a/source/blender/nodes/function/nodes/node_fn_object_transforms.cc b/source/blender/nodes/function/nodes/node_fn_object_transforms.cc
new file mode 100644
index 00000000000..26b25406590
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_object_transforms.cc
@@ -0,0 +1,88 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_function_util.hh"
+
+#include "BKE_persistent_data_handle.hh"
+
+static bNodeSocketTemplate fn_node_object_transforms_in[] = {
+ {SOCK_OBJECT, N_("Object")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate fn_node_object_transforms_out[] = {
+ {SOCK_VECTOR, N_("Location")},
+ {-1, ""},
+};
+
+class ObjectTransformsFunction : public blender::fn::MultiFunction {
+ public:
+ ObjectTransformsFunction()
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Object Transforms");
+ signature.depends_on_context();
+ signature.single_input<blender::bke::PersistentObjectHandle>("Object");
+ signature.single_output<blender::float3>("Location");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext context) const override
+ {
+ blender::fn::VSpan handles =
+ params.readonly_single_input<blender::bke::PersistentObjectHandle>(0, "Object");
+ blender::MutableSpan locations = params.uninitialized_single_output<blender::float3>(
+ 1, "Location");
+
+ const blender::bke::PersistentDataHandleMap *handle_map =
+ context.get_global_context<blender::bke::PersistentDataHandleMap>(
+ "PersistentDataHandleMap");
+ if (handle_map == nullptr) {
+ locations.fill_indices(mask, {0, 0, 0});
+ return;
+ }
+
+ for (int64_t i : mask) {
+ blender::bke::PersistentObjectHandle handle = handles[i];
+ const Object *object = handle_map->lookup(handle);
+ blender::float3 location;
+ if (object == nullptr) {
+ location = {0, 0, 0};
+ }
+ else {
+ location = object->loc;
+ }
+ locations[i] = location;
+ }
+ }
+};
+
+static void fn_node_object_transforms_expand_in_mf_network(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static ObjectTransformsFunction fn;
+ builder.set_matching_fn(fn);
+}
+
+void register_node_type_fn_object_transforms()
+{
+ static bNodeType ntype;
+
+ fn_node_type_base(&ntype, FN_NODE_OBJECT_TRANSFORMS, "Object Transforms", 0, 0);
+ node_type_socket_templates(&ntype, fn_node_object_transforms_in, fn_node_object_transforms_out);
+ ntype.expand_in_mf_network = fn_node_object_transforms_expand_in_mf_network;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index 3a82438a211..49868505d68 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -34,6 +34,7 @@
#include "BKE_lib_id.h"
#include "BKE_node.h"
+#include "BKE_persistent_data_handle.hh"
#include "RNA_access.h"
#include "RNA_types.h"
@@ -583,6 +584,59 @@ static bNodeSocketType *make_socket_type_string()
return socktype;
}
+class ObjectSocketMultiFunction : public blender::fn::MultiFunction {
+ private:
+ const Object *object_;
+
+ public:
+ ObjectSocketMultiFunction(const Object *object) : object_(object)
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Object Socket");
+ signature.depends_on_context();
+ signature.single_output<blender::bke::PersistentObjectHandle>("Object");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext context) const override
+ {
+ blender::MutableSpan output =
+ params.uninitialized_single_output<blender::bke::PersistentObjectHandle>(0, "Object");
+
+ /* Try to get a handle map, so that the object can be converted to a handle. */
+ const blender::bke::PersistentDataHandleMap *handle_map =
+ context.get_global_context<blender::bke::PersistentDataHandleMap>(
+ "PersistentDataHandleMap");
+
+ if (handle_map == nullptr) {
+ /* Return empty handles when there is no handle map. */
+ output.fill_indices(mask, blender::bke::PersistentObjectHandle());
+ return;
+ }
+
+ blender::bke::PersistentObjectHandle handle = handle_map->lookup(object_);
+ for (int64_t i : mask) {
+ output[i] = handle;
+ }
+ }
+};
+
+MAKE_CPP_TYPE(PersistentObjectHandle, blender::bke::PersistentObjectHandle);
+
+static bNodeSocketType *make_socket_type_object()
+{
+ bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE);
+ socktype->get_mf_data_type = []() {
+ /* Objects are not passed along as raw pointers, but as handles. */
+ return blender::fn::MFDataType::ForSingle<blender::bke::PersistentObjectHandle>();
+ };
+ socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
+ const Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value;
+ builder.construct_generator_fn<ObjectSocketMultiFunction>(object);
+ };
+ return socktype;
+}
+
void register_standard_node_socket_types(void)
{
/* draw callbacks are set in drawnode.c to avoid bad-level calls */
@@ -615,7 +669,7 @@ void register_standard_node_socket_types(void)
nodeRegisterSocketType(make_standard_socket_type(SOCK_SHADER, PROP_NONE));
- nodeRegisterSocketType(make_standard_socket_type(SOCK_OBJECT, PROP_NONE));
+ nodeRegisterSocketType(make_socket_type_object());
nodeRegisterSocketType(make_standard_socket_type(SOCK_IMAGE, PROP_NONE));