PrivatesavedPrivatesavedPrivatesavedPrivatesavedPrivaterecordingReadonlysliderPrivatestopReadonlysceneReadonlyanimationPrivate ReadonlyhooksWire the panel's stop callback used by indicator-click and Escape.
Save current DPR, renderer size, and resize-lock state, then apply
recording-safe defaults (disable adaptive DPR, lock resize, optionally
scale resolution). Call restoreRecordingState() to undo all changes.
Restore DPR, renderer size, resize lock, and panels to pre-recording state. Safe to call multiple times (no-ops if no saved state).
Restore auto-rotation to its pre-turntable state.
Capture and pause auto-rotation; restore via restoreAutoRotate().
Restore the auto-dolly to its pre-recording state.
Capture and pause the auto-dolly; restore via restoreAutoDolly().
Kept separate from pauseAutoRotate rather than folded into it so neither name lies about what it touches. Both are paused for the same reason: a turntable recording drives the camera itself (from a frame index offline, from wall-clock progress live), and the interactive animation would compound with it.
Snapshot current panel visibility, hide the recording panel itself,
and optionally hide all other panels (per showPanels flag).
Restore the snapshot taken by hideAllPanels. No-op while capture active.
Unwind Session-owned state. Idempotent — every step tolerates missing-state, so dispose() is safe to call multiple times.
Important: this does NOT early-return on disposed=true. The Panel
may have set disposed=true BEFORE calling dispose() so that
any async callback (e.g. mediaRecorder.onstop) fired during
Panel's own cleanup short-circuits via isDisposed(). We still
need the actual unwind steps to run.
NOTE: Strategy-owned state (mediaRecorder tracks, offline AbortController,
per-frame callbacks registered by Video/Offline strategies) is NOT cleaned
up here. The Panel's dispose() is responsible for orchestrating those
teardowns BEFORE calling session.dispose().
True while the animation loop's OWN render is redundant because someone else owns the pipeline for the frame (today: the offline capture, which renders its own pass per frame).
Deliberately separate from
isOfflineCaptureActive. This is the narrower, shorter-lived claim — it is dropped the moment the capture stops driving the pipeline, so a wedged teardown can never freeze the viewport.isOfflineCaptureActiveis a mutual-exclusion flag and must stay true until the session has fully unwound.