125 lines
3.7 KiB
Markdown
125 lines
3.7 KiB
Markdown
# 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.
|