// // Created by martin on 25.03.22. // #ifndef ANIMTESTBED_ANIMGRAPHDATA_H #define ANIMTESTBED_ANIMGRAPHDATA_H #include #include #include #include "SyncTrack.h" // // Data types // struct AnimData { float m_bone_transforms[16]; }; typedef float Vec3[3]; typedef float Quat[4]; enum class SocketType { SocketTypeUndefined = 0, SocketTypeBool, SocketTypeAnimation, SocketTypeFloat, SocketTypeVec3, SocketTypeQuat, SocketTypeString, SocketTypeLast }; static const char* SocketTypeNames[] = {"", "Bool", "Animation", "Float", "Vec3", "Quat", "String"}; enum SocketFlags { SocketFlagAffectsTime = 1 }; struct Socket { std::string m_name; SocketType m_type = SocketType::SocketTypeUndefined; union SocketValue { void* ptr; void** ptr_ptr; }; SocketValue m_value = {nullptr}; int m_flags = 0; size_t m_type_size = 0; }; struct NodeSocketAccessorBase { std::vector m_properties; std::vector m_inputs; std::vector m_outputs; NodeSocketAccessorBase() {} virtual ~NodeSocketAccessorBase() {} virtual void UpdateFlags(){}; Socket* FindSocket(std::vector& sockets, const std::string& name) { Socket* result = nullptr; for (size_t i = 0, n = sockets.size(); i < n; i++) { if (sockets[i].m_name == name) { result = &sockets[i]; break; } } return result; } const Socket* FindSocket( const std::vector& sockets, const std::string& name) const { const Socket* result = nullptr; for (size_t i = 0, n = sockets.size(); i < n; i++) { if (sockets[i].m_name == name) { result = &sockets[i]; break; } } return result; } SocketType GetSocketType( const std::vector& sockets, const std::string& name) { const Socket* socket = FindSocket(sockets, name); if (socket == nullptr) { return SocketType::SocketTypeUndefined; } return socket->m_type; } size_t GetSocketIndex( const std::vector& sockets, const std::string& name) const { for (size_t i = 0, n = sockets.size(); i < n; i++) { if (sockets[i].m_name == name) { return i; } } return -1; } template T GetSocketValue( const std::vector& sockets, const std::string& name, T default_value) { const Socket* socket = FindSocket(sockets, name); if (socket == nullptr) { return default_value; } return *static_cast(socket->m_value.ptr); } template void SetSocketValue( const std::vector& sockets, const std::string& name, const T& value) { const Socket* socket = FindSocket(sockets, name); if (socket == nullptr) { std::cerr << "Error: could not set value of socket with name " << name << ": no socket found." << std::endl; return; } *static_cast(socket->m_value.ptr) = value; } template bool RegisterSocket( std::vector& sockets, const std::string& name, T* value_ptr, int flags = 0) { Socket* socket = FindSocket(sockets, name); if (socket != nullptr) { std::cerr << "Socket " << name << " already registered." << std::endl; return false; } sockets.push_back(Socket()); socket = &sockets[sockets.size() - 1]; socket->m_name = name; socket->m_type_size = sizeof(T); socket->m_flags = flags; if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeFloat; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeBool; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeVec3; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeQuat; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeAnimation; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeString; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeFloat; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeBool; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeVec3; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeQuat; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeAnimation; } else if constexpr (std::is_same::value) { socket->m_type = SocketType::SocketTypeString; } else { std::cerr << "Cannot register socket, invalid type." << std::endl; return false; } socket->m_value.ptr = value_ptr; return true; } template bool RegisterProperty(const std::string& name, T* value) { return RegisterSocket(m_properties, name, value); } template void SetProperty(const std::string& name, const T& value) { SetSocketValue(m_properties, name, value); } template T GetProperty(const std::string& name, T default_value) { return GetSocketValue(m_properties, name, default_value); } SocketType GetPropertyType(const std::string& name) { return GetSocketType(m_properties, name); } template bool RegisterInput(const std::string& name, T** value, int flags = 0) { return RegisterSocket(m_inputs, name, value, flags); } template T* GetInput(const std::string& name, T* value) { return GetSocketValue(m_inputs, name, value); } Socket* FindInputSocket(const std::string& name) { return FindSocket(m_inputs, name); } SocketType GetInputType(const std::string& name) { return GetSocketType(m_inputs, name); } size_t GetInputIndex(const std::string& name) { return GetSocketIndex(m_inputs, name); } template bool RegisterOutput(const std::string& name, T* value, int flags = 0) { return RegisterSocket(m_outputs, name, value, flags); } template bool RegisterOutput(const std::string& name, T** value, int flags = 0) { return RegisterSocket(m_outputs, name, value, flags); } SocketType GetOutputType(const std::string& name) { return GetSocketType(m_outputs, name); } Socket* FindOutputSocket(const std::string& name) { return FindSocket(m_outputs, name); } size_t GetOutputIndex(const std::string& name) { return GetSocketIndex(m_outputs, name); } }; template struct NodeSocketAccessor : public NodeSocketAccessorBase { virtual ~NodeSocketAccessor() {} }; #endif //ANIMTESTBED_ANIMGRAPHDATA_H