AnimTestbed/src/AnimGraph/AnimGraphData.h

360 lines
11 KiB
C
Raw Normal View History

2022-03-25 11:46:44 +01:00
//
// Created by martin on 25.03.22.
//
#ifndef ANIMTESTBED_ANIMGRAPHDATA_H
#define ANIMTESTBED_ANIMGRAPHDATA_H
#include <cstring>
#include <iostream>
2022-03-25 11:46:44 +01:00
#include <string>
#include <vector>
#include "SyncTrack.h"
#include "ozz/base/containers/vector.h"
#include <ozz/base/maths/soa_transform.h>
#include "ozz/animation/runtime/skeleton.h"
2022-03-25 11:46:44 +01:00
//
// Data types
//
struct AnimGraph;
struct AnimGraphContext {
AnimGraph* m_graph = nullptr;
ozz::animation::Skeleton* m_skeleton = nullptr;
};
2022-03-25 11:46:44 +01:00
struct AnimData {
ozz::vector<ozz::math::SoaTransform> m_local_matrices;
2022-03-25 11:46:44 +01:00
};
typedef float Vec3[3];
typedef float Quat[4];
enum class SocketType {
SocketTypeUndefined = 0,
SocketTypeBool,
SocketTypeAnimation,
SocketTypeFloat,
SocketTypeVec3,
SocketTypeQuat,
SocketTypeString,
SocketTypeLast
};
constexpr size_t cSocketStringValueMaxLength = 256;
2022-03-25 11:46:44 +01:00
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 {
bool flag;
float float_value;
float vec3[3];
float quat[4];
char str[cSocketStringValueMaxLength];
};
SocketValue m_value = { 0 };
union SocketReference {
2022-03-25 11:46:44 +01:00
void* ptr;
void** ptr_ptr;
};
SocketReference m_reference;
2022-03-25 11:46:44 +01:00
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_reference.ptr);
2022-03-25 11:46:44 +01:00
}
template <typename T>
void SetSocketReferenceValue(Socket* socket, T value) {
std::cerr << "Could not find template specialization for socket type "
<< static_cast<int>(socket->m_type) << " ("
<< SocketTypeNames[static_cast<int>(socket->m_type)] << ")."
<< std::endl;
// *static_cast<T*>(socket->m_value.ptr) = value;
}
2022-03-25 11:46:44 +01:00
template <typename T>
void SetSocketValue(Socket* socket, T value) {
std::cerr << "Could not find template specialization for socket type "
<< static_cast<int>(socket->m_type) << " ("
<< SocketTypeNames[static_cast<int>(socket->m_type)] << ")."
<< std::endl;
// *static_cast<T*>(socket->m_value.ptr) = value;
2022-03-25 11:46:44 +01:00
}
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_reference.ptr = value_ptr;
2022-03-25 11:46:44 +01:00
return true;
}
template <typename T>
bool RegisterProperty(const std::string& name, T* value) {
return RegisterSocket(m_properties, name, value);
}
template <typename T>
void SetPropertyReferenceValue(const std::string& name, T value) {
Socket* socket = FindSocket(m_properties, name);
SetSocketReferenceValue<T>(socket, value);
}
template <typename T>
void SetPropertyValue(const std::string& name, T value) {
Socket* socket = FindSocket(m_properties, name);
SetSocketValue<T>(socket, value);
2022-03-25 11:46:44 +01:00
}
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>
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);
}
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);
}
};
//
// SetSocketReferenceValue<> specializations
//
template <>
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const bool&>(Socket* socket, const bool& value) {
*static_cast<bool*>(socket->m_reference.ptr) = value;
}
template <>
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const float&>(Socket* socket, const float& value) {
*static_cast<float*>(socket->m_reference.ptr) = value;
}
template <>
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const Vec3&>(Socket* socket, const Vec3& value) {
static_cast<float*>(socket->m_reference.ptr)[0] = value[0];
static_cast<float*>(socket->m_reference.ptr)[1] = value[1];
static_cast<float*>(socket->m_reference.ptr)[2] = value[2];
}
template <>
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const Quat&>(Socket* socket, const Quat& value) {
static_cast<float*>(socket->m_reference.ptr)[0] = value[0];
static_cast<float*>(socket->m_reference.ptr)[1] = value[1];
static_cast<float*>(socket->m_reference.ptr)[2] = value[2];
static_cast<float*>(socket->m_reference.ptr)[3] = value[3];
}
template <>
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const std::string&>(Socket* socket, const std::string& value) {
*static_cast<std::string*>(socket->m_reference.ptr) = value;
}
template <>
inline void NodeSocketAccessorBase::SetSocketReferenceValue<const char*>(Socket* socket, const char* value) {
std::string value_string (value);
SetSocketReferenceValue<const std::string&>(socket, value_string);
}
//
// SetSocketValue<> specializations
//
template <>
inline void NodeSocketAccessorBase::SetSocketValue<const bool&>(Socket* socket, const bool& value) {
socket->m_value.flag = value;
}
template <>
inline void NodeSocketAccessorBase::SetSocketValue<const float&>(Socket* socket, const float& value) {
socket->m_value.float_value = value;
}
template <>
inline void NodeSocketAccessorBase::SetSocketValue<const Vec3&>(Socket* socket, const Vec3& value) {
socket->m_value.vec3[0] = value[0];
socket->m_value.vec3[1] = value[1];
socket->m_value.vec3[2] = value[2];
}
template <>
inline void NodeSocketAccessorBase::SetSocketValue<const Quat&>(Socket* socket, const Quat& value) {
socket->m_value.quat[0] = value[0];
socket->m_value.quat[1] = value[1];
socket->m_value.quat[2] = value[2];
socket->m_value.quat[3] = value[3];
}
template <>
inline void NodeSocketAccessorBase::SetSocketValue<const std::string&>(Socket* socket, const std::string& value) {
constexpr size_t string_max_length = sizeof(socket->m_value.str) - 1;
strncpy(socket->m_value.str, value.data(), string_max_length);
socket->m_value.str[value.size() > string_max_length ? string_max_length : value.size() ] = 0;
}
template <>
inline void NodeSocketAccessorBase::SetSocketValue<const char*>(Socket* socket, const char* value) {
SetSocketValue<const std::string&>(socket, value);
}
2022-03-25 11:46:44 +01:00
template <typename T>
struct NodeSocketAccessor : public NodeSocketAccessorBase {
virtual ~NodeSocketAccessor() {}
};
2022-03-25 11:46:44 +01:00
#endif //ANIMTESTBED_ANIMGRAPHDATA_H