Refine CSG spatial query doctrine

This commit is contained in:
Meta Vens 2026-05-07 07:58:05 +01:00
commit 587408c6fa
2 changed files with 50 additions and 7 deletions

View file

@ -162,8 +162,25 @@ or sweep than by carving:
The immediate next upgrade is not "more primitives." It is the category-router
kernel: split crossing polygons, route classified source polygons through
boolean branches, preserve material/surface metadata, and then add a BVH or
spatial hash so cutter cost does not scale like a punishment.
boolean branches, and preserve material/surface metadata.
The next accelerator should not be a reflexive BVH-shaped apology. The
EpiphanyAquarium memory points at a stronger pattern from GigaVoxels, froxels,
and Dreams: let the consumer define the query frontier. For CSG, the consumer is
not always "the whole scene." It can be the moved brush, the current branch, the
editor tile, the requested output mesh, or the visible/view-tested surface set.
So the near-term spatial plan is:
- use branch and brush bounds as semantic gates before cutting;
- keep dirty/touched brush discovery separate from polygon classification;
- build affected brush-pair or surface-frontier batches from those gates;
- measure those batches before adding a generic BVH, loose grid, or spatial
hash;
- only promote an index if it beats the demand-shaped frontier on dirty rebuilds
and preserves exact output parity.
Sideways version: do not ask every cutter whether it matters. Ask the branch,
dirty region, and requested output which pairs deserve to exist this frame.
Performance fixtures live in `docs/research/csg-performance-fixtures.md` and
`tools/run_csg_perf.ps1`. They time our release fixture now and reserve a JSONL

View file

@ -142,6 +142,28 @@ Implication for `vg_csg`: every brush, polygon batch, and branch needs cheap
bounds. Later BVH, hashed grid, or sweep-and-prune should be measured against
the built-in tree culling instead of assumed superior by vibes in a lab coat.
The EpiphanyAquarium research memory adds a sharper rule: treat spatial queries
as a demand problem before treating them as an index problem. GigaVoxels uses
visible rays as the oracle for which bricks deserve high resolution. Wronski fog
uses the camera froxel volume as the field where sources are injected once and
sampled many times. Dreams' prototype refined frustum cells, shortened object
lists as cells split, then switched to per-pixel sorted lists that could truncate
at the first solid hit.
For `vg_csg`, that translates to consumer-shaped query frontiers:
- dirty brush movement asks for affected brush pairs, not a world rebuild;
- branch evaluation asks for left/right bounds gates before polygon tests;
- an editor viewport or tile asks for surfaces that can contribute to the
requested output, not every latent overlap in the level;
- repeated cutters ask for cached pair classifications or brush-frontier batches,
not a thousand independent list walks.
This does not outlaw BVHs, grids, or sweep-and-prune. It demotes them. They are
candidate storage layouts for a demand frontier, not the central idea. The
central idea is that the request already contains spatial information; make the
kernel exploit that before building a generic little bureaucracy with boxes.
### 7. Realtime Means Incremental, Not Global
The public notes frame the algorithm as fast for updating affected brushes, not
@ -273,8 +295,10 @@ Algorithm migration steps:
6. Implement boolean branch routing using category list swizzles.
7. Add bounds early-outs before every expensive classification.
8. Add dirty-set and touching-brush discovery.
9. Convert categorized visible polygons to Bevy mesh buffers.
10. Benchmark global rebuild, affected-brush rebuild, and worst-case overlap
9. Add a demand-frontier prototype that produces affected brush-pair batches
from dirty brushes, branch bounds, and requested output scope.
10. Convert categorized visible polygons to Bevy mesh buffers.
11. Benchmark global rebuild, affected-brush rebuild, and worst-case overlap
scenes before making performance claims.
## Acceptance Tests To Add
@ -303,8 +327,10 @@ Algorithm migration steps:
cut material?
- Should Bevy output preserve large n-gons for later optimization, or triangulate
at the boundary immediately?
- What is the best initial spatial rejection structure after branch bounds:
loose grid, BVH, sweep-and-prune, or no extra structure until profiling says
the tree culling is insufficient?
- What is the smallest demand frontier after branch bounds: dirty affected
brush pairs, viewport/tile-frontier batches, pair-classification caches, or no
extra structure until profiling says tree culling is insufficient?
- If a frontier needs storage, which layout wins under dirty rebuild timings:
loose grid, BVH, sweep-and-prune, pair cache, or sorted frontier batches?
- How much topology should live in reusable library code versus Bevy ECS
components?