#ifdef ENABLE_EDITOR
#define IMGUI_DEFINE_MATH_OPERATORS
#include "editor.h"
#include <imgui.h>
#include <cstdio>
#include "scene/scene.h"
namespace editor {
void draw_node_tree(const Scene &scene, const AssetManager &mgr, u32 node, int depth, int &selected_node) {
const SceneGraph &sc = scene.scene_graph;
if (!sc.is_node_alive(node)) {
return;
}
ImGui::PushID((int)node);
bool is_leaf = sc.first_child[node] == SCENE_INVALID;
u32 flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanFullWidth;
if (is_leaf) {
flags |= ImGuiTreeNodeFlags_Leaf;
}
if ((int)node == selected_node) {
flags |= ImGuiTreeNodeFlags_Selected;
}
char type_prefix[16] = "";
int tp_len = 0;
for (u32 mn : scene.mesh_nodes) {
if (mn == node) {
tp_len += snprintf(type_prefix + tp_len, sizeof(type_prefix) - tp_len, "[M]");
break;
}
}
for (auto &cam : scene.cameras) {
if (cam.node == node) {
tp_len += snprintf(type_prefix + tp_len, sizeof(type_prefix) - tp_len, "[C]");
break;
}
}
for (auto &dl : scene.directional_lights) {
if (dl.node == node) {
tp_len += snprintf(type_prefix + tp_len, sizeof(type_prefix) - tp_len, "[D]");
break;
}
}
for (auto &pl : scene.point_lights) {
if (pl.node == node) {
tp_len += snprintf(type_prefix + tp_len, sizeof(type_prefix) - tp_len, "[L]");
break;
}
}
char label[128];
const char *name = scene.node_name(mgr, node);
if (name) {
if (tp_len > 0) {
(void)snprintf(label, sizeof(label), "%s %s", type_prefix, name);
} else {
(void)snprintf(label, sizeof(label), "%s", name);
}
} else if (tp_len > 0) {
(void)snprintf(label, sizeof(label), "%s Node %u", type_prefix, node);
} else {
(void)snprintf(label, sizeof(label), "[N] Node %u", node);
}
bool open = ImGui::TreeNodeEx(label, flags);
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) {
selected_node = (int)node;
}
if (open) {
for (u32 child = sc.first_child[node]; child != SCENE_INVALID; child = sc.next_sibling[child]) {
draw_node_tree(scene, mgr, child, depth + 1, selected_node);
}
ImGui::TreePop();
}
ImGui::PopID();
}
void draw_scene_graph_window(Scene &scene, const AssetManager &mgr, int &selected_node) {
if (ImGui::Begin("Hierarchy", nullptr, PANEL_FLAGS)) {
SceneGraph *sc = &scene.scene_graph;
if (!sc || sc->node_count == 0) {
ImGui::TextUnformatted("No scene graph loaded");
ImGui::End();
return;
}
ImGui::Text("Nodes: %u Roots: %zu", sc->node_count, sc->roots.size());
ImGui::BeginChild("TreePanel", ImVec2(0, 0), 0);
for (u32 root : sc->roots) {
draw_node_tree(scene, mgr, root, 0, selected_node);
}
ImGui::EndChild();
}
ImGui::End();
}
} // namespace editor
#endif // ENABLE_EDITOR