fix: signed-overflow UB in VoxelHash made cave placement compiler-dependent; all generators LOD0-8; speed matrix (L60)
VoxelHash::Cell/Pair, legacy Cellular3D and the shared Core cellular hash added 0x7FFFFFFF to a signed int32 before casting to uint32; overflow is undefined, so Clang and GCC placed cave passage 1 differently (first differing sample at LOD1 tile (0,64,-512)). The bias is now done in unsigned arithmetic, in both the standalone copy and the Unreal plugin header (Source/VoxelForge/Public/VoxelCaveMorphology.h). Native caves, motifs and lattice now stream LOD0-8 with skirts and cross-level transitions. New verify.py --speed-matrix runs every generator on one asserted-identical view (5 interleaved runs): motifs 1.33, profiles 1.30-1.32, caves 1.41, natural SW 1.67, lattice 1.70, FI 4.93 s whole view. fast/medium/full PASS, Clang/GCC peer hashes equal. Research R29 (open-edge ledge) and R30 (compiler-divergence suspects). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
fbae82e024
commit
c0c204ba50
15 files changed
+938
-65
No files matched your search
@@ -0,0 +1,114 @@
|
||||
# VoxelForge R29 — revised self-check
|
||||
|
||||
## Mechanism in the L59 field
|
||||
|
||||
I read the L59 implementation on `wip/l59-open-shaft`. It constructs the shaft and ramp as cavity fields, then applies a support cap. The source gives a specific reason to investigate the support and the touching cavity surfaces; it does not prove which one produced each visible shard.
|
||||
|
||||
The core void is a radial cylinder clipped at the room floor:
|
||||
|
||||
```cpp
|
||||
const double radial = hypot(point[0]-center[0], point[1]-center[1])-radius;
|
||||
const double bottom = floor-point[2];
|
||||
featureVoid = std::max(radial,bottom);
|
||||
```
|
||||
|
||||
`wip/l59-open-shaft:Standalone/Core/src/ShapeWorldInternal.h:7340–7346`
|
||||
|
||||
The open ramp’s radial tube is centered at 6 m with a 1.5 m bore radius:
|
||||
|
||||
```cpp
|
||||
nearestRadial = abs(shaftRadial-centerlineRadius);
|
||||
tube = nearestRadial-radius;
|
||||
```
|
||||
|
||||
Its vertical corridor runs from each turn’s floor to `floorZ+height`; adjacent turns are combined with a minimum:
|
||||
|
||||
```cpp
|
||||
return max((floorZ-point[2])*openHelixVerticalScale,
|
||||
(point[2]-(floorZ+height))*openHelixVerticalScale);
|
||||
openHelixVerticalSdf = min(corridorSdf(turnA),corridorSdf(turnB));
|
||||
```
|
||||
|
||||
`wip/l59-open-shaft:Standalone/Core/src/ShapeWorldInternal.h:7380–7385, 7410–7417`
|
||||
|
||||
The tube and corridor are intersected with a smooth max. The core and ramp voids are then unioned with a smooth min, followed by one subtraction from the host field:
|
||||
|
||||
```cpp
|
||||
featureVoid = SmoothMaxMetres(tube,openHelixVerticalSdf,width);
|
||||
caveVoid = SmoothMinMetres(caveVoid,featureVoid,...);
|
||||
composed = SmoothMaxMetres(hostDistance,-caveVoid,0.0);
|
||||
```
|
||||
|
||||
`wip/l59-open-shaft:Standalone/Core/src/ShapeWorldInternal.h:7522–7524, 7533–7541, 7547–7550`
|
||||
|
||||
The geometry report gives a 4.5 m core radius, 6 m ramp centerline, 3 m ramp width, and 1 m support depth. Thus, at the inner edge, the core’s radial zero is `r−4.5`; the ramp tube’s inner zero is `6−r−1.5 = 4.5−r`. Their zero surfaces coincide at 4.5 m with opposite radial gradients. The code smooths the ramp intersection and cavity union, but the tracked L59 report does not record the actual smooth or union widths. I can’t establish that the live edge used a hard intersection; that depends on those values.
|
||||
|
||||
There is a more concrete issue in the support field. Its vertical terms are:
|
||||
|
||||
```cpp
|
||||
const double vertical = max((floorZ-point[2])*scale,
|
||||
(point[2]-(floorZ-supportDepth))*scale);
|
||||
return max(nearestRadial-radius,vertical);
|
||||
...
|
||||
composed = min(composed,latticeFloorSupportMinimum);
|
||||
```
|
||||
|
||||
`wip/l59-open-shaft:Standalone/Core/src/ShapeWorldInternal.h:7502–7515, 7551–7555`
|
||||
|
||||
At mid-depth below the floor, both vertical terms are positive. With this field’s sign convention—host rock is `-32 m`, and cavity interior is positive—the cap therefore cannot force the nominal support volume solid. It may leave rock solid where the host already does so, but it cannot restore solid under an overlapping cavity. This is my strongest code-specific suspect, though the source alone cannot prove it caused the photographed shards.
|
||||
|
||||
The nominal 1 m depth is four LOD0 cell intervals, so simple under-sampling is a weaker explanation at the captured LOD. The free edge has no explicit bullnose radius. A hard or too-narrow crease remains possible if the configured widths are zero or small. Relief noise is unlikely on this path: the open-helix branch returns before the legacy edge relief code (`ShapeWorldInternal.h:7187–7191, 7249–7255`).
|
||||
|
||||
The geometry and reported route measurements are in `wip/l59-open-shaft:Standalone/Research/WorldAssemblerM3/Linux59/REPORT.md:5–7`.
|
||||
|
||||
## Construction and dimensions
|
||||
|
||||
Use the 25 cm LOD0 spacing as the baseline. The practical minimum `R=2h` and preferred `R=3h` are sampling targets, not guarantees for every field gradient or grid phase. For VoxelForge’s cubic smooth-min/max, `W≈2√2·R` applies to a local cross-section of perpendicular unit-gradient planes; the ramp’s coincident radial surfaces need slice validation. See `Research16/REPORT.md:20–31`.
|
||||
|
||||
The L59 owner uses 25 cm Core voxels, 32 cells at full resolution, two full-resolution LOD levels, and 16 cells per coarse tile. Applying the mesher’s `extent=32<<LOD` and cell-count rule gives these normal steps (`VoxelForgeCore.cpp:2058, 2121–2122`; `owner_world.json:1`):
|
||||
|
||||
| LOD | Step `h` | Current 1 m depth in steps | Minimum `R=2h` | `W≈2√2R` | Full two-sided bullnose thickness `T≥2R` |
|
||||
|---:|---:|---:|---:|---:|---:|
|
||||
| 0 | 0.25 m | 4 | 0.5 m | 1.41 m | 1 m |
|
||||
| 1 | 0.5 m | 2 | 1 m | 2.83 m | 2 m |
|
||||
| 2 | 2 m | 0.5 | 4 m | 11.31 m | 8 m |
|
||||
| 3 | 4 m | 0.25 | 8 m | 22.63 m | 16 m |
|
||||
| 4 | 8 m | 0.125 | 16 m | 45.25 m | 32 m |
|
||||
| 5 | 16 m | 0.0625 | 32 m | 90.51 m | 64 m |
|
||||
| 6 | 32 m | 0.03125 | 64 m | 181.02 m | 128 m |
|
||||
| 7 | 64 m | 0.015625 | 128 m | 362.04 m | 256 m |
|
||||
| 8 | 128 m | 0.0078125 | 256 m | 724.08 m | 512 m |
|
||||
|
||||
A basic two-interval slab needs `T≥2h`; roundovers on both top and underside require `T≥2R=4h`. The table shows the latter. The current 1 m support is four intervals at LOD0, two at LOD1, and only half a cell at LOD2.
|
||||
|
||||
**Near-LOD proposal:** give the open edge an explicit 0.5 m geometric bullnose (`R=2h` at LOD0), with `W≈1.41 m`. Set support depth to **1.5 m**: that is six LOD0 intervals, enough for two 0.5 m roundovers and a 0.5 m web. Build the support as negative solid in its intended volume; for the vertical band, the inside terms should be `(z-floorZ)` and `(floorZ-supportDepth-z)` before taking their maximum.
|
||||
|
||||
Keep the bullnose below the walk-floor plane and into the open-core side, leaving the floor edge at `r=4.5 m`. The 6 m route centerline then remains 1.5 m from that edge, and the 3 m radial tread remains `r=4.5–7.5 m`. A smooth-max width is a field-space parameter, so `W<3 m` alone does not prove that the 3 m walking surface survives; the zero contour must be checked in slices. If the finished floor edge moves into the tread, this construction fails the stated route margin.
|
||||
|
||||
At LOD1, the normal 0.5 m step makes a 0.5 m radius only one interval. I would refine ramp-intersecting LOD1 tiles to the 0.25 m Core step, keeping the same bullnose and support geometry. The current refinement in `VoxelForgeCore.cpp:2124–2149` applies to a different feature type; it does not show that resolved shaft-ramp edges already receive this treatment.
|
||||
|
||||
With the top floor unchanged, the reported maximum grade stays 10.028°, below 15°. Thickening only downward leaves the measured 2.20 m headroom unchanged. At 5 m pitch, a 1.5 m support leaves **3.5 m** from the lower floor to the next tread’s underside, so it does not intrude into the 2.20 m clearance.
|
||||
|
||||
## Far LOD and seams
|
||||
|
||||
The LOD numbers in the actual L59 fixture are coarser than “0.5–2 m at LOD2–8”: LOD1 is 0.5 m, LOD2 is 2 m, and LOD3–8 run from 4 m to 128 m.
|
||||
|
||||
At LOD2, a compliant bullnose would need `R=4 m`, `W≈11.31 m`, and `T≥8 m`. That exceeds the 3 m tread width and 5 m pitch. **Do not thicken the ledge.** My concrete proxy is:
|
||||
|
||||
- LOD0–1: the rounded helix ledge, with ramp tiles sampled at 0.25 m.
|
||||
- LOD2–3: remove the helical ledge and support; retain a smooth cylindrical core subtraction. Its 9 m diameter spans 4.5 LOD2 steps and 2.25 LOD3 steps.
|
||||
- LOD4–8: fade the local core opening into the surrounding host field. At LOD4 its 9 m diameter is only about 1.1 steps.
|
||||
|
||||
A field switch alone does **not** establish closed seams. The regular LOD1-to-LOD2 sampling ratio is 4:1; local LOD1 refinement makes it 8:1 at this feature. Both sides need a shared LOD morph evaluated at the same world positions, plus transition cells or a verified skirt stitch for that ratio. The owner requests skirts, but the branch has no L59 captures above LOD0 to demonstrate that this ledge-to-cylinder or cylinder-to-host transition stays closed. The far-LOD proposal is therefore a specific representation plan, not a proven seam result.
|
||||
|
||||
## Audit and slice plan
|
||||
|
||||
The L59 audit excluded the shaft-core room (`AuditLatticeSurfaceL59.py:82–91`) and set a 0.25 m corridor margin (`:229–248`). Its bounds and corridor test expand by that margin (`:159–199`). Shard triangles protruding farther into the core fall outside that ROI.
|
||||
|
||||
Extend an edge-focused ROI along the full helix, including the free edge and an apron on both the core and tread sides. At each LOD, use an edge band of at least `max(1 m, 4h, W_edge+W_union)` from the nominal edge; include the full floor, support underside, and headroom in the vertical bounds. Add edge-specific shard, normal-discontinuity, and open-boundary checks instead of relying only on the corridor’s broad surface score.
|
||||
|
||||
Keep the original L59 LOD0 mesh as a negative control: its free edge must fail the expanded edge checks; the repaired edge must pass; retain a plain-native pass control. Slice the analytic field radially through the edge at several azimuths and turn phases, then unwrap the full four-turn edge. Check the 0.5 m bullnose and 1.5 m support at sub-voxel resolution, including half-cell grid offsets. Recheck the 883 route stations and the reported capsule, support, and headroom samples, with gates of grade ≤15°, headroom ≥2.2 m, and route-centerline distance to the finished edge ≥1.5 m. Inspect LOD1/2 and LOD3/4 transition boundaries separately.
|
||||
|
||||
## Assumptions and skipped evidence
|
||||
|
||||
The tracked L59 report contains the visual diagnosis, but the branch’s `Linux59` directory does not include the resolved-layout JSON or exported `.vfmesh`. The capture script explicitly exports `--max-level=0` (`CaptureNativeLatticeL59.py:78–85`). I therefore do not know the recorded smooth and union widths, and I did not inspect triangle normals or re-view the JPEG pixels. Those gaps prevent me from proving which field term made the observed shards. I did not run scripts, tests, builds, or binaries, and made no source edits.
|
||||
Reference in new issue
Block a user