diff --git a/src/AnimGraph/AnimGraphEditor.cc b/src/AnimGraph/AnimGraphEditor.cc index d3b98f9..0f5513f 100644 --- a/src/AnimGraph/AnimGraphEditor.cc +++ b/src/AnimGraph/AnimGraphEditor.cc @@ -13,8 +13,7 @@ #include "imnodes.h" #include "misc/cpp/imgui_stdlib.h" -static AnimGraphResource sGraphGresource = - AnimGraphResource(); +static AnimGraphResource sGraphGresource = AnimGraphResource(); static bool sGraphLoadedThisFrame = false; ImNodesPinShape sGetSocketShapeFromSocketType(const SocketType& socket_type) { @@ -58,14 +57,14 @@ void NodeSocketEditor(Socket& socket) { } } -void RemoveConnectionsForSocket( - AnimGraphResource& graph_resource, - AnimNodeResource& node_resource, +void RemoveBlendTreeConnectionsForSocket( + BlendTreeResource& blend_tree_resource, + AnimNodeResource* node_resource, Socket& socket) { std::vector::iterator iter = - graph_resource.m_blend_tree_resource.m_connections.begin(); + blend_tree_resource.m_connections.begin(); - while (iter != graph_resource.m_blend_tree_resource.m_connections.end()) { + while (iter != blend_tree_resource.m_connections.end()) { // TODO adjust for refactor assert(false); @@ -160,24 +159,24 @@ void SkinnedMeshWidget(SkinnedMesh* skinned_mesh) { } void AnimGraphEditorRenderSidebar( - AnimGraphBlendTreeResource& graph_resource, - AnimNodeResource& node_resource) { - ImGui::Text("[%s]", node_resource.m_node_type_name.c_str()); + BlendTreeResource& blend_tree_resource, + AnimNodeResource* node_resource) { + ImGui::Text("[%s]", node_resource->m_node_type_name.c_str()); char node_name_buffer[256]; memset(node_name_buffer, 0, sizeof(node_name_buffer)); strncpy( node_name_buffer, - node_resource.m_name.c_str(), - std::min(node_resource.m_name.size(), sizeof(node_name_buffer))); + node_resource->m_name.c_str(), + std::min(node_resource->m_name.size(), sizeof(node_name_buffer))); if (ImGui::InputText("Name", node_name_buffer, sizeof(node_name_buffer))) { - node_resource.m_name = node_name_buffer; + node_resource->m_name = node_name_buffer; } - int num_properties = node_resource.m_socket_accessor->m_properties.size(); + int num_properties = node_resource->m_socket_accessor->m_properties.size(); for (int i = 0; i < num_properties; i++) { - Socket& property = node_resource.m_socket_accessor->m_properties[i]; + Socket& property = node_resource->m_socket_accessor->m_properties[i]; if (property.m_type == SocketType::SocketTypeInt) { ImGui::InputInt( property.m_name.c_str(), @@ -212,11 +211,11 @@ void AnimGraphEditorRenderSidebar( } } - if (&node_resource == &graph_resource.getGraphOutputNode()) { + if (node_resource == blend_tree_resource.GetGraphOutputNode()) { ImGui::Text("Outputs"); // Graph outputs are the inputs of the output node! - std::vector& outputs = node_resource.m_socket_accessor->m_inputs; + std::vector& outputs = node_resource->m_socket_accessor->m_inputs; std::vector::iterator iter = outputs.begin(); while (iter != outputs.end()) { @@ -224,7 +223,10 @@ void AnimGraphEditorRenderSidebar( ImGui::PushID(&output); NodeSocketEditor(output); if (ImGui::Button("X")) { - RemoveConnectionsForSocket(graph_resource, node_resource, output); + RemoveBlendTreeConnectionsForSocket( + blend_tree_resource, + node_resource, + output); iter = outputs.erase(iter); } else { iter++; @@ -233,11 +235,11 @@ void AnimGraphEditorRenderSidebar( } } - if (&node_resource == &graph_resource.getGraphInputNode()) { + if (node_resource == blend_tree_resource.GetGraphInputNode()) { ImGui::Text("Inputs"); // Graph inputs are the outputs of the input node! - std::vector& inputs = node_resource.m_socket_accessor->m_outputs; + std::vector& inputs = node_resource->m_socket_accessor->m_outputs; std::vector::iterator iter = inputs.begin(); while (iter != inputs.end()) { @@ -245,7 +247,10 @@ void AnimGraphEditorRenderSidebar( ImGui::PushID(&input); NodeSocketEditor(input); if (ImGui::Button("X")) { - RemoveConnectionsForSocket(graph_resource, node_resource, input); + RemoveBlendTreeConnectionsForSocket( + blend_tree_resource, + node_resource, + input); iter = inputs.erase(iter); } else { iter++; @@ -258,10 +263,10 @@ void AnimGraphEditorRenderSidebar( void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { ImGui::BeginMenuBar(); if (ImGui::Button("Save")) { - sGraphGresource.saveToFile("editor_graph.json"); + sGraphGresource.SaveToFile("editor_graph.json"); } if (ImGui::Button("Load")) { - sGraphGresource.loadFromFile("editor_graph.json"); + sGraphGresource.LoadFromFile("editor_graph.json"); sGraphLoadedThisFrame = true; // for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) { @@ -272,7 +277,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { // } } if (ImGui::Button("Clear")) { - sGraphGresource.clear(); + sGraphGresource.Clear(); } char graph_name_buffer[256]; memset(graph_name_buffer, 0, sizeof(graph_name_buffer)); @@ -293,9 +298,12 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { ax::NodeEditor::Begin("Graph Editor"); #if 1 - for (size_t node_id = 0, n = sGraphGresource.m_nodes.size(); node_id < n; + for (size_t node_id = 0, + n = sGraphGresource.m_blend_tree_resource.m_nodes.size(); + node_id < n; node_id++) { - AnimNodeResource& node_resource = sGraphGresource.m_nodes[node_id]; + AnimNodeResource* node_resource = + sGraphGresource.m_blend_tree_resource.m_nodes[node_id]; if (node_id == 0 || node_id == 1) { // continue; @@ -304,14 +312,14 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { if (sGraphLoadedThisFrame) { ax::NodeEditor::SetNodePosition( node_id, - ImVec2(node_resource.m_position[0], node_resource.m_position[1])); + ImVec2(node_resource->m_position[0], node_resource->m_position[1])); } ax::NodeEditor::BeginNode(node_id); - ImGui::Text("%s", node_resource.m_node_type_name.c_str()); + ImGui::Text("%s", node_resource->m_node_type_name.c_str()); // Inputs std::vector& node_inputs = - node_resource.m_socket_accessor->m_inputs; + node_resource->m_socket_accessor->m_inputs; for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) { Socket& socket = node_inputs[j]; ax::NodeEditor::BeginPin( @@ -323,7 +331,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { // Outputs std::vector& node_outputs = - node_resource.m_socket_accessor->m_outputs; + node_resource->m_socket_accessor->m_outputs; for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) { Socket& socket = node_outputs[j]; ax::NodeEditor::BeginPin( @@ -337,26 +345,39 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { } int link_id = 0; - for (size_t connection_id = 0, n = sGraphGresource.m_connections.size(); connection_id < n; + for (size_t connection_id = 0, + n = sGraphGresource.m_blend_tree_resource.m_connections.size(); + connection_id < n; connection_id++) { - const AnimGraphConnectionResource& connection_resource = sGraphGresource.m_connections[connection_id]; + const BlendTreeConnectionResource& connection_resource = + sGraphGresource.m_blend_tree_resource.m_connections[connection_id]; - const AnimNodeResource& source_node_resource = sGraphGresource.m_nodes[connection_resource.source_node_index]; - int source_socket_index = source_node_resource.m_socket_accessor->GetOutputIndex(connection_resource.source_socket_name.c_str()); + const AnimNodeResource* source_node_resource = + sGraphGresource.m_blend_tree_resource + .m_nodes[connection_resource.source_node_index]; + int source_socket_index = + source_node_resource->m_socket_accessor->GetOutputIndex( + connection_resource.source_socket_name.c_str()); - const AnimNodeResource& target_node_resource = sGraphGresource.m_nodes[connection_resource.target_node_index]; - int target_socket_index = target_node_resource.m_socket_accessor->GetInputIndex(connection_resource.target_socket_name.c_str()); + const AnimNodeResource* target_node_resource = + sGraphGresource.m_blend_tree_resource + .m_nodes[connection_resource.target_node_index]; + int target_socket_index = + target_node_resource->m_socket_accessor->GetInputIndex( + connection_resource.target_socket_name.c_str()); - int source_socket_id = GetNodeOutputSocketId(static_cast(connection_resource.source_node_index), source_socket_index); - int target_socket_id = GetNodeInputSocketId(static_cast(connection_resource.target_node_index), target_socket_index); + int source_socket_id = GetNodeOutputSocketId( + static_cast(connection_resource.source_node_index), + source_socket_index); + int target_socket_id = GetNodeInputSocketId( + static_cast(connection_resource.target_node_index), + target_socket_index); ax::NodeEditor::Link(link_id++, source_socket_id, target_socket_id); } - #endif - #if 1 // Create Connections if (ax::NodeEditor::BeginCreate()) { @@ -381,20 +402,23 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) { void LegacyAnimGraphEditorUpdate() { ImGui::BeginMenuBar(); if (ImGui::Button("Save")) { - sGraphGresource.saveToFile("editor_graph.json"); + sGraphGresource.SaveToFile("editor_graph.json"); } if (ImGui::Button("Load")) { - sGraphGresource.loadFromFile("editor_graph.json"); + sGraphGresource.LoadFromFile("editor_graph.json"); - for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) { - const AnimNodeResource& node_resource = sGraphGresource.m_nodes[i]; + for (size_t i = 0, n = sGraphGresource.m_blend_tree_resource.m_nodes.size(); + i < n; + i++) { + const AnimNodeResource* node_resource = + sGraphGresource.m_blend_tree_resource.m_nodes[i]; ImNodes::SetNodeGridSpacePos( i, - ImVec2(node_resource.m_position[0], node_resource.m_position[1])); + ImVec2(node_resource->m_position[0], node_resource->m_position[1])); } } if (ImGui::Button("Clear")) { - sGraphGresource.clear(); + sGraphGresource.Clear(); } char graph_name_buffer[256]; memset(graph_name_buffer, 0, sizeof(graph_name_buffer)); @@ -459,11 +483,11 @@ void LegacyAnimGraphEditorUpdate() { } if (node_type_name != "") { - AnimNodeResource node_resource = + AnimNodeResource* node_resource = AnimNodeResourceFactory(node_type_name); - size_t node_id = sGraphGresource.m_nodes.size(); + size_t node_id = sGraphGresource.m_blend_tree_resource.m_nodes.size(); ImNodes::SetNodeScreenSpacePos(node_id, ImGui::GetMousePos()); - sGraphGresource.m_nodes.push_back(node_resource); + sGraphGresource.m_blend_tree_resource.m_nodes.push_back(node_resource); } ImGui::EndPopup(); @@ -472,26 +496,32 @@ void LegacyAnimGraphEditorUpdate() { ImGui::PopStyleVar(ImGuiStyleVar_WindowPadding); } - for (size_t i = 0, n = sGraphGresource.m_nodes.size(); i < n; i++) { - AnimNodeResource& node_resource = sGraphGresource.m_nodes[i]; + for (size_t i = 0, n = sGraphGresource.m_blend_tree_resource.m_nodes.size(); + i < n; + i++) { + AnimNodeResource* node_resource = + sGraphGresource.m_blend_tree_resource.m_nodes[i]; ImNodes::BeginNode(i); ImGui::PushItemWidth(110.0f); // Header ImNodes::BeginNodeTitleBar(); - if (&node_resource == &sGraphGresource.getGraphOutputNode()) { + if (node_resource + == sGraphGresource.m_blend_tree_resource.GetGraphOutputNode()) { ImGui::TextUnformatted("Graph Outputs"); - } else if (&node_resource == &sGraphGresource.getGraphInputNode()) { + } else if ( + node_resource + == sGraphGresource.m_blend_tree_resource.GetGraphInputNode()) { ImGui::TextUnformatted("Graph Inputs"); } else { - ImGui::TextUnformatted(node_resource.m_node_type_name.c_str()); + ImGui::TextUnformatted(node_resource->m_node_type_name.c_str()); } ImNodes::EndNodeTitleBar(); // Inputs std::vector& node_inputs = - node_resource.m_socket_accessor->m_inputs; + node_resource->m_socket_accessor->m_inputs; for (size_t j = 0, ni = node_inputs.size(); j < ni; j++) { Socket& socket = node_inputs[j]; @@ -507,7 +537,9 @@ void LegacyAnimGraphEditorUpdate() { ImGui::TextUnformatted(socket.m_name.c_str()); bool socket_connected = - sGraphGresource.isSocketConnected(node_resource, socket.m_name); + sGraphGresource.m_blend_tree_resource.IsSocketConnected( + node_resource, + socket.m_name); if (!socket_connected && (socket.m_type == SocketType::SocketTypeFloat)) { ImGui::SameLine(); float socket_value = socket.m_value.float_value; @@ -537,7 +569,7 @@ void LegacyAnimGraphEditorUpdate() { // Outputs const std::vector& node_outputs = - node_resource.m_socket_accessor->m_outputs; + node_resource->m_socket_accessor->m_outputs; for (size_t j = 0, ni = node_outputs.size(); j < ni; j++) { const Socket& socket = node_outputs[j]; ImNodes::BeginOutputAttribute( @@ -553,27 +585,27 @@ void LegacyAnimGraphEditorUpdate() { // Graph output node if (i == 0) { if (ImGui::Button("+Output")) { - AnimNodeResource& graph_output_node = - sGraphGresource.getGraphOutputNode(); + AnimNodeResource* graph_output_node = + sGraphGresource.m_blend_tree_resource.GetGraphOutputNode(); static float bla = 0.f; std::string socket_name = "Output"; socket_name += std::to_string( - graph_output_node.m_socket_accessor->m_inputs.size()); - graph_output_node.m_socket_accessor->RegisterInput( + graph_output_node->m_socket_accessor->m_inputs.size()); + graph_output_node->m_socket_accessor->RegisterInput( socket_name.c_str(), nullptr); } } else if (i == 1) { if (ImGui::Button("+Input")) { - AnimNodeResource& graph_input_node = - sGraphGresource.getGraphInputNode(); + AnimNodeResource* graph_input_node = + sGraphGresource.m_blend_tree_resource.GetGraphInputNode(); static float bla = 0.f; std::string socket_name = "Input"; socket_name += std::to_string( - graph_input_node.m_socket_accessor->m_outputs.size()); - graph_input_node.m_socket_accessor->RegisterOutput( + graph_input_node->m_socket_accessor->m_outputs.size()); + graph_input_node->m_socket_accessor->RegisterOutput( socket_name.c_str(), nullptr); } @@ -581,29 +613,34 @@ void LegacyAnimGraphEditorUpdate() { // Save state in node resource ImVec2 node_pos = ImNodes::GetNodeGridSpacePos(i); - node_resource.m_position[0] = node_pos[0]; - node_resource.m_position[1] = node_pos[1]; + node_resource->m_position[0] = node_pos[0]; + node_resource->m_position[1] = node_pos[1]; ImGui::PopItemWidth(); ImNodes::EndNode(); // Ensure flags such as SocketFlagAffectsTime are properly set. - node_resource.m_socket_accessor->UpdateFlags(); + node_resource->m_socket_accessor->UpdateFlags(); } - for (size_t i = 0, n = sGraphGresource.m_connections.size(); i < n; i++) { - const AnimGraphConnectionResource& connection = - sGraphGresource.m_connections[i]; + for (size_t i = 0, + n = sGraphGresource.m_blend_tree_resource.m_connections.size(); + i < n; + i++) { + const BlendTreeConnectionResource& connection = + sGraphGresource.m_blend_tree_resource.m_connections[i]; int start_attr, end_attr; - const AnimNodeResource& source_node = - sGraphGresource.m_nodes[connection.source_node_index]; - int source_socket_index = source_node.m_socket_accessor->GetOutputIndex( + const AnimNodeResource* source_node = + sGraphGresource.m_blend_tree_resource + .m_nodes[connection.source_node_index]; + int source_socket_index = source_node->m_socket_accessor->GetOutputIndex( connection.source_socket_name.c_str()); - const AnimNodeResource& target_node = - sGraphGresource.m_nodes[connection.target_node_index]; - int target_socket_index = target_node.m_socket_accessor->GetInputIndex( + const AnimNodeResource* target_node = + sGraphGresource.m_blend_tree_resource + .m_nodes[connection.target_node_index]; + int target_socket_index = target_node->m_socket_accessor->GetInputIndex( connection.target_socket_name.c_str()); start_attr = GenerateOutputAttributeId( @@ -632,20 +669,21 @@ void LegacyAnimGraphEditorUpdate() { int node_end_input_index; SplitInputAttributeId(end_attr, &node_end_id, &node_end_input_index); - AnimGraphConnectionResource connection; + BlendTreeConnectionResource connection; connection.source_node_index = node_start_id; - const AnimNodeResource& source_node = - sGraphGresource.m_nodes[node_start_id]; + const AnimNodeResource* source_node = + sGraphGresource.m_blend_tree_resource.m_nodes[node_start_id]; connection.source_socket_name = - source_node.m_socket_accessor->m_outputs[node_start_output_index] + source_node->m_socket_accessor->m_outputs[node_start_output_index] .m_name; connection.target_node_index = node_end_id; - const AnimNodeResource& target_node = sGraphGresource.m_nodes[node_end_id]; + const AnimNodeResource* target_node = + sGraphGresource.m_blend_tree_resource.m_nodes[node_end_id]; connection.target_socket_name = - target_node.m_socket_accessor->m_inputs[node_end_input_index].m_name; + target_node->m_socket_accessor->m_inputs[node_end_input_index].m_name; - sGraphGresource.m_connections.push_back(connection); + sGraphGresource.m_blend_tree_resource.m_connections.push_back(connection); } if (ImGui::IsKeyPressed(ImGuiKey_Delete, false)) { @@ -655,8 +693,8 @@ void LegacyAnimGraphEditorUpdate() { // Handle link detachements. int link_id = 0; if (ImNodes::IsLinkDestroyed(&link_id)) { - sGraphGresource.m_connections.erase( - sGraphGresource.m_connections.begin() + link_id); + sGraphGresource.m_blend_tree_resource.m_connections.erase( + sGraphGresource.m_blend_tree_resource.m_connections.begin() + link_id); } int selected_nodes[ImNodes::NumSelectedNodes()]; @@ -668,16 +706,19 @@ void LegacyAnimGraphEditorUpdate() { ImGui::NextColumn(); if (ImNodes::NumSelectedNodes() == 1) { - if (selected_nodes[0] < sGraphGresource.m_nodes.size()) { - AnimNodeResource& selected_node = - sGraphGresource.m_nodes[selected_nodes[0]]; - AnimGraphEditorRenderSidebar(sGraphGresource, selected_node); + if (selected_nodes[0] + < sGraphGresource.m_blend_tree_resource.m_nodes.size()) { + AnimNodeResource* selected_node = + sGraphGresource.m_blend_tree_resource.m_nodes[selected_nodes[0]]; + AnimGraphEditorRenderSidebar( + sGraphGresource.m_blend_tree_resource, + selected_node); } } ImGui::Columns(1); } -void AnimGraphEditorGetRuntimeGraph(AnimGraph& anim_graph) { - sGraphGresource.createInstance(anim_graph); +void AnimGraphEditorGetRuntimeGraph(AnimGraphBlendTree& blend_tree) { + sGraphGresource.CreateBlendTreeInstance(blend_tree); } \ No newline at end of file diff --git a/src/AnimGraph/AnimGraphEditor.h b/src/AnimGraph/AnimGraphEditor.h index 08686b1..31814b6 100644 --- a/src/AnimGraph/AnimGraphEditor.h +++ b/src/AnimGraph/AnimGraphEditor.h @@ -10,6 +10,8 @@ struct EditorContext; } // namespace ax::NodeEditor struct SkinnedMesh; +struct AnimGraphBlendTree; +struct SyncTrack; inline int GenerateInputAttributeId(int node_id, int input_index) { return ((input_index + 1) << 14) + node_id; @@ -39,6 +41,6 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context); void LegacyAnimGraphEditorUpdate(); -void AnimGraphEditorGetRuntimeGraph(AnimGraph& anim_graph); +void AnimGraphEditorGetRuntimeGraph(AnimGraphBlendTree& anim_graph); #endif //ANIMTESTBED_ANIMGRAPHEDITOR_H diff --git a/src/AnimGraph/AnimGraphNodes.h b/src/AnimGraph/AnimGraphNodes.h index c7ef514..54cc3cd 100644 --- a/src/AnimGraph/AnimGraphNodes.h +++ b/src/AnimGraph/AnimGraphNodes.h @@ -115,8 +115,8 @@ struct AnimSamplerNode : public AnimNode { ozz::animation::SamplingJob::Context m_sampling_context; ozz::animation::Animation* m_animation = nullptr; - virtual ~AnimSamplerNode(); - virtual bool Init(AnimGraphContext& context) override; + ~AnimSamplerNode() noexcept override; + bool Init(AnimGraphContext& context) override; void UpdateTime(float time_last, float time_now) override { m_time_last = time_last; m_time_now = time_now; diff --git a/src/AnimGraph/AnimGraphResource.h b/src/AnimGraph/AnimGraphResource.h index 5558443..7138af0 100644 --- a/src/AnimGraph/AnimGraphResource.h +++ b/src/AnimGraph/AnimGraphResource.h @@ -107,6 +107,13 @@ struct BlendTreeResource { return result; } + bool IsSocketConnected( + const AnimNodeResource* source_node, + const std::string& socket_name) { + assert(false && "Not yet implemented"); + return false; + } + size_t GetNodeIndexForOutputSocket(const std::string& socket_name) const { for (size_t i = 0; i < m_connections.size(); i++) { const BlendTreeConnectionResource& connection = m_connections[i]; @@ -156,6 +163,7 @@ struct AnimGraphResource : AnimNodeResource { BlendTreeResource m_blend_tree_resource; StateMachineResource m_state_machine_resource; + void Clear() { m_blend_tree_resource.Reset(); } bool SaveToFile(const char* filename) const; bool LoadFromFile(const char* filename);