WIP AnimGraph instantiation.
This commit is contained in:
@@ -43,7 +43,7 @@ void AnimGraphEditorUpdate() {
|
||||
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && ImNodes::IsEditorHovered()
|
||||
&& ImGui::IsMouseReleased(ImGuiMouseButton_Right)) {
|
||||
AnimNodeResource node_resource = AnimNodeResourceFactory("Blend2");
|
||||
AnimNodeResource node_resource = AnimNodeResourceFactory("SpeedScale");
|
||||
size_t node_id = gGraphResource.m_nodes.size();
|
||||
ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos());
|
||||
gGraphResource.m_nodes.push_back(node_resource);
|
||||
|
||||
@@ -88,6 +88,9 @@ AnimGraphConnection sAnimGraphConnectionFromJson(const json& json_node) {
|
||||
void AnimGraphResource::clear() {
|
||||
m_name = "";
|
||||
m_nodes.clear();
|
||||
|
||||
m_nodes.push_back(AnimNodeResourceFactory("BlendTree"));
|
||||
|
||||
m_connections.clear();
|
||||
}
|
||||
|
||||
|
||||
+90
-17
@@ -62,12 +62,14 @@ struct Socket {
|
||||
Vec3* vec3;
|
||||
Quat* quat;
|
||||
std::string* str;
|
||||
void* ptr;
|
||||
bool** flag_ptr;
|
||||
AnimData** anim_data_ptr;
|
||||
float** real_ptr;
|
||||
float** vec3_ptr;
|
||||
float** quat_ptr;
|
||||
std::string** str_ptr;
|
||||
void** ptr_ptr;
|
||||
};
|
||||
Value m_value;
|
||||
};
|
||||
@@ -111,16 +113,43 @@ struct NodeSocketAccessorBase {
|
||||
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::vector<Socket>& sockets,
|
||||
const std::string& name) {
|
||||
Socket* socket = FindSocket(m_properties, 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++) {
|
||||
std::cout << i << ", " << sockets[i].m_name << std::endl;
|
||||
if (sockets[i].m_name == name) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool RegisterSocket(
|
||||
std::vector<Socket>& sockets,
|
||||
@@ -294,9 +323,15 @@ struct NodeSocketAccessorBase {
|
||||
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) {
|
||||
@@ -309,6 +344,12 @@ struct NodeSocketAccessorBase {
|
||||
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);
|
||||
}
|
||||
|
||||
std::vector<Socket> m_properties;
|
||||
std::vector<Socket> m_inputs;
|
||||
@@ -327,6 +368,13 @@ struct NodeRegistry {
|
||||
AnimNode* node);
|
||||
};
|
||||
|
||||
struct BlendTreeNode : public AnimNode {};
|
||||
|
||||
template <>
|
||||
struct NodeSocketAccessor<BlendTreeNode> : public NodeSocketAccessorBase {
|
||||
NodeSocketAccessor(AnimNode* node_) : NodeSocketAccessorBase(node_) {}
|
||||
};
|
||||
|
||||
struct Blend2Node : public AnimNode {
|
||||
AnimData m_input0;
|
||||
AnimData m_input1;
|
||||
@@ -392,21 +440,41 @@ struct AnimGraphResource {
|
||||
std::string m_name;
|
||||
std::vector<AnimNodeResource> m_nodes;
|
||||
std::vector<AnimGraphConnection> m_connections;
|
||||
std::vector<Socket> m_inputs;
|
||||
std::vector<Socket> m_outputs;
|
||||
|
||||
~AnimGraphResource() {
|
||||
for (size_t i = 0, n = m_nodes.size(); i < n; i++) {
|
||||
delete m_nodes[i].m_anim_node;
|
||||
delete m_nodes[i].m_socket_accessor;
|
||||
}
|
||||
}
|
||||
|
||||
AnimGraphResource() { clear(); }
|
||||
|
||||
void clear();
|
||||
bool saveToFile(const char* filename) const;
|
||||
bool loadFromFile(const char* filename);
|
||||
|
||||
size_t addNode(AnimNodeResource node_resource) {
|
||||
m_nodes.push_back(node_resource);
|
||||
return m_nodes.size() - 1;
|
||||
}
|
||||
};
|
||||
|
||||
static inline AnimNode* AnimNodeFactory(const std::string& name) {
|
||||
AnimNode* result;
|
||||
if (name == "Blend2") {
|
||||
return new Blend2Node;
|
||||
result = new Blend2Node;
|
||||
} else if (name == "SpeedScale") {
|
||||
return new SpeedScaleNode;
|
||||
result = new SpeedScaleNode;
|
||||
} else if (name == "AnimSampler") {
|
||||
return new AnimSamplerNode;
|
||||
result = new AnimSamplerNode;
|
||||
} else if (name == "BlendTree") {
|
||||
result = new BlendTreeNode;
|
||||
}
|
||||
|
||||
if (result != nullptr) {
|
||||
result->m_node_type_name = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::cerr << "Invalid node type: " << name << std::endl;
|
||||
@@ -422,6 +490,8 @@ static inline NodeSocketAccessorBase* AnimNodeAccessorFactory(
|
||||
return new NodeSocketAccessor<SpeedScaleNode>(node);
|
||||
} else if (node_type_name == "AnimSampler") {
|
||||
return new NodeSocketAccessor<AnimSamplerNode>(node);
|
||||
} else if (node_type_name == "BlendTree") {
|
||||
return new NodeSocketAccessor<BlendTreeNode>(node);
|
||||
} else {
|
||||
std::cerr << "Invalid node type name " << node_type_name << "."
|
||||
<< std::endl;
|
||||
@@ -529,23 +599,26 @@ struct AnimGraph {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (source_node_accessor->m_outputs[connection.m_source_socket_index].m_type
|
||||
!= target_node_accessor->m_inputs[connection.m_target_socket_index].m_type) {
|
||||
if (source_node_accessor->m_outputs[connection.m_source_socket_index]
|
||||
.m_type
|
||||
!= target_node_accessor->m_inputs[connection.m_target_socket_index]
|
||||
.m_type) {
|
||||
std::cerr << "Invalid connection connecting nodes '" << source_node_name
|
||||
<< "' and '" << target_node_name << "'." << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO! How to wire up the different types?
|
||||
// std::string socket_name = connection.m_target_socket_name;
|
||||
// AnimData* input_ref =
|
||||
// target_node_accessor->GetInput<AnimData>(socket_name, nullptr);
|
||||
// source_node_accessor->SetOutputRef(
|
||||
// connection.m_source_socket_name,
|
||||
// input_ref);
|
||||
Socket* source_socket =
|
||||
&source_node_accessor->m_outputs[connection.m_source_socket_index];
|
||||
Socket* target_socket =
|
||||
&target_node_accessor->m_inputs[connection.m_target_socket_index];
|
||||
if (source_socket->m_type != target_socket->m_type) {
|
||||
std::cerr << "Cannot connect sockets: invalid types!" << std::endl;
|
||||
}
|
||||
|
||||
(*source_socket->m_value.ptr_ptr) = target_socket->m_value.ptr;
|
||||
|
||||
size_t target_node_index = result.getAnimNodeIndex(target_node);
|
||||
|
||||
result.m_node_inputs[target_node_index].push_back(source_node);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user