From cff6a50f90b577b7eafcb4cb6b4ef2a40e3ba9c0 Mon Sep 17 00:00:00 2001 From: type-two Date: Sat, 25 Jul 2026 18:57:06 +1000 Subject: [PATCH] THE MACHINE: the air fryer is a real object now, and the camera steps back to show it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First prop off the MODELBEAST station lane (gen-assets.sh stations — 14 hero props for every bench built this month, all local, all free). air_fryer.glb replaces the eight-sided black drum that was standing in. The prop exposed a staging problem worth fixing: at the old camera the machine was entirely out of frame — you were cooking in a void with a floating tray. Pulled back and up (0,5.4,3.5 looking slightly past the basket) and now the shot reads as a kitchen counter: the appliance, its open drawer, the wings on the rack, the pantry lamp behind. The basket still fills the working area, so the arrangement game is unchanged. Drag mapping is camera-independent by construction (world-space rays and world→NDC projection), so nothing needed re-tuning: the day-23 demo still runs the card exactly — 180° then 190°, shaken at half-time, 9.5. Co-Authored-By: Claude Fable 5 --- src/scenes/airfryer.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/scenes/airfryer.ts b/src/scenes/airfryer.ts index 41b6c6d..186e6b2 100644 --- a/src/scenes/airfryer.ts +++ b/src/scenes/airfryer.ts @@ -17,6 +17,7 @@ import { } from '../sim/airfryer'; import { el, Panel } from '../ui/hud'; import { loadBackdrop } from './props'; +import { loadProp } from './assets'; const TRAY_Y = 0.5; const TRAY_W = 3.2; // world size of the 1×1 tray space @@ -92,6 +93,14 @@ export class AirFryerView implements View { this.body.position.set(0, 0.5, -2.6); this.body.castShadow = true; this.root.add(this.body); + // The real machine, when it loads. The block above is the understudy. + void loadProp('/assets/models/air_fryer.glb', 2.3) + .then((prop) => { + prop.position.set(0, 0.0, -3.1); + this.body.visible = false; + this.root.add(prop); + }) + .catch(() => undefined); // The basket tray: a dark wire square, seen from above. this.tray = new THREE.Mesh( @@ -147,8 +156,10 @@ export class AirFryerView implements View { } update(dt: number): void { - this.app.camera.position.set(0, 4.4, 2.3); - this.app.camera.lookAt(0, TRAY_Y, 0.1); + // Back and up: the basket still fills the working area, but the machine it + // slides out of is in the shot. You should see what you are cooking IN. + this.app.camera.position.set(0, 5.4, 3.5); + this.app.camera.lookAt(0, TRAY_Y, -0.55); const s = this.session; if (!s) return; const inp = this.app.input;