feat(vcam): use a phone on the network as a virtual camera

SCENES > VCAM pairs a phone through a QR code and turns it into a
handheld camera, after Unreal's Live Link VCAM and Blender's VirtuCamera:

- Android Chrome tracks 6DoF through WebXR immersive-ar; iPhone Safari,
  which has no WebXR AR, tracks rotation through DeviceOrientation, and
  thumb sticks dolly, truck, crane and pan.
- A motion scale (1:1 walk to 1:10000 orbit), smoothing, height and
  horizon locks, hold/clutch and recenter, none of which make the camera
  jump. Focal length and scale-aware depth of field with tap-to-focus.
- The phone shows the app's render as a monitor (newest-frame JPEG pull).
- REC records a take as a version-7 track shot in the selected scene.
- The rig claims the camera through the navigation seam (Cockpit refuses
  it) and holds on any other navigation, scene run or globe input.

Pairing never exposes the app: a loopback-only session request starts a
separate HTTPS listener (VCAM_PORT, default 4174) that serves only the
static phone page and a token-paired relay, and stops after the last
session. Its certificate comes from a local CA built with node:crypto, which
an iPhone can trust once; without it the phone falls back from WebSocket to
HTTPS requests, which iOS allows past a certificate warning.

scripts/qa-vcam.mjs drives it end to end: the real phone page over the
HTTPS fallback, a scripted 6DoF phone, a recorded and replayed take, depth
of field and camera handoff.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_015H1iLusTzWpVKitGic2AW8
This commit is contained in:
Claude committed 2026-10-19 04:03:02 +00:00
1 parent c330eb801a
commit 56586a234b
33 files changed
+5472 -6

No files matched your search

+14
View File
@@ -429,6 +429,20 @@ or unknown freshness and transport failures retain their warnings. Partial
snapshots still retain missing contacts within the existing age and row limits.
A complete successful snapshot clears the partial indicator.
SCENES › VCAM pairs a phone on the same network as a virtual camera. Opening
the card creates a loopback-only session and starts a separate HTTPS phone
listener (`VCAM_PORT`, default 4174) that serves only the phone page and relay;
END, or two minutes after the last session, stops it. Android Chrome tracks
6DoF through WebXR `immersive-ar`; iPhone Safari tracks rotation through
DeviceOrientation with on-screen sticks, falling back from WebSocket to HTTPS
requests under an untrusted certificate. The rig claims the camera through the
navigation seam (Cockpit refuses it) and holds on any other navigation, scene
run or globe pointer input. Motion scale, smoothing, height and horizon locks,
focal length and scale-aware depth of field are shared by phone and card. REC
writes version-7 track shots (`move.track`, up to 10,000 samples with focal
length) into the selected scene; shots may also carry a `lens`. See
[VCAM](VCAM.md); gate: `node scripts/qa-vcam.mjs`.
Director imports now open a non-mutating preview before Apply. EDIT DETAILS
authors validated anchor, camera, pack and interaction drafts; SHARE SCENE exports
a selected scene or a bounded bundle of explicitly chosen pack files. Bundled