Properly store and restore node positions in editor.
parent
7c7a765455
commit
84fc49af30
|
@ -160,7 +160,11 @@ void SkinnedMeshWidget(SkinnedMesh* skinned_mesh) {
|
||||||
void AnimGraphEditorRenderSidebar(
|
void AnimGraphEditorRenderSidebar(
|
||||||
BlendTreeResource& blend_tree_resource,
|
BlendTreeResource& blend_tree_resource,
|
||||||
AnimNodeResource* node_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];
|
char node_name_buffer[256];
|
||||||
memset(node_name_buffer, 0, sizeof(node_name_buffer));
|
memset(node_name_buffer, 0, sizeof(node_name_buffer));
|
||||||
|
@ -263,7 +267,10 @@ void AnimGraphEditorRenderSidebar(
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimGraphEditorClear() {
|
void AnimGraphEditorClear() {
|
||||||
sEditorState.hierarchyStack.clear();
|
if (ax::NodeEditor::GetCurrentEditor() != nullptr) {
|
||||||
|
ax::NodeEditor::ClearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
delete sEditorState.rootGraphResource;
|
delete sEditorState.rootGraphResource;
|
||||||
|
|
||||||
sEditorState.rootGraphResource = new AnimGraphResource();
|
sEditorState.rootGraphResource = new AnimGraphResource();
|
||||||
|
@ -271,9 +278,11 @@ void AnimGraphEditorClear() {
|
||||||
sEditorState.rootGraphResource->m_graph_type_name = "BlendTree";
|
sEditorState.rootGraphResource->m_graph_type_name = "BlendTree";
|
||||||
sEditorState.rootGraphResource->m_blend_tree_resource.InitGraphConnectors();
|
sEditorState.rootGraphResource->m_blend_tree_resource.InitGraphConnectors();
|
||||||
|
|
||||||
|
sEditorState.hierarchyStack.clear();
|
||||||
sEditorState.hierarchyStack.push_back(sEditorState.rootGraphResource);
|
sEditorState.hierarchyStack.push_back(sEditorState.rootGraphResource);
|
||||||
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex] =
|
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex] =
|
||||||
sEditorState.hierarchyStack.back();
|
sEditorState.hierarchyStack.back();
|
||||||
|
sEditorState.hierarchyStackIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
||||||
|
@ -287,6 +296,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
||||||
sEditorState.rootGraphResource->SaveToFile("editor_graph.json");
|
sEditorState.rootGraphResource->SaveToFile("editor_graph.json");
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Load")) {
|
if (ImGui::Button("Load")) {
|
||||||
|
AnimGraphEditorClear();
|
||||||
sEditorState.rootGraphResource->LoadFromFile("editor_graph.json");
|
sEditorState.rootGraphResource->LoadFromFile("editor_graph.json");
|
||||||
sEditorState.isGraphLoadedThisFrame = true;
|
sEditorState.isGraphLoadedThisFrame = true;
|
||||||
}
|
}
|
||||||
|
@ -348,18 +358,15 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
||||||
//
|
//
|
||||||
ax::NodeEditor::Begin("Graph Editor");
|
ax::NodeEditor::Begin("Graph Editor");
|
||||||
|
|
||||||
for (size_t node_id = 0,
|
for (size_t node_index = 0,
|
||||||
n = sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
n = sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
||||||
->m_blend_tree_resource.GetNumNodes();
|
->m_blend_tree_resource.GetNumNodes();
|
||||||
node_id < n;
|
node_index < n;
|
||||||
node_id++) {
|
node_index++) {
|
||||||
AnimNodeResource* node_resource =
|
AnimNodeResource* node_resource =
|
||||||
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
||||||
->m_blend_tree_resource.GetNode(node_id);
|
->m_blend_tree_resource.GetNode(node_index);
|
||||||
|
ax::NodeEditor::NodeId node_id(node_resource);
|
||||||
if (node_id == 0 || node_id == 1) {
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sEditorState.isGraphLoadedThisFrame) {
|
if (sEditorState.isGraphLoadedThisFrame) {
|
||||||
ax::NodeEditor::SetNodePosition(
|
ax::NodeEditor::SetNodePosition(
|
||||||
|
@ -377,7 +384,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
||||||
Socket& socket = node_inputs[j];
|
Socket& socket = node_inputs[j];
|
||||||
ax::NodeEditor::BeginPin(
|
ax::NodeEditor::BeginPin(
|
||||||
NodeIndexAndSocketIndexToInputPinId(
|
NodeIndexAndSocketIndexToInputPinId(
|
||||||
static_cast<int>(node_id),
|
static_cast<int>(node_index),
|
||||||
static_cast<int>(j)),
|
static_cast<int>(j)),
|
||||||
ax::NodeEditor::PinKind::Input);
|
ax::NodeEditor::PinKind::Input);
|
||||||
ImGui::Text("%s", socket.m_name.c_str());
|
ImGui::Text("%s", socket.m_name.c_str());
|
||||||
|
@ -392,7 +399,7 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
||||||
Socket& socket = node_outputs[j];
|
Socket& socket = node_outputs[j];
|
||||||
ax::NodeEditor::BeginPin(
|
ax::NodeEditor::BeginPin(
|
||||||
NodeIndexAndSocketIndexToOutputPinId(
|
NodeIndexAndSocketIndexToOutputPinId(
|
||||||
static_cast<int>(node_id),
|
static_cast<int>(node_index),
|
||||||
static_cast<int>(j)),
|
static_cast<int>(j)),
|
||||||
ax::NodeEditor::PinKind::Output);
|
ax::NodeEditor::PinKind::Output);
|
||||||
ImGui::Text("%s", socket.m_name.c_str());
|
ImGui::Text("%s", socket.m_name.c_str());
|
||||||
|
@ -597,22 +604,32 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
||||||
AnimGraphEditorRenderSidebar(
|
AnimGraphEditorRenderSidebar(
|
||||||
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
||||||
->m_blend_tree_resource,
|
->m_blend_tree_resource,
|
||||||
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
selected_node_id.AsPointer<AnimNodeResource>());
|
||||||
->m_blend_tree_resource.GetNode(selected_node_id.Get()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Columns(1);
|
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::NodeId double_clicked_node_id =
|
||||||
ax::NodeEditor::GetDoubleClickedNode();
|
ax::NodeEditor::GetDoubleClickedNode();
|
||||||
if (!double_clicked_node_id.Invalid) {
|
if (!double_clicked_node_id.Invalid) {
|
||||||
AnimNodeResource* clicked_node_resource =
|
AnimNodeResource* clicked_node_resource =
|
||||||
sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex]
|
double_clicked_node_id.AsPointer<AnimNodeResource>();
|
||||||
->m_blend_tree_resource.GetNode(double_clicked_node_id.Get());
|
|
||||||
if (clicked_node_resource->m_node_type_name == "BlendTree") {
|
if (clicked_node_resource != nullptr
|
||||||
|
&& clicked_node_resource->m_node_type_name == "BlendTree") {
|
||||||
AnimGraphResource* clicked_graph_resource =
|
AnimGraphResource* clicked_graph_resource =
|
||||||
dynamic_cast<AnimGraphResource*>(clicked_node_resource);
|
dynamic_cast<AnimGraphResource*>(clicked_node_resource);
|
||||||
|
|
||||||
|
assert(clicked_graph_resource != nullptr);
|
||||||
|
|
||||||
if (sEditorState.hierarchyStack.size()
|
if (sEditorState.hierarchyStack.size()
|
||||||
> sEditorState.hierarchyStackIndex + 1
|
> sEditorState.hierarchyStackIndex + 1
|
||||||
&& sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex + 1]
|
&& sEditorState.hierarchyStack[sEditorState.hierarchyStackIndex + 1]
|
||||||
|
@ -625,12 +642,12 @@ void AnimGraphEditorUpdate(ax::NodeEditor::EditorContext* context) {
|
||||||
sEditorState.hierarchyStackIndex++;
|
sEditorState.hierarchyStackIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sEditorState.isGraphLoadedThisFrame = true;
|
||||||
ax::NodeEditor::ClearSelection();
|
ax::NodeEditor::ClearSelection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ax::NodeEditor::SetCurrentEditor(nullptr);
|
ax::NodeEditor::SetCurrentEditor(nullptr);
|
||||||
sEditorState.isGraphLoadedThisFrame = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimGraphEditorGetRuntimeGraph(AnimGraphBlendTree& blend_tree) {
|
void AnimGraphEditorGetRuntimeGraph(AnimGraphBlendTree& blend_tree) {
|
||||||
|
|
|
@ -256,6 +256,8 @@ static json sAnimGraphResourceBlendTreeToJson(
|
||||||
result["name"] = anim_graph_resource.m_name;
|
result["name"] = anim_graph_resource.m_name;
|
||||||
result["type"] = "AnimNodeResource";
|
result["type"] = "AnimNodeResource";
|
||||||
result["node_type"] = "BlendTree";
|
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 =
|
const BlendTreeResource& blend_tree_resource =
|
||||||
anim_graph_resource.m_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_graph_type_name = "BlendTree";
|
||||||
result_graph_resource->m_node_type_name = "BlendTree";
|
result_graph_resource->m_node_type_name = "BlendTree";
|
||||||
result_graph_resource->m_name = json_data["name"];
|
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
|
// Load nodes
|
||||||
for (size_t i = 0, n = json_data["nodes"].size(); i < n; i++) {
|
for (size_t i = 0, n = json_data["nodes"].size(); i < n; i++) {
|
||||||
|
|
Loading…
Reference in New Issue