Luxar Viewer API Documentation - v2026.9.22
    Preparing search index...

    Module data/loaders/progressive/streaming-policy

    Streaming policy for the progressive loaders (GSplats, Points, Lines, and the Mesh reveal ladder).

    A progressive loader streams an additive LOD ladder coarse→fine. HOW MANY levels a single updateView pass loads — and when it stops — depends on why the pass is running. Encoding that decision as pure functions keeps the geometry loaders' streaming loops identical by construction (they share this module rather than each re-deriving the rule), and makes the policy unit-testable in isolation.

    The three disciplines:

    • playback — foreground, under a per-frame budget (a dimension is playing/scrubbing). Responsiveness dominates, so a cold level is never worth blocking on. Whether the pass starts EMPTY or restores a cached prefix, it streams levels that come back CACHE-RESIDENT until the budget is spent, stopping at the first cold or slow one exactly as refine does.

      It used to load LOD 0 and nothing else, on the reasoning that even a resident level costs ~10-20 ms of dequant+project. That is true, and the budget deadline is what bounds it — but a level-1 gate is the wrong instrument, because it assumes LOD 0 is a usable picture. On a node the viewer SLICES it is not: an additive ladder's rungs are sized against the WHOLE node, so on a 500-timepoint gsplat leaf LOD 0 is ~42 splats of a 166,443-splat frame and playback rendered an empty screen (#2374, #2376). Streaming the resident levels costs approximately no network — the coarse rungs of a sliced ladder are small enough to sit in ONE chunk each, so they are fetched once and serve every slice — and the worst case is unchanged at one cold load per pass, since the first cold level still stops the loop.

      Quality is still deepened for later loops by the background prefetch pass; foreground playback only spends budget remaining in the current tick.

    • prefetch — background shadow pass warming the next timepoint. No first-paint constraint, so it deepens toward the FULL decoded ladder (the only thing that yields the single-concat fast revisit); it never stops at a cache miss and is bounded only by the pass budget + abort.

    • refine — foreground with no budget (a static view, or the refine-on- pause pass). Stream cache-resident levels and stop at the first cold/slow one so the frame renders; a later pass picks up the rest.

    • pinned — a pinned ladder depth is set (ViewState.ladderDepth, the playback "detail" setting), foreground or shadow. The loader bounds its loop at the pinned rung count, and neither the deadline nor a cold level stops it before that bound — a frame is drawn at the pinned depth or the tick waits. Takes precedence over the other three. Only the refinement residency allowance still applies.

    StreamingPassKind
    classifyStreamingPass
    shouldStopBeforeLevel
    shouldStopAfterLevel
    normalizeLadderDepth
    resolveLadderDepth