Skip to main content

Module scene

Module scene 

Source
Expand description

The demo’s scene: its constants, its objects, and the worlds that run them.

The windowed binary and the headless run both build on this module: everything here is world-shaped, free of window and thread plumbing, so the same objects drive the windowed show and the deterministic headless capture.

The gameplay world is a set of objects rather than one state blob. The tick module says how one is put together; the objects themselves are:

  • SceneState builds the scene’s assets once; every drop asks the render world for an instance of its own.
  • spawn_floor puts the ground under the balls, in physics and in the render world.
  • Balls drops the balls: each one is a Ball entity of its own, which both the render world and the physics world answer by name, and the poses the physics world reports are published from it.
  • SceneAudio installs the synthesizer’s voice and starts the music: the Tracks it spawns own their clocks here, and each tick sends the audio world the messages that came due.
  • mount_controls is the panel. It lives here with the rest, and the render world draws it: the panel’s egui context runs in this world, which lays it out, and the render world’s UiSource holds and draws every frame it is sent.

The panel is the one object whose drawing happens in another world: it carries a UiPanel, and the UiPanelHost spawned beside it holds the context its interface is built in, laying a frame out each tick and sending it to the render world as a job. It reads input like any other object, from this world’s own buffer, so the events that move it are the ones this world’s tick dispatched.

The setup spawns the objects in whatever order reads best, and only the two that read what another object writes state an order: the balls tick after the default band the assets are built in, and the panel’s publish after both. Everything else is in the default band, where the dispatch promises nothing about which of them runs first.

Re-exports§

use std::sync::Arc; 🔒
use std::sync::atomic::AtomicU32; 🔒
use std::sync::atomic::Ordering; 🔒
use std::time::Duration; 🔒
use glam::Quat; 🔒
use glam::Vec3; 🔒
use hashbrown::HashMap; 🔒
use unlit_ecs::bundle; 🔒
use unlit_ecs::Entity; 🔒
use unlit_ecs::World; 🔒
use unlit_wgpu::resources::ResourceGraph; 🔒
use unlit3d::components::Transform; 🔒
use unlit3d::frame::Frame; 🔒
use unlit3d::frame::dispatch_frame; 🔒
use unlit3d::ui::UiTarget; 🔒
use unlit3dx::physics::PhysicsWorld; 🔒
use unlit3dx::ui::UiPanelHost; 🔒
use crate::render::RenderEntity; 🔒
use crate::render::camera_looking_at; 🔒
use crate::render::mesh_source; 🔒
use self::audio::Music; 🔒
use self::balls::BallDrops; 🔒
use self::shared::SceneBuild; 🔒
pub use audio::AudioSetup;
pub use audio::SceneAudio;
pub use audio::SceneTracks;
pub use audio::Track;
pub use audio::install_synth;
pub use balls::Ball;
pub use balls::BallPhase;
pub use balls::Balls;
pub use floor::GROUND_CHECKER_DARK;
pub use floor::GROUND_CHECKER_SIZE;
pub use floor::GROUND_COLOR;
pub use floor::GROUND_HALF;
pub use floor::GROUND_POSITION;
pub use floor::checker_ground;
pub use floor::spawn_floor;
pub use music::ELECTRIC_PIANO_PROGRAM;
pub use music::MUSIC_BOX_PROGRAM;
pub use music::SCALE;
pub use music::bgm_midi;
pub use music::sequence_midi;
pub use shapes::BALL_COLORS;
pub use shapes::BALL_RADIUS;
pub use shapes::PATTERN_SIZE;
pub use shapes::SHAPE_KINDS;
pub use shapes::ShapeKind;
pub use shapes::pattern_texture;
pub use shapes::shape_body;
pub use shapes::shape_kind;
pub use shapes::shape_mesh;
pub use shared::SceneAssets;
pub use shared::SceneState;
pub use ui::control_panel_job;
pub use ui::mount_controls;
use unlit3d::prelude::*; 🔒
use unlit3dx::prelude::*; 🔒

Modules§

audio 🔒
The scene’s music: the synthesizer’s voice, and the sequences played into it.
balls 🔒
The balls: dropping them, giving each one a render instance and a physics body, and publishing where they are.
floor 🔒
The ground the balls land on: one fixed body in physics, one instance in the render world, wearing a checker so motion reads against it.
music 🔒
The demo’s two pieces of music, written out as MIDI events.
shapes 🔒
The shapes the scene cycles through: their meshes, colliders and textures.
shared 🔒
The scene’s assets, built once in the render world.
tick 🔒
The behaviour that ticks a gameplay object.
ui 🔒
The control panel: the scene’s UI, drawn over the frame.

Structs§

GamePhysics
The physics state the demo subscribes to: where every body is.
PanelLayout
The clickable rectangles the control panel laid out most recently.
PanelSlots
What the two worlds holding the panel share.
Scene
The other worlds, as the scene’s objects reach them.
SceneHandles
The scene’s worlds, however they are driven.
ScenePoses
The poses gameplay sends the render world every frame: one Transform per live body, at its physics pose. An instance that is hidden or waiting for a body is not named: the show job already put it where it belongs. pose_job turns one into the job that writes them onto the entities they name.
SceneStepper
The pacing a host uses to step a scene’s worlds frame by frame.

Constants§

BALLS_ORDER 🔒
The order the balls tick at: after the default band, where the scene’s assets are built, since a tick reads the assets the build wrote.
GAMEPLAY_HZ
The gameplay world’s pacing rate, in hertz, until the window reports the refresh rate of the display it is on.
HEADLESS_HZ
The rate a run without a window steps its frames at, in hertz.
HIDDEN_POSITION
Where a hidden instance waits, far below everything the camera sees.
ORBIT_HEIGHT
The camera’s orbit height, in metres.
ORBIT_RADIUS
The camera’s orbit radius, in metres.
ORBIT_SPEED
How fast the camera circles the scene, in radians per second.
ORBIT_START
Where the camera’s orbit starts, in radians.
ORBIT_TARGET
The point the camera looks at.
PANEL_SLOT 🔒
The slot a panel publishes its frames into.
PUBLISH_ORDER 🔒
The order the panel publishes at: after every object, the balls included, since the panel shows what they wrote this frame.
RENDER_COMMAND_CAPACITY
The render sub-world’s command queue depth. A frame sends the scene build, the ground, one creation and one show per drop, one pose job and a periodic sweep, with the clears adding a batch despawn, so the capacity keeps every request in flight.
WINDOW_SIZE
The window opens at this size, in logical pixels.

Functions§

camera_job
A job that gives the render world this scene’s camera: one entity holding a camera aimed at the scene, and the frame behaviour that walks it around its orbit.
clear_balls_in
Ask the balls to go away, from inside the gameplay world.
drop_ball
Ask the balls to drop the next one, from another world.
drop_ball_in
Ask the balls to drop the next one, from inside the gameplay world.
mount_scene_content
Queue this scene’s own content on the render world: its camera, and — where there is a panel to draw — the UI source that draws it.
orbit_eye 🔒
The point on the orbit the camera sits at for one azimuth.
pose_job
A job that writes poses onto the render entities they name.
publish_panels 🔒
Lay this tick’s panel out and publish it, if it could differ from the one the drawing side holds.
setup_render_world
Set up the render sub-world: the resource graph, the renderer, the pass its sources draw into, and the asset-server source. Answers the renderer resource entity and the pass entity.
spawn_scene
Build the scene’s worlds with the runner R: on their own threads, or stepped by the host.
watch_poses 🔒
Watch the physics world’s body poses.
world_ended 🔒
Whether the world behind a port has ended.