mirror of
https://github.com/goodpuppies/petplay.git
synced 2026-10-23 16:00:51 +02:00
--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
20 lines
898 B
TypeScript
20 lines
898 B
TypeScript
import { captureTextBatchTransforms, textBatchTransformsMatch } from "./uiTextBatchTransforms.ts";
|
|
|
|
Deno.test("world-baked text cache invalidates when tracking mutates the same snapshot", () => {
|
|
const matrix = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
|
|
const texts = [{ worldMatrix: matrix }];
|
|
const cached = captureTextBatchTransforms(texts);
|
|
if (!textBatchTransformsMatch(texts, cached)) {
|
|
throw new Error("Unchanged stereo eye should reuse batch");
|
|
}
|
|
matrix[12] = .25;
|
|
if (textBatchTransformsMatch(texts, cached)) {
|
|
throw new Error("Tracked text reused stale world vertices");
|
|
}
|
|
const updated = captureTextBatchTransforms(texts);
|
|
if (!textBatchTransformsMatch(texts, updated)) {
|
|
throw new Error("Updated batch should be reusable for second eye");
|
|
}
|
|
if (cached[12] !== 0) throw new Error("Cache must own its transform snapshot");
|
|
});
|