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:
1 parent
a3b7d2015e
commit
22a6b30494
21 files changed
+3009
-23
No files matched your search
@@ -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.
|
||||
@@ -0,0 +1 @@
|
||||
{"schema_version":1,"content_hash":"b3d0e439a6dc2b3d","recipe":{"schema_version":1,"evaluator_version":4,"units_per_voxel":256,"seed":0,"biome_cell_size_q":204800,"biome_warp_q":64000,"biome_warp_wavelength_q":142222,"biome_border_blend_q":30720,"climate_relief_wavelength_q":853333,"climate_moisture_wavelength_q":640000,"climate_relief_contrast_q16":131072,"content_hash":"c37de78b759c0a4c","biomes":[{"id":4097,"base_height_q":-516096,"continent_amplitude_q":128000,"continent_wavelength_q":256000,"mountain_amplitude_q":0,"mountain_wavelength_q":128000,"detail_amplitude_q":512,"detail_wavelength_q":6400,"relief_min_q16":0,"relief_max_q16":19661,"moisture_min_q16":0,"moisture_max_q16":19661,"relief_strength_q16":6554,"relief_contrast_q16":104858,"relief_wavelength_q":2560000,"height_warp_strength_q":12288,"height_warp_wavelength_q":32000,"beach_width_q":3072,"cliff_strength_q16":0,"cliff_slope_threshold_q16":32768,"cliff_sharpness_q16":131072,"cliff_sample_distance_q":512,"cliff_max_displacement_q":0,"cap_enabled":true,"cap_height_q":-149094,"cap_warp_strength_q":0,"cap_warp_wavelength_q":25600,"cap_undulation_q":256000,"cap_wavelength_q":1280000,"cap_detail_amplitude_q":2560,"cap_detail_wavelength_q":25600,"cap_ridge_amplitude_q":0,"cap_ridge_wavelength_q":12800},{"id":4098,"base_height_q":-484639,"continent_amplitude_q":128000,"continent_wavelength_q":256000,"mountain_amplitude_q":128000,"mountain_wavelength_q":512000,"detail_amplitude_q":512,"detail_wavelength_q":25600,"relief_min_q16":52429,"relief_max_q16":65536,"moisture_min_q16":52429,"moisture_max_q16":65536,"relief_strength_q16":45875,"relief_contrast_q16":104858,"relief_wavelength_q":170667,"height_warp_strength_q":12288,"height_warp_wavelength_q":25600,"beach_width_q":3072,"cliff_strength_q16":65536,"cliff_slope_threshold_q16":19661,"cliff_sharpness_q16":327680,"cliff_sample_distance_q":5120,"cliff_max_displacement_q":2570240,"cap_enabled":true,"cap_height_q":-149094,"cap_warp_strength_q":0,"cap_warp_wavelength_q":25600,"cap_undulation_q":230400,"cap_wavelength_q":1280000,"cap_detail_amplitude_q":2560,"cap_detail_wavelength_q":25600,"cap_ridge_amplitude_q":0,"cap_ridge_wavelength_q":12800},{"id":4099,"base_height_q":-516096,"continent_amplitude_q":20480,"continent_wavelength_q":85333,"mountain_amplitude_q":0,"mountain_wavelength_q":128000,"detail_amplitude_q":512,"detail_wavelength_q":6400,"relief_min_q16":6554,"relief_max_q16":26214,"moisture_min_q16":32768,"moisture_max_q16":52429,"relief_strength_q16":0,"relief_contrast_q16":16384,"relief_wavelength_q":170752,"height_warp_strength_q":16640,"height_warp_wavelength_q":32000,"beach_width_q":3072,"cliff_strength_q16":0,"cliff_slope_threshold_q16":32768,"cliff_sharpness_q16":131072,"cliff_sample_distance_q":512,"cliff_max_displacement_q":0,"cap_enabled":true,"cap_height_q":-149094,"cap_warp_strength_q":0,"cap_warp_wavelength_q":25600,"cap_undulation_q":256000,"cap_wavelength_q":1280000,"cap_detail_amplitude_q":2560,"cap_detail_wavelength_q":25600,"cap_ridge_amplitude_q":0,"cap_ridge_wavelength_q":12800},{"id":4100,"base_height_q":-385024,"continent_amplitude_q":20480,"continent_wavelength_q":256000,"mountain_amplitude_q":20480,"mountain_wavelength_q":512000,"detail_amplitude_q":512,"detail_wavelength_q":25600,"relief_min_q16":64881,"relief_max_q16":65536,"moisture_min_q16":52429,"moisture_max_q16":65536,"relief_strength_q16":45875,"relief_contrast_q16":104858,"relief_wavelength_q":170667,"height_warp_strength_q":12288,"height_warp_wavelength_q":25600,"beach_width_q":3072,"cliff_strength_q16":0,"cliff_slope_threshold_q16":32768,"cliff_sharpness_q16":131072,"cliff_sample_distance_q":512,"cliff_max_displacement_q":0,"cap_enabled":true,"cap_height_q":-149094,"cap_warp_strength_q":0,"cap_warp_wavelength_q":25600,"cap_undulation_q":230400,"cap_wavelength_q":1280000,"cap_detail_amplitude_q":2560,"cap_detail_wavelength_q":25600,"cap_ridge_amplitude_q":0,"cap_ridge_wavelength_q":12800}]},"plan":{"schema_version":1,"content_hash":"1f2b139a595f8a05","strates":[{"strate_index":1,"top_chunk_z":-16,"bottom_chunk_z":-79,"cap_height_q":-149094,"cap_undulation_q":0,"cap_wavelength_q":64000,"cap_detail_amplitude_q":1536,"cap_detail_wavelength_q":6400,"cap_ridge_amplitude_q":0,"cap_ridge_wavelength_q":12800,"water_surface_q":-505610,"water_enabled":true,"content_hash":"6f5842ebaa29ea85","features":[{"stable_id":"09812c26310b90c9","type":4,"min_q":[-183296,96256,-512629],"max_q":[-160768,118784,-412102],"parameters_q":[0,256,16384,18432]},{"stable_id":"4d32460000000001","type":2,"min_q":[8704,41984,-515867],"max_q":[11008,43008,-513307],"parameters_q":[0,0,0,0]},{"stable_id":"4d32460000000002","type":2,"min_q":[9984,43008,-515867],"max_q":[11008,44288,-513307],"parameters_q":[0,0,0,0]},{"stable_id":"4d32460000000003","type":2,"min_q":[12032,41984,-515774],"max_q":[13056,43008,-512702],"parameters_q":[0,0,0,0]},{"stable_id":"4d32460000000004","type":2,"min_q":[14592,41984,-515774],"max_q":[15616,43008,-512702],"parameterLine truncated
|
||||
Reference in new issue
Block a user