2022-03-25 11:46:44 +01:00
|
|
|
//
|
|
|
|
// Created by martin on 25.03.22.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef ANIMTESTBED_ANIMGRAPHDATA_H
|
|
|
|
#define ANIMTESTBED_ANIMGRAPHDATA_H
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#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<Socket> m_properties;
|
|
|
|
std::vector<Socket> m_inputs;
|
|
|
|
std::vector<Socket> m_outputs;
|
|
|
|
|
|
|
|
NodeSocketAccessorBase() {}
|
|
|
|
virtual ~NodeSocketAccessorBase() {}
|
|
|
|
|
|
|
|
virtual void UpdateFlags(){};
|
|
|
|
|
|
|
|
Socket* FindSocket(std::vector<Socket>& 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<Socket>& 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<Socket>& 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<Socket>& 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 <typename T>
|
|
|
|
T GetSocketValue(
|
|
|
|
const std::vector<Socket>& sockets,
|
|
|
|
const std::string& name,
|
|
|
|
T default_value) {
|
|
|
|
const Socket* socket = FindSocket(sockets, name);
|
|
|
|
if (socket == nullptr) {
|
|
|
|
return default_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *static_cast<T*>(socket->m_value.ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void SetSocketValue(
|
|
|
|
const std::vector<Socket>& 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<T*>(socket->m_value.ptr) = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool RegisterSocket(
|
|
|
|
std::vector<Socket>& 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<T, float>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeFloat;
|
|
|
|
} else if constexpr (std::is_same<T, bool>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeBool;
|
|
|
|
} else if constexpr (std::is_same<T, Vec3>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeVec3;
|
|
|
|
} else if constexpr (std::is_same<T, Quat>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeQuat;
|
|
|
|
} else if constexpr (std::is_same<T, AnimData>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeAnimation;
|
|
|
|
} else if constexpr (std::is_same<T, std::string>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeString;
|
|
|
|
} else if constexpr (std::is_same<T, float*>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeFloat;
|
|
|
|
} else if constexpr (std::is_same<T, bool*>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeBool;
|
|
|
|
} else if constexpr (std::is_same<T, Vec3*>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeVec3;
|
|
|
|
} else if constexpr (std::is_same<T, Quat*>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeQuat;
|
|
|
|
} else if constexpr (std::is_same<T, AnimData*>::value) {
|
|
|
|
socket->m_type = SocketType::SocketTypeAnimation;
|
|
|
|
} else if constexpr (std::is_same<T, std::string*>::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 <typename T>
|
|
|
|
bool RegisterProperty(const std::string& name, T* value) {
|
|
|
|
return RegisterSocket(m_properties, name, value);
|
|
|
|
}
|
|
|
|
template <typename T>
|
|
|
|
void SetProperty(const std::string& name, const T& value) {
|
|
|
|
SetSocketValue(m_properties, name, value);
|
|
|
|
}
|
|
|
|
template <typename T>
|
|
|
|
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 <typename T>
|
2022-04-01 13:19:54 +02:00
|
|
|
bool RegisterInput(const std::string& name, T** value, int flags = 0) {
|
2022-03-25 11:46:44 +01:00
|
|
|
return RegisterSocket(m_inputs, name, value, flags);
|
|
|
|
}
|
|
|
|
template <typename T>
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-04-01 13:19:54 +02:00
|
|
|
template <typename T>
|
|
|
|
bool RegisterOutput(const std::string& name, T* value, int flags = 0) {
|
|
|
|
return RegisterSocket(m_outputs, name, value, flags);
|
|
|
|
}
|
2022-03-25 11:46:44 +01:00
|
|
|
template <typename T>
|
|
|
|
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 <typename T>
|
|
|
|
struct NodeSocketAccessor : public NodeSocketAccessorBase {
|
|
|
|
virtual ~NodeSocketAccessor() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif //ANIMTESTBED_ANIMGRAPHDATA_H
|