A scene is an entry in the open registry LabScenes, shown on a plate: a flat lit disc, the package's own small sky with the sun at one hour, and a frame clock. Headless each camera (lab_shot, lab_shot_at) settles and is written as build/lab/<scene>/<shot>.png (a stored PNG, written here); in a window N and P step through them. tools/lab/run.sh and sheet.py make the contact sheet; tools/lab/plate_build.py makes plate/. ludic.render3d gains r3d_plate_mode (no terrain, grass or water is made) and r3d_sky_path. quit() in a program with no frame loop links. The example takes ~120 MB resident, 417 MiB peak footprint. Reseed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
1.6 KiB
Text
50 lines
1.6 KiB
Text
# loop.ludic - each frame: the scene's tick by a fixed step, the shot's camera, its caption, and -
|
|
# headless - the picture once the shot has settled, then the next shot, then quit. In a window
|
|
# N and P step through the shots.
|
|
export function lab_input() -> void {
|
|
if not lb_windowed { return }
|
|
Input.poll()
|
|
let n = lab_shot_count()
|
|
if n > 0 and Input.key_pressed(key: 'n') {
|
|
lb_shot = (lb_shot + 1) % n
|
|
lab_shot_apply(lb_shot)
|
|
}
|
|
if n > 0 and Input.key_pressed(key: 'p') {
|
|
lb_shot = (lb_shot + n - 1) % n
|
|
lab_shot_apply(lb_shot)
|
|
}
|
|
}
|
|
export function lab_render() -> void {
|
|
lb_frame += 1
|
|
let k = labscenes_find(lb_scene)
|
|
if k >= 0 and LabScenes[k].tick != null { LabScenes[k].tick(1.0 / 60.0) }
|
|
r3d_frame(lab_time())
|
|
lab_caption()
|
|
if not lb_windowed { lab_take() }
|
|
r3d_present()
|
|
}
|
|
function lab_caption() -> void {
|
|
if lb_font == "" { return }
|
|
ov_begin()
|
|
var name = ""
|
|
if lb_shot < lab_shot_count() { name = lb_shot_names[lb_shot] }
|
|
ov_rect(0, 0, 900, 64, 0.0, 0.0, 0.0, 0.55)
|
|
ov_text(20, 10, 30, `{lb_scene} / {name} ({lb_shot + 1} of {lab_shot_count()})`, 1.0, 1.0, 1.0, 1.0)
|
|
if len(lb_note) > 0 { ov_text(20, 42, 18, lb_note, 0.8, 0.8, 0.8, 1.0) }
|
|
ov_end()
|
|
}
|
|
function lab_take() -> void {
|
|
lb_wait += 1
|
|
if lb_wait < lb_settle { return }
|
|
let base = `{lb_out}/{lb_shot_names[lb_shot]}`
|
|
r3d_screenshot(`{base}.ppm`)
|
|
if lab_ppm_to_png(`{base}.ppm`, `{base}.png`) { print(`lab: shot {base}.png`) } else { print(`lab: shot {base}.ppm`) }
|
|
lb_shots_taken += 1
|
|
lb_wait = 0
|
|
lb_shot += 1
|
|
if lb_shot >= lab_shot_count() {
|
|
quit()
|
|
return
|
|
}
|
|
lab_shot_apply(lb_shot)
|
|
}
|