#pragma once
#include <vector>
#include "asset/asset.h"
#include "core/globals.h"
#include "core/math_rtm.h"
#include "scene/camera.h"
#include "scene/ibl.h"
#include "scene/light.h"
#include "shaders/renderer_types.h"
class AssetManager;
constexpr u32 SCENE_INVALID = 0xffffffffu;
struct SceneGraph {
// Hierarchy (sibling-chain)
std::vector<int> parent; // parent index (-1 = root)
std::vector<u32> first_child; // first child index (SCENE_INVALID = none)
std::vector<u32> next_sibling; // next sibling index (SCENE_INVALID = none)
std::vector<u8> alive;
std::vector<u32> free_nodes;
// Local transforms (SoA)
std::vector<vec3> translations;
std::vector<rtm::quatf> rotations;
std::vector<vec3> scales;
std::vector<mat4> locals;
// Computed world transforms
std::vector<mat4> worlds;
// Roots
std::vector<u32> roots;
// Per-node source asset link (parallel; ASSET_INVALID = manual node)
std::vector<AssetHandle> asset;
std::vector<u32> asset_index;
// Per-node runtime instance state (parallel; block base/count in Scene::instance_locals)
std::vector<u32> instance_base;
std::vector<u32> instance_count;
u32 node_count = 0;
u32 add_node(int parent_idx, const TRS &local);
u32 add_node(int parent_idx, const mat4 &local);
bool delete_node(u32 node);
bool is_node_alive(u32 node) const;
bool is_descendant(u32 node, u32 ancestor) const;
bool reparent(u32 node, int new_parent);
bool reparent_keep_world(u32 node, int new_parent);
void set_local_trs(u32 index, const TRS &trs);
void set_local_matrix(u32 index, const mat4 &m);
void set_translation(u32 index, const vec3 &translation);
void set_rotation(u32 index, const rtm::quatf &rotation);
void set_scale(u32 index, const vec3 &scale);
void update_world_transforms();
TRS get_local_trs(u32 index) const;
mat4 get_local_matrix(u32 index) const;
mat4 get_world(u32 index) const;
};
struct Scene {
SceneGraph scene_graph;
EnvMap env;
std::vector<TRS> instance_locals; // per-instance local TRS pool; slot index == GPU transform slot
std::vector<u32> mesh_nodes; // scene nodes that carry a mesh (built at instantiate)
// Cameras / lights
std::vector<Camera> cameras;
u32 active_camera = NODE_INVALID;
std::vector<Light> directional_lights;
std::vector<PointLight> point_lights;
u32 instantiate(AssetManager &mgr, AssetHandle handle, int parent_idx = -1);
void evaluate();
mat4 instance_world(u32 node, u32 k) const;
const AssetScene *node_source(const AssetManager &mgr, u32 node) const;
const char *node_name(const AssetManager &mgr, u32 node) const;
};