From 9dd10e8f2754253563c291bf6e32806772573c4b Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Wed, 29 Mar 2023 22:25:09 +0200 Subject: [PATCH] Initial version of NodeDescriptor which aims to replace NodeSocketAccessor. --- CMakeLists.txt | 1 + src/AnimGraph/AnimGraphData.h | 131 +++++++++++++++++++++++++++++++++ src/AnimGraph/AnimGraphNodes.h | 14 ++++ tests/NodeDescriptorTests.cc | 37 ++++++++++ 4 files changed, 183 insertions(+) create mode 100644 tests/NodeDescriptorTests.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index e72cef3..4e3ec64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,7 @@ set(ozz_offline_test_objs target_sources(runtests PRIVATE tests/AnimGraphResourceTests.cc tests/AnimGraphEvalTests.cc + tests/NodeDescriptorTests.cc tests/SyncTrackTests.cc tests/main.cc ${ozz_offline_test_objs} diff --git a/src/AnimGraph/AnimGraphData.h b/src/AnimGraph/AnimGraphData.h index 6c8ac39..9b2cdeb 100644 --- a/src/AnimGraph/AnimGraphData.h +++ b/src/AnimGraph/AnimGraphData.h @@ -145,6 +145,137 @@ struct Socket { size_t m_type_size = 0; }; +template +SocketType GetSocketType() { + if constexpr (std::is_same::value) { + return SocketType::SocketTypeBool; + } + + if constexpr (std::is_same::value) { + return SocketType::SocketTypeAnimation; + } + + if constexpr (std::is_same::value) { + return SocketType::SocketTypeFloat; + } + + if constexpr (std::is_same::value) { + return SocketType::SocketTypeVec3; + } + + if constexpr (std::is_same::value) { + return SocketType::SocketTypeQuat; + } + + if constexpr (std::is_same::value) { + return SocketType::SocketTypeString; + } + + assert(false && "This should not be reachable"); + abort(); + return SocketType::SocketTypeUndefined; +} + +struct NodeDescriptorBase { + std::vector m_properties; + std::vector m_inputs; + std::vector m_outputs; + + template + bool RegisterInput(const char* name, T** value_ptr_ptr) { + return RegisterSocket(name, value_ptr_ptr, m_inputs); + } + + template + bool RegisterOutput(const char* name, T** value_ptr_ptr) { + return RegisterSocket(name, value_ptr_ptr, m_outputs); + } + + template + bool RegisterProperty(const char* name, T* value_ptr, int flags = 0) { + for (int i = 0; i < m_properties.size(); i++) { + if (m_properties[i].m_name == name) { + return false; + } + } + + Socket socket; + socket.m_name = name; + socket.m_type = GetSocketType(); + socket.m_reference.ptr = static_cast(value_ptr); + socket.m_flags = flags; + socket.m_type_size = sizeof(T); + + m_properties.push_back(socket); + + return true; + } + + template + T* GetInput(const char* name) { + Socket* socket = FindSocket(name, m_inputs); + assert(GetSocketType() == socket->m_type); + return *socket->m_reference.ptr_ptr; + } + + template + void SetInput(const char* name, T* value_ptr) { + Socket* socket = FindSocket(name, m_inputs); + assert(GetSocketType() == socket->m_type); + *socket->m_reference.ptr_ptr = value_ptr; + } + + template + void SetProperty(const char* name, const T& value) { + Socket* socket = FindSocket(name, m_properties); + assert(GetSocketType() == socket->m_type); + *static_cast(socket->m_reference.ptr) = value; + } + + template + const T& GetProperty(const char* name) { + Socket* socket = FindSocket(name, m_properties); + assert(GetSocketType() == socket->m_type); + return *static_cast(socket->m_reference.ptr); + } + + private: + Socket* FindSocket(const char* name, std::vector& sockets) { + for (int i = 0, n = sockets.size(); i < n; i++) { + if (sockets[i].m_name == name) { + return &sockets[i]; + } + } + + return nullptr; + } + + template + bool RegisterSocket(const char* name, T** value_ptr_ptr, std::vector& sockets) { + for (int i = 0; i < sockets.size(); i++) { + if (sockets[i].m_name == name) { + return false; + } + } + + Socket socket; + socket.m_name = name; + socket.m_type = GetSocketType(); + socket.m_reference.ptr_ptr = (void**)(value_ptr_ptr); + socket.m_type_size = sizeof(T); + + sockets.push_back(socket); + + return true; + } +}; + +template +struct NodeDescriptor : public NodeDescriptorBase { + virtual ~NodeDescriptor() {} +}; + + struct NodeSocketAccessorBase { std::vector m_properties; std::vector m_inputs; diff --git a/src/AnimGraph/AnimGraphNodes.h b/src/AnimGraph/AnimGraphNodes.h index 678d9f1..7507be7 100644 --- a/src/AnimGraph/AnimGraphNodes.h +++ b/src/AnimGraph/AnimGraphNodes.h @@ -150,6 +150,20 @@ struct NodeSocketAccessor : public NodeSocketAccessorBase { } }; +template <> +struct NodeDescriptor : public NodeDescriptorBase { + NodeDescriptor(Blend2Node* node) { + RegisterInput("Input0", &node->i_input0); + RegisterInput("Input1", &node->i_input1); + RegisterInput("Weight", &node->i_blend_weight); + + RegisterOutput("Output", &node->o_output); + + RegisterProperty("Sync", &node->m_sync_blend); + } +}; + + // // SpeedScaleNode // diff --git a/tests/NodeDescriptorTests.cc b/tests/NodeDescriptorTests.cc new file mode 100644 index 0000000..574461a --- /dev/null +++ b/tests/NodeDescriptorTests.cc @@ -0,0 +1,37 @@ +// +// Created by martin on 04.02.22. +// + +#include "AnimGraph/AnimGraphData.h" +#include "AnimGraph/AnimGraphNodes.h" +#include "catch.hpp" + +TEST_CASE("Descriptor Access", "[NodeDescriptorTests]") { + Blend2Node blend2Node; + NodeDescriptor blend2Descriptor (&blend2Node); + CHECK(blend2Descriptor.m_inputs.size() == 3); + CHECK(*blend2Descriptor.m_inputs[0].m_reference.ptr_ptr == blend2Node.i_input0); + CHECK(*blend2Descriptor.m_inputs[1].m_reference.ptr_ptr == blend2Node.i_input1); + CHECK(*blend2Descriptor.m_inputs[2].m_reference.ptr_ptr == blend2Node.i_blend_weight); + + CHECK(blend2Descriptor.m_inputs[0].m_type_size == sizeof(AnimData)); + CHECK(blend2Descriptor.m_inputs[2].m_type_size == 4); + + CHECK(blend2Descriptor.m_outputs.size() == 1); + CHECK(*blend2Descriptor.m_outputs[0].m_reference.ptr_ptr == blend2Node.o_output); + + CHECK(blend2Descriptor.m_properties.size() == 1); + CHECK(blend2Descriptor.m_properties[0].m_reference.ptr == &blend2Node.m_sync_blend); + + CHECK(blend2Node.i_input0 == nullptr); + AnimData some_anim_data; + blend2Descriptor.SetInput("Input0", &some_anim_data); + CHECK(blend2Node.i_input0 == &some_anim_data); + + CHECK(blend2Node.m_sync_blend == false); + CHECK(blend2Descriptor.GetProperty("Sync") == false); + blend2Descriptor.SetProperty("Sync", true); + CHECK(blend2Node.m_sync_blend == true); + CHECK(blend2Descriptor.GetProperty("Sync") == true); +} +