import type { Framebuffer } from "../engine/render/Framebuffer" import type { RenderConfig } from "../engine/render/RenderConfig" import { MOB_KINDS } from "../engine/scene/Mob" import { renderBand, MOB_FLOATS, type MobDraw, type Scene } from "./renderScene" /** One-time setup: shared framebuffer + control/param buffers, the (cloned) * scene, this worker's row band, and its index into the per-worker times array. */ type Init = { colorSAB: SharedArrayBuffer depthSAB: SharedArrayBuffer width: number height: number scene: Scene band: [number, number] config: RenderConfig skyStep: number ctrlSAB: SharedArrayBuffer camSAB: SharedArrayBuffer vpSAB: SharedArrayBuffer visSAB: SharedArrayBuffer mobSAB: SharedArrayBuffer timesSAB: SharedArrayBuffer index: number } const FRAME = 0 const DONE = 1 const VIS = 2 const MOBVIS = 3 const ctx = globalThis as unknown as { addEventListener: (type: "message", handler: (e: { data: Init }) => void) => void } ctx.addEventListener("message", (e) => { const m = e.data const fb: Framebuffer = { width: m.width, height: m.height, color: new Uint32Array(m.colorSAB), depth: new Float32Array(m.depthSAB), } const ctrl = new Int32Array(m.ctrlSAB) const cam = new Float64Array(m.camSAB) const vp = new Float32Array(m.vpSAB) const vis = new Int32Array(m.visSAB) const mob = new Float32Array(m.mobSAB) const times = new Float64Array(m.timesSAB) const { scene, band, config, skyStep, index } = m // Lock-free frame loop: block until main bumps the frame counter, render this // band, record the band time, and signal done. No messages per frame. let last = 0 for (;;) { Atomics.wait(ctrl, FRAME, last) last = Atomics.load(ctrl, FRAME) const t0 = performance.now() const camera = { position: { x: cam[0], y: cam[1], z: cam[2] }, yaw: cam[3], pitch: cam[4], fov: cam[5] } const count = Atomics.load(ctrl, VIS) const visible = [...vis.subarray(0, count)] const mobCount = Atomics.load(ctrl, MOBVIS) const mobDraws: MobDraw[] = [] for (let i = 0; i < mobCount; i++) { const o = i * MOB_FLOATS mobDraws.push({ kind: MOB_KINDS[mob[o]] ?? "frog", x: mob[o + 1], y: mob[o + 2], z: mob[o + 3], heading: mob[o + 4], scale: mob[o + 5] }) } renderBand(fb, scene, camera, vp, visible, mobDraws, config, skyStep, cam[6], band[0], band[1]) times[index] = performance.now() - t0 Atomics.add(ctrl, DONE, 1) } })