Properly store and restore node positions in editor.

RefactorUnifiedBlendTreeStateMachineHandling
Martin Felis 2024-05-01 12:50:16 +02:00
parent 7c7a765455
commit 84fc49af30
2 changed files with 39 additions and 18 deletions

View File

@ -160,7 +160,11 @@ void SkinnedMeshWidget(SkinnedMesh* skinned_mesh) {
void AnimGraphEditorRenderSidebar(
BlendTreeResource& blend_tree_resource,
AnimNodeResource* node_resource) {
ImGui::Text("[%s]", node_resource->m_node_type_name.c_str());
ImGui::Text(
"[%s (%2.2f, %2.2f)]",
node_resource->m_node_type_name.c_str(),
node_resource->m_position[0],
node_resource->m_position[1]);
char node_name_buffer[256];
memset(node_name_buffer, 0, sizeof(node_name_buffer));
@ -263,7 +267,10 @@ void AnimGraphEditorRenderSidebar(
}
void AnimGraphEditorClear() {
sEditorState.hierarchyStack.clear();
if (ax::NodeEditor::GetCurrentEditor() != nullptr) {
ax::NodeEditor::ClearSelection();
}
delete sEditorState.rootGraphResource;
sEditorState.rootGraphResource = new AnimGraphResource();
@ -271,9 +278,11 @@ void AnimGraphEditorClear() {
sEditorState.rootGraphResource->m_graph_type_name = "BlendTree";
sEditorState.rootGraphResource->m_blend_tree_resource.InitGraphConnectors();
sEditorState.hierarchyStack.clear();
sEditorState.hierarchyStack.push_back(sEditorState.rootGraphResource);
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex] =
sEditorState.hierarchyStack.back();
sEditorState.hierarchyStackIndex = 0;
}
void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
@ -287,6 +296,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
sEditorState.rootGraphResource->SaveToFile("editor_graph.json");
}
if (ImGui::Button("Load")) {
AnimGraphEditorClear();
sEditorState.rootGraphResource->LoadFromFile("editor_graph.json");
sEditorState.isGraphLoadedThisFrame = true;
}
@ -348,18 +358,15 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
//
ax::NodeEditor::Begin("Graph Editor");
for (size_t node_id = 0,
for (size_t node_index = 0,
n = sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
->m_blend_tree_resource.GetNumNodes();
node_id < n;
node_id++) {
node_index < n;
node_index++) {
AnimNodeResource* node_resource =
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
->m_blend_tree_resource.GetNode(node_id);
if (node_id == 0 || node_id == 1) {
// continue;
}
->m_blend_tree_resource.GetNode(node_index);
ax::NodeEditor::NodeId node_id(node_resource);
if (sEditorState.isGraphLoadedThisFrame) {
ax::NodeEditor::SetNodePosition(
@ -377,7 +384,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
Socket& socket = node_inputs[j];
ax::NodeEditor::BeginPin(
NodeIndexAndSocketIndexToInputPinId(
static_cast<int>(node_id),
static_cast<int>(node_index),
static_cast<int>(j)),
ax::NodeEditor::PinKind::Input);
ImGui::Text("%s", socket.m_name.c_str());
@ -392,7 +399,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
Socket& socket = node_outputs[j];
ax::NodeEditor::BeginPin(
NodeIndexAndSocketIndexToOutputPinId(
static_cast<int>(node_id),
static_cast<int>(node_index),
static_cast<int>(j)),
ax::NodeEditor::PinKind::Output);
ImGui::Text("%s", socket.m_name.c_str());
@ -597,22 +604,32 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
AnimGraphEditorRenderSidebar(
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
->m_blend_tree_resource,
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
->m_blend_tree_resource.GetNode(selected_node_id.Get()));
selected_node_id.AsPointer<AnimNodeResource>());
}
}
ImGui::Columns(1);
// Clear flag, however it may be re-set further down when handling double
// clicking into subgraphs.
sEditorState.isGraphLoadedThisFrame = false;
//
// Handle double click into subgraphs
//
ax::NodeEditor::NodeId double_clicked_node_id =
ax::NodeEditor::GetDoubleClickedNode();
if (!double_clicked_node_id.Invalid) {
AnimNodeResource* clicked_node_resource =
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
->m_blend_tree_resource.GetNode(double_clicked_node_id.Get());
if (clicked_node_resource->m_node_type_name == "BlendTree") {
double_clicked_node_id.AsPointer<AnimNodeResource>();
if (clicked_node_resource != nullptr
&& clicked_node_resource->m_node_type_name == "BlendTree") {
AnimGraphResource* clicked_graph_resource =
dynamic_cast<AnimGraphResource*>(clicked_node_resource);
assert(clicked_graph_resource != nullptr);
if (sEditorState.hierarchyStack.size()
> sEditorState.hierarchyStackIndex + 1
&& sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex + 1]
@ -625,12 +642,12 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
sEditorState.hierarchyStackIndex++;
}
sEditorState.isGraphLoadedThisFrame = true;
ax::NodeEditor::ClearSelection();
}
}
ax::NodeEditor::SetCurrentEditor(nullptr);
sEditorState.isGraphLoadedThisFrame = false;
}
void AnimGraphEditorGetRuntimeGraph(AnimGraphBlendTree& blend_tree) {

View File

@ -256,6 +256,8 @@ static json sAnimGraphResourceBlendTreeToJson(
result["name"] = anim_graph_resource.m_name;
result["type"] = "AnimNodeResource";
result["node_type"] = "BlendTree";
result["position"][0] = anim_graph_resource.m_position[0];
result["position"][1] = anim_graph_resource.m_position[1];
const BlendTreeResource& blend_tree_resource =
anim_graph_resource.m_blend_tree_resource;
@ -307,6 +309,8 @@ static bool sAnimGraphResourceBlendTreeFromJson(
result_graph_resource->m_graph_type_name = "BlendTree";
result_graph_resource->m_node_type_name = "BlendTree";
result_graph_resource->m_name = json_data["name"];
result_graph_resource->m_position[0] = json_data["position"][0];
result_graph_resource->m_position[1] = json_data["position"][1];
// Load nodes
for (size_t i = 0, n = json_data["nodes"].size(); i < n; i++) {