[m7-A] non-mixamo rig support + world-integrated backdrops (+4 sync7 render fixes)
Lane A: bone-alias layer so CC_Base_*/Unreal-HumanIK/Rigify/Rokoko/Biped rigs fold onto the canonical mixamo names — lady.glb pairs 52/102 bones and retargets (53 tracks) where she previously threw 'missing hips'; mixamo→mixamo pairing asserted bit-identical. Backdrops gain frustum auto-fit, floor tint sampled from the plate, and FogExp2 in the plate's colour via a keyable param. Also caught: _buildLight ran _refreshDefaults before registration, so scene lights never dimmed the built-in hemi (every preset was washed out). Orchestrator SYNC-7 fixes (found only by rendering actual frames): - editor chrome (gizmo/grid/helpers/cam proxies) was baked into output mp4s - timeline's per-tick rest transform dragged fitted plates out of frame - fit used the viewport aspect, output renders at its own → letterboxed plates - plate offset put its top edge on the lens axis → void above centre-frame; now params.fitAnchor (default 0.75) picks the row that sits at eye level Verified: 5 suites green; 1280x720 render shows a CC character dancing a mixamo clip against an edge-to-edge Flow plate with a horizon and matched ground. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
fe3d5404a9
commit
7fea880286
@ -217,3 +217,28 @@ 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.
|
||||
|
||||
### 2026-07-25 — M7-A ACCEPTED at SYNC 7. Outstanding work; four orchestrator fixes to absorb.
|
||||
Verified live: `?selftest=1` PASS+alias ok; **lady.glb (CC_Base rig) retargets — 53 tracks
|
||||
where she used to throw**; man.fbx unchanged (66); both clips land; fog FogExp2 #4b3320 from
|
||||
the plate; floor tinted #452f1d; old `sync2-sunset` (no `fit`) loads unchanged. The
|
||||
`_refreshDefaults` catch was real — presets read far stronger now.
|
||||
|
||||
Four things only a rendered frame could show, fixed by the orchestrator in stage.js — absorb,
|
||||
don't revert:
|
||||
1. **Editor chrome was baked into the mp4** — a green translate gizmo across every frame.
|
||||
`_chrome(false)` now hides gizmo/grid/helpers/camera proxies whenever `_paused` (which is
|
||||
exactly "the caller is rendering output"); camera proxies carry `userData.chrome`.
|
||||
2. **The timeline dragged fitted plates out of frame** — `evaluate()` re-applies each entity's
|
||||
rest transform every tick, undoing the fit. `setTransform` now re-fits instead for
|
||||
`fit:'frustum'` backdrops (the lens owns them; keyframe a plate only with fit:'free').
|
||||
3. **Plates letterboxed in every render** — fit used the LIVE viewport aspect while output
|
||||
renders at its own (1280×720 etc). `_render` re-fits when the aspect it's about to draw at
|
||||
differs. Pure algebra, no re-sampling.
|
||||
4. **`root.position.y = -height/2` put the plate's TOP EDGE on the lens axis**, so everything
|
||||
above centre-frame was void; centring instead put the road at eye level. Now
|
||||
`params.fitAnchor` (default 0.75) = which fraction of the image sits at eye level. Expose it
|
||||
in the inspector next to fitDist.
|
||||
NEXT for Lane A (not urgent): expose `fitAnchor`; the hard plate/floor horizon seam could use a
|
||||
soft gradient; and lady's hips-travel `ratio` 0 (Z-up CC export) still means CC clips play in
|
||||
place — fine for machinima (keyframe the walk) but worth a look if a walk cycle ever needs root motion.
|
||||
|
||||
116
logs/laneA.md
116
logs/laneA.md
@ -295,3 +295,119 @@ NEXT / orchestrator SYNC checklist (browser):
|
||||
4. finalRender a 2s scene with the plate — frames must show advancing video (syncVideos is
|
||||
awaited by render.js already).
|
||||
5. NL box stays hidden until /director exists (probe is GET → expect 405 to reveal).
|
||||
|
||||
## 2026-07-25 session 6 (M7-A1 non-mixamo rigs + M7-A2 world-integrated backdrops)
|
||||
DONE — both M7 items, headless-verified (no browser, no servers touched, per orchestrator order):
|
||||
|
||||
**M7-A1 — bone aliasing.** `canon()` used to strip a mixamorig prefix and nothing else, so every
|
||||
non-mixamo skeleton paired 0 bones and died at "missing hips" (lady.glb has never been animatable).
|
||||
- `room3d.js:70` legacy strip is now `rawCanon`; `room3d.js:136` `canon = raw ∈ CANON ? raw : alias(n) || raw`.
|
||||
The CANON short-circuit is what makes mixamo→mixamo **bit-identical** — a name that already canons
|
||||
to a mixamo bone never touches the alias tables (test asserts all 65 man.fbx bones × 5 namespace
|
||||
spellings against an inlined copy of the old one-liner).
|
||||
- Tables (room3d.js:77–125): `CANON` (the 54 mixamo names, generated), `EXACT` side-less bones,
|
||||
`STEMS` sided stems + generated finger stems, `SIDES` side decompositions. `alias()` walks 4
|
||||
progressively-normalised candidates — raw → prefix-stripped → index-stripped → both — and takes the
|
||||
first hit, so **`CC_Base_Spine01` (2nd spine bone) beats the generic `spine_01` (1st) reading**.
|
||||
Structure handled: namespaces (`mixamorig4:`, `Armature|`), rig prefixes (`CC_Base_`, `DEF-`/`ORG-`/
|
||||
`MCH-`, `Bip01 `), CC's per-export numeric tail (`_02`, `_0100`), and side spellings
|
||||
`L_`/`_l`/`.L`/`Left`. A decomposition only counts when the leftover stem is known, so `lowerarm`
|
||||
is never read as left-"owerarm" and `shoulder` is never read as "shoulde"+right.
|
||||
- Covered: Character Creator (bone names read out of the REAL lady.glb JSON chunk, not guessed),
|
||||
Unreal/HumanIK, Blender Rigify, Unity-humanoid/VRM/Rokoko long names, plain lowercase, 3ds Max Biped.
|
||||
Twist / share / toe-detail / facial / breast / eye bones deliberately stay UNMAPPED — the pair map
|
||||
already tolerates missing pairs, and a guessed mapping is worse than an unbaked bone.
|
||||
- Guardrail: pairing moved out of `bakeRetarget` into three-free `pairBones()` (room3d.js:146). Under
|
||||
`min(8, boneCount)` matches it throws e.g.
|
||||
`retarget: only 1/54 bones matched (target looks like 'CC_Base', source looks like 'mixamo'; first
|
||||
unmatched bone 'CC_Base_BoneRoot_01'); unsupported skeleton`. `rigStyle()` (room3d.js:127) does the
|
||||
detection. The missing-hips error (room3d.js:176) now names both styles too. `min(8, …)` keeps
|
||||
`_selftest`'s 3-bone synthetic skeletons legal.
|
||||
- **Result on the real asset: lady.glb pairs 52/102 bones** — core 6 + both arms/legs + all 30 finger
|
||||
bones, `CC_Base_Hip` wins `hips` and `CC_Base_Pelvis` folds onto the same key and is left unbaked
|
||||
(dedupe does the right thing). Reverse direction (CC as the clip SOURCE onto a mixamo body) is 52/52.
|
||||
|
||||
**M7-A2 — world-integrated backdrops.** A plate read as a billboard in the void: gap under it, alien
|
||||
floor, no air. Three fixes, all recomputed on load/param/camera change, never per frame (stage.js:340–415).
|
||||
- `params.fit:'frustum'` — `_fitBackdrop` scales `en.root` to COVER the active camera's frustum at
|
||||
`params.fitDist` (default 14m) with 6% bleed, drops the plate's centre onto the wrapper origin, parks
|
||||
the wrapper on the camera axis and `lookAt`s the camera. Because the plate now extends BELOW y=0 the
|
||||
floor cuts it at a clean horizon — the gap is gone. `fitScale()` (stage.js:62) is a pure export so
|
||||
node can assert the algebra. Recompute triggers: `addEntity`, `_rebuild`, `setParam(fov)` on the
|
||||
ACTIVE cam, `setActiveCamera`, `_resize`, end of `applyState`, and the inspector's `⤢ refit`.
|
||||
Absent `fit` = old behaviour (saved scenes unchanged); dock-added plates default to `'frustum'`.
|
||||
- `params.groundTint` (default on) — `_plateGround` draws the plate's map (image, poster, or video
|
||||
frame) into a 24×24 2D canvas and averages the bottom 7 rows, once per load/param change; the stage
|
||||
floor takes that colour ×0.85 and the grid helper fades to 0.12 opacity while a plate is present.
|
||||
- Atmosphere — `FogExp2` coloured from the same sample, density from a **keyable `fog` param on the
|
||||
ambient light entity** (same trick as `bg`: Lane B's params track drives it with zero schema change).
|
||||
Default 0.02, off with no plate. Plate/dome materials get `fog:false` so atmosphere sits between the
|
||||
camera and the plate instead of washing it out. Fog object is mutated, not reallocated, when keyed.
|
||||
- dock.js: inspector gains `fit` select, `fit dist`, `⤢ refit to camera`, `ground tint` checkbox
|
||||
(new `_chk` helper, dock.js:250) and `fog` on ambient lights; new `_chk` styling in style.css:52.
|
||||
|
||||
VERIFICATION (headless only):
|
||||
- `node scenegod/web/room3d_test.mjs` → `ALL PASS (26 CC bones paired against mixamo)`. NEW file; it
|
||||
loads the REAL room3d.js with the three imports stripped and imported as a data: URL, so the shipped
|
||||
tables are what's asserted (no drift-prone copy). Covers: 65 mixamo bones × 5 namespaces identical to
|
||||
the legacy canon; 20 CC name→canonical assertions; 8 CC twist/share/facial bones must stay unmapped;
|
||||
36 Unreal/Rigify/Unity/Biped assertions; side-less limbs must stay unmapped; CC↔mixamo pairing = 26
|
||||
on the sample; mixamo→mixamo pairing 65/65 unchanged; the guardrail throws with style + unmatched
|
||||
root in the message; 3-bone `_selftest` skeletons still legal; `rigStyle` on 5 rigs.
|
||||
- `node scenegod/web/stage_test.mjs` → `ALL PASS (fit s=2.186 → plate 21.9×12.3m over a 20.6×11.6m
|
||||
frame at 14m)`. NEW file, same import trick on stage.js: frustum size, cover-on-both-axes, bleed
|
||||
factor, portrait/letterbox plates scaling on the tight axis, distance-invariance of framing, longer
|
||||
lens → smaller plate.
|
||||
- `node scenegod/web/presets_test.mjs` (M5) and `timeline_test.mjs` (Lane B) still pass unchanged.
|
||||
- `node --check` clean on room3d.js / stage.js / dock.js / presets.js / grammar.js and on index.html's
|
||||
inline module.
|
||||
|
||||
DECISIONS:
|
||||
- Aliasing lives in `canon()` behind a CANON short-circuit rather than a new module — Lane A owns 5
|
||||
files and the baker is the only consumer. `pairBones`/`rigStyle`/`fitScale` are exported THREE-free
|
||||
so node can test the parts that actually encode judgement.
|
||||
- Ambiguity resolved by qualification, not by guessing: CC's 3-bone torso (Waist/Spine01/Spine02) maps
|
||||
to mixamo Spine/Spine1/Spine2 via `ccbase*` keys; UE's `spine_01/02/03` maps to the same three via
|
||||
generic keys. Chains longer than mixamo's 3 (UE `spine_04/05`, rigify `spine.003+`) stay unmapped.
|
||||
- **Known limit, marked `ponytail:` at room3d.js:190**: lady.glb hangs its hip height off LOCAL Z
|
||||
(Z-up CC export), so the hips-travel `ratio` lands 0 and clips play IN PLACE. That is the safe read —
|
||||
the source's travel delta is in the SOURCE's axes and scaling it into a Z-up hip would fly the
|
||||
character. Rotations are unaffected (they transfer through world space), so she dances correctly.
|
||||
Proper fix = rotate the travel delta through both rests' parent world quats; deliberately not done,
|
||||
since it would perturb the verified mixamo→mixamo path for a case nobody has asked for yet.
|
||||
- Auto-fit OWNS the backdrop's wrapper transform (marked `ponytail:` at stage.js:355) — keyframe a
|
||||
plate only with `fit:'free'`. Fit is NOT recomputed on camera *movement* (only fov/cut/resize):
|
||||
following a dolly would glue the plate to the lens and kill parallax.
|
||||
- **Absorbed bug fix you should know about (visual delta):** `_buildLight` ran `_refreshDefaults()`
|
||||
BEFORE the entity was registered in `_entities`, so adding a scene light never dimmed the built-in
|
||||
hemi (2.2) / key — every M5 lighting preset was being washed out by studio defaults. Now refreshed
|
||||
after registration (stage.js:197). Expect noir/night/golden_hour to read much stronger than in the
|
||||
SYNC-6 screenshots; RoomEnvironment IBL still keeps nothing pitch black.
|
||||
|
||||
BLOCKED/REQUESTS:
|
||||
- @orchestrator (PLAN §4.1 amendment, no code impact): backdrop `params` gains `fit:"frustum"|"free"`,
|
||||
`fitDist` (m, default 14) and `groundTint` (bool, default true); `light` params gain `fog` (FogExp2
|
||||
density, keyable, lives on the ambient entity next to `bg`). All round-trip through
|
||||
captureState/applyState today.
|
||||
- @Lane B (free win, not blocking): `fog` behaves exactly like `bg` — a params-track key on the ambient
|
||||
light entity animates the atmosphere. A "haze up over 2s" key is now a one-liner for the DIRECT panel.
|
||||
- Still owed by John: a viseme-bearing test character (carried from session 4).
|
||||
|
||||
NEXT / orchestrator SYNC checklist (browser, :8020):
|
||||
1. `?selftest=1` → header badge must read `selftest: PASS (maxErr=…, alias ok)` — the alias check is
|
||||
new (index.html:33), it canons CC + Unreal + namespaced-mixamo names in-page.
|
||||
2. **Lady dances (the headline):** CHARACTERS → lady → ANIMATIONS → hiphop.fbx (drag onto her, or
|
||||
select her and click the card) → block lands on the timeline → press play. Before today this threw
|
||||
`retarget: missing hips (mixamorig skeleton?)`. Console proof if you want it:
|
||||
`stage.prepareClip('e1','animations/test/hiphop.fbx',0).then(c=>console.log(c.tracks.length))` →
|
||||
expect **53** tracks (52 bone quats + 1 hips position). She dances in place by design (see the
|
||||
ponytail note above); man.fbx is unchanged and still travels.
|
||||
3. **Plate fills frame + ground + fog:** BACKDROPS → the golden-hour video plate (or street.jpg) →
|
||||
it should land already filling the view with no gap under it, the floor should go warm/orange, the
|
||||
grid should nearly vanish. Inspector shows `fit: frustum`, `fit dist 14`, `ground tint ✓`. Move the
|
||||
director cam and hit `⤢ refit to camera` to re-fill. Add an ambient light → its inspector `fog`
|
||||
field (0.02 default) — crank to 0.08 to see the haze eat the far floor, 0 to kill it.
|
||||
4. Cut to a scene camera (◉ set active camera) — the plate refits to THAT lens; change its fov and it
|
||||
refits again. PiP should show the same filled frame.
|
||||
5. Regression watch: existing saved scenes (`sync2-sunset`) have no `fit` param → plates must load at
|
||||
their old size/place. Lighting will look stronger than before (see the `_refreshDefaults` note).
|
||||
|
||||
@ -36,3 +36,663 @@ INFO: 127.0.0.1:57176 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:57177 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57177 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57221 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56254 - "GET /?selftest=1 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56254 - "GET /web/style.css HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56254 - "GET /web/stage.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56255 - "GET /web/dock.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56255 - "GET /web/room3d.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56255 - "GET /favicon.ico HTTP/1.1" 404 Not Found
|
||||
INFO: 127.0.0.1:56254 - "GET /web/presets.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56255 - "GET /assets/tree HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56255 - "GET /web/grammar.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56255 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:56254 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56254 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56323 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56323 - "GET /assets/thumb?path=backdrops%2Fvideo%2Fscenegod_plates%2Fsuburb_strip_goldenhour.mp4 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56502 - "GET /scenes/sync2-sunset HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56502 - "GET /assets/file?path=backdrops%2Ftest%2Fstreet.jpg HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56502 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56606 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56606 - "GET /web/style.css HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56607 - "GET /web/dock.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56606 - "GET /web/stage.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56606 - "GET /web/room3d.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56608 - "GET /favicon.ico HTTP/1.1" 404 Not Found
|
||||
INFO: 127.0.0.1:56607 - "GET /web/presets.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56606 - "GET /assets/tree HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56607 - "GET /web/grammar.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56607 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:56606 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56606 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "GET /web/render.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/begin HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/0 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/1 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/2 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/3 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/4 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/5 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/6 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/7 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/8 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/9 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/10 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/11 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/12 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/13 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/14 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/15 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/16 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/17 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/18 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/19 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/20 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/21 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/22 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/23 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/24 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/25 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/26 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/27 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/28 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/29 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/30 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/31 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/32 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/33 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/34 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/35 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/36 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/37 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/38 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/39 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/40 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/41 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/42 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/43 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/44 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/45 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/46 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/47 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/48 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/49 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/50 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/51 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/52 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/53 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/54 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/55 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/56 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/57 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/58 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/59 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/60 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/61 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/62 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/63 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/64 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/65 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/66 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/67 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/68 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/69 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/70 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/71 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/72 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/73 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/74 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/75 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/76 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/77 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/78 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/79 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/80 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/81 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/82 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/83 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/84 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/85 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/86 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/87 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/88 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/frame/89 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "POST /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/end HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:56730 - "GET /render/3a5ca564eb7840ceae8ae1c5dcd9bfe3/status HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57926 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57926 - "GET /web/style.css HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57928 - "GET /web/dock.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57927 - "GET /web/stage.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57927 - "GET /web/room3d.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57928 - "GET /web/presets.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57926 - "GET /favicon.ico HTTP/1.1" 404 Not Found
|
||||
INFO: 127.0.0.1:57927 - "GET /assets/tree HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57927 - "GET /web/grammar.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57927 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:57926 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:57926 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "GET /web/render.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/begin HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/0 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/1 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/2 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/3 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/4 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/5 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/6 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/7 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/8 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/9 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/10 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/11 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/12 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/13 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/14 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/15 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/16 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/17 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/18 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/19 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/20 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/21 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/22 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/23 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/24 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/25 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/26 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/27 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/28 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/29 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/30 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/31 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/32 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/33 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/34 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/35 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/36 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/37 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/38 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/39 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/40 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/41 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/42 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/43 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/44 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/45 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/46 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/47 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/48 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/49 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/50 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/51 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/52 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/53 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/54 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/55 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/56 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/57 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/58 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/59 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/60 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/61 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/62 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/63 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/64 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/65 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/66 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/67 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/68 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/69 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/70 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/71 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/72 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/73 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/74 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/75 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/76 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/77 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/78 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/79 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/80 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/81 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/82 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/83 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/84 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/85 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/86 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/87 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/88 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/frame/89 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "POST /render/a219ad7a213f499f9630c36a62e6c90f/end HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:58008 - "GET /render/a219ad7a213f499f9630c36a62e6c90f/status HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59022 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59022 - "GET /web/style.css HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59023 - "GET /web/stage.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59024 - "GET /web/dock.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59024 - "GET /web/room3d.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59023 - "GET /web/presets.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59024 - "GET /assets/tree HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59022 - "GET /favicon.ico HTTP/1.1" 404 Not Found
|
||||
INFO: 127.0.0.1:59023 - "GET /web/grammar.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59023 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:59022 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59022 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "GET /web/render.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/begin HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/0 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/1 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/2 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/3 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/4 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/5 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/6 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/7 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/8 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/9 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/10 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/11 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/12 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/13 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/14 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/15 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/16 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/17 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/18 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/19 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/20 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/21 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/22 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/23 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/24 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/25 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/26 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/27 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/28 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/29 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/30 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/31 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/32 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/33 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/34 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/35 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/36 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/37 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/38 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/39 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/40 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/41 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/42 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/43 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/44 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/45 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/46 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/47 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/48 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/49 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/50 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/51 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/52 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/53 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/54 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/55 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/56 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/57 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/58 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/59 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/60 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/61 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/62 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/63 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/64 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/65 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/66 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/67 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/68 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/69 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/70 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/71 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/72 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/73 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/74 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/75 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/76 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/77 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/78 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/79 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/80 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/81 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/82 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/83 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/84 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/85 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/86 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/87 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/88 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/frame/89 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "POST /render/203d2bb3faa24225a1a6f42eec25a555/end HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59090 - "GET /render/203d2bb3faa24225a1a6f42eec25a555/status HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59731 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59731 - "GET /web/style.css HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59731 - "GET /web/stage.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59732 - "GET /web/dock.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59732 - "GET /web/room3d.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59731 - "GET /web/presets.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59732 - "GET /assets/tree HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59733 - "GET /favicon.ico HTTP/1.1" 404 Not Found
|
||||
INFO: 127.0.0.1:59731 - "GET /web/grammar.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59731 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:59733 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59733 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "GET /web/render.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/begin HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/0 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/1 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/2 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/3 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/4 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/5 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/6 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/7 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/8 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/9 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/10 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/11 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/12 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/13 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/14 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/15 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/16 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/17 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/18 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/19 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/20 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/21 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/22 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/23 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/24 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/25 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/26 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/27 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/28 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/29 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/30 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/31 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/32 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/33 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/34 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/35 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/36 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/37 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/38 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/39 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/40 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/41 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/42 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/43 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/44 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/45 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/46 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/47 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/48 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/49 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/50 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/51 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/52 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/53 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/54 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/55 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/56 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/57 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/58 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/59 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/60 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/61 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/62 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/63 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/64 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/65 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/66 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/67 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/68 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/69 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/70 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/71 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/72 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/73 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/74 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/75 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/76 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/77 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/78 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/79 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/80 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/81 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/82 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/83 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/84 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/85 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/86 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/87 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/88 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/frame/89 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "POST /render/a1ecf39dda9d46179a3ae1cc4eb413f8/end HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:59798 - "GET /render/a1ecf39dda9d46179a3ae1cc4eb413f8/status HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60685 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60685 - "GET /web/style.css HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60687 - "GET /web/dock.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60686 - "GET /web/stage.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60686 - "GET /web/room3d.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60687 - "GET /web/presets.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60686 - "GET /assets/tree HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60686 - "GET /favicon.ico HTTP/1.1" 404 Not Found
|
||||
INFO: 127.0.0.1:60686 - "GET /web/grammar.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60686 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:60687 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60687 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "GET /web/render.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/begin HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/0 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/1 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/2 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/3 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/4 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/5 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/6 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/7 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/8 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/9 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/10 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/11 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/12 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/13 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/14 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/15 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/16 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/17 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/18 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/19 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/20 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/21 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/22 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/23 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/24 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/25 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/26 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/27 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/28 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/29 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/30 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/31 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/32 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/33 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/34 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/35 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/36 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/37 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/38 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/39 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/40 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/41 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/42 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/43 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/44 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/45 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/46 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/47 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/48 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/49 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/50 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/51 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/52 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/53 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/54 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/55 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/56 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/57 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/58 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/59 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/60 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/61 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/62 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/63 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/64 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/65 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/66 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/67 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/68 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/69 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/70 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/71 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/72 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/73 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/74 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/75 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/76 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/77 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/78 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/79 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/80 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/81 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/82 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/83 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/84 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/85 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/86 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/87 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/88 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/frame/89 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "POST /render/8794e7fdcd1d4551b1c030ac66c53675/end HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:60784 - "GET /render/8794e7fdcd1d4551b1c030ac66c53675/status HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61453 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61516 - "GET / HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61516 - "GET /web/style.css HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61517 - "GET /web/stage.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61518 - "GET /web/dock.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61517 - "GET /web/room3d.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61517 - "GET /assets/tree HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61516 - "GET /favicon.ico HTTP/1.1" 404 Not Found
|
||||
INFO: 127.0.0.1:61518 - "GET /web/presets.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61518 - "GET /web/grammar.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61518 - "GET /director HTTP/1.1" 405 Method Not Allowed
|
||||
INFO: 127.0.0.1:61516 - "GET /web/timeline.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61516 - "GET /web/tlui.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "GET /assets/file?path=characters%2Ftest%2Flady.glb HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "GET /web/render.js HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/begin HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/0 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/1 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/2 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/3 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/4 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/5 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/6 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/7 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/8 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/9 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/10 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/11 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/12 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/13 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/14 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/15 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/16 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/17 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/18 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/19 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/20 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/21 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/22 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/23 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/24 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/25 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/26 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/27 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/28 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/29 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/30 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/31 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/32 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/33 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/34 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/35 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/36 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/37 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/38 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/39 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/40 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/41 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/42 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/43 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/44 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/45 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/46 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/47 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/48 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/49 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/50 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/51 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/52 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/53 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/54 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/55 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/56 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/57 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/58 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/59 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/60 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/61 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/62 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/63 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/64 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/65 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/66 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/67 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/68 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/69 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/70 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/71 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/72 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/73 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/74 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/75 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/76 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/77 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/78 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/79 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/80 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/81 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/82 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/83 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/84 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/85 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/86 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/87 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/88 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/frame/89 HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "POST /render/b727c44ecdd846aba6da356db2b7afa2/end HTTP/1.1" 200 OK
|
||||
INFO: 127.0.0.1:61602 - "GET /render/b727c44ecdd846aba6da356db2b7afa2/status HTTP/1.1" 200 OK
|
||||
|
||||
@ -74,7 +74,8 @@ export class Dock {
|
||||
const kind = tab === 'characters' ? 'character' : tab === 'props' ? 'prop' : 'backdrop';
|
||||
const desc = { kind, label: name, source:{ type:'assets', path: video || path } };
|
||||
if(kind === 'backdrop') desc.params = video
|
||||
? { mode:'video', image:video, width:12 } : { mode:'plane', image:path, width:10 };
|
||||
? { mode:'video', image:video, width:12, fit:'frustum' }
|
||||
: { mode:'plane', image:path, width:10, fit:'frustum' };
|
||||
else desc.transform = { pos: this.stage.screenToFloor(e.clientX, e.clientY), rot:[0,0,0], scale:1 };
|
||||
const en = await this.stage.addEntity(desc);
|
||||
this.stage.select(en.id);
|
||||
@ -133,7 +134,9 @@ export class Dock {
|
||||
const desc = { kind, label: this._name(it), source: { type:'assets', path } };
|
||||
if(kind === 'backdrop'){
|
||||
const vp = this._videoPath(it); // video plate → video plane; else image plane
|
||||
desc.params = vp ? { mode:'video', image:vp, width:12 } : { mode:'plane', image:path, width:10 };
|
||||
// M7: new plates auto-fit the camera frustum (saved scenes without `fit` keep their sizing)
|
||||
desc.params = vp ? { mode:'video', image:vp, width:12, fit:'frustum' }
|
||||
: { mode:'plane', image:path, width:10, fit:'frustum' };
|
||||
if(vp) desc.source = { type:'assets', path: vp };
|
||||
}
|
||||
this._toast('loading ' + this._name(it) + '…');
|
||||
@ -210,10 +213,22 @@ export class Dock {
|
||||
if(en.kind === 'light'){
|
||||
el.appendChild(this._num('intensity', en.params.intensity ?? 1.5, v => this.stage.setParam(en.id, 'intensity', v)));
|
||||
el.appendChild(this._color('color', en.params.color || '#ffffff', v => this.stage.setParam(en.id, 'color', v)));
|
||||
if(en.params.type === 'ambient') // M7: keyable atmosphere (0 = off), coloured from the plate
|
||||
el.appendChild(this._num('fog', en.params.fog ?? 0.02, v => this.stage.setParam(en.id, 'fog', v)));
|
||||
}
|
||||
if(en.kind === 'backdrop'){
|
||||
el.appendChild(this._sel('mode', ['plane','corner','dome','video'], en.params.mode || 'plane',
|
||||
v => this.stage.setParam(en.id, 'mode', v))); // stage rebuilds the mesh on change
|
||||
el.appendChild(this._sel('fit', ['frustum','free'], en.params.fit || 'free',
|
||||
v => { this.stage.setParam(en.id, 'fit', v); this.renderInspector(en); }));
|
||||
if(en.params.fit === 'frustum'){
|
||||
el.appendChild(this._num('fit dist', en.params.fitDist ?? 14, v => this.stage.setParam(en.id, 'fitDist', v)));
|
||||
const re = document.createElement('button'); re.textContent = '⤢ refit to camera'; re.className = 'wide';
|
||||
re.onclick = () => this.stage.setParam(en.id, 'fit', 'frustum'); // after moving the camera
|
||||
el.appendChild(re);
|
||||
}
|
||||
el.appendChild(this._chk('ground tint', en.params.groundTint ?? true,
|
||||
v => this.stage.setParam(en.id, 'groundTint', v)));
|
||||
if(en.video) el.appendChild(this._num('vid start', en.params.videoStart ?? 0,
|
||||
v => this.stage.setParam(en.id, 'videoStart', v)));
|
||||
}
|
||||
@ -238,6 +253,8 @@ export class Dock {
|
||||
i.oninput = () => cb(parseFloat(i.value) || 0); return this._field(label, i); }
|
||||
_color(label, val, cb){ const i = document.createElement('input'); i.type='color'; i.value=val;
|
||||
i.oninput = () => cb(i.value); return this._field(label, i); }
|
||||
_chk(label, val, cb){ const i = document.createElement('input'); i.type='checkbox'; i.checked=!!val;
|
||||
i.onchange = () => cb(i.checked); return this._field(label, i); }
|
||||
_sel(label, opts, val, cb){ const s = document.createElement('select');
|
||||
for(const o of opts){ const op = document.createElement('option'); op.value=op.textContent=o; if(o===val) op.selected=true; s.appendChild(op); }
|
||||
s.onchange = () => cb(s.value); return this._field(label, s); }
|
||||
@ -260,12 +277,12 @@ export class Dock {
|
||||
if(/\.(png|jpe?g|webp)$/.test(nm)){
|
||||
const url = URL.createObjectURL(f);
|
||||
const en = await this.stage.addEntity({ kind:'backdrop', label:f.name,
|
||||
source:{ type:'upload', path:f.name, _url:url }, params:{ mode:'plane' } });
|
||||
source:{ type:'upload', path:f.name, _url:url }, params:{ mode:'plane', fit:'frustum' } });
|
||||
this.stage.select(en.id);
|
||||
} else if(/\.(mp4|webm|mov)$/.test(nm)){ // M6: dropped video → video plate (upload, warn on save)
|
||||
const url = URL.createObjectURL(f);
|
||||
const en = await this.stage.addEntity({ kind:'backdrop', label:f.name,
|
||||
source:{ type:'upload', path:f.name, _url:url }, params:{ mode:'video', width:12 } });
|
||||
source:{ type:'upload', path:f.name, _url:url }, params:{ mode:'video', width:12, fit:'frustum' } });
|
||||
this.stage.select(en.id);
|
||||
} else if(/\.(glb|gltf|fbx|obj|bvh)$/.test(nm)){
|
||||
const buf = await f.arrayBuffer();
|
||||
|
||||
@ -30,12 +30,15 @@ import { Dock } from './web/dock.js';
|
||||
|
||||
// retarget self-check (?selftest=1) — proves the crown-jewel bake before anything else
|
||||
if(new URLSearchParams(location.search).has('selftest')){
|
||||
const { _selftest } = await import('./web/room3d.js');
|
||||
const { _selftest, canon } = await import('./web/room3d.js');
|
||||
const r = _selftest();
|
||||
// M7 bone aliasing: non-mixamo rigs must fold onto the canonical names (node: room3d_test.mjs)
|
||||
const alias = canon('CC_Base_Hip_02') === 'hips' && canon('CC_Base_L_Upperarm_050') === 'leftarm'
|
||||
&& canon('upperarm_l') === 'leftarm' && canon('mixamorig4:LeftHand') === 'lefthand';
|
||||
const el = document.getElementById('selftest');
|
||||
el.textContent = `selftest: ${r.ok ? 'PASS' : 'FAIL'} (maxErr=${r.maxErr.toExponential(2)})`;
|
||||
el.className = r.ok ? 'ok' : 'bad';
|
||||
console.log('[room3d selftest]', r);
|
||||
el.textContent = `selftest: ${r.ok && alias ? 'PASS' : 'FAIL'} (maxErr=${r.maxErr.toExponential(2)}, alias ${alias ? 'ok' : 'BAD'})`;
|
||||
el.className = r.ok && alias ? 'ok' : 'bad';
|
||||
console.log('[room3d selftest]', r, 'alias', alias);
|
||||
}
|
||||
|
||||
const stage = new Stage(document.getElementById('view'));
|
||||
|
||||
@ -67,12 +67,96 @@ export function disposeRoot(root){
|
||||
|
||||
// canonical bone key: "mixamorig:LeftUpLeg" / "mixamorig_LeftUpLeg" / "mixamorig4LeftUpLeg" → "leftupleg"
|
||||
// (mixamo numbers the namespace per-download — strip digits too). Encodes real Mixamo quirks; keep as-is.
|
||||
export const canon = n => n.replace(/^.*?mixamorig\d*[:_]?/i,'').replace(/[^a-z0-9]/gi,'').toLowerCase();
|
||||
const rawCanon = n => n.replace(/^.*?mixamorig\d*[:_]?/i,'').replace(/[^a-z0-9]/gi,'').toLowerCase();
|
||||
|
||||
// ---- bone aliasing (M7) -------------------------------------------------------------------------
|
||||
// The bake is name-driven, so a NON-mixamo rig (Character Creator, Unreal/HumanIK, Rigify, Rokoko,
|
||||
// Unity/VRM) used to pair zero bones and die at "missing hips". canon() now folds foreign names onto
|
||||
// the canonical mixamo names the baker already speaks. Anything that already canons to a mixamo bone
|
||||
// is returned untouched → mixamo→mixamo pairing is bit-identical (room3d_test.mjs asserts all 65).
|
||||
const LIMBS = ['shoulder','arm','forearm','hand','upleg','leg','foot','toebase'];
|
||||
const FINGS = ['handthumb','handindex','handmiddle','handring','handpinky'];
|
||||
export const CANON = new Set(['hips','spine','spine1','spine2','neck','head',
|
||||
...['left','right'].flatMap(s => [...LIMBS.map(b => s+b),
|
||||
...FINGS.flatMap(f => [1,2,3].map(i => s+f+i))])]);
|
||||
|
||||
// side-less bones. CC-qualified keys are listed where the generic reading differs: UE `spine_01` is
|
||||
// the FIRST spine bone, CC's `CC_Base_Spine01` is the SECOND (CC_Base_Waist is first). Spine chains
|
||||
// longer than mixamo's 3 (UE spine_04/05, rigify spine.003+) are deliberately left unmapped.
|
||||
const EXACT = {
|
||||
hip:'hips', pelvis:'hips',
|
||||
waist:'spine', spine01:'spine', abdomen:'spine', ccbasewaist:'spine',
|
||||
chest:'spine1', spine02:'spine1', spine001:'spine1', abdomen2:'spine1', ccbasespine01:'spine1',
|
||||
upperchest:'spine2', spine03:'spine2', spine002:'spine2', ccbasespine02:'spine2',
|
||||
neck01:'neck', neck1:'neck', necktwist01:'neck', ccbasenecktwist01:'neck',
|
||||
};
|
||||
// sided stems → canonical suffix (side prefix/suffix is peeled off first)
|
||||
const STEMS = { shoulder:'shoulder', clavicle:'shoulder', collar:'shoulder',
|
||||
arm:'arm', upperarm:'arm', armupper:'arm',
|
||||
forearm:'forearm', lowerarm:'forearm', armlower:'forearm',
|
||||
hand:'hand', wrist:'hand',
|
||||
upleg:'upleg', thigh:'upleg', upperleg:'upleg', legupper:'upleg',
|
||||
leg:'leg', calf:'leg', shin:'leg', lowerleg:'leg', leglower:'leg',
|
||||
foot:'foot', ankle:'foot',
|
||||
toebase:'toebase', toe:'toebase', toes:'toebase', ball:'toebase' };
|
||||
for(const [k, v] of Object.entries({ thumb:'handthumb', index:'handindex', findex:'handindex',
|
||||
mid:'handmiddle', middle:'handmiddle', fmiddle:'handmiddle', ring:'handring', fring:'handring',
|
||||
pinky:'handpinky', little:'handpinky', fpinky:'handpinky' }))
|
||||
for(const i of [1,2,3]){ STEMS[k+i] = v+i; STEMS[k+'0'+i] = v+i; }
|
||||
// longest side spellings first; a decomposition only counts when the leftover stem is known
|
||||
// (so "lowerarm" isn't read as left-"owerarm", and "shoulder" isn't read as "shoulde"-right).
|
||||
const SIDES = [['left',/^left(.+)/], ['right',/^right(.+)/], ['left',/(.+)left$/], ['right',/(.+)right$/],
|
||||
['left',/^l(.+)/], ['right',/^r(.+)/], ['left',/(.+)l$/], ['right',/(.+)r$/]];
|
||||
const nsStrip = s => s.replace(/^.*[:|]/, ''); // "mixamorig:X", "Armature|X"
|
||||
const pfxStrip = s => s.replace(/^(cc[_ ]?base|def|org|mch|bip\d*|biped)[._\-| ]+/i, '');
|
||||
const idxStrip = s => s.replace(/[._\- ]\d+$/, ''); // CC's per-export "_02" tail
|
||||
const flat = s => s.replace(/[^a-z0-9]/gi, '').toLowerCase();
|
||||
function alias(name){
|
||||
const b = nsStrip(String(name));
|
||||
// most-qualified first: "ccbasespine01" must beat the generic "spine01" reading
|
||||
for(const s of [b, pfxStrip(b), idxStrip(b), pfxStrip(idxStrip(b))]){
|
||||
const k = flat(s);
|
||||
if(CANON.has(k)) return k;
|
||||
if(EXACT[k]) return EXACT[k];
|
||||
for(const [side, re] of SIDES){ const m = k.match(re), stem = m && STEMS[m[1]];
|
||||
if(stem) return side + stem; }
|
||||
}
|
||||
return null; // never fabricate — an unmapped bone just stays unbaked
|
||||
}
|
||||
// what kind of skeleton is this? (error messages only — the mapping itself is per-bone)
|
||||
export function rigStyle(names){
|
||||
const s = (names || []).join('\n');
|
||||
for(const [re, label] of [[/mixamorig/i,'mixamo'], [/CC_Base/i,'CC_Base'], [/^(DEF|ORG|MCH)-/m,'Rigify'],
|
||||
[/(upperarm|lowerarm|thigh|calf|clavicle|ball)_[lr]\b/i,'Unreal/HumanIK'], [/Bip\d/,'3dsMax Biped'],
|
||||
[/(LeftUpLeg|LeftForeArm|LeftToeBase)/i,'mixamo-style']])
|
||||
if(re.test(s)) return label;
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
export const canon = n => { const raw = rawCanon(n); return CANON.has(raw) ? raw : (alias(n) || raw); };
|
||||
export function boneMap(root){
|
||||
const m={}; root.traverse(o=>{ if(o.isBone && !(canon(o.name) in m)) m[canon(o.name)] = o; }); return m;
|
||||
}
|
||||
const hipsOf = map => map['hips'] || null;
|
||||
|
||||
// target bone → source bone, by canonical name. Dedupe by canon key: fbx files often carry a
|
||||
// DUPLICATE hierarchy, and aliased rigs can fold two bones onto one key (CC Hip + Pelvis → hips) —
|
||||
// bind only the first, which is what boneMap picks. THREE-free so node can test it.
|
||||
const MINPAIR = 8; // below this a "retarget" is garbage — fail loudly instead of animating soup
|
||||
export function pairBones(tOrder, srcMap, hasRest = () => true){
|
||||
const pairs = new Map(), used = new Set();
|
||||
for(const tb of tOrder){ const k = canon(tb.name), sb = srcMap[k];
|
||||
if(sb && hasRest(sb) && !used.has(k)){ pairs.set(tb, sb); used.add(k); } }
|
||||
if(pairs.size < Math.min(MINPAIR, tOrder.length)){
|
||||
const un = tOrder.find(tb => !pairs.has(tb));
|
||||
throw new Error(`retarget: only ${pairs.size}/${tOrder.length} bones matched (target looks like `
|
||||
+ `'${rigStyle(tOrder.map(b => b.name))}', source looks like `
|
||||
+ `'${rigStyle(Object.values(srcMap).map(b => b.name))}'; first unmatched bone `
|
||||
+ `'${un ? un.name : '?'}'); unsupported skeleton`);
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
// bind-pose snapshot — retargets are world-space deltas against THIS. Capture BEFORE any clip poses it.
|
||||
export function captureRest(root){
|
||||
root.updateMatrixWorld(true);
|
||||
@ -89,15 +173,18 @@ export function captureRest(root){
|
||||
export function bakeRetarget(clip, srcRoot, srcRest, tgtRoot, tgtRest, opts={}){
|
||||
const tgt = boneMap(tgtRoot), src = boneMap(srcRoot);
|
||||
const tHips = hipsOf(tgt), sHips = hipsOf(src);
|
||||
if(!tHips || !sHips) throw new Error('retarget: missing hips (mixamorig skeleton?)');
|
||||
const sRest = srcRest.rest, tRest = tgtRest.rest, tOrder = tgtRest.order;
|
||||
const pairs = new Map(); // target bone → source bone. Dedupe by canon key: fbx files often
|
||||
const used = new Set(); // carry a DUPLICATE hierarchy — bind only the first (what boneMap picks)
|
||||
for(const tb of tOrder){ const k=canon(tb.name), sb=src[k];
|
||||
if(sb && sRest.has(sb) && !used.has(k)){ pairs.set(tb, sb); used.add(k); } }
|
||||
if(!pairs.size) throw new Error('retarget: no matching bones');
|
||||
if(!tHips || !sHips) throw new Error(`retarget: no bone maps to 'hips' on the `
|
||||
+ `${tHips ? 'source' : 'target'} (target looks like '${rigStyle(tOrder.map(b => b.name))}', `
|
||||
+ `source looks like '${rigStyle(srcRest.order.map(b => b.name))}'); unsupported skeleton`);
|
||||
const pairs = pairBones(tOrder, src, sb => sRest.has(sb));
|
||||
let ratio=1; // hips travel: local hip-height ratio (cm fbx vs m glb sorts itself out)
|
||||
if(sHips.position.y > 1e-6) ratio = tHips.position.y / sHips.position.y;
|
||||
// ponytail: axis-swapped rigs (lady.glb hangs its hip height off LOCAL Z, not Y — CC via a Z-up
|
||||
// exporter) land ratio 0, so the clip plays IN PLACE. That is the safe read: the source's travel
|
||||
// delta is expressed in the SOURCE's axes, and scaling it into a Z-up hip would fly the character.
|
||||
// Rotations are unaffected (they transfer through world space). Proper fix = rotate the travel
|
||||
// delta through both rests' parent world quats — not needed until a CC rig has to walk a mark.
|
||||
const fps=30, n=Math.max(2, Math.ceil(clip.duration*fps)+1);
|
||||
const times = new Float32Array(n);
|
||||
const qData = new Map([...pairs.keys()].map(tb=>[tb, new Float32Array(n*4)]));
|
||||
|
||||
116
scenegod/web/room3d_test.mjs
Normal file
116
scenegod/web/room3d_test.mjs
Normal file
@ -0,0 +1,116 @@
|
||||
// room3d_test.mjs — Lane A M7-A1 check: bone aliasing + the retarget guardrail.
|
||||
// Runs under plain `node`, no deps and no three.js: it loads the REAL room3d.js with the three
|
||||
// imports stripped (nothing at module top level touches THREE), so the tables under test are the
|
||||
// shipped ones — not a copy that can drift.
|
||||
// node scenegod/web/room3d_test.mjs
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const src = fs.readFileSync(new URL('./room3d.js', import.meta.url), 'utf8')
|
||||
.replace(/^import .*from ['"]three(\/[^'"]*)?['"];$/gm, '');
|
||||
const { canon, pairBones, rigStyle } = await import(
|
||||
'data:text/javascript;base64,' + Buffer.from(src).toString('base64'));
|
||||
|
||||
// ---- 1. BACKWARD COMPAT: every mixamo bone canons exactly as the pre-M7 one-liner did ----------
|
||||
const legacy = n => n.replace(/^.*?mixamorig\d*[:_]?/i, '').replace(/[^a-z0-9]/gi, '').toLowerCase();
|
||||
const MIXAMO = ['Hips','Spine','Spine1','Spine2','Neck','Head','HeadTop_End',
|
||||
...['Left','Right'].flatMap(s => [s+'Shoulder', s+'Arm', s+'ForeArm', s+'Hand', s+'UpLeg', s+'Leg',
|
||||
s+'Foot', s+'ToeBase', s+'Toe_End',
|
||||
...['Thumb','Index','Middle','Ring','Pinky'].flatMap(f => [1,2,3,4].map(i => `${s}Hand${f}${i}`))])];
|
||||
assert.equal(MIXAMO.length, 65, 'the man.fbx bone list');
|
||||
for(const n of MIXAMO) for(const ns of ['mixamorig:', 'mixamorig_', 'mixamorig4:', 'mixamorig1_', ''])
|
||||
assert.equal(canon(ns + n), legacy(ns + n), `mixamo canon changed: ${ns + n}`);
|
||||
assert.equal(canon('mixamorig4:LeftHand'), 'lefthand', 'per-download namespace still collapses');
|
||||
assert.equal(canon('mixamorig:Hips'), 'hips');
|
||||
assert.equal(canon('mixamorig:LeftToe_End'), 'lefttoeend', 'end effectors stay legacy (unmapped)');
|
||||
|
||||
// ---- 2. Character Creator (the real lady.glb names, verified out of the GLB's JSON chunk) -------
|
||||
const CC = ['CC_Base_BoneRoot_01','CC_Base_Hip_02','CC_Base_Pelvis_03','CC_Base_L_Thigh_04',
|
||||
'CC_Base_L_Calf_05','CC_Base_L_Foot_06','CC_Base_L_ToeBaseShareBone_07','CC_Base_L_ToeBase_08',
|
||||
'CC_Base_L_CalfTwist01_014','CC_Base_R_Thigh_018','CC_Base_R_Calf_019','CC_Base_R_Foot_021',
|
||||
'CC_Base_R_ToeBase_022','CC_Base_Waist_033','CC_Base_Spine01_034','CC_Base_Spine02_035',
|
||||
'CC_Base_NeckTwist01_036','CC_Base_NeckTwist02_037','CC_Base_Head_038','CC_Base_L_Eye_046',
|
||||
'CC_Base_L_Clavicle_049','CC_Base_L_Upperarm_050','CC_Base_L_Forearm_051',
|
||||
'CC_Base_L_ForearmTwist01_052','CC_Base_L_Hand_055','CC_Base_L_Pinky1_056','CC_Base_L_Mid1_062',
|
||||
'CC_Base_L_Thumb1_068','CC_Base_L_Breast_074','CC_Base_R_Clavicle_077','CC_Base_R_Upperarm_078',
|
||||
'CC_Base_R_Forearm_079','CC_Base_R_Hand_083','CC_Base_R_Index3_095',
|
||||
'CC_Base_R_UpperarmTwist02_0100'];
|
||||
for(const [name, want] of [
|
||||
['CC_Base_Hip_02','hips'], ['CC_Base_L_Thigh_04','leftupleg'], ['CC_Base_L_Calf_05','leftleg'],
|
||||
['CC_Base_L_Foot_06','leftfoot'], ['CC_Base_L_ToeBase_08','lefttoebase'],
|
||||
['CC_Base_R_Thigh_018','rightupleg'], ['CC_Base_Waist_033','spine'],
|
||||
['CC_Base_Spine01_034','spine1'], ['CC_Base_Spine02_035','spine2'],
|
||||
['CC_Base_NeckTwist01_036','neck'], ['CC_Base_Head_038','head'],
|
||||
['CC_Base_L_Clavicle_049','leftshoulder'], ['CC_Base_L_Upperarm_050','leftarm'],
|
||||
['CC_Base_L_Forearm_051','leftforearm'], ['CC_Base_L_Hand_055','lefthand'],
|
||||
['CC_Base_R_Hand_083','righthand'], ['CC_Base_L_Thumb1_068','lefthandthumb1'],
|
||||
['CC_Base_L_Mid1_062','lefthandmiddle1'], ['CC_Base_R_Index3_095','righthandindex3'],
|
||||
['CC_Base_L_Pinky1_056','lefthandpinky1']])
|
||||
assert.equal(canon(name), want, `CC ${name} → ${canon(name)}, want ${want}`);
|
||||
// twist / share / cosmetic bones have no mixamo counterpart: they must stay UNMAPPED, not guess
|
||||
for(const n of ['CC_Base_L_CalfTwist01_014','CC_Base_L_ToeBaseShareBone_07','CC_Base_L_Eye_046',
|
||||
'CC_Base_L_Breast_074','CC_Base_L_ForearmTwist01_052','CC_Base_R_UpperarmTwist02_0100',
|
||||
'CC_Base_BoneRoot_01','CC_Base_NeckTwist02_037'])
|
||||
assert.ok(!canon(n).match(/^(hips|spine|neck|head|left|right)/), `${n} must stay unmapped, got ${canon(n)}`);
|
||||
|
||||
// ---- 3. Unreal / HumanIK, Rigify, Unity-VRM / Rokoko, plain lowercase --------------------------
|
||||
for(const [name, want] of [
|
||||
// Unreal mannequin / HumanIK
|
||||
['pelvis','hips'], ['spine_01','spine'], ['spine_02','spine1'], ['spine_03','spine2'],
|
||||
['neck_01','neck'], ['head','head'], ['clavicle_l','leftshoulder'], ['upperarm_l','leftarm'],
|
||||
['lowerarm_l','leftforearm'], ['hand_r','righthand'], ['thigh_r','rightupleg'],
|
||||
['calf_l','leftleg'], ['foot_r','rightfoot'], ['ball_l','lefttoebase'],
|
||||
['thumb_01_l','lefthandthumb1'], ['index_03_r','righthandindex3'],
|
||||
// Blender Rigify (deform bones are what gets skinned)
|
||||
['DEF-spine','spine'], ['DEF-spine.001','spine1'], ['DEF-spine.002','spine2'],
|
||||
['DEF-shoulder.L','leftshoulder'], ['DEF-upper_arm.L','leftarm'], ['DEF-forearm.R','rightforearm'],
|
||||
['DEF-hand.L','lefthand'], ['DEF-thigh.R','rightupleg'], ['DEF-shin.L','leftleg'],
|
||||
['DEF-foot.L','leftfoot'], ['DEF-toe.R','righttoebase'], ['DEF-thumb.01.L','lefthandthumb1'],
|
||||
['DEF-f_index.02.R','righthandindex2'], ['ORG-upper_arm.R','rightarm'],
|
||||
// Unity humanoid / VRM / Rokoko-style long names + plain lowercase
|
||||
['LeftUpperArm','leftarm'], ['RightLowerArm','rightforearm'], ['LeftUpperLeg','leftupleg'],
|
||||
['RightLowerLeg','rightleg'], ['Chest','spine1'], ['UpperChest','spine2'], ['Hips','hips'],
|
||||
['leftshoulder','leftshoulder'], ['l_hand','lefthand'], ['R_Foot','rightfoot'],
|
||||
['Bip01 Pelvis','hips'], ['Bip01 L Clavicle','leftshoulder']])
|
||||
assert.equal(canon(name), want, `${name} → ${canon(name)}, want ${want}`);
|
||||
// side-less limbs stay unmapped (guessing a side would silently mirror a character)
|
||||
for(const n of ['thigh','upperarm','hand','shoulder','lowerarm','toe'])
|
||||
assert.ok(!canon(n).match(/^(left|right)/), `side-less "${n}" must stay unmapped, got ${canon(n)}`);
|
||||
|
||||
// ---- 4. pairing: a CC target against a mixamo source ------------------------------------------
|
||||
const boneList = names => names.map(name => ({ name }));
|
||||
const mapOf = names => { const m = {};
|
||||
for(const b of boneList(names)) if(!(canon(b.name) in m)) m[canon(b.name)] = b; return m; };
|
||||
const mixamoSrc = mapOf(MIXAMO.map(n => 'mixamorig:' + n));
|
||||
const ccPairs = pairBones(boneList(CC), mixamoSrc);
|
||||
assert.ok(ccPairs.size >= 8, `CC target paired only ${ccPairs.size} bones`);
|
||||
assert.equal(ccPairs.size, 26, 'every mappable bone in the CC sample pairs exactly once');
|
||||
// (the full 102-bone lady.glb skeleton pairs 52: core + both arms/legs + all 30 finger bones —
|
||||
// every twist/share/toe-detail/facial bone correctly stays unmapped)
|
||||
// CC_Base_Hip wins 'hips'; CC_Base_Pelvis folds onto the same key and is left unbaked (not doubled)
|
||||
const paired = [...ccPairs.keys()].map(b => b.name);
|
||||
assert.ok(paired.includes('CC_Base_Hip_02') && !paired.includes('CC_Base_Pelvis_03'), 'hips dedupe');
|
||||
// mixamo→mixamo is unaffected
|
||||
assert.equal(pairBones(boneList(MIXAMO.map(n => 'mixamorig4:' + n)), mixamoSrc).size, 65);
|
||||
|
||||
// ---- 5. the guardrail: an unmappable rig fails loudly instead of baking soup -------------------
|
||||
const junk = boneList(['CC_Base_BoneRoot_01', ...Array.from({length: 53}, (_, i) => `joint_x${i}`)]);
|
||||
assert.throws(() => pairBones(junk, mixamoSrc), err => {
|
||||
assert.match(err.message, /only \d+\/54 bones matched/, err.message);
|
||||
assert.match(err.message, /CC_Base/, 'names the detected skeleton style');
|
||||
assert.match(err.message, /first unmatched bone 'joint_x0'|first unmatched bone 'CC_Base_BoneRoot_01'/);
|
||||
assert.match(err.message, /unsupported skeleton/);
|
||||
return true;
|
||||
}, 'a 0-8 match rig must throw');
|
||||
// tiny synthetic skeletons (room3d _selftest builds a 3-bone pair) must still bake
|
||||
assert.equal(pairBones(boneList(['mixamorig4_Hips','mixamorig4_Spine','mixamorig4_Head']),
|
||||
mapOf(['mixamorig1_Hips','mixamorig1_Spine','mixamorig1_Head'])).size, 3, '_selftest skeletons');
|
||||
|
||||
// ---- 6. style detection -----------------------------------------------------------------------
|
||||
assert.equal(rigStyle(CC), 'CC_Base');
|
||||
assert.equal(rigStyle(MIXAMO.map(n => 'mixamorig:' + n)), 'mixamo');
|
||||
assert.equal(rigStyle(['pelvis','spine_01','upperarm_l','thigh_r']), 'Unreal/HumanIK');
|
||||
assert.equal(rigStyle(['DEF-spine','DEF-upper_arm.L']), 'Rigify');
|
||||
assert.equal(rigStyle(['bone_a','bone_b']), 'unknown');
|
||||
|
||||
console.log(`room3d_test: ALL PASS (${ccPairs.size} CC bones paired against mixamo)`);
|
||||
@ -56,6 +56,14 @@ export function visemeSelfCheck(){
|
||||
return { ok: detectOk && driveOk, found: Object.keys(visemes).sort().join(','), visemes };
|
||||
}
|
||||
|
||||
// M7 backdrop auto-fit, kept pure so node can check the algebra (stage_test.mjs): the frustum is
|
||||
// `fh` tall at `dist`, and the plate scales to COVER it (either axis, whichever is tighter) + bleed.
|
||||
export const BLEED = 1.06;
|
||||
export function fitScale(fovDeg, aspect, dist, planeW, planeH){
|
||||
const fh = 2 * Math.tan(fovDeg * Math.PI / 360) * dist, fw = fh * aspect;
|
||||
return { fh, fw, s: Math.max(fw / planeW, fh / planeH) * BLEED };
|
||||
}
|
||||
|
||||
export class Stage {
|
||||
constructor(viewEl){
|
||||
this.view = viewEl;
|
||||
@ -95,10 +103,12 @@ export class Stage {
|
||||
this._defHemi = new THREE.HemisphereLight(0xffffff, 0x555a66, 2.2); scene.add(this._defHemi);
|
||||
this._defKey = new THREE.DirectionalLight(0xffffff, 1.8); this._defKey.position.set(3, 5, 2); scene.add(this._defKey);
|
||||
|
||||
const floor = new THREE.Mesh(new THREE.CircleGeometry(30, 64).rotateX(-Math.PI/2),
|
||||
const floor = this._floor = new THREE.Mesh(new THREE.CircleGeometry(30, 64).rotateX(-Math.PI/2),
|
||||
new THREE.MeshStandardMaterial({color:0x141a20, roughness:.97}));
|
||||
floor.receiveShadow = true; scene.add(floor);
|
||||
scene.add(new THREE.GridHelper(60, 60, 0x2a323b, 0x1c232b));
|
||||
this._floorBase = new THREE.Color(0x141a20);
|
||||
const grid = this._grid = new THREE.GridHelper(60, 60, 0x2a323b, 0x1c232b);
|
||||
grid.material.transparent = true; scene.add(grid);
|
||||
|
||||
// gizmo
|
||||
const tc = this._tc = new TransformControls(cam, r.domElement);
|
||||
@ -132,7 +142,9 @@ export class Stage {
|
||||
this.renderer.setSize(w, h, false); this._dirCam.aspect = w/h; this._dirCam.updateProjectionMatrix();
|
||||
// size the inset here — CSS aspect-ratio/% is unreliable on a <canvas>
|
||||
const pw = Math.max(180, Math.min(340, w*0.24));
|
||||
this._pip.style.width = Math.round(pw)+'px'; this._pip.style.height = Math.round(pw*9/16)+'px'; }
|
||||
this._pip.style.width = Math.round(pw)+'px'; this._pip.style.height = Math.round(pw*9/16)+'px';
|
||||
this.fitBackdrops(); // frame aspect changed → auto-fit plates no longer fill it
|
||||
}
|
||||
|
||||
// ---- callbacks ----
|
||||
onSelect(cb){ this._selCbs.push(cb); }
|
||||
@ -151,7 +163,8 @@ export class Stage {
|
||||
const noAsset = desc.kind === 'camera' || desc.kind === 'light'; // rig entities have no file
|
||||
const en = { id, kind: desc.kind, label: desc.label || desc.kind,
|
||||
source: desc.source || (noAsset ? {type:'none'} : null), params: {...(desc.params||{})},
|
||||
wrapper, root:null, mixer:null, rest:null, cam:null, light:null, morphs:null, visemes:null, video:null };
|
||||
wrapper, root:null, mixer:null, rest:null, cam:null, light:null, morphs:null, visemes:null,
|
||||
video:null, ground:null };
|
||||
|
||||
if(desc.kind === 'character' || desc.kind === 'prop'){
|
||||
const { root } = await this._loadAsset(desc);
|
||||
@ -170,7 +183,8 @@ export class Stage {
|
||||
wrapper.add(en.cam);
|
||||
const proxy = new THREE.Mesh(new THREE.ConeGeometry(0.18, 0.35, 4).rotateX(-Math.PI/2),
|
||||
new THREE.MeshBasicMaterial({color:0x43c0cf, wireframe:true}));
|
||||
proxy.position.z = 0.18; wrapper.add(proxy);
|
||||
proxy.position.z = 0.18; proxy.userData.chrome = true; // SYNC7: editor-only, never in a render
|
||||
wrapper.add(proxy); en.proxy = proxy;
|
||||
} else if(desc.kind === 'light'){
|
||||
this._buildLight(en);
|
||||
} else throw new Error('unknown kind: ' + desc.kind);
|
||||
@ -178,6 +192,10 @@ export class Stage {
|
||||
this.scene.add(wrapper);
|
||||
this._entities.set(id, en);
|
||||
if(desc.transform) this.setTransform(id, desc.transform);
|
||||
if(en.kind === 'backdrop'){ this._fitBackdrop(en); this._sampleGround(en); } // M7: world tie-in
|
||||
// _buildLight ran BEFORE the entity was registered, so its _refreshDefaults couldn't see it —
|
||||
// without this the built-in hemi stayed at 2.2 and washed every lighting preset out.
|
||||
if(en.kind === 'light'){ this._refreshDefaults(); this._applyWorld(); }
|
||||
this._fireChange(en); // tlui/dock build a row per entity off onChange (incl. applyState loads)
|
||||
return en;
|
||||
}
|
||||
@ -192,6 +210,7 @@ export class Stage {
|
||||
this._entities.delete(id);
|
||||
for(const k of [...this._baked.keys()]) if(k.startsWith(id+'|')) this._baked.delete(k);
|
||||
if(en.kind === 'light') this._refreshDefaults();
|
||||
if(en.kind === 'backdrop' || en.kind === 'light') this._applyWorld(); // floor/grid/fog follow the plates
|
||||
this._fireChange(en); // trigger a row resync so the deleted entity drops out
|
||||
}
|
||||
|
||||
@ -247,11 +266,12 @@ export class Stage {
|
||||
}
|
||||
const w = p.width || 10, h = w / aspect;
|
||||
const grp = new THREE.Group(), mats = [];
|
||||
// fog:false — the plate IS the distance; atmosphere is for what stands in front of it
|
||||
if(p.mode === 'dome'){
|
||||
const dm = new THREE.MeshBasicMaterial({map:tex, side:THREE.BackSide}); mats.push(dm);
|
||||
const dm = new THREE.MeshBasicMaterial({map:tex, side:THREE.BackSide, fog:false}); mats.push(dm);
|
||||
grp.add(new THREE.Mesh(new THREE.SphereGeometry(40, 40, 24), dm));
|
||||
} else {
|
||||
const mat = new THREE.MeshStandardMaterial({map:tex, roughness:1, metalness:0}); mats.push(mat);
|
||||
const mat = new THREE.MeshStandardMaterial({map:tex, roughness:1, metalness:0, fog:false}); mats.push(mat);
|
||||
const wall = new THREE.Mesh(new THREE.PlaneGeometry(w, h), mat);
|
||||
wall.position.y = h/2; wall.receiveShadow = true; grp.add(wall);
|
||||
if(p.mode === 'corner'){ // cheap "L": duplicate lower third laid flat as ground
|
||||
@ -318,6 +338,90 @@ export class Stage {
|
||||
en.video.pause(); en.video.removeAttribute('src'); en.video.load(); en.video = null;
|
||||
}
|
||||
|
||||
// ---- world-integrated backdrops (M7) ---------------------------------------------------------
|
||||
// A plate used to read as a billboard in the void: a gap between its bottom edge and the grid, a
|
||||
// floor that belongs to a different scene, no air between camera and horizon. Three cheap fixes,
|
||||
// all recomputed on load / param change / camera change — NEVER per frame.
|
||||
// params.fit:'frustum' size+place the plate so it fills the active camera's frustum (+bleed)
|
||||
// params.groundTint tint the stage floor to the plate's bottom rows (default on)
|
||||
// params `fog` on the ambient light keyable FogExp2 density, coloured from the plate
|
||||
|
||||
_activeAspect(){ const c = this._activeCam();
|
||||
return c.aspect || (this.view.clientWidth / this.view.clientHeight) || 16/9; }
|
||||
|
||||
fitBackdrops(){ for(const en of this._entities.values())
|
||||
if(en.kind === 'backdrop') this._fitBackdrop(en); }
|
||||
|
||||
// Scale/park the plate on the active camera's axis so it covers the frame at params.fitDist.
|
||||
// ponytail: fit OWNS the backdrop's wrapper transform — keyframe a plate only with fit:'free'.
|
||||
_fitBackdrop(en){
|
||||
const p = en.params, root = en.root;
|
||||
if(!root || p.fit !== 'frustum') return;
|
||||
if(p.mode === 'dome' || p.mode === 'corner') return; // dome already wraps; corner needs its floor flat
|
||||
const mesh = root.children[0], g = mesh && mesh.geometry && mesh.geometry.parameters;
|
||||
if(!g || !g.width) return;
|
||||
const cam = this._activeCam(); cam.updateMatrixWorld(true);
|
||||
const d = p.fitDist || 14; // far enough to read as background
|
||||
const { s } = fitScale(cam.fov, this._activeAspect(), d, g.width, g.height);
|
||||
root.scale.setScalar(s);
|
||||
// SYNC7: which row of the plate sits at eye level. 1.0 parked the plate's TOP EDGE on the
|
||||
// camera axis (void above centre-frame); 0.5 put the image's middle — road tarmac, for a
|
||||
// street plate — at eye height. params.fitAnchor is the fraction of image height at the
|
||||
// lens axis: 0.75 lands a typical plate's horizon near eye level and still fills upward.
|
||||
const anchor = p.fitAnchor == null ? 0.75 : p.fitAnchor;
|
||||
root.position.set(0, (0.5 - anchor) * g.height * s, 0);
|
||||
const camPos = cam.getWorldPosition(new THREE.Vector3());
|
||||
const fwd = new THREE.Vector3(0, 0, -1).applyQuaternion(cam.getWorldQuaternion(new THREE.Quaternion()));
|
||||
en.wrapper.position.copy(camPos).addScaledVector(fwd, d);
|
||||
en.wrapper.lookAt(camPos); // plane normal is +Z
|
||||
en.wrapper.scale.setScalar(1);
|
||||
}
|
||||
_unfitBackdrop(en){ if(en.root){ en.root.scale.setScalar(1); en.root.position.set(0,0,0); } }
|
||||
|
||||
// average colour of the plate's bottom rows — the ground the character should be standing on.
|
||||
// Works for images and for video (poster or current frame); same-origin, so the canvas is clean.
|
||||
_plateGround(en){
|
||||
const mesh = en.root && en.root.children[0], tex = mesh && mesh.material && mesh.material.map;
|
||||
const img = tex && tex.image;
|
||||
if(!img || !(img.width || img.videoWidth)) return null;
|
||||
if(img.videoWidth && img.readyState < 2) return null; // no decoded frame yet → sample black
|
||||
try {
|
||||
const c = document.createElement('canvas'); c.width = c.height = 24;
|
||||
const g = c.getContext('2d', { willReadFrequently: true });
|
||||
g.drawImage(img, 0, 0, 24, 24);
|
||||
const d = g.getImageData(0, 17, 24, 7).data; // bottom ~quarter
|
||||
let r = 0, gr = 0, b = 0; const n = d.length / 4;
|
||||
for(let i = 0; i < d.length; i += 4){ r += d[i]; gr += d[i+1]; b += d[i+2]; }
|
||||
return new THREE.Color().setRGB(r/n/255, gr/n/255, b/n/255, THREE.SRGBColorSpace);
|
||||
} catch(e){ return null; } // tainted canvas / no frame yet
|
||||
}
|
||||
_sampleGround(en){
|
||||
const col = this._plateGround(en);
|
||||
if(col) en.ground = col;
|
||||
else if(en.video) // no decoded frame yet — take the first one that lands
|
||||
en.video.addEventListener('loadeddata', () => this._sampleGround(en), { once:true });
|
||||
this._applyWorld(); // grid/fog follow the plate even when sampling came back empty
|
||||
}
|
||||
|
||||
// floor tint + grid fade + fog, derived from whatever plates are on stage
|
||||
_applyWorld(){
|
||||
const plates = this.entities().filter(e => e.kind === 'backdrop');
|
||||
const tint = plates.filter(e => e.ground && (e.params.groundTint ?? true)).pop();
|
||||
const col = tint ? tint.ground : null;
|
||||
this._floor.material.color.copy(col ? col.clone().multiplyScalar(0.85) : this._floorBase);
|
||||
this._grid.material.opacity = plates.length ? 0.12 : 1; // fade the studio grid out under a plate
|
||||
const amb = this.entities().find(e => e.kind === 'light' && e.params.type === 'ambient');
|
||||
const dens = amb && amb.params.fog != null ? amb.params.fog : (col ? 0.02 : 0); // subtle default
|
||||
const had = !!this.scene.fog;
|
||||
if(col && dens > 0){ // Lane B can key `fog` per tick — mutate, don't reallocate
|
||||
if(had){ this.scene.fog.color.copy(col); this.scene.fog.density = dens; }
|
||||
else this.scene.fog = new THREE.FogExp2(col.getHex(), dens);
|
||||
} else this.scene.fog = null;
|
||||
// toggling fog on/off changes the shader program — materials must recompile (once, not per frame)
|
||||
if(had !== !!this.scene.fog) this.scene.traverse(o => { const m = o.material;
|
||||
if(m) (Array.isArray(m) ? m : [m]).forEach(x => x.needsUpdate = true); });
|
||||
}
|
||||
|
||||
_buildLight(en){
|
||||
const p = en.params;
|
||||
if(p.type === 'ambient'){
|
||||
@ -377,7 +481,11 @@ export class Stage {
|
||||
scale: w.scale.x };
|
||||
}
|
||||
setTransform(id, {pos, rot, scale}){
|
||||
const w = this._entities.get(id)?.wrapper; if(!w) return;
|
||||
const en = this._entities.get(id); const w = en?.wrapper; if(!w) return;
|
||||
// SYNC7: a frustum-fitted plate is placed BY THE LENS, not by the user. The timeline
|
||||
// re-applies every entity's rest transform each tick, which dragged the plate back to
|
||||
// its authored pos and left a black bar at frame top. Camera owns it; ignore the rest.
|
||||
if(en.kind === 'backdrop' && en.params && en.params.fit === 'frustum'){ this._fitBackdrop(en); return; }
|
||||
if(pos) w.position.set(pos[0], pos[1], pos[2]);
|
||||
if(rot) w.rotation.set(rot[0], rot[1], rot[2]);
|
||||
if(scale != null) w.scale.setScalar(scale);
|
||||
@ -385,12 +493,19 @@ export class Stage {
|
||||
setParam(id, key, value){
|
||||
const en = this._entities.get(id); if(!en) return;
|
||||
en.params[key] = value;
|
||||
if(en.cam && key === 'fov'){ en.cam.fov = value; en.cam.updateProjectionMatrix(); }
|
||||
if(en.cam && key === 'fov'){ en.cam.fov = value; en.cam.updateProjectionMatrix();
|
||||
if(en.id === this._activeCamId) this.fitBackdrops(); } // the frame changed shape
|
||||
if(en.light){
|
||||
if(key === 'intensity') en.light.intensity = value;
|
||||
if(key === 'color') en.light.color.set(value);
|
||||
if(key === 'castShadow' && en.light.isDirectionalLight) en.light.castShadow = !!value;
|
||||
if(key === 'bg') this.scene.background = new THREE.Color(value); // bg rides the ambient entity (keyable, persists)
|
||||
if(key === 'fog') this._applyWorld(); // keyable atmosphere, same pattern as bg
|
||||
}
|
||||
if(en.kind === 'backdrop'){
|
||||
if(key === 'fit') value === 'frustum' ? this._fitBackdrop(en) : this._unfitBackdrop(en);
|
||||
if(key === 'fitDist') this._fitBackdrop(en);
|
||||
if(key === 'groundTint') this._applyWorld();
|
||||
}
|
||||
const rebuild = () => this._rebuild(en).catch(e => console.warn('media rebuild failed:', en.id, e));
|
||||
if(en.kind === 'backdrop' && (key === 'mode' || key === 'image' || key === 'width'))
|
||||
@ -408,6 +523,7 @@ export class Stage {
|
||||
en.root = en.kind === 'screen' ? await this._buildScreen(en) : await this._buildBackdrop(en);
|
||||
en.wrapper.add(en.root);
|
||||
if(old){ en.wrapper.remove(old); disposeRoot(old); }
|
||||
if(en.kind === 'backdrop'){ this._fitBackdrop(en); en.ground = null; this._sampleGround(en); }
|
||||
}
|
||||
|
||||
// ---- clips (bake is expensive — cache per path parse and per (entity,path,index) bake) ----
|
||||
@ -466,17 +582,35 @@ export class Stage {
|
||||
setActiveCamera(id){
|
||||
this._activeCamId = id;
|
||||
this._pip.style.display = (id && this._entities.get(id)?.cam) ? 'block' : 'none';
|
||||
this.fitBackdrops(); // auto-fit plates belong to whichever camera is shooting
|
||||
}
|
||||
_activeCam(){ const en = this._activeCamId && this._entities.get(this._activeCamId);
|
||||
return en && en.cam ? en.cam : this._dirCam; }
|
||||
// render `cam` to the main WebGL canvas at the target's aspect; if `canvas` given, blit there and
|
||||
// restore the cam's aspect (so using a cam for the inset never distorts it in the main view).
|
||||
// SYNC7: gizmo + helpers were being BAKED INTO THE FINAL MP4 (a green translate
|
||||
// arrow across every frame). Anything that's editor chrome hides while paused —
|
||||
// pause() is exactly "the caller is rendering output now".
|
||||
_chrome(visible){
|
||||
const set = o => { if(o) o.visible = visible; };
|
||||
set(this._tc); set(this._grid);
|
||||
this.scene.traverse(o => { if(o.userData.chrome || o.isTransformControls || o.type === 'GridHelper'
|
||||
|| o.isCameraHelper || o.isDirectionalLightHelper || o.isBox3Helper || o.isSkeletonHelper) o.visible = visible; });
|
||||
for(const en of this._entities.values()) if(en.helper) en.helper.visible = visible;
|
||||
}
|
||||
_render(cam, canvas){
|
||||
const w = canvas ? canvas.width : this.renderer.domElement.width;
|
||||
const h = canvas ? canvas.height : this.renderer.domElement.height;
|
||||
const prev = cam.aspect;
|
||||
if(cam.isPerspectiveCamera){ cam.aspect = w/h; cam.updateProjectionMatrix(); }
|
||||
// SYNC7: plates are fitted to the LIVE viewport aspect, but output renders at their own
|
||||
// (960x540 etc). A narrower output frame is taller than what the plate was sized for →
|
||||
// black bars top and bottom of every rendered film. Refit to the aspect we're about to
|
||||
// draw at. Pure algebra (no texture sampling), so per-frame is fine.
|
||||
if(cam.isPerspectiveCamera && Math.abs((prev || 0) - cam.aspect) > 1e-4) this.fitBackdrops();
|
||||
if(this._paused) this._chrome(false);
|
||||
this.renderer.render(this.scene, cam);
|
||||
if(this._paused) this._chrome(true);
|
||||
if(canvas){ canvas.getContext('2d').drawImage(this.renderer.domElement, 0, 0, canvas.width, canvas.height);
|
||||
if(cam.isPerspectiveCamera && cam.aspect !== prev){ cam.aspect = prev; cam.updateProjectionMatrix(); } }
|
||||
}
|
||||
@ -561,5 +695,6 @@ export class Stage {
|
||||
console.warn('skipping upload entity (no bytes):', d.id); continue; }
|
||||
try { await this.addEntity(d); } catch(err){ console.error('addEntity failed', d.id, err); }
|
||||
}
|
||||
this.fitBackdrops(); // cameras usually load after their plates
|
||||
}
|
||||
}
|
||||
|
||||
36
scenegod/web/stage_test.mjs
Normal file
36
scenegod/web/stage_test.mjs
Normal file
@ -0,0 +1,36 @@
|
||||
// stage_test.mjs — Lane A M7-A2 check: the backdrop auto-fit algebra. Plain `node`, no three.js:
|
||||
// loads the REAL stage.js with its three/room3d imports stripped (nothing at module top level
|
||||
// touches them), so the shipped formula is what gets asserted.
|
||||
// node scenegod/web/stage_test.mjs
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const src = fs.readFileSync(new URL('./stage.js', import.meta.url), 'utf8')
|
||||
.replace(/^import .*from ['"](three(\/[^'"]*)?|\.\/room3d\.js)['"];$/gm, '');
|
||||
const { fitScale, BLEED } = await import(
|
||||
'data:text/javascript;base64,' + Buffer.from(src).toString('base64'));
|
||||
|
||||
// a 16:9 plate built 10m wide (dock default) seen by a 45° camera 14m away (fitDist default)
|
||||
const camA = 16/9, fov = 45, d = 14, pw = 10, ph = 10 / (16/9);
|
||||
const f = fitScale(fov, camA, d, pw, ph);
|
||||
assert.ok(Math.abs(f.fh - 2 * Math.tan(fov * Math.PI/360) * d) < 1e-12, 'frustum height at dist');
|
||||
assert.ok(Math.abs(f.fw - f.fh * camA) < 1e-12, 'frustum width from aspect');
|
||||
// the scaled plate COVERS the frame with bleed on both axes — no void showing at the edges
|
||||
assert.ok(pw * f.s >= f.fw * 1.0599 && ph * f.s >= f.fh * 0.9999, 'covers the frame');
|
||||
assert.ok(Math.abs(pw * f.s / f.fw - BLEED) < 1e-9, 'matched aspect → exactly the bleed factor');
|
||||
|
||||
// a portrait plate in a wide frame must scale on WIDTH (the tighter axis), and vice-versa
|
||||
const port = fitScale(fov, camA, d, 4, 9);
|
||||
assert.ok(4 * port.s >= port.fw && 9 * port.s > port.fh * 1.5, 'portrait plate covers width, overshoots height');
|
||||
const wide = fitScale(fov, 1.0, d, 20, 2);
|
||||
assert.ok(2 * wide.s >= wide.fh && 20 * wide.s > wide.fw, 'letterbox plate covers height');
|
||||
|
||||
// framing is scale-free in distance: doubling fitDist doubles the plate, so it fills the same frame
|
||||
const near = fitScale(fov, camA, 7, pw, ph), far = fitScale(fov, camA, 14, pw, ph);
|
||||
assert.ok(Math.abs(far.s / near.s - 2) < 1e-9, 'distance only changes parallax, not framing');
|
||||
// a longer lens (smaller fov) needs a smaller plate at the same distance
|
||||
assert.ok(fitScale(20, camA, d, pw, ph).s < f.s, 'tighter fov → smaller plate');
|
||||
|
||||
console.log('stage_test: ALL PASS (fit s=' + f.s.toFixed(3) + ' → plate '
|
||||
+ (pw * f.s).toFixed(1) + '×' + (ph * f.s).toFixed(1) + 'm over a '
|
||||
+ f.fw.toFixed(1) + '×' + f.fh.toFixed(1) + 'm frame at ' + d + 'm)');
|
||||
@ -49,6 +49,7 @@ header .tag{font-family:var(--mono);font-size:10px;color:var(--teal);letter-spac
|
||||
.fld input,.fld select{flex:1;min-width:0;background:var(--panel);border:1px solid var(--line2);color:var(--ink);
|
||||
border-radius:6px;padding:5px 7px;font-family:var(--mono);font-size:11px}
|
||||
.fld input[type=color]{padding:2px;height:26px}
|
||||
.fld input[type=checkbox]{flex:0 0 auto;width:15px;height:15px;accent-color:var(--teal)}
|
||||
.fld.vec input{width:100%}
|
||||
.fld.vec{align-items:center}
|
||||
.ibtns{display:flex;gap:8px;margin-top:14px}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user