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

    Interface LODGroupChild

    One LOD-group child as tracked by the registry.

    interface LODGroupChild {
        object: Object3D;
        nodePath?: string;
        coverageFraction: number;
        medianFootprint?: number;
        footprintDims?: readonly number[];
        positionBounds: { min: readonly number[]; max: readonly number[] };
        lodBounds?: { min: readonly number[]; max: readonly number[] };
        ready?: boolean;
        loading?: boolean;
        failed?: boolean;
        permanentlyFailed?: boolean;
        failureReason?: string;
        failedTick?: number;
        ensureLoaded?: () => void;
        release?: () => void;
        lastVisibleTick?: number;
        hasMoreLODs?: () => boolean;
        deferredGroup?: boolean;
    }
    Index
    object: Object3D

    The leaf THREE node (gsplats / points / lines / group). For a lazily-loaded child this is the empty placeholder mesh attached at registration; geometry is committed into it by ensureLoaded.

    nodePath?: string

    Authored scene-node path, including for anonymous deferred-group placeholders.

    coverageFraction: number

    Viewport-relative LOD-switch threshold, strictly monotonic increasing in coarsest→finest order (coarsest 0.0). Its UNITS — and so its finest anchor — come from the entry's selector:

    • 'screen-area' (every ladder the producer derives today): a literal fraction of the viewport AREA, compared against projectBoxAreaFraction. A whole-object ladder anchors its finest at 0.5 (full detail while the object covers at least half the screen); one bound to a spatial partition anchors at 1.0 (the tile alone fills the screen), which the producer derives for it automatically because a tile projects to only a fraction of the whole object's rect.
    • 'coverage' (legacy stores, and explicitly authored coverage_fractions=[...] lists): multiplied by FILL_FACTOR × fittedAxisPx at selection time and compared against the group's projected bbox DIAGONAL in pixels, so 1.0 activates once that diagonal reaches half of the fitted screen axis. An author may go up to SCREEN_FILL_DIAGONAL_RATIO / FILL_FACTOR (4.0, roughly a screen-filling object) to hold a level until later than that.

    No upper bound is enforced here.

    medianFootprint?: number

    Median element footprint in node-local scene units.

    footprintDims?: readonly number[]

    Data columns included in the median footprint measurement.

    positionBounds: { min: readonly number[]; max: readonly number[] }

    Raw nD position bounds (from the child's position_bounds zarr attribute). Stored unprojected because displayDims can change at runtime (user picks different dimensions to display) — the selector re-projects each frame.

    lodBounds?: { min: readonly number[]; max: readonly number[] }

    Optional robust nD bounds from the child's lod_bounds zarr attribute. The selector uses these only to size the node for either LOD metric; frustum gating and eviction keep the full positionBounds so visible outliers are never treated as absent. Missing bounds fall back to positionBounds for legacy stores.

    ready?: boolean

    Lazy-loading readiness. undefined means "always ready" (eagerly loaded — the default for callers that don't opt into lazy loading, including unit tests that construct children directly). false means the child's geometry has not been committed yet, so the selector must not make it visible; it fires ensureLoaded instead and waits for a later frame to swap once the thunk sets this true.

    loading?: boolean

    Set by the registry when it fires ensureLoaded; cleared by the thunk.

    failed?: boolean

    Set by the thunk on load failure to stop per-frame retry storms.

    permanentlyFailed?: boolean

    Marks the lazy branch that observed a latched archive fault, so monitor rows and explicit Retry can target it even when its THREE placeholder is anonymous. The owning loader's archive latch is the shared dataset-fault oracle; this branch marker is cleared by an explicit retry.

    failureReason?: string

    Human-readable reason retained for monitor rows after the loader latch clears.

    failedTick?: number

    Registry tick when failed was first observed. Drives the transient-failure retry cooldown (FAILED_RETRY_FRAMES): once it elapses the registry clears failed and retries the load, so a level that fails on reload (after a successful load + byte-eviction) is not stuck on its placeholder forever. Cleared alongside failed.

    ensureLoaded?: () => void

    Idempotent fire-and-forget loader for a lazy child. Kicks the deferred geometry load; on success sets ready=true and clears loading; on failure sets failed=true and clears loading. A container fault may additionally set permanentlyFailed. Must not touch object.visible — the registry owns the swap.

    release?: () => void

    Release this lazy level's GPU geometry back to the evictable pool and reset its readiness so a later selection reloads it. Called by the registry's LRU eviction when GPU memory is over budget — never eagerly on swap (retention keeps re-shows free). Absent on eagerly-loaded children (e.g. the coarsest default level), which therefore stay resident as the always-available fallback and are never evicted.

    lastVisibleTick?: number

    Registry tick when this level was last the visible/active child. The eviction LRU evicts the coldest (lowest tick) loaded levels first. Undefined ⇒ never been shown, so not an eviction candidate (avoids evicting a just-loaded level in the 1-frame gap before its swap).

    hasMoreLODs?: () => boolean

    For a lazy level backed by a PROGRESSIVE loader (a substitutive level whose geometry is itself an additive ladder, e.g. the pyramid recipe): reports whether more additive LODs remain to stream for the current view. The registry treats "ready & fresh but hasMoreLODs" like a not-yet-final state and re-fires ensureLoaded (settle-gated) to advance the ladder until it completes — driving progressive refinement entirely from the registry, since lazy levels no longer ride the per-slice sweep. Absent / () => false on a single-LOD level (the common case) ⇒ no extra refinement passes.

    deferredGroup?: boolean

    true for a deferred GROUP child (a kind=partition / nested kind=lod level — the overview recipe's fine branch), whose ensureLoaded runs loadChildren once to attach the whole subtree. The registry never re-fires such a child for staleness or refinement: its leaves are sweep-registered and re-stamp themselves, and a second activation would attach a second copy of the subtree. Set by load-lod-group-node.