wip(assembler): M2 round 3 -- opt-in hybrid sharp mesher (WorldAssemblerHybridV1) in the Unreal Core route

Default MarchingCubesV1 unchanged (W1/W8/W16 = round-6 hashes). Hybrid DC only in LOD0 interior cells
with tagged features; tile-border cells and LOD1+ stay MC. BuildHost: fixtures repeat exactly, cooked
collision bounds = render bounds, same-LOD borders pass, sampled SurfaceWorld cliff bit-identical to MC.
Open: tagged tiles cost 5.7-6.7x MC; corner-top field contact error 20 cm; 5 MC doorway LOD cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-10 09:53:04 +02:00
1 parent a3b7d2015e
commit 22a6b30494
21 files changed
+3009 -23

No files matched your search

+137 -4
View File
@@ -89,9 +89,12 @@ These timings are **not comparable to the optimized production MC mesher**. The
The [updated offline contact sheet](results/captures/contact_sheet.jpg) is 864 × 1,968 pixels. It contains the five analytic fixtures, the sampled SurfaceWorld cliff, and both LOD seam views, with MC/Hybrid/DC columns. The 24 individual JPEGs are 288 × 246 pixels; all 25 files including the sheet are below 300 KB. No viewer or GPU path was used.
## Recommendation and round-3 Unreal plan
## Round-2 recommendation and proposed round-3 work (historical)
Do not select or enable the hybrid in the owner project yet. The same-LOD gate is closed, but the full LOD gate is not. The current Core world hash/default path is untouched.
At the end of round 2, the recommendation was not to select or enable the hybrid in the owner
project: same-LOD passed, but the full LOD gate did not. Round 3 later narrowed the policy to LOD0
interior feature cells with MC at borders and coarser LODs; the implementation and its remaining
transition limitation are recorded below. The following list preserves the original round-2 plan.
When the standalone LOD gate passes, round 3 should:
@@ -117,10 +120,140 @@ When the standalone LOD gate passes, round 3 should:
Every final build, mesher, analysis, and renderer process ran BelowNormal with affinity `0xFF00`; the scripts enforce an 8 GB private-memory limit and 15-minute timeout. Peak observed mesher private memory was under 0.2 GB. No final process crashed, exceeded a limit, or needed a retry.
All edits and outputs are under `Plugins/VoxelForge/Standalone/Research/WorldAssemblerM2`, plus this dialogue log. No `Source/` file, Core source, owner project file, `.uasset`, or editor was touched. No commit, push, or stash was made.
For round 2, all edits and outputs were under `Plugins/VoxelForge/Standalone/Research/WorldAssemblerM2`, plus its dialogue log. No `Source/` file, Core source, owner project file, `.uasset`, or editor was touched in that round. No commit, push, or stash was made.
## Files changed and new source files
## Round-2 files changed and new source files
Updated existing standalone files: [SharpMesherSpike.cpp](SharpMesherSpike.cpp), [BuildSharpMesherSpike.ps1](BuildSharpMesherSpike.ps1), [RunSharpMesherSpike.ps1](RunSharpMesherSpike.ps1), and [RenderSharpMesherCaptures.py](RenderSharpMesherCaptures.py). Updated this report and appended the M2 round-2 dialogue entry.
**New source files this round: none.** CSVs, OBJ meshes, JPEG captures, logs, and local build outputs are generated research artifacts; none were committed.
## Round-3 Unreal integration (2026-10-10)
The round-3 proposal is now in the plugin Core route as the versioned, opt-in
`WorldAssemblerHybridV1` recipe. `bUseVoxelForgeCore` remains off by default, and the Core recipe
defaults to `MarchingCubesV1`. The hybrid only consumes tagged type-2 world-plan feature boxes at
LOD0. Cells touching a tile border and every LOD1+ cell use MC; existing border skirts remain. The
selected recipe participates in Core content identity only when selected, so the disabled path and
the default MC path retain their existing identities.
### BuildHost evidence
The latest BuildHost UBT build and link-safety audit passed after the collision diagnostic was
changed to compare the runtime component trace and cooked-body bounds. The full null-RHI actor
commandlet ran for 11m00s and logged `pass complete=1`, `Success - 0 error(s)`. The PowerShell
wrapper then returned 1 while formatting its final status because it cast a `SwitchParameter` to
`Int32`; that print now uses the numeric fixture flag already computed by the script. A focused run
after this correction returned 0. The corrected full actor wrapper was then rerun and returned 0:
11m06s, peak sampled private memory 4,007,432,192 bytes (3.73 GiB), `pass complete=1`, and zero
engine errors. The final log is
[`CoreWorldValidation.log`](../../../Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/CoreWorldValidation.log).
W1/W8/W16 remained bit-stable at the round-6 Core hashes: density `0x8cc18e2981c50c4e`, mesh
`0x78e9c8ea42ff2965`, payload `0x380e8e11e76b47ca`, topology `0x24e40452e99fe482`. The actor passed
initial streaming, anchor movement, edit, height agreement, switch-off content gating, Blueprint
carve/fill, surface travel, and native SurfaceWorld travel. On the surface route, all 2,553 desired
visual tiles matched; 573 local tiles, 3,438 neighbor faces, and 432 LOD transitions were checked.
The actor run used about 2.8 GiB private memory. The only UECC directory is the older
2026-09-17 folder; no round-3 process crashed or retried on `0xC0000142`.
The hybrid selects triangles from the existing field and does not change field density, route
constraints, or signed-density bounds. This actor rerun passed height agreement, plan import,
anchor/edit/travel, switch-off gating, and Blueprint carve/fill. The last recorded full standalone
field audits remain the M1 round-4 results: 298 bounds / 8,046 samples with zero misses or unknown
ranges; 29,929 half-voxel shelf columns with zero sub-voxel runs; and a 530-center, 143,630-point
route sweep with zero blocked, unsupported, or grade-failing samples. Their negative controls were
detected. Those standalone audits were not rerun in round 3; the fresh route-related evidence is the
BuildHost actor travel/height pass above.
The focused production-mesher check passed all five fixture repeats. The separately staged native
SurfaceWorld type-4 cliff tile at `(-22,13,-58)` also passed a BuildHost MC/hybrid bit-identity
check: 10,231 vertices, 10,360 triangles, mesh hash `0xfc7bd7a3cf997992`. The full Core actor
session ran the TunnelNetwork cave path; its organic cave chamber fixture stayed on MC and produced
the same 2,408 triangles as MC.
Same-LOD borders are generated independently and pass with 63 MC segments and 63 hybrid/fallback
segments. The 125-phase LOD0/LOD1 doorway probe had zero cases and zero probes above 50 cm; its
worst measured contour mismatch was 22.844 cm. This does not close the known MC topology failures:
the standalone full transition matrix still has five failed doorway cases out of 625. This policy
keeps the existing skirts as the repair and leaves a true transition template for later work.
At LOD0, the measured 17.68 cm corner bevel is 0.35 of the 50 cm LOD1 sample. It may round off and
pop at the LOD threshold. Null RHI provided no projected-error or live visual measurement; the
owner must judge it at the target camera and movement speed.
### Cooked collision contacts
All five fixture contacts hit the actor's Pawn channel and the target RMC component. The actor's
Core render hash matched the standalone tile, render and cooked Chaos body bounds matched, and the
direct component trace differed from the world trace by 0.000 cm. Density-field contact error was
within one 25 cm Core voxel:
| Contact | World position (cm) | Field contact error |
|---|---:|---:|
| Corner top | (1025, 4150, −50127.64) | 20.332 cm |
| Doorway lintel | (1350, 4150, −50068.55) | 5.951 cm |
| Riser face | (1350, 4600, −50257.71) | 0.000 cm |
| Ledge top | (1450, 4600, −50140.14) | 8.956 cm |
| Ledge underside | (1450, 4600, −50190.14) | 13.262 cm |
### Production mesher cost
These BuildHost timings compare the plugin's production MC and hybrid routes after field sampling.
They measure meshing, not render upload or collision cooking.
| Fixture, 32³ cells | MC | Hybrid | Hybrid / MC | Triangles (MC / hybrid) |
|---|---:|---:|---:|---:|
| 90° corner | 2.246 ms | 15.048 ms | 6.70× | 3,196 / 3,200 |
| Doorway | 1.819 ms | 11.538 ms | 6.34× | 1,724 / 1,712 |
| 1 m riser | 1.979 ms | 11.974 ms | 6.05× | 2,108 / 2,112 |
| Cliff ledge | 2.270 ms | 12.839 ms | 5.66× | 3,132 / 3,128 |
| Organic cave | 2.106 ms | 2.089 ms | 0.992× | 2,408 / 2,408 |
Sharp-tagged fixtures cost roughly 5.66–6.70× MC in this plugin harness. The untagged cave is
effectively unchanged. This is a substantial local CPU cost where the tagged feature path runs.
### Owner hand-off and source inventory
In the owner project, enable `Use VoxelForge Core` on the `AVoxelWorld` and set `Core Mesher Recipe`
to `World Assembler Hybrid V1`. Both switches remain opt-in; the default recipe is MC. To preview
the surface-strate placements, duplicate the settings asset, import
[`surface_hybrid_fixture_plan.json`](round3/surface_hybrid_fixture_plan.json) through
`SourceWorldAssemblyManifestJson` / `ImportWorldAssemblyManifestJson`, then visit the corner,
doorway, riser, and ledge around the coordinates in the contact table. The plan carries nine stable
type-2 feature boxes and retains the sampled type-4 cliff. The owner should review the corner and
doorway as distance increases and cross the LOD threshold with skirts visible. No owner asset was
edited; all checks here used BuildHost with null RHI, so no visual capture was produced.
New source files this round are the mirrored private mesher headers
[`VoxelHybridSharpMesher.h`](../../../Source/VoxelForge/Private/VoxelHybridSharpMesher.h) and
[`VoxelHybridSharpMesher.h`](../../Source/VoxelForge/Private/VoxelHybridSharpMesher.h). No new
`.cpp` or generated header was added. Likely compile touchpoints are `VoxelWorld.h/.cpp`,
`VoxelTypes.h`, `VoxelMarchingCubesMesher.h/.cpp`, both hybrid mesher headers,
`Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`,
`Standalone/Core/src/VoxelForgeCore.cpp`, `VoxelForgeExploreCommandlet.cpp`, and
`VoxelForgeEditor.Build.cs`.
### Round-3 failed-run ledger
Times below are BuildHost log stamps. Repeated attempts are listed individually; each was null-RHI
BuildHost work. The final passing commandlet and focused checks are described above.
| Run(s) | Result and correction |
|---|---|
| 02:32:40, 02:45:03 | The exact-output check failed for the tagged corner (`stable=1`, `expected_mc_identity=0`). Corrected the fixture assertion; the final five-fixture repeat check passes. |
| 03:00:55, 03:04:08 | The doorway probe compared the full coarse span with the fine span and reported 125/125 over-budget cases, worst 800.047 cm. Restricted comparison to their shared overlap; the final 125-phase probe is below budget. |
| 03:06:12, 03:24:05, 04:23:42 | Focused five-fixture checks passed. |
| 03:19:40 | Actor collision contact fixture failed before it recorded a corner contact. |
| 03:35:38, 03:52:53, 04:08:52, 04:21:48, 04:35:15, 04:51:17, 05:09:02, 05:22:12, 05:35:24, 05:52:51 | Actor checks exposed misses in the old pawn/visibility/closest-triangle diagnostic. Replaced that test with a direct RMC component trace plus cooked-body/render-bounds comparison. |
| 06:13:08 | Actor process hit the 900-second timeout at about 3.95 GiB and was stopped. No crash folder appeared. |
| 06:19:47 | Geometry audit included an injected synthetic fixture tile and rejected its 51.570 cm edge. Excluded injected fixture tiles from the natural-terrain scale audit. |
| 06:32:52 | Pawn/capsule hits worked, but the riser expected point was 100 cm from the actual contact (corner error 20.332 cm). Corrected the fixture anchor. |
| 06:48:33 | Pawn contacts worked, but the standalone closest-ray helper reported no visual hits; riser anchor was still offset. Replaced the unreliable helper and corrected the anchor again. |
| 07:03:11 | Double-precision triangle-ray helper still reported no visual hits; the riser target at x=1,250 cm missed the actual x=1,350 cm contact. Replaced this check with component tracing and render/cooked bounds. |
| 07:05–07:17 | A duplicate wrapper launch was refused because BuildHost PID 5616 was already active; its command line was verified as the requested null-RHI test and monitored. That actor run failed on the stale visual-ray helper and riser anchor. |
| Before final UBT pass | One compile failed because commandlet checks referenced `ReferenceWorld`, `TravelOptions`, and `CoreError` after their scope. Moved the check into scope; the next BuildHost UBT and link audit passed. |
| 07:22–07:33 | Full actor commandlet completed all assertions with `pass complete=1` and zero engine errors, but the wrapper returned 1 on its final `[int]$EnableHybridFixturePlacement` formatting cast. Fixed the status print to use the existing numeric flag; focused fixture and cliff wrappers then exited 0. |
| 07:40–07:51 | Reran the full actor path after the wrapper fix. Commandlet and wrapper both passed in 11m06s; peak sampled private memory was 4,007,432,192 bytes (3.73 GiB), and the engine reported zero errors. |
No new UECC folder, process crash, or `0xC0000142` retry occurred in round 3. No owner project/editor was
opened or built; no `.uasset` was edited; no commit, push, or stash was made.