diff options
Diffstat (limited to 'source/blender/nodes')
-rw-r--r-- | source/blender/nodes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/nodes/NOD_function.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/NOD_node_tree_multi_function.hh | 7 | ||||
-rw-r--r-- | source/blender/nodes/NOD_static_types.h | 2 | ||||
-rw-r--r-- | source/blender/nodes/function/nodes/node_fn_object_transforms.cc | 88 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_socket.cc | 56 |
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)); |