# Scenegraph This project uses a lightweight hierarchy component to model parent/child relationships in ECS. The scenegraph is EnTT-friendly and uses a linked-list structure for children. ## Components ### `Hierarchy` Each entity can have a `Hierarchy` component with these fields: - `parent` — parent entity or `null` - `first` — first child entity - `prev` / `next` — sibling links This mirrors the common EnTT scenegraph pattern and avoids storing vectors of children inside a component. ### `ECSTransform` (local) Stores local position/scale and a Y-axis rotation (radians). ### `WorldTransform` (computed) Computed each frame from the hierarchy and local transform. Rendering uses `WorldTransform` so children move with parents. ## Update Order 1. Systems update local transforms (e.g., velocity system). 2. `UpdateWorldTransforms()` traverses the hierarchy and computes `WorldTransform`. 3. Rendering draws from `WorldTransform` + `ModelRenderer`. ## Script API ```angelscript ECS::SetParent(child, parent); ECS::ClearParent(child); uint p = ECS::GetParent(child); bool has = ECS::HasParent(child); ``` ## Scene File Format (TOML) Scenes are stored in `scenes/*.toml` using a minimal TOML-like structure. Example: ```toml scene_script = "scripts/scene.as" [[entity]] id = "root" tag = "Root" position = [0.0, 0.0, 0.0] rotation_deg = 0.0 scale = [1.0, 1.0, 1.0] [[entity]] id = "parent" parent = "root" tag = "Parent" position = [2.0, 0.0, 0.0] model = "cube" model_asset = "unit_cube" model_size = [1.0, 1.0, 1.0] color = 0x00FF00FF shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" shader_asset = "toon" texture = "assets/textures/grid.png" texture_asset = "grid" uv_scale = [2.0, 2.0] uv_offset = [0.0, 0.0] material_asset = "toon_mat" [[entity]] id = "child" parent = "parent" tag = "Child" position = [0.0, 1.25, 0.0] model = "sphere" radius = 0.5 color = 0xFF0000FF shader_vs = "shaders/toon.vs" shader_fs = "shaders/toon.fs" ``` ### Supported Keys - `scene_script` (string) — scene-level script path (outside entity blocks) - `id` (string) — unique identifier for parent links - `parent` (string) — parent entity id - `tag` (string) — `Tag` component value - `position` (vec3) - `rotation` (radians) or `rotation_deg` (degrees) - `scale` (vec3) - `model` — `cube`, `sphere`, `plane`, or file path - `model_asset` (string) — asset key for models - `model_id` (int) — numeric model id - `model_size` (vec3) for cubes/planes - `radius`, `rings`, `slices` for spheres - `color` — hex `0xRRGGBBAA` (matches script colors) - `outline_size` — optional model outline - `shader_vs`, `shader_fs` — optional shader paths - `shader_asset` (string) — asset key for shaders - `shader_id` (int) — numeric shader id - `texture` (string) — texture path - `texture_asset` (string) — asset key for textures - `texture_id` (int) — numeric texture id - `material_asset` (string) — asset key for materials - `material_id` (int) — numeric material id - `uv_scale` (vec2) - `uv_offset` (vec2) - `uv_rotation` (radians) - `script` (string) — per-entity script path - `script_enabled` (bool) - `script_class` (string) - `script_var_*` (string) — per-field overrides for script-editable values ## Loading a Scene ```angelscript uint root = Scene::Load("scenes/demo.toml"); ``` `Scene::Load` returns a root entity that parents all top-level entities. Use `ECS::IsValid(root)` to check success on the scene load. ## Editor Run the app with `--editor` to open the ImGui editor. The **Scene** window shows the hierarchy tree, supports drag-and-drop reparenting, and lets you create/delete entities. The **Inspector** window shows components for the selected entity and allows live editing.