Files
mommysgoodpuppy 3f5e919698 Decoupled renderer: own process, tracking and present cadence
--webxr-decoupled-renderer moves raylib rendering out of the webxr worker
into an overlay_renderer child process (petplay/overlayRenderOwner.ts). The
worker extracts the scene and delivers it over the wire format in
overlaySceneWire.ts. Delivery is credit-based (overlaySceneDelivery.ts), and a
credit held more than a second is reclaimed, so a lost receipt can no longer
stall every scene. The worker skips extraction while every view's credits are
busy. The renderer paces itself, reads fresh HMD and controller poses, and
re-anchors tagged head, hand and ray subtrees (renderTrackingAnchor) to them,
so head and lasers stay smooth while the simulation stalls.

It presents in one of two modes, switchable at runtime with SETPRESENTMODE:
- projection: per-eye projection overlays published by a small native helper
  (native/overlayPresenter, built by `deno task overlay:presenter:build`).
  SteamVR reprojects them, but draws them behind every quad overlay,
  PetPlay's display screens included.
- panorama: the old head-locked stereo panorama. It sorts normally with the
  screens. Pacing and prediction stay live-tunable through SETRENDERERDEBUG,
  since swim and jitter are still being worked on. The default is
  frame-sync pacing with one extra frame of prediction.

Also: aim beam and cursor ignore depth so they stay over the screen they hit,
text batches compare world transforms instead of object identity,
projection-overlay docs and RE notes, a future plan for drawing the screens
inside the projection image, and an independence check script.

Agent: Claude Code 2.1.296; model claude-opus-5-5; thread c2136a88-9899-4b80-84e8-64fc160b5fd7
2026-10-15 21:49:40 +03:00

24 lines
793 B
TypeScript

type TextTransform = { worldMatrix: ArrayLike<number> };
/** Batch vertices are baked into world space; object identity does not freeze tracking matrices. */
export function textBatchTransformsMatch(
texts: readonly TextTransform[],
saved: Float64Array,
): boolean {
if (saved.length !== texts.length * 16) return false;
for (let t = 0; t < texts.length; t++) {
for (let i = 0; i < 16; i++) {
if (saved[t * 16 + i] !== texts[t].worldMatrix[i]) return false;
}
}
return true;
}
export function captureTextBatchTransforms(texts: readonly TextTransform[]): Float64Array {
const saved = new Float64Array(texts.length * 16);
for (let t = 0; t < texts.length; t++) {
for (let i = 0; i < 16; i++) saved[t * 16 + i] = texts[t].worldMatrix[i];
}
return saved;
}