diff --git a/docs/realtime-csg-bevy-assembler.md b/docs/realtime-csg-bevy-assembler.md index 2742bca..adb3763 100644 --- a/docs/realtime-csg-bevy-assembler.md +++ b/docs/realtime-csg-bevy-assembler.md @@ -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 diff --git a/docs/realtime-csg-doctrine.md b/docs/realtime-csg-doctrine.md index ee47b14..c01f0c8 100644 --- a/docs/realtime-csg-doctrine.md +++ b/docs/realtime-csg-doctrine.md @@ -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?