INVARIANT: this equality is the linchpin of the no-op commit skip AND
the append fast path's generation reset. When it reports equal AND no
new LODs loaded, the loader returns the MEMOIZED concatenation — same
object reference — and the commit pipeline treats reference equality
as content equality (mesh.userData.committedData === data); when it
reports unequal, the loader bumps its reset generation, which drops
the prefix lineage so the append gate full-rewrites. Any new
query-affecting field added to ViewState MUST be compared
here, or the skip serves stale data. Per-pass directives that are NOT
part of the query (e.g. frameBudgetMs, prefetch, ladderDepth) must NOT be
compared — they would defeat the memoization. If a geometry ever
specializes its *ViewState alias (today all three are plain
aliases of ViewState) with its own query-affecting field,
that loader must fork this comparison — the shared version would
silently ignore the new field.
Element-wise view-state equality (query-affecting fields only).
INVARIANT: this equality is the linchpin of the no-op commit skip AND the append fast path's generation reset. When it reports equal AND no new LODs loaded, the loader returns the MEMOIZED concatenation — same object reference — and the commit pipeline treats reference equality as content equality (
mesh.userData.committedData === data); when it reports unequal, the loader bumps its reset generation, which drops the prefix lineage so the append gate full-rewrites. Any new query-affecting field added to ViewState MUST be compared here, or the skip serves stale data. Per-pass directives that are NOT part of the query (e.g.frameBudgetMs,prefetch,ladderDepth) must NOT be compared — they would defeat the memoization. If a geometry ever specializes its*ViewStatealias (today all three are plain aliases of ViewState) with its own query-affecting field, that loader must fork this comparison — the shared version would silently ignore the new field.