Summary
VirtualTilesController.updateTiles walks _samplesDimensions and runs CameraUtils.collides(box, planes) per sample (frustum plus clipping planes) on every real view change — a flat O(samples) sweep per model, even when most of the model is far outside the view, which is the normal case for interior navigation. VirtualBoxStructure already holds the spatial hierarchy used by raycasting (collideFrustum / collideRay), but the cull pass doesn't use it.
Proposed fix
VirtualBoxCollider gets an allocation-free mask traversal (frustumFillOutsideMask) that shares the exact walk and plane semantics of frustumCollide (collide() is refactored onto the same traversal), and VirtualTilesController rebuilds a per-sample outside-mask on every real view change, so samples in branches that provably miss the view skip the per-sample plane math. Every surviving candidate still runs the original exact test, so the classification of any sample is unchanged; fully included branches collect their leaves without per-leaf tests, so the whole-model-in-view case stays fast too.
Measurements
- 13 real project models (
.frag, converted from IFC; headless Chromium): interior look-around CPU −14 %, settle after orbiting 44 → 23 ms, idle and whole-building orbit unchanged.
- 8 models, exterior views only (Radeon 780M): neutral on its own, settle after orbit −11 … −23 % together with the idle-loop fix; draw calls and screenshots unchanged (rendered triangle counts identical across fixed poses).
Branch: perf/c4d-hierarchical-cull (single commit on main). Happy to open the PR.
Summary
VirtualTilesController.updateTileswalks_samplesDimensionsand runsCameraUtils.collides(box, planes)per sample (frustum plus clipping planes) on every real view change — a flat O(samples) sweep per model, even when most of the model is far outside the view, which is the normal case for interior navigation.VirtualBoxStructurealready holds the spatial hierarchy used by raycasting (collideFrustum/collideRay), but the cull pass doesn't use it.Proposed fix
VirtualBoxCollidergets an allocation-free mask traversal (frustumFillOutsideMask) that shares the exact walk and plane semantics offrustumCollide(collide()is refactored onto the same traversal), andVirtualTilesControllerrebuilds a per-sample outside-mask on every real view change, so samples in branches that provably miss the view skip the per-sample plane math. Every surviving candidate still runs the original exact test, so the classification of any sample is unchanged; fully included branches collect their leaves without per-leaf tests, so the whole-model-in-view case stays fast too.Measurements
.frag, converted from IFC; headless Chromium): interior look-around CPU −14 %, settle after orbiting 44 → 23 ms, idle and whole-building orbit unchanged.Branch:
perf/c4d-hierarchical-cull(single commit onmain). Happy to open the PR.