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

    Function remapWindowToLeafRange

    • Re-express a scalar LUT window stated on a layer's REFERENCE data range in the units of one leaf's OWN data range, keeping the window's relative position inside the range.

      The layers panel composes ONE display window per layer, but a kind=lod layer fans it out over LEVELS whose scalars do not share a range: gsplat LOD merging SUMS amplitudes, so a coarsened level carries a different amplitude_data_range from the finest one for the same physical signal. The wrapper's reference range is just whichever descendant deriveScalarRangeFromDescendants picked — the one with the largest n_splats, or, when no descendant declares one (points/lines/mesh write n_points, never n_splats) or several tie, simply the first visited. Pushing that one window into every level renders the whole layer on the reference level's window — the per-level differentiation the producer stamped is discarded, and a level created lazily after the last panel commit renders on its own window until the next one, so two levels of the same object can be windowed differently depending only on load order (#1753).

      This is a helper about RANGES, not about structure, so it does not know which sibling relations may be remapped across. The caller decides: LayerApplyEngine.composedWindowIsInReferenceBasis allows it only across kind=lod groups, never across a kind=partition boundary — partition parts are disjoint spatial subsets of one field at the SAME scale, so re-expressing the window per part is per-tile auto-contrast and puts a colour discontinuity at every seam.

      Mapping the window through t = (w − ref₀) / (ref₁ − ref₀) and back out on the leaf's range means "the middle 40% of the layer's signal" stays the middle 40% of each leaf's signal, which is what the slider means to the user.

      The window is returned UNCHANGED — no remap at all — in four cases, each of which would otherwise silently produce a different window rather than a refined one:

      • Either range missing. Nothing to map between; the incoming window is already the best available answer.
      • A non-remappable reference range (isRemappableRange, file-private). A degenerate [x, x] range is legitimate — every classical splat import has amplitudes = 1, and constant-amplitude producers emit it on purpose — and dividing by its ~zero span would yield ±∞/NaN. Below 1e-10 there is a sharper reason than the arithmetic: the panel seeds the layer's window FROM this range, so a degenerate one means the incoming window is a single point as well, and t₀/t₁ come out as 0/0 or an arbitrary multiple of 1e10.
      • A non-remappable leaf range. A degenerate leaf range collapses the window to a single point, and updateScalarRange hands that straight to computeScalarRangeUniforms, which answers a sub-eps span with the LUT MIDPOINT (scalarMin = min − 0.5, scalarScale = 1, deliberately, #631) — so every element of that leaf would render as one flat neutral colour.
      • The two ranges are equal. The overwhelmingly common case (the finest level IS the reference, and every leaf of an ordinary single-range layer). Short-circuiting keeps the window bit-exact instead of round-tripping it through two floating-point divisions.

      Parameters

      • window: { min: number; max: number }

        The layer's OWN window (LayerInfo.displayMin/Max), which is the one stated in ref units. Deliberately not the COMPOSED window: that one already carries whatever gain the ancestry above the layer contributes, so reading it as a position inside ref is a basis error (it cancels only when ref₀/refSpan === leafRange₀/leafSpan). The caller re-applies the ancestor gain to the result instead.

      • ref: readonly [number, number] | undefined

        The layer's reference scalar range (LayerInfo.scalarDataRange).

      • leafRange: readonly [number, number] | undefined

        This leaf's own scalar_data_range / amplitude_data_range.

      Returns { min: number; max: number }