Which dimensions to display (max 3, indices into nD space)
Current position in nD space (one value per dimension)
Tolerance for slicing in each dimension (radius in non-displayed dims, 0 for displayed)
OptionaldimensionsDimension metadata for the dataset.
IMPORTANT: This field is REQUIRED for the extend_to_all feature to work.
If extend_to_all is configured on a node but dimensions is undefined,
the optimization will silently be skipped.
Always provide dimensions when using nD datasets with extend_to_all.
Same shape as LinesViewState.dimensions, GSplatsViewState.dimensions,
PointsViewState.dimensions, and BaseViewState.dimensions. Callers
that need richer dimension state (selected dim, animation state, etc.)
read it off sceneDimsManager directly rather than reaching for a
different shape on this field.
OptionalframePer-tick LOD time budget (ms) for progressive loaders during dimension ANIMATION playback, or absent for normal full-refinement behavior.
PER-PASS DIRECTIVE, not state. This field rides only the
updateView(partial) call: the scene loader destructures it OUT before
merging into its persistent view state (a stale budget would leave
loaders capped after playback ends), threads it through the per-type
handler ctxs, and injects it into the DERIVED per-node view state right
before loader.updateView — so refinement and retry passes (which
derive independently) are budget-free by construction. It must never
enter viewStatesEqual (would reset ladders on play/pause) nor the
SliceCache key (buildSliceViewSig).
OptionalladderPinned additive-ladder depth for progressive loaders during dimension
playback and scrubbing — the "playback detail" setting. A number makes a
pass load EXACTLY min(ladderDepth, nLods) rungs, cold or not, ignoring the
time budget, so every frame of a time-lapse is drawn at the same rung and
the tick waits for the data instead of showing whatever happened to be
resident. 'auto' lets each loader resolve its own depth from its energy
stamps (resolveLadderDepth); a ladder without stamps stays time-budgeted.
Absent = the time-budgeted behaviour.
Like frameBudgetMs this is a PER-PASS DIRECTIVE, not state: the scene
loader strips it before persisting the view state, threads it through the
handler ctxs into the DERIVED per-node view state, and the SlicePrefetcher
hands the same value to its shadow passes so the t+1 S-cache entry carries
the pinned prefix. It must never enter viewStatesEqual nor the SliceCache
key.
OptionalprefetchSet only on the SlicePrefetcher's shadow pass: marks stores as PREFETCH so
the loader pins the cached ladder until the foreground tick restores it
(see SliceCache.set({ pin })). Without the pin, the just-stored t+1 is the
MRU entry and the FIRST victim of a subsequent scan-eviction under budget
pressure — defeating the prefetch exactly in the thrash regime. Like
frameBudgetMs this is a per-pass directive: it must never enter
viewStatesEqual nor the SliceCache key (buildSliceViewSig).
OptionalnoSet by deriveNodeViewState when this node's composed nd_transform maps
the current WORLD slice to a position that no local value can occupy — a
DISCRETE dimension whose inverse image falls between grid points (e.g.
scale: 2 at an odd world frame). The node must then render NOTHING.
DERIVED PER-NODE, not global state. It is computed from the node's own
transform in invertNdTransformForQuery (which documents the rule), so it
only ever appears on the derived per-node view state, never on the scene
loader's shared one. Each geometry's range query honours it by returning an
empty range list, whose existing "no visible elements" path clears the
geometry. It must never enter viewStatesEqual nor the SliceCache key —
both already vary with slicePosition, from which this is a pure function.
Represents the current view state for data loading. This determines what portion of the nD dataset should be loaded.
Canonical definition lives here in
types/(moved fromdata/data-loader-types.ts, which re-exports it —data/may import fromtypes/, never the reverse).Array fields are typed
readonly number[]so the contents cannot be mutated (arr[i] = …,arr.push(…)). The fields themselves are still re-assignable, so callers that need to update the view state should construct a fresh array (tolerance: [...prev, x]) rather than mutating in place. This prevents the cross-method mutation races flagged in the 2026-05-06 review.