Pick the desired child index given a scalar view metric and the
current active index. Applies 10% asymmetric hysteresis on the
downgrade direction.
metric is whatever scalar the group's selector names — the viewport
AREA fraction under 'screen-area' (what derived ladders stamp), the
dimensionless normalised diagonal (projected bbox diagonal ÷ FILL_FACTOR × fittedAxisPx, where fittedAxisPx is min(viewport.width, viewport.height)) under the legacy 'coverage' — and thresholds are
the per-child coverage_fraction values, in whichever units that
selector names. Under 'screen-area' the derived finest anchor is 0.5
whole-object / 1.0 partition-bound; under legacy 'coverage' it is 1.0
whole-object, and an explicitly authored or partition-bound threshold may
exceed 1 (up to SCREEN_FILL_DIAGONAL_RATIO / FILL_FACTOR) to hold a level
until later — both ceilings are enforced Python-side (validate_lod_group),
never here. The "natural" pick is the finest child whose
coverageFraction is less than or equal to metric. Hysteresis only
resists dropping back to a coarser level: when downgrading from index
currentIdx, the metric must fall below the current threshold by a margin
that is hysteresisRatio (default 10%) of the GAP to the adjacent coarser
threshold — i.e. below
thresholds[currentIdx] - hysteresisRatio * (thresholds[currentIdx] - thresholds[currentIdx - 1]); otherwise we stay on the current level
even though the natural pick is coarser. (At the bottom level
thresholds[currentIdx - 1] is effectively 0, reducing the margin to
hysteresisRatio * thresholds[currentIdx] — the old isolated-threshold
form.) Upgrades to a finer level are immediate (no hysteresis).
Pick the desired child index given a scalar view
metricand the current active index. Applies 10% asymmetric hysteresis on the downgrade direction.metricis whatever scalar the group'sselectornames — the viewport AREA fraction under'screen-area'(what derived ladders stamp), the dimensionless normalised diagonal (projected bbox diagonal ÷FILL_FACTOR × fittedAxisPx, wherefittedAxisPxismin(viewport.width, viewport.height)) under the legacy'coverage'— andthresholdsare the per-childcoverage_fractionvalues, in whichever units thatselectornames. Under'screen-area'the derived finest anchor is 0.5 whole-object / 1.0 partition-bound; under legacy'coverage'it is 1.0 whole-object, and an explicitly authored or partition-bound threshold may exceed 1 (up toSCREEN_FILL_DIAGONAL_RATIO / FILL_FACTOR) to hold a level until later — both ceilings are enforced Python-side (validate_lod_group), never here. The "natural" pick is the finest child whosecoverageFractionis less than or equal tometric. Hysteresis only resists dropping back to a coarser level: when downgrading from indexcurrentIdx, the metric must fall below the current threshold by a margin that ishysteresisRatio(default 10%) of the GAP to the adjacent coarser threshold — i.e. belowthresholds[currentIdx] - hysteresisRatio * (thresholds[currentIdx] - thresholds[currentIdx - 1]); otherwise we stay on the current level even though the natural pick is coarser. (At the bottom levelthresholds[currentIdx - 1]is effectively 0, reducing the margin tohysteresisRatio * thresholds[currentIdx]— the old isolated-threshold form.) Upgrades to a finer level are immediate (no hysteresis).Exported for unit testing.