OHAO · Implementation Monograph

Monograph · 02 · Scene & ECS

02

Foundations · deep dive

Scene & ECS

Chapter contract

How a world is represented before Vulkan: actors, components, loaders, physics attachment, and the hand-off when the renderer uploads. After this, “scene” is not a vague bag of meshes.

Scene lifecycle

From construction to simulation
  1. Scene(name) creates a root actor "World", registers it, constructs PhysicsWorld with default gravity (0,−9.81,0)
  2. Examples/tools call createActor / load models into actors
  3. initialize() walks all actors → each component initialize()
  4. Per-frame: optional physics step, actor update, then renderer reads components
  5. destroy / removeActor unregisters hierarchy and tears down components

Lookups: by id, by exact name, by partial name, by tag. Maps: actors (id) and actorsByName.

Actor & component workflow

Every Actor is a SceneObject with hierarchy (parent/children) and a component bag. Constructor always installs a TransformComponent.

Actor Transform Mesh Material Light Physics FIG. SC-1 · COMPOSITION
Fig. SC-1

Renderer queries components; physics binds through PhysicsComponent into the scene’s world.

Actor lifecycle methods
  1. initialize — each component + children
  2. start — first-frame hooks
  3. update(dt) — logic; transform may be written by physics
  4. render — rarely used for GPU draw; visual path is renderer-driven
  5. destroy — reverse teardown
Why components not inheritance

A light does not need a mesh; a static prop does not need a rigid body. Composition keeps loaders and the renderer generic: “for each MeshComponent, upload…”.

Asset load workflow

From file to components
  1. Detect format (extension / header)
  2. GLTF/GLB → tinygltf: nodes, primitives, metallic-roughness, embedded images
  3. FBX/… → Assimp: meshes, materials, embedded textures
  4. OBJ → custom parser + texture folder heuristics; filter alpha-card junk materials
  5. Build CPU Model / mesh data; create or fill Mesh + Material components on actors
  6. Auto up-axis fix (Y vs Z) so DamagedHelmet-class assets stand correctly
  7. Per-triangle material IDs for multi-material meshes (RT needs them)

Loaders do not touch Vulkan. GPU upload is a later phase owned by Ch. 03.

Physics attachment

Scene owns one PhysicsWorld. Attaching simulation: add PhysicsComponent, configure shape/body type, register with the world. Each step, transforms can write back so rendering sees motion. Details in Ch. 11.

Hand-off to renderer

Contract at the boundary:

  • Scene pointer is stable for the frame
  • MeshComponent → positions/indices/UVs/normals available on CPU (or already uploaded handles)
  • MaterialComponent → PBR params + logical texture names/indices
  • LightComponent → typed lights for UBO/SSBO packing
  • Transform → world matrix for TLAS instances and model matrices
Design

Scene never includes vulkan.h

Keeps unit tests and tools able to build scenes without a GPU. The renderer is the only Vulkan citizen for visual data.

Files

scene/scene.*Ownership, physics world, initialize
actor/actor.*Hierarchy + components
component/*Transform mesh material light
asset/model_*.cppGLTF / FBX / OBJ
component_factory.*Primitive actor kits

Design units in this module

Each card is a focused design page (what / how / why + sources). Full tree: Sitemap.