- room3d.js: pure-module port of rigroom retarget, target parameterized; _selftest bakes across two mismatched-rest skeletons (maxErr 6.4e-12) - stage.js: Stage class (IBL, gizmo, entities, clip bake cache) per PLAN §4.2 - dock.js: asset dock + inspector, offline file-drop + clip retarget - index.html/style.css: grid layout, guarded timeline import (page survives B absent) Verified in-browser end-to-end: Mixamo char loaded+normalized, backdrop plane, gizmo move, running clip retargeted (66 tracks) and animating live. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.6 KiB
3.6 KiB
Lane A log — append-only, newest at bottom
Format per session:
## <date> session N
DONE: …
DECISIONS: …
BLOCKED/REQUESTS: …
NEXT: …
(no sessions yet)
2026-07-18 session 1
DONE: M1 shipped and verified end-to-end in a browser.
web/room3d.js— ported the rigroom retarget as a pure ES module (no DOM/globals). Exports parseAny/canon/boneMap/captureRest/bakeRetarget/disposeRoot/stats +_selftest. bakeRetarget is now(clip, srcRoot, srcRest, tgtRoot, tgtRest, opts?)— target is a parameter instead of the closed-overchar. Algorithm kept byte-for-byte (30fps world-delta bake, hips-height ratio, quat sign continuity, dup-hierarchy dedupe). Added.bvhto parseAny.web/stage.js—class Stageper PLAN §4.2. IBL (RoomEnvironment+PMREM), grid+circle floor, OrbitControls director cam, TransformControls gizmo (W/E/R), raycast select, shadow-casting. addEntity handles character/prop/backdrop(plane|corner|dome)/camera/light; wrapper-Group holds all transforms, loaded root normalized+grounded underneath. prepareClip caches parse-per-path and bake-per-(entity,path,index). captureState/applyState round-trip entities.web/dock.js— asset dock (Characters/Props/Backdrops/Animations tabs from/assets/tree, offline→file-drop) + inspector (transform/params editors, ⏺key dispatchesscenegod:capturekey, delete). Local drop: image→backdrop, mesh→character, clip-onto-selected-character→bake+play.web/index.html+web/style.css— CSS-grid layout (dock/view/inspector/timeline), rigroom importmap (three 0.160.0),?selftest=1badge. Timeline loaded via guarded dynamic import so the page never breaks when Lane B's file is absent.
VERIFICATION (browser, in-app):
?selftest=1: PASS — two 3-bone skeletons, different rests+namespaces, baked 1s clip, world-delta match maxErr=6.4e-12, srcMoved=0.224rad (guard against a silently-frozen source).- Real end-to-end (Female_mixamo.fbx char + "Running.fbx" clip + a jpg backdrop, served from a
throwaway scratchpad harness): char loaded (65 bones, 18.6k tris, normalized), gizmo-moved,
clip retargeted (66 tracks) and animating live. Screenshot:
logs/shots/m1-lady-running.png. - Page boots with zero console errors with BOTH timeline.js and the server absent.
DECISIONS:
- selftest uses underscore namespaces (
mixamorig1_/mixamorig4_), not colon — a colon in a bone name breaks three's PropertyBinding so the source clip wouldn't bind (silent pass). canon() still collapses both to the same key, which is the thing under test. - Added
Stage.prepareClipUpload(id, buf, name, idx)(bake from in-memory bytes) so the offline file-drop path can retarget without a server.Stage.setMixerAuto(false)lets Lane B take over mixer stepping at SYNC 1 (default true so dropped clips preview standalone now). - backdrop param edits (mode/image/width) don't rebuild the mesh yet — marked M2. fov/light color/intensity are live.
BLOCKED/REQUESTS:
- @Lane C: please confirm the item shape inside
/assets/treearrays. dock.js tolerates both a bare path string and{path,name,files:[{path,ext}]}(rigroom-style) for now — tell me the real one and I'll drop the fallback. Also confirm the page is served such that absolute/web/*.jsimports resolve (I used/web/...to be URL-independent).
NEXT (M2, do not start until orchestrator flips the milestone line):
- multiple cameras + PiP overlay via renderActiveCamera, light entity param plumbing polish, backdrop rebuild-on-param-change, drag-from-dock onto viewport (currently click-to-add).