Static
Scene placement establishes fixed collision geometry.
This page highlights the decisions that control lifetime, host time, simulation mutation, render-data flow, physics synchronization, and platform execution. The API reference records exact contracts; the Janus demo shows them running.
01 / Ownership and boundaries
Application owns both the active Scene and the Runner that drives it. Runner retains a non-owning Scene&, separating update policy from ownership of simulation state.
Scene retains the root hierarchy and owns independently replaceable visual, physics, and input systems. The important classes are introduced through these responsibilities rather than repeated as a catalog.
Runnerdrives through Scene&Scene02 / Host updates and simulation
Each Runner update samples host time, calls variable-rate application work, updates platform and input state, executes zero or more bounded fixed steps, and then renders the completed state.
Pause, explicit single-step, resettable simulation time, and discarded-time accounting remain part of the scheduler rather than ad hoc demo behavior.
sceneWillStepsceneDidStepCommands originating from input or UI are moved into explicit simulation boundaries. Each queue is exchanged before execution, so work enqueued by a running command waits for a later step.
03 / Rendering architecture
VisualWorld coordinates the frame, but scene objects are not submitted directly as graphics commands. Gathering extracts visible state, packetization converts it into backend-oriented work, and Renderer owns OpenGL/WebGL execution.
04 / Scene and physics integration
A Node owns its PhysicsBody; bodies may share PhysicsShape objects. Public A3D types delegate through proxy interfaces, allowing Bullet to implement worlds, bodies, and shapes without becoming the public object model.
PhysicsWorld→PhysicsWorldProxy→btDynamicsWorldPhysicsBody→PhysicsBodyProxy→btRigidBodyPhysicsShape→PhysicsShapeProxy→btCollisionShapeScene edits synchronize position and orientation toward Bullet. Dynamic results return through Bullet's motion state, with the local COM offset removed before the owning Node is updated.
Exact axis, transform, angle, scale, time, and viewport rules live in Coordinate and Transform Conventions.
05 / Other design details
Native + web
Application::Run↓while (update())emscripten main loopNative builds block in the host loop; web builds install the same update path into the browser. Visibility changes suspend the simulation clock so hidden-page time does not become catch-up work.
Runtime instrumentation
Runner also records step counts, simulation time, discarded catch-up time, contacts, body types, and collision-shape inventory for the live statistics overlay.
Hit testing
Search modes return any, closest, or all near-to-far hits. Bounds-only queries can stop before the two-sided Möller–Trumbore triangle stage.
Scene importing
glTF / GLB→fastgltf→GlTFImporter→Scene + NodesImport options independently select meshes, materials, cameras, and lights. Imported hierarchy and transforms enter the same representation used by programmatically assembled scenes.
Reference and proof