Search for userData.positionBounds in the scene graph. Returns
the first match. The scene loader attaches the metadata to the
root group, which is added as a child of the THREE.Scene, so
the match is normally found on that root group near the TOP of
the graph — not on the first visited object (which is the bare
THREE.Scene, carrying no positionBounds). But
THREE.Object3D.traverse cannot stop early (the if (result) return below skips visit bodies, not the recursion), so this
walks the WHOLE graph on every call, hit or miss. Callers must
cache the result (SceneBoundsCache.ensure caches the hit; a
metadata-less scene re-pays the full walk each
call — measured harmless at real scene sizes, ~0.1 ms at ~2k
objects, since Luxar geometry is instanced and graphs stay small).
Search for
userData.positionBoundsin the scene graph. Returns the first match. The scene loader attaches the metadata to the root group, which is added as a child of theTHREE.Scene, so the match is normally found on that root group near the TOP of the graph — not on the first visited object (which is the bareTHREE.Scene, carrying nopositionBounds). ButTHREE.Object3D.traversecannot stop early (theif (result) returnbelow skips visit bodies, not the recursion), so this walks the WHOLE graph on every call, hit or miss. Callers must cache the result (SceneBoundsCache.ensurecaches the hit; a metadata-less scene re-pays the full walk each call — measured harmless at real scene sizes, ~0.1 ms at ~2k objects, since Luxar geometry is instanced and graphs stay small).