diff --git a/lanes/A-stage.md b/lanes/A-stage.md index bab4a9b..b05ad5d 100644 --- a/lanes/A-stage.md +++ b/lanes/A-stage.md @@ -206,3 +206,14 @@ as keys via B (scrub proves it) and is undo-able. ### 2026-07-19 — M6 FLOW VIDEO PLATES queued behind M5 (full spec PLAN §5 M6). Do M5 first; M6 is unlocked the moment your M5 acceptance is logged. Test media will be arriving in assets/backdrops/video/ via scripts/flow_intake.py. + +### 2026-07-20 — M5+M6 ACCEPTED at SYNC 6 (all lanes ran as orchestrator subagents). +Verified live: DIRECT bar CU/low/frame → camera+keys+cut, ONE undo reverts; +golden_hour keys; video plate follows the clock frame-exact; finalRender shows +the Flow plate behind an animating character. Orchestrator seam fixes to absorb: +(1) server: VIDEO_EXTS in tree/media-types, video beats poster as primary; +(2) stage.entityVideo(id) added (Lane B seam); (3) syncVideos forces +videoTex.needsUpdate — r160 VideoTexture rides requestVideoFrameCallback which +never fires in hidden tabs → black plates in renders. Backlog carried: honor +audio in/out at mux (C), walk-to-mark prevPos pre-apply (A), live viseme asset +still owed by John. diff --git a/lanes/B-timeline.md b/lanes/B-timeline.md index 0c22c39..6f0b933 100644 --- a/lanes/B-timeline.md +++ b/lanes/B-timeline.md @@ -166,3 +166,14 @@ discover the panel scrolls — consider wheel = scroll, Cmd/Ctrl+wheel = zoom. ### 2026-07-19 — M6 FLOW VIDEO PLATES queued behind M5 (full spec PLAN §5 M6). Do M5 first; M6 is unlocked the moment your M5 acceptance is logged. Test media will be arriving in assets/backdrops/video/ via scripts/flow_intake.py. + +### 2026-07-20 — M5+M6 ACCEPTED at SYNC 6 (all lanes ran as orchestrator subagents). +Verified live: DIRECT bar CU/low/frame → camera+keys+cut, ONE undo reverts; +golden_hour keys; video plate follows the clock frame-exact; finalRender shows +the Flow plate behind an animating character. Orchestrator seam fixes to absorb: +(1) server: VIDEO_EXTS in tree/media-types, video beats poster as primary; +(2) stage.entityVideo(id) added (Lane B seam); (3) syncVideos forces +videoTex.needsUpdate — r160 VideoTexture rides requestVideoFrameCallback which +never fires in hidden tabs → black plates in renders. Backlog carried: honor +audio in/out at mux (C), walk-to-mark prevPos pre-apply (A), live viseme asset +still owed by John. diff --git a/lanes/C-server.md b/lanes/C-server.md index 32a90e8..470c478 100644 --- a/lanes/C-server.md +++ b/lanes/C-server.md @@ -161,3 +161,14 @@ it needs more than that. ### 2026-07-19 — M6 FLOW VIDEO PLATES queued behind M5 (full spec PLAN §5 M6). Do M5 first; M6 is unlocked the moment your M5 acceptance is logged. Test media will be arriving in assets/backdrops/video/ via scripts/flow_intake.py. + +### 2026-07-20 — M5+M6 ACCEPTED at SYNC 6 (all lanes ran as orchestrator subagents). +Verified live: DIRECT bar CU/low/frame → camera+keys+cut, ONE undo reverts; +golden_hour keys; video plate follows the clock frame-exact; finalRender shows +the Flow plate behind an animating character. Orchestrator seam fixes to absorb: +(1) server: VIDEO_EXTS in tree/media-types, video beats poster as primary; +(2) stage.entityVideo(id) added (Lane B seam); (3) syncVideos forces +videoTex.needsUpdate — r160 VideoTexture rides requestVideoFrameCallback which +never fires in hidden tabs → black plates in renders. Backlog carried: honor +audio in/out at mux (C), walk-to-mark prevPos pre-apply (A), live viseme asset +still owed by John. diff --git a/logs/laneA.md b/logs/laneA.md index c17d7f4..b78242e 100644 --- a/logs/laneA.md +++ b/logs/laneA.md @@ -185,3 +185,113 @@ BLOCKED/REQUESTS: I'll confirm live and Lane B can validate Rhubarb end-to-end. NEXT: hold at M4-A boundary. Available for a live viseme asset check and any SYNC findings. + +## 2026-07-20 session 5 (M5 DIRECTOR MODE + M6 FLOW VIDEO PLATES) +DONE — both milestones, headless-verified (no browser/servers touched per orchestrator order): + +M5: +- `web/grammar.js` (NEW, pure data, zero imports): SHOTS (exact spans/centers from the lane + spec), ANGLES (eye/low −18°/high +22°/dutch 8° roll/ots_L/ots_R), FOCALS [18,24,35,50,85], + LIGHTS (day/golden_hour/night/noir/horror-underlight/neon/overcast — {sun{color,intensity, + elev,azim}, ambient{color,intensity}, bg}), MARKS (center/two_shot_L/R/face_camera/face_other). +- `web/presets.js` (NEW, NO three.js import — node-runnable): fovForFocal (presets.js:11), + lookAtEuler w/ dutch roll + three-matching XYZ euler extraction (:14), solveShot bbox→ + pos/rot/fov/dist deterministic solver incl. OTS over-the-shoulder placement (:37), + frameSubject (:62, bbox via new stage.entityBBox), applyLight (:75 — ensures/reuses one + sun+ambient pair, writes grammar values verbatim, aims a 20m sun boom via lookAtEuler, + background rides the AMBIENT entity as param `bg` so it's keyable AND survives save/load), + applyMark (:99, pos marks keep y; face marks yaw toward active cam / nearest character), + applyOps (:139) — ONE op runner shared by panel buttons and /director NL, fires + `scenegod:direct {op, ...values, entityIds}` per action (B keys them; I never touch the + timeline), mountDirectPanel (:174) — shot/angle/lens segments + 🎥 frame, light buttons, + mark buttons, NL box. +- NL box: POST /director {text, selected, entities:[{id,kind,label}]} → expects {ops:[...]}, + applied via applyOps. Hidden by default; probe `GET /director` shows it on 405/200 (FastAPI + 405 = POST route exists); hides itself again when a POST returns 503. +- index.html:14 `#direct` bar + guarded dynamic import (:49) — page survives presets.js absent. + style.css:85 DIRECT styles (before the LANE B marker). +- stage.js additions for M5: entityBBox (stage.js:490, plain arrays — keeps presets three-free), + cameraWorldPos (:497), light param `bg` → scene.background live (:393) + restored at + _buildLight (:335) so a loaded scene gets its sky back. + +M6: +- `_buildBackdrop` rework (stage.js:225): params.mode gains "video" (renders as plane), and + plane/corner/dome accept .mp4/.webm/.mov sources; THREE.VideoTexture muted+loop+playsInline, + SRGB; poster jpg (server /assets/thumb same-stem sidecar) shown until first play/seek then + swapped in via _swapOnPlay (:309). Standalone page (no timeline → _mixerAuto) auto-plays as + ambient preview; with a timeline mounted videos stay paused at poster for B's clock. +- NEW kind `screen` (addEntity :165, _buildScreen :272): video plane, params {video,width, + emissive}, MeshStandard + emissiveMap boost (default 0.6) so club screens read "on" under + noir/night. ponytail: CRT curve skipped until a real TV asset asks. +- `stage.syncVideos(t)` (:506): seeks every video to ((t−videoStart) mod duration), pauses, + awaits 'seeked' per video (1.5s timeout guard so a stuck decoder can't hang a render), skips + sub-4ms deltas. render.js already awaits it per frame (Lane C landed the hook). Plus + videos() (:501) + setVideoPlaying(on) (:503) for Lane B's clock-follow, and params.videoStart + plumbed (inspector fields, dock.js:214/220). +- dock.js: _videoPath (:86, derives . from formats), 🎞 badge + 📺 + add-as-screen button on video backdrop cards (:106), click/drag adds mode:'video' plates + (:132 and _viewDrop), local .mp4 drop → upload video plate, screen/backdrop inspector fields + (width/emissive/vid start; mode select gains 'video'). +- Lifecycle: removeEntity/_rebuild release the