From dcf0763ec51e27021a26a7c2d02eccf2ad686017 Mon Sep 17 00:00:00 2001 From: Fr0zka Date: Tue, 20 Oct 2026 07:55:53 +0200 Subject: [PATCH] wip(assembler): round L18 -- FloatingIslands false floors removed; shared strate ceiling FI geometry v3 drops the all-XY lower boundary seal that created false floors (3.5/8 m); the ceiling comes from the shared VF_ApplyUpperBoundarySeal and AppendStratumBoundaryCeilings path for every generator, at each strate's own configured upper boundary (owner: every strate has a ceiling). Far-LOD ceiling continuity: 0 gaps at LOD4-8. SurfaceWorld bit-identical to L14 (14 configs + 24 m crossing); FI deterministic (28-row matrix); route parity and proofs pass. Unreal: FI geometryVersion 2->3 and the shared upper-seal helper extracted (UBT compile needed on the owner PC). Open: small ceiling holes; lower-stratum LOD ring steps seen through the FI void. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX --- ARCHITECTURE.md | 26 ++- CODEMAP.md | 17 +- .../Private/VoxelForgeCoreAdapter.cpp | 2 +- .../Public/VoxelDensityPrimitives.h | 32 +++- Standalone/Core/API.md | 9 +- .../include/VoxelForgeCore/VoxelForgeCore.h | 4 +- Standalone/Core/src/FarShellsInternal.h | 176 +++++++++++++++++- Standalone/Core/src/FloatingIslandsInternal.h | 2 +- Standalone/Core/src/ShapeWorldInternal.h | 101 ++++++++-- Standalone/Core/src/VoxelForgeCore.cpp | 2 + .../Linux18/BuildResources.md | 9 + .../Linux18/CaptureLinux18.py | 52 ++++++ .../Linux18/CeilingContinuity.py | 165 ++++++++++++++++ .../Linux18/CheckCrossingHashes.py | 25 +++ .../Linux18/CheckSurfaceHashes.py | 25 +++ .../Linux18/FloatingIslandDensityProbe.cpp | 149 +++++++++++++++ .../WorldAssemblerM3/Linux18/MeasureBuild.py | 67 +++++++ .../WorldAssemblerM3/Linux18/MeshProbe.py | 100 ++++++++++ .../Linux18/ProbeCaptureRays.py | 152 +++++++++++++++ .../WorldAssemblerM3/Linux18/REPORT.md | 132 +++++++++++++ .../WorldAssemblerM3/Linux18/RingProbe.py | 151 +++++++++++++++ .../WorldAssemblerM3/Linux18/RunCrossing.py | 82 ++++++++ .../WorldAssemblerM3/Linux18/RunMatrix.py | 132 +++++++++++++ .../captures/floating-islands-ceiling-up.jpg | Bin 0 -> 34570 bytes .../floating-islands-flat-square-after.jpg | Bin 0 -> 47962 bytes .../floating-islands-flat-square-before.jpg | Bin 0 -> 70166 bytes .../floating-islands-flat-square-no-edges.jpg | Bin 0 -> 32606 bytes .../floating-islands-island-view-after.jpg | Bin 0 -> 44687 bytes .../floating-islands-island-view-before.jpg | Bin 0 -> 70813 bytes .../captures/surface-world-horizon-after.jpg | Bin 0 -> 33609 bytes .../captures/surface-world-horizon-before.jpg | Bin 0 -> 34039 bytes .../captures/surface-world-l1-spawn-after.jpg | Bin 0 -> 33389 bytes .../surface-world-l1-spawn-before.jpg | Bin 0 -> 33489 bytes Standalone/Source/LinuxOffscreenCapture.cpp | 94 +++++++++- .../Public/VoxelDensityPrimitives.h | 32 +++- Standalone/Source/WorldAssemblyPrototype.h | 6 +- 36 files changed, 1690 insertions(+), 54 deletions(-) create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/BuildResources.md create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/CaptureLinux18.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/CeilingContinuity.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/CheckCrossingHashes.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/CheckSurfaceHashes.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/FloatingIslandDensityProbe.cpp create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/MeasureBuild.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/MeshProbe.py create mode 100755 Standalone/Research/WorldAssemblerM3/Linux18/ProbeCaptureRays.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/RingProbe.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/RunCrossing.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/RunMatrix.py create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-ceiling-up.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-flat-square-after.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-flat-square-before.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-flat-square-no-edges.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-island-view-after.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-island-view-before.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-horizon-after.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-horizon-before.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-l1-spawn-after.jpg create mode 100644 Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-l1-spawn-before.jpg diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 9a4bcbd..f37b266 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -73,7 +73,7 @@ is the only density path; a degenerate (zero-height) strate has none and is open | Maze | `FMazeGenerationParams` | `BuildMazeStack` | origin-directed spanning-tree corridors on a 3D lattice, with capped loop edges and a thread-local per-cell capsule cache | | SurfaceWorld | `FSurfaceGenerationParams` | `BuildSurfaceStack` | heightfield terrain: domain-warped continents+ridged mtns+detail, a low-freq **relief map** (`M`) that scales mountains/elevation for plains↔highland variety, **F20 heightfield terrain ops** (`Surface|Ops` — all default off ⇒ byte-identical): **Cliff** (slope-gated steepening — where the analytic structural slope > `CliffSlopeThreshold`, push the height away from the local mean by `CliffSharpness` ⇒ gentle slopes become sheer walls/canyon faces that hug real steep ground, gentle areas untouched; 4 structural resamples only when enabled), **Terrace** (relief-gated plateau quantize + `TerraceHardness` soft-round↔crisp-mesa), **LayerLines** (sedimentary sine shelves, slope-expressed) — pure per-column height remaps in the single oracle `ComputeSurfaceTerrainZ` (`SampleSurfaceStructuralZ` = pre-op raw height, re-sampled at an XY offset for Cliff's slope), biome-selected + border-blended for free via each biome's `SurfaceParams` + the height output-lerp; plus **phase-2 Overhang** (the first VOLUMETRIC op — real jutting shelves like a cliff lip): in `FOverhangShelfMod`, for AIR voxels in the window `(TerrainZ, TerrainZ+OverhangHeight]` above a steep slope, the heightfield is re-sampled UPHILL (toward the cliff) by a reach that GROWS with height and unioned in. Low in the window the shift is ~0 (borrows nearby low rock ⇒ stays air over the void); high up it reaches the far cliff (solid) ⇒ a shelf attached to the cliff, tapering out over the void with air underneath. Per-column `OverhangAmp`(=strength·slope-gate) + unit uphill dir `(DirX,DirY)` are resolved once in `ComputeSurfaceColumn` — the gradient sampled at the REACH scale (`OverhangReach`) so a point out over the void can "see" the cliff to know which way is uphill — and cached on `FSurfaceColumn`. It's genuine 3D (per-voxel structural re-eval), so it's gated hard to steep overhang columns; the union only ADDS rock (never removes), capped at `TerrainZ+OverhangHeight`, so `ClassifyTile` forces Mixed only in `(TerrainZ, TerrainZ+OverhangMargin]` (upward-only; margin = max `OverhangHeight`) — a shelf never holes a trivially-skipped tile, and only the thin cliff-edge band of air tiles is woken (NOT far-field like phase-3 spikes/holes). Overhang undersides classify as ground rock by the F17 rule (down-facing but below `TerrainZ`). Known v1 limit: applies at all LODs (Step-agnostic) — may alias far; gate to fine tiles later. Beaches at water line, high sky-cap ceiling. The cap is shapeable terrain in its own right (`ComputeSurfaceCeiling`, `Surface|Sky` params: `CeilingUndulation` broad inverted hills/valleys, `CeilingRidgeStrength` hanging ridgelines, `CeilingRoughness`+freq fine bumps, `CeilingWarp*`) — defaults (strengths 0, freq 0.04) = old flat-ish cap. (`Surface|Macro` params = the cheap precursor to biomes; `ReliefStrength=0` ⇒ old uniform terrain.) **Sky-cap vs ground is a PER-TRIANGLE surface class (F17), not a per-tile verdict**: the mesher classifies each unique vertex on the **worker** — only down-facing verts (`N.Z<-0.1`) pay a memoized `GetSurfaceHeightAt` column query; nearer `CeilSurf` ⇒ sky-cap, nearer `TerrainZ` ⇒ terrain overhang stays ground (a future SurfaceWorld cave roof — down-facing but below `TerrainZ` — also lands ground by the same rule; non-surface strates always ground). Triangles take the majority class of their 3 verts and are packed as **two contiguous index runs** (ground then cap, `FVoxelMeshData::NumCeilingTriangles`; skirts inherit their source triangle's run) → RMC **polygroups 0/1** → one **section per non-empty group** (`ApplyMeshToTile`, material slot = group index): slot 0 = strate `OverrideMaterial`/default (min-corner chunk), slot 1 = `CeilingMaterial` resolved at the tile's **TOP chunk** (mid as gap fallback, then min; fallback: ground material) — a coarse tile is 2^level chunks tall, so its min corner can sit in a lower strate/gap while the cap belongs to the strate above (this was the "far cap = ground material" residue), so the shadowless overhead rock is tinted separately instead of reading flat/bright. Shadow is **per section** via `FRealtimeMeshSectionConfig::bCastsShadow` (NOT the component `SetCastShadow` — RMC's proxy ignores the component flag; this is also why level≥2 far tiles only stopped casting once the section flag was wired): ground casts at level≤1, the cap section never casts, so the rock ceiling never shadows the terrain below it. History: v1 was a game-thread centre height-oracle (misclassified coarse far tiles → terrain material on the cap underside); v2 a whole-tile worker normal VOTE — which painted **mixed coarse tiles** (one far tile spanning terrain AND cap) entirely with the winner's material, and put sky material under terrain overhangs. The per-triangle class fixes both and is the identity channel caves/F8 will reuse. | | VerticalShafts | `FVerticalShaftParams` | `BuildVerticalShaftStack` | full-height shafts + horizontal connectors + partial ledges | -| FloatingIslands | `FFloatingIslandParams` | `BuildFloatingIslandStack` | asymmetric islands: flat land top + underside tapering to a point, lobed (domain-warped) outline, in an open void | +| FloatingIslands | `FFloatingIslandParams` | `BuildFloatingIslandStack` | asymmetric islands: flat land top + underside tapering to a point, lobed (domain-warped) outline, beneath the shared ceiling at its configured strate upper boundary | | Underwater | `FStrateGenerationParams` + water | (reuses `BuildTunnelNetworkStack`) | tunnel rock + high water table | All stacks share the convention: internal **positive=solid**, and `AppendStructuralPost` ends every @@ -1431,8 +1431,9 @@ density roots, including a 100 cm datum-offset negative control. See evaluators keep their recorded cap behavior. The clip joins the exact near density root at the owning boundary without changing LOD0–3 density hashes. Future families with planar roofs must declare their cap height and bounds through the family plan/provider contract; the shared tile generator consumes - that declaration. FloatingIslands declares no planar roof, so open sky above a surface island is the - expected view. + that declaration. FloatingIslands uses the same resolved strate-boundary data flow: its upper seal + follows its plan's chunk range and the shared boundary-seal primitive, while SurfaceWorld keeps its + existing heightfield cap. For each requested far SurfaceWorld XY column at LOD4–8, desired-tile selection adds cap-height bands only when they do not overlap an existing or already accepted 3D clipmap tile. The original @@ -1471,8 +1472,9 @@ neighborhood have installed collision (or are explicitly collision-not-required) now** — the active view has ground, horizon and the family-appropriate ceiling, with no exposed coverage hole or unexpected sky; (3) **refined soon** — each target LOD resolves within its stated time or travel distance after entering range. While moving, report the largest frame/time gap in -enclosure and maximum distance that unresolved work trails the pawn. FloatingIslands has open sky by -design, so its enclosure check excludes a planar roof. +enclosure and maximum distance that unresolved work trails the pawn. FloatingIslands is enclosed by a +planar roof at the upper boundary of its configured strate range; a taller strate places that roof +farther above its islands. The shared `AVoxelWorld::UpdateChunksAroundPosition` scheduler serves both the Core snapshot path and Core-off legacy path. It admits the collision-critical 3×3 ring first. The measured S5 order remains @@ -1840,6 +1842,20 @@ fill and check page tiles against the evaluator they actually sample. This is th the Unreal adapter and its asynchronous MPSC/Epoch flow are unchanged. See [`Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md). +### 8.37 Shared strate boundaries and FloatingIslands lower seal — World Assembler L18 + +`FStandaloneShapeWorld::GetResolvedStratumBounds` supplies one physical lower/upper-bound descriptor +to layer ranges, far-field sample protection, and far-shell continuity for every strate. SurfaceWorld +retains its exact `topChunkZ * 32` Core-voxel mapping and native heightfield cap. Native FloatingIslands +takes its resolved bounds from its plan, whose chunk range is converted through the serialized +owner/Core voxel ratio. Its version-3 field removes only the lower all-XY seal and calls the same +`VF_ApplyUpperBoundarySeal` primitive used by the shared two-sided `VF_ApplyBoundarySeal` for its upper +boundary. The ceiling therefore sits at that strate's own upper boundary, with the common +`boundarySealSubvoxels` thickness; there is no FloatingIslands-specific height. The recipe range is +un-inset to match the Unreal adapter. Versions 1 and 2 retain their serialized two-sided seals. +SurfaceWorld's field and output hashes remain unchanged. See +[`Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md). + ## 9. Multiplayer model (listen-server first, dedicated-friendly) > **Status: transport is DESIGN ONLY — nothing is networked in-tree yet** (no `Replicated`/`HasAuthority`/RPCs; a diff --git a/CODEMAP.md b/CODEMAP.md index 2d0f7e7..433dfb3 100644 --- a/CODEMAP.md +++ b/CODEMAP.md @@ -208,14 +208,16 @@ all eight archetypes; there is no other path. See [Docs/archive/OPSTACK-PLAN.md] | `FVoxelBoxHypotheses` + `FVoxelBoxSdfInterval` + `VF_ForceHypotheses` / `VF_FoldEffect` / `VF_FoldOp` | The fold that turns a stack into an `EVoxelTileClass`, carrying the SDF interval between independent writers and consumers. Unknown is biased toward `Mixed`; the mapping and soundness rule are written out in the header. | ### 3.2c Structural primitives — `Public/VoxelDensityPrimitives.h` -`VF_ApplyOriginSpine` · `VF_ApplyBoundarySeal` · `VF_ApplyPassageCarving` · `VF_ApplyXYEdgeSeal` — +`VF_ApplyOriginSpine` · `VF_ApplyBoundarySeal` · `VF_ApplyUpperBoundarySeal` · `VF_ApplyPassageCarving` · `VF_ApplyXYEdgeSeal` — the four world invariants every archetype appends, with landing/floor geometry joined by the manager passage post, **moved here 2026-07-27** so the generator and the operator stack share ONE copy. The XY helper is a radial smooth ramp in actor-space and is a true no-op when `WorldRadiusVoxels == 0`; `VF_XYEdgeSealForcedMarginOverBox` is the shared sound proof for `ClassifyBox` and T1.d's global shell skip. `VoxelGenerator.cpp` keeps same-named `static FORCEINLINE` forwarders for `ApplyBoundarySeal` and `ApplyOriginSpine`; the passage and -edge helpers are called directly. **Convention: INTERNAL (positive = solid); `VF_ApplyXYEdgeSealMC` is the output wrapper.** +edge helpers are called directly. `VF_ApplyUpperBoundarySealValue` contains the common upper-band +math used by both one-sided and two-sided seals. **Convention: INTERNAL (positive = solid); +`VF_ApplyXYEdgeSealMC` is the output wrapper.** ### 3.2d Operator stack — `Public/VoxelDensityOpStack.h` + `Private/VoxelDensityOpStack.cpp` ⚠️ **This IS the game's generation path.** `GetDensityAt` builds the stack in its per-chunk refetch @@ -1137,6 +1139,17 @@ Implementation and evidence: [`Standalone/Research/WorldAssemblerM3/Linux9/REPOR The base manifest field is authoritative for tile generation and exact queries. See ARCHITECTURE §8.36 and [`Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux13/REPORT.md). +### 3.23 Shared strate boundaries and FloatingIslands seal — World Assembler M3 Linux18 + +| Symbol | Canonical file | Role | +|---|---|---| +| `FStandaloneShapeWorld::FResolvedStratumBounds`, `MakeResolvedStratumBounds`, `GetResolvedStratumBounds` | `Standalone/Core/src/ShapeWorldInternal.h` | Resolves each strate's physical lower/upper range and seal width for layer ranges, far-field sample protection, and far-shell continuity. Native FloatingIslands uses its plan's owner/Core ratio; SurfaceWorld retains its `32` Core voxels per slot chunk. | +| `VF_ApplyUpperBoundarySeal` / `VF_ApplyUpperBoundarySealValue` | `Standalone/Source/VoxelForge/Public/VoxelDensityPrimitives.h` and `Source/VoxelForge/Public/VoxelDensityPrimitives.h` | Shared one-sided top seal used by version-3 native FloatingIslands; the two-sided seal reuses the same upper-band math. | + +Geometry version 3 removes the FI lower all-XY seal while retaining its ceiling through the shared +upper-bound path. Versions 1 and 2 retain their serialized two-sided behavior. See ARCHITECTURE §8.37 +and [`Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md). + ## 4. The density pipeline (most-edited hot path) ### 4.1 `GetDensityWithParams` (TunnelNetwork) — VoxelGenerator.cpp:3749 diff --git a/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp b/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp index 7a3f9f0..3a9064e 100644 --- a/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp +++ b/Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp @@ -450,7 +450,7 @@ bool BuildFloatingIslandStratumPlan(const UVoxelStrateManager* StrateManager, IslandPlan.topChunkZ = Slot.TopChunkZ; IslandPlan.bottomChunkZ = Slot.BottomChunkZ; auto& Recipe = IslandPlan.manifest.recipe; - Recipe.geometryVersion = 2; + Recipe.geometryVersion = 3; Recipe.seed = static_cast(StrateManager->GetWorldSeed()); Recipe.ownerVoxelSizeMicrons = static_cast(std::llround(OwnerVoxelSizeCm * 10000.0)); Recipe.coreVoxelSizeMicrons = static_cast(std::llround(CoreVoxelSizeCm * 10000.0)); diff --git a/Source/VoxelForge/Public/VoxelDensityPrimitives.h b/Source/VoxelForge/Public/VoxelDensityPrimitives.h index 7fb17f4..8e2c4c3 100644 --- a/Source/VoxelForge/Public/VoxelDensityPrimitives.h +++ b/Source/VoxelForge/Public/VoxelDensityPrimitives.h @@ -41,21 +41,27 @@ // SealFactor > 0 et BaseDensity > 0, le résultat est solide GARANTI quelle qu'ait été l'entrée. // C'est exactement ce qu'encode `IVoxelDensityOp::ClassifyBox` (voir VoxelDensityOp.h), et la // raison pour laquelle cette méthode existe. -FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ, - float StrateTopZ, float StrateBottomZ, - float Thickness, float BaseDensity) +FORCEINLINE void VF_ApplyUpperBoundarySealValue(float& Density, float WorldZ, + float StrateTopZ, float Thickness, float BaseDensity) { - if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return; - - const float DistTop = StrateTopZ - WorldZ; // + si on est sous le plafond - const float DistBot = WorldZ - StrateBottomZ; // + si on est au-dessus du sol - + const float DistTop = StrateTopZ - WorldZ; if (DistTop >= 0.0f && DistTop < Thickness) { float SealFactor = 1.0f - (DistTop / Thickness); SealFactor = SmoothStep01(SealFactor); Density = FMath::Max(Density, SealFactor * BaseDensity); } +} + +FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ, + float StrateTopZ, float StrateBottomZ, + float Thickness, float BaseDensity) +{ + if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return; + + const float DistBot = WorldZ - StrateBottomZ; // + si on est au-dessus du sol + + VF_ApplyUpperBoundarySealValue(Density, WorldZ, StrateTopZ, Thickness, BaseDensity); if (DistBot >= 0.0f && DistBot < Thickness) { float SealFactor = 1.0f - (DistBot / Thickness); @@ -64,6 +70,16 @@ FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ, } } +// The same structural seal, limited to a strate's upper boundary. Native finite fields use this +// when their lower boundary intentionally has no seal; keeping the math here makes that ceiling +// use the same shared density primitive as every two-sided strate seal. +FORCEINLINE void VF_ApplyUpperBoundarySeal(float& Density, float WorldZ, + float StrateTopZ, float Thickness, float BaseDensity) +{ + if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return; + VF_ApplyUpperBoundarySealValue(Density, WorldZ, StrateTopZ, Thickness, BaseDensity); +} + //============================================================================= // CARVE DE PASSAGE / PASSAGE CARVING //============================================================================= diff --git a/Standalone/Core/API.md b/Standalone/Core/API.md index a83d569..fa08deb 100644 --- a/Standalone/Core/API.md +++ b/Standalone/Core/API.md @@ -153,8 +153,13 @@ radius range, top flattening, taper, bounded contour warp, roughness, blend, con route constraints. `PlanFloatingIslandCluster` emits stable island and connector IDs, a connected cluster graph, conservative influence AABBs, and a centerline route. At least the primary chain is always planned; `islandDensityQ16` controls up to two optional side sites. Connectors carry a sharp-tag -ready bit for a later hybrid-mesher adapter. The schema accepts geometry version 1 and 2. Manifests -without a geometry version retain version-1 evaluation and canonical hashes. +ready bit for a later hybrid-mesher adapter. The schema accepts geometry versions 1 through 3. +Version 3 keeps the version-2 island form, removes the all-XY lower seal, and obtains its ceiling from +the shared upper-strate boundary seal. The resolved upper bound comes from the strate's own chunk +range; `boundarySealSubvoxels` sets the shared seal thickness and remains a planning margin for island +features. It does not define a FloatingIslands-specific ceiling height. Versions 1 and 2 retain their +recorded two-sided boundary seals. Manifests without a geometry version retain version-1 evaluation +and canonical hashes. `FloatingIslandFieldV1::densitySubvoxels` evaluates the canonical island and connector field. `interval` returns unknown for boxes overlapping any influence AABB and a certified all-air range diff --git a/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h b/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h index d46e08d..4c85c4d 100644 --- a/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h +++ b/Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h @@ -392,7 +392,9 @@ namespace VoxelForgeCore std::uint32_t schemaVersion = 1; // Profile 1 preserves the original shallow pads. Profile 2 adds a thick crust, // bounded lobed roots and arched spans without changing the feature-family schema. - std::uint32_t geometryVersion = 2; + // Version 3 keeps the version-2 island shapes, removes the all-XY lower boundary seal, + // and routes its upper seal through the shared strate-boundary primitive. + std::uint32_t geometryVersion = 3; std::uint32_t unitsPerVoxel = static_cast(WorldAssemblySubvoxelsPerVoxel); // Import scale is explicit in microns; the reduced ratio maps owner-authored lengths to Core voxels. // L'echelle d'import est explicite en microns; le rapport reduit convertit les longueurs owner. diff --git a/Standalone/Core/src/FarShellsInternal.h b/Standalone/Core/src/FarShellsInternal.h index da08747..53622d9 100644 --- a/Standalone/Core/src/FarShellsInternal.h +++ b/Standalone/Core/src/FarShellsInternal.h @@ -864,6 +864,46 @@ struct FFarMeshColumnIndex return Hits; } + bool HasDownwardHit(double X,double Y,double Z,double Tolerance) const + { + const int32 CX=std::clamp(static_cast(std::floor((X-Origin.X)/Step)),0,Cells-1); + const int32 CY=std::clamp(static_cast(std::floor((Y-Origin.Y)/Step)),0,Cells-1); + const auto& Candidates=ByColumn[static_cast(CY)*Cells+CX]; + for(const int32 Triangle:Candidates) + { + const int32 IA=Mesh.Triangles[Triangle*3],IB=Mesh.Triangles[Triangle*3+1], + IC=Mesh.Triangles[Triangle*3+2]; + if(IA<0||IB<0||IC<0||IA>=Mesh.Normals.Num()||IB>=Mesh.Normals.Num() + ||IC>=Mesh.Normals.Num())continue; + if(Mesh.Normals[IA].Z+Mesh.Normals[IB].Z+Mesh.Normals[IC].Z>=-1.5)continue; + const double AX=PositionAxis(IA,0),AY=PositionAxis(IA,1),AZ=PositionAxis(IA,2); + const double BX=PositionAxis(IB,0),BY=PositionAxis(IB,1),BZ=PositionAxis(IB,2); + const double CXv=PositionAxis(IC,0),CYv=PositionAxis(IC,1),CZ=PositionAxis(IC,2); + const double Den=(BX-AX)*(CYv-AY)-(BY-AY)*(CXv-AX); + if(std::abs(Den)<1.0e-10)continue; + const double U=((X-AX)*(CYv-AY)-(Y-AY)*(CXv-AX))/Den; + const double V=((BX-AX)*(Y-AY)-(BY-AY)*(X-AX))/Den; + const double W=1.0-U-V; + if(U<-1.0e-7||V<-1.0e-7||W<-1.0e-7)continue; + const double Hit=AZ+U*(BZ-AZ)+V*(CZ-AZ); + if(std::abs(Hit-Z)<=Tolerance)return true; + } + return false; + } + + bool HasDownwardCellCoverage(double X0,double Y0,double X1,double Y1, + double Z,double Tolerance) const + { + constexpr double Samples[3]={0.125,0.5,0.875}; + for(const double V:Samples)for(const double U:Samples) + { + const double X=X0+(X1-X0)*U; + const double Y=Y0+(Y1-Y0)*V; + if(!HasDownwardHit(X,Y,Z,Tolerance))return false; + } + return true; + } + private: double PositionAxis(int32 Index,int32 Axis) const { @@ -974,11 +1014,11 @@ inline void AppendFarStratumShells(const FStandaloneOwnerWorld& World,const FSta std::vector Boundaries; for(const FStrateSlot& Slot:Layout) { - const FStrateGenerationParams Params=World.Manager->GetGenerationParams( - FIntVector(0,0,(Slot.TopChunkZ+Slot.BottomChunkZ)/2)); - const double HalfWidth=std::max(8.0,static_cast(Params.BoundarySealThickness)+8.0); - Boundaries.push_back({static_cast(Slot.BottomChunkZ)*CHUNK_SIZE,HalfWidth}); - Boundaries.push_back({static_cast(Slot.TopChunkZ+1)*CHUNK_SIZE,HalfWidth}); + FStandaloneShapeWorld::FResolvedStratumBounds Resolved; + if(!Shape.GetResolvedStratumBounds(Slot,Resolved))continue; + const double HalfWidth=std::max(8.0,Resolved.SealThickness+8.0); + Boundaries.push_back({Resolved.BottomZ,HalfWidth}); + Boundaries.push_back({Resolved.TopZ,HalfWidth}); } std::sort(Boundaries.begin(),Boundaries.end(),[](const FBoundary& A,const FBoundary& B){return A.Z Crossing; + }; + std::vector Candidates; + for(const FStrateSlot& Slot:World.Manager->GetLayout()) + { + FCandidate Candidate; + if(!Shape.GetResolvedStratumBounds(Slot,Candidate.Bounds) + ||Candidate.Bounds.SealThickness<=0.0 + ||Candidate.Bounds.TopZOrigin.Z+Extent+1.0e-6)continue; + const double Epsilon=std::min(0.5,Candidate.Bounds.SealThickness*0.25); + if(Epsilon<=0.0)continue; + Candidate.Crossing.resize(static_cast(GridSide)*GridSide,0); + bool AnyCrossing=false; + for(int32 Y=0;Y(WorldX),static_cast(WorldY), + static_cast(Candidate.Bounds.TopZ-Epsilon)); + const float Above=Shape.DensityAt(static_cast(WorldX),static_cast(WorldY), + static_cast(Candidate.Bounds.TopZ+Epsilon)); + const bool bCrosses=std::isfinite(Below)&&std::isfinite(Above)&&Below<0.0f&&Above>0.0f; + Candidate.Crossing[static_cast(Y*GridSide+X)]=bCrosses?1:0; + AnyCrossing=AnyCrossing||bCrosses; + } + if(AnyCrossing)Candidates.push_back(std::move(Candidate)); + } + if(Candidates.empty())return; + + const int32 Cells=std::max(1,World.CoarseTileCells); + FFarMeshColumnIndex MeshIndex(Mesh,Origin,Extent,Cells,Step); + const int32 OldVertexCount=Mesh.Vertices.Num(); + const int32 OldSurfaceVertices=std::clamp(Mesh.NumSurfaceVertices,0,OldVertexCount); + const bool bHasUVs=Mesh.UVs.Num()==OldVertexCount; + const bool bHasColors=Mesh.Colors.Num()==OldVertexCount; + const FColor Color=bHasColors&&OldVertexCount>0?Mesh.Colors[0]:FColor(160,160,160,255); + const double VoxelSizeCm=static_cast(World.CoreVoxelSizeMicrons)/10000.0; + std::vector NewVertices,NewNormals; + std::vector NewUVs; + std::vector NewColors; + std::vector NewTriangles; + for(const FCandidate& Candidate:Candidates) + { + std::vector VertexMap(static_cast(GridSide)*GridSide,INDEX_NONE); + const double CeilingZ=Candidate.Bounds.TopZ; + const auto AddVertex=[&](int32 X,int32 Y) + { + const std::size_t GridIndex=static_cast(Y*GridSide+X); + int32& Mapped=VertexMap[GridIndex]; + if(Mapped!=INDEX_NONE)return Mapped; + Mapped=static_cast(NewVertices.size()); + const double WorldX=Origin.X+X*GridStep,WorldY=Origin.Y+Y*GridStep; + NewVertices.emplace_back(WorldX*VoxelSizeCm,WorldY*VoxelSizeCm,CeilingZ*VoxelSizeCm); + NewNormals.emplace_back(0.0,0.0,-1.0); + if(bHasUVs)NewUVs.emplace_back(static_cast(WorldX),static_cast(WorldY)); + if(bHasColors)NewColors.push_back(Color); + return Mapped; + }; + for(int32 Y=0;Y+1(Y*GridSide+X); + const std::size_t I10=I00+1,I01=I00+GridSide,I11=I01+1; + if(!Candidate.Crossing[I00]||!Candidate.Crossing[I10] + ||!Candidate.Crossing[I01]||!Candidate.Crossing[I11])continue; + const double CellX0=Origin.X+X*GridStep,CellY0=Origin.Y+Y*GridStep; + const double CellX1=CellX0+GridStep,CellY1=CellY0+GridStep; + // Suppress a coincident plane only when it covers the full cell. A hit at just the + // center of a curved shell triangle is not enough to leave the rest of this cap cell open. + if(MeshIndex.HasDownwardCellCoverage(CellX0,CellY0,CellX1,CellY1,CeilingZ,0.001))continue; + const int32 A=AddVertex(X,Y),B=AddVertex(X+1,Y); + const int32 C=AddVertex(X+1,Y+1),D=AddVertex(X,Y+1); + NewTriangles.insert(NewTriangles.end(),{A,C,B,A,D,C}); + } + } + if(NewTriangles.empty())return; + + const int32 AddedVertices=static_cast(NewVertices.size()); + auto InsertVertices=[&](auto& Existing,const auto& Added) + { + using TArrayType=std::remove_reference_t; + TArrayType Combined;Combined.Reserve(Existing.Num()+static_cast(Added.size())); + for(int32 I=0;I=OldSurfaceVertices)Index+=AddedVertices; + const int32 CeilingStart=std::max(0,Mesh.Triangles.Num()-Mesh.NumCeilingTriangles*3); + TArray CombinedTriangles;CombinedTriangles.Reserve( + Mesh.Triangles.Num()+static_cast(NewTriangles.size())); + for(int32 I=0;I ExistingFaceMasks=Mesh.TriangleSkirtFaceMasks; + ExistingFaceMasks.SetNum(OldTriangleCount); + TArray CombinedFaceMasks;CombinedFaceMasks.Reserve( + OldTriangleCount+static_cast(NewTriangles.size()/3)); + for(int32 Triangle=0;Triangle(NewTriangles.size()/3); +} diff --git a/Standalone/Core/src/FloatingIslandsInternal.h b/Standalone/Core/src/FloatingIslandsInternal.h index fbb8555..b872f5a 100644 --- a/Standalone/Core/src/FloatingIslandsInternal.h +++ b/Standalone/Core/src/FloatingIslandsInternal.h @@ -266,7 +266,7 @@ namespace floating_island_detail ? recipe.ownerVoxelSizeMicrons / ScaleGcd : 0; const std::uint32_t ExpectedDenominator = ScaleGcd > 0 ? recipe.coreVoxelSizeMicrons / ScaleGcd : 0; - if (recipe.schemaVersion != 1 || (recipe.geometryVersion != 1 && recipe.geometryVersion != 2) + if (recipe.schemaVersion != 1 || recipe.geometryVersion < 1 || recipe.geometryVersion > 3 || (recipe.geometryVersion == 1 && (recipe.crustDepthBonusQ16 != 0 || recipe.rootDepthRatioQ16 != 0)) || recipe.unitsPerVoxel != Q diff --git a/Standalone/Core/src/ShapeWorldInternal.h b/Standalone/Core/src/ShapeWorldInternal.h index f05f7ee..deb2d87 100644 --- a/Standalone/Core/src/ShapeWorldInternal.h +++ b/Standalone/Core/src/ShapeWorldInternal.h @@ -5,6 +5,7 @@ #include "VoxelCaveMorphology.h" #include "VoxelNoise.h" #include "VoxelStrateManager.h" +#include "VoxelDensityPrimitives.h" #include "VoxelForgeCore/VoxelForgeCore.h" #include "VoxelForgeFieldShared.h" @@ -32,6 +33,13 @@ class FStandaloneShapeWorld { public: + struct FResolvedStratumBounds + { + double BottomZ=0.0; + double TopZ=0.0; + double SealThickness=0.0; + }; + double GetCoreVoxelSizeCm() const { return Owner == nullptr || Owner->CoreVoxelSizeMicrons == 0 @@ -47,6 +55,41 @@ public: return static_cast(CHUNK_SIZE) * OwnerVoxelSizeCm / GetCoreVoxelSizeCm(); } + static bool MakeResolvedStratumBounds(double BottomZ,double TopZ,double SealThickness, + FResolvedStratumBounds& Out) + { + if(!std::isfinite(BottomZ)||!std::isfinite(TopZ)||!std::isfinite(SealThickness) + ||TopZ<=BottomZ||SealThickness<0.0)return false; + Out={BottomZ,TopZ,SealThickness}; + return true; + } + + bool GetResolvedStratumBounds(const FStrateSlot& Slot,FResolvedStratumBounds& Out) const + { + if(!Owner||!Owner->Manager)return false; + const int32 MidChunkZ=(Slot.TopChunkZ+Slot.BottomChunkZ)/2; + if(bUseNativeManifestFields&&WorldAssembly + &&Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,MidChunkZ)) + ==ECaveGeneratorType::FloatingIslands) + { + const auto* Plan=FindWorldAssemblyFloatingIslandStratum(Slot.StrateIndex,MidChunkZ); + if(Plan&&Plan->manifest.recipe.geometryVersion>=3) + { + constexpr double Scale=static_cast( + VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel); + return MakeResolvedStratumBounds( + static_cast(Plan->manifest.recipe.layoutMinimumZSubvoxels)/Scale, + static_cast(Plan->manifest.recipe.layoutMaximumZSubvoxels)/Scale, + static_cast(Plan->manifest.recipe.boundarySealSubvoxels)/Scale,Out); + } + } + const FStrateGenerationParams Params=Owner->Manager->GetGenerationParams( + FIntVector(0,0,MidChunkZ)); + return MakeResolvedStratumBounds(static_cast(Slot.BottomChunkZ)*CHUNK_SIZE, + static_cast(Slot.TopChunkZ+1)*CHUNK_SIZE, + static_cast(Params.BoundarySealThickness),Out); + } + enum class EDetailVariant : uint8 { Coherent, Smooth, PerVoxel }; struct FBoxClassification { @@ -714,12 +757,12 @@ public: const double TileZ0=Origin.Z,TileZ1=Origin.Z+static_cast(Cells)*Step; for(const FStrateSlot& Slot:Owner->Manager->GetLayout()) { - const FStrateGenerationParams Params=Owner->Manager->GetGenerationParams( - FIntVector(0,0,(Slot.TopChunkZ+Slot.BottomChunkZ)/2)); + FResolvedStratumBounds Bounds; + if(!GetResolvedStratumBounds(Slot,Bounds))continue; const float HalfWidth=static_cast(std::max(8.0, - static_cast(Params.BoundarySealThickness)+8.0)); - const float Boundaries[2]={static_cast(Slot.BottomChunkZ)*CHUNK_SIZE, - static_cast(Slot.TopChunkZ+1)*CHUNK_SIZE}; + Bounds.SealThickness+8.0)); + const float Boundaries[2]={static_cast(Bounds.BottomZ), + static_cast(Bounds.TopZ)}; for(const float Z:Boundaries) if(Z+HalfWidth>=TileZ0&&Z-HalfWidth<=TileZ1) Out.stratumBoundaries.push_back({Z,HalfWidth}); @@ -1549,13 +1592,18 @@ public: const std::int64_t Seal=IslandPlan->manifest.recipe.boundarySealSubvoxels; const std::int64_t BoxBottom=static_cast(BMin[2])*Scale; const std::int64_t BoxTop=static_cast(BMax[2])*Scale; - const bool bBottomSealOverlap=BoxBottom=Bottom; - const bool bTopSealOverlap=BoxBottom<=Top&&BoxTop>Top-Seal; + const bool bSharedTopSealEnabled=IslandPlan->manifest.recipe.geometryVersion<3 + ||!VoxelDensityAblation::IsBoundarySealOff(); + const bool bTopSealOverlap=bSharedTopSealEnabled + &&BoxBottom<=Top&&BoxTop>Top-Seal; + const bool bBottomSealOverlap=IslandPlan->manifest.recipe.geometryVersion<3 + &&BoxBottom=Bottom; if(bBottomSealOverlap) return Finish(BoxBottom>=Bottom&&BoxTop<=Bottom+Seal ?EVoxelTileClass::AllSolid:EVoxelTileClass::Mixed); if(bTopSealOverlap) - return Finish(BoxBottom>=Top-Seal&&BoxTop<=Top + return Finish((IslandPlan->manifest.recipe.geometryVersion<3 + ?BoxBottom>=Top-Seal:BoxBottom>Top-Seal)&&BoxTop<=Top ?EVoxelTileClass::AllSolid:EVoxelTileClass::Mixed); const VoxelForgeCore::FloatingIslandFieldV1 Block( IslandPlan->manifest.recipe,IslandPlan->manifest.plan); @@ -2130,9 +2178,28 @@ private: const std::int64_t Top=Plan->manifest.recipe.layoutMaximumZSubvoxels; const std::int64_t Seal=Plan->manifest.recipe.boundarySealSubvoxels; const std::int64_t Zq=ToFixed(Z); - if(Zq>=Bottom&&Zq(1,Zq-Bottom)); - if(Zq<=Top&&Zq>Top-Seal)Density=std::min(Density,-std::max(1,Top-Zq)); - OutDensity=static_cast(static_cast(Density)/Scale); + if(Plan->manifest.recipe.geometryVersion<3) + { + if(Zq>=Bottom&&Zq(1,Zq-Bottom)); + if(Zq<=Top&&Zq>Top-Seal) + Density=std::min(Density,-std::max(1,Top-Zq)); + OutDensity=static_cast(static_cast(Density)/Scale); + } + else + { + OutDensity=static_cast(static_cast(Density)/Scale); + FResolvedStratumBounds Bounds; + if(!MakeResolvedStratumBounds(static_cast(Bottom)/Scale, + static_cast(Top)/Scale,static_cast(Seal)/Scale,Bounds)) + return false; + const FFloatingIslandParams Params=Owner->Manager->GetFloatingIslandParamsForChunk( + FIntVector(0,0,ChunkZ)); + float InternalDensity=-OutDensity; + VF_ApplyUpperBoundarySeal(InternalDensity,Z,static_cast(Bounds.TopZ), + static_cast(Bounds.SealThickness),Params.BaseDensity); + OutDensity=-InternalDensity; + } return std::isfinite(OutDensity); } @@ -2351,19 +2418,23 @@ private: int32 Top=MIN_int32,Bottom=MAX_int32; for(const FStrateSlot& Slot:Layout) { - Top=std::max(Top,Slot.TopChunkZ);Bottom=std::min(Bottom,Slot.BottomChunkZ); + FResolvedStratumBounds Bounds; + if(!GetResolvedStratumBounds(Slot,Bounds))continue; + const int32 ResolvedBottom=FMath::FloorToInt(static_cast(Bounds.BottomZ)); + const int32 ResolvedTop=FMath::CeilToInt(static_cast(Bounds.TopZ)); + Top=std::max(Top,ResolvedTop);Bottom=std::min(Bottom,ResolvedBottom); if(!Slot.Definition)continue; const int32 MidChunkZ=(Slot.TopChunkZ+Slot.BottomChunkZ)/2; FLayerField Field; - Field.Lo=Slot.BottomChunkZ*CHUNK_SIZE; - Field.Hi=(Slot.TopChunkZ+1)*CHUNK_SIZE; + Field.Lo=ResolvedBottom; + Field.Hi=ResolvedTop; Field.StrateIndex=Slot.StrateIndex; Field.Params=Owner->Manager->GetGenerationParams(FIntVector(0,0,MidChunkZ)); LayerFields.push_back(std::move(Field)); } if(Top>=Bottom) { - LayerRanges.push_back({Bottom*CHUNK_SIZE,(Top+1)*CHUNK_SIZE}); + LayerRanges.push_back({Bottom,Top}); } } diff --git a/Standalone/Core/src/VoxelForgeCore.cpp b/Standalone/Core/src/VoxelForgeCore.cpp index 1952e96..0ff684e 100644 --- a/Standalone/Core/src/VoxelForgeCore.cpp +++ b/Standalone/Core/src/VoxelForgeCore.cpp @@ -2204,6 +2204,8 @@ namespace VoxelForgeCore out.diagnostics.horizonGroundTrianglesRemoved=GroundStats.RemovedTriangles; out.diagnostics.horizonCapTriangles=CapStats.Triangles; } + if(impl_->worldAssembly&&!bOverlapsPlayerEdit) + AppendStratumBoundaryCeilings(world,farShape,nativeKey,step,mesh); out.densitySampleCount=static_cast(std::max(0,sampleCount)); if(bHasWorldAssembly) diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/BuildResources.md b/Standalone/Research/WorldAssemblerM3/Linux18/BuildResources.md new file mode 100644 index 0000000..5371e96 --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/BuildResources.md @@ -0,0 +1,9 @@ +# L18 build resources + +Limits: CPUs 0–11, `-j12`, normal priority, 6 GiB address-space cap. Governor stayed `powersave`. +These are the final builds after the cell-coverage and owner ceiling corrections. + +- Clang 19, `-ffp-contract=off`: exit 0, 31.689 s, peak process RSS 436,088 KiB, peak VMS 586,240 KiB. +- GCC 14, default FP contraction: exit 0, 48.648 s, peak process RSS 903,168 KiB, peak VMS 1,014,716 KiB. +- Largest measured runtime process was the final Clang gate run at 897,276 KiB RSS. The determinism matrix peaked at 603,172 KiB and the crossing matrix at 548,664 KiB. +- An earlier GCC build was interrupted by owner steering before producing a binary; the final GCC build above completed successfully. diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/CaptureLinux18.py b/Standalone/Research/WorldAssemblerM3/Linux18/CaptureLinux18.py new file mode 100644 index 0000000..53cd38e --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/CaptureLinux18.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +"""Render the matched L18 review views as small readable JPEGs.""" +import os +import subprocess +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[4] +CAPTURE = ROOT / "Standalone/bin/linux/VoxelForgeOffscreenCapture-linux18-clang" +EXPORTS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux18/exports" +OUT = ROOT / "Standalone/Research/WorldAssemblerM3/Linux18/captures" +LOGS = ROOT / "Saved/Linux" +OUT.mkdir(parents=True, exist_ok=True) +env = os.environ.copy() +env["LP_NUM_THREADS"] = "12" +env["XDG_CACHE_HOME"] = str(ROOT / "Saved/Linux/mesa-cache") + +views = [ + ("floating-islands-flat-square-after", "floating-islands-flat-square.vfmesh", + (-11.612444, -118.221237, -19.8452), 0, 0, True), + ("floating-islands-flat-square-no-edges", "floating-islands-flat-square.vfmesh", + (-11.612444, -118.221237, -19.8452), 0, 0, False), + ("floating-islands-island-view-after", "floating-islands-island-view.vfmesh", + (-22, -19, -22.8), 0, -4, True), + ("floating-islands-ceiling-up", "floating-islands-island-view.vfmesh", + (-22, -19, -22.8), 0, 80, True), + ("surface-world-l1-spawn-after", "surface-world-l1-spawn.vfmesh", + (0, -35, -487.94), 0, -22, False), + ("surface-world-horizon-after", "surface-world-l1-spawn.vfmesh", + (0, -35, -487.94), 0, 0, False), +] + +for name, scene_name, camera, yaw, pitch, tile_edges in views: + scene = EXPORTS / scene_name + png = LOGS / f"l18-{name}.png" + jpg = OUT / f"{name}.jpg" + render_log = LOGS / f"l18-{name}-render.log" + convert_log = LOGS / f"l18-{name}-jpeg.log" + command = [str(CAPTURE), str(scene), str(png), "--size=1600x900", + "--shade=readable", f"--tile-edges={'on' if tile_edges else 'off'}", + "--tile-edge-width-m=0.15", "--camera-m="+",".join(map(str, camera)), + f"--yaw-deg={yaw}", f"--pitch-deg={pitch}"] + with render_log.open("w", encoding="utf-8") as stream: + subprocess.run(command, cwd=ROOT, env=env, stdout=stream, + stderr=subprocess.STDOUT, check=True) + ffmpeg = ["ffmpeg", "-nostdin", "-hide_banner", "-loglevel", "error", "-y", + "-i", str(png), "-frames:v", "1", "-q:v", "4", str(jpg)] + with convert_log.open("w", encoding="utf-8") as stream: + subprocess.run(ffmpeg, cwd=ROOT, env=env, stdout=stream, + stderr=subprocess.STDOUT, check=True) + if jpg.stat().st_size > 300_000: + raise SystemExit(f"{jpg.name} exceeds the 300 KB review limit") + print(f"[Capture] {jpg.relative_to(ROOT)} bytes={jpg.stat().st_size} status=PASS") diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/CeilingContinuity.py b/Standalone/Research/WorldAssemblerM3/Linux18/CeilingContinuity.py new file mode 100644 index 0000000..bf9ba7f --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/CeilingContinuity.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +"""Audit the emitted FloatingIslands roof faces and same-LOD tile-edge continuity.""" +import array +import collections +import math +import struct +import sys + + +def read_exact(stream, size): + data = stream.read(size) + if len(data) != size: + raise EOFError(f"wanted {size} bytes, got {len(data)}") + return data + + +def height_at(triangles, x, y, preferred_z): + best = None + for (x0, y0, z0), (x1, y1, z1), (x2, y2, z2) in triangles: + den = (y1-y2)*(x0-x2)+(x2-x1)*(y0-y2) + if abs(den) < 1.0e-10: + continue + a = ((y1-y2)*(x-x2)+(x2-x1)*(y-y2))/den + b = ((y2-y0)*(x-x2)+(x0-x2)*(y-y2))/den + c = 1.0-a-b + if min(a,b,c) >= -1.0e-5: + z = a*z0+b*z1+c*z2 + if best is None or abs(z-preferred_z) < abs(best-preferred_z): + best = z + return best + + +def quantile(values, fraction): + if not values: + return math.nan + ordered = sorted(values) + return ordered[math.floor(fraction*(len(ordered)-1))] + + +if len(sys.argv) != 3: + raise SystemExit("usage: CeilingContinuity.py scene.vfmesh expected-cap-plane-metres") +scene_path = sys.argv[1] +root_z = float(sys.argv[2]) +tiles = {} +voxel_size_m = None +with open(scene_path, "rb") as stream: + if read_exact(stream, 8) != b"VFMSH001": + raise SystemExit("invalid VFMSH001 scene") + version, voxel_um, tile_count = struct.unpack("<3I", read_exact(stream, 12)) + camera = struct.unpack("<3d", read_exact(stream, 24)) + yaw, pitch = struct.unpack("<2d", read_exact(stream, 16)) + voxel_size_m = voxel_um/1_000_000.0 + for _ in range(tile_count): + key = struct.unpack("<4i", read_exact(stream, 16)) + surface_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack( + "<5I", read_exact(stream, 20)) + positions = array.array("f") + positions.frombytes(read_exact(stream, vertex_count*12)) + normals = array.array("f") + normals.frombytes(read_exact(stream, vertex_count*12)) + indices = array.array("I") + indices.frombytes(read_exact(stream, index_count*4)) + masks = read_exact(stream, mask_count) + if sys.byteorder != "little": + positions.byteswap() + normals.byteswap() + indices.byteswap() + extent = 32*(1 << key[3])*voxel_size_m + z0, z1 = key[2]*extent, (key[2]+1)*extent + ceiling = [] + for triangle in range(index_count//3): + if masks and masks[triangle] != 0: + continue + a,b,c = indices[triangle*3:triangle*3+3] + if max(a,b,c) >= surface_vertices: + continue + nz = (normals[a*3+2]+normals[b*3+2]+normals[c*3+2])/3.0 + if nz > -0.65: + continue + points = tuple((positions[v*3],positions[v*3+1],positions[v*3+2]) + for v in (a,b,c)) + center_z = sum(point[2] for point in points)/3.0 + if abs(center_z-root_z) <= 1.0: + ceiling.append(points) + tiles[key] = { + "extent": extent, "x0": key[0]*extent, "y0": key[1]*extent, + "x1": (key[0]+1)*extent, "y1": (key[1]+1)*extent, + "z0": z0, "z1": z1, "ceiling": ceiling, + } + +by_lod = collections.defaultdict(dict) +for key, tile in tiles.items(): + if tile["z0"] <= root_z+1.0 and tile["z1"] >= root_z-1.0: + by_lod[key[3]][key] = tile + +print(f"scene={scene_path} version={version} voxel_um={voxel_um} tiles={tile_count} " + f"camera_m={camera} yaw={yaw} pitch={pitch} expected_cap_m={root_z:.9f}") +print("lod zband_tiles cap_tiles missing_tiles cap_triangles face_z_m_p05/median/p95 " + "tile_samples hit_samples max_abs_root_delta_cm shared_edges shared_hits edge_gaps " + "edge_delta_cm_median/p95/max") +all_pass = True +for lod in range(9): + target = by_lod[lod] + cap_tiles = {key: tile for key,tile in target.items() if tile["ceiling"]} + face_z = [point[2] for tile in cap_tiles.values() for tri in tile["ceiling"] + for point in tri] + deltas = [] + sample_count = 0 + hit_count = 0 + for key,tile in target.items(): + if not tile["ceiling"]: + continue + for iy in range(16): + for ix in range(16): + x = tile["x0"]+(ix+0.5)*tile["extent"]/16 + y = tile["y0"]+(iy+0.5)*tile["extent"]/16 + sample_count += 1 + height = height_at(tile["ceiling"],x,y,root_z) + if height is not None: + hit_count += 1 + deltas.append(abs(height-root_z)*100.0) + + edge_deltas = [] + edge_count = 0 + edge_gaps = 0 + for key,a in cap_tiles.items(): + x,y,z,level = key + for neighbor_key,axis in (((x+1,y,z,level),"x"),((x,y+1,z,level),"y")): + b = cap_tiles.get(neighbor_key) + if b is None: + continue + edge_count += 1 + epsilon = min(0.02,a["extent"]*1.0e-4) + matched = 0 + for index in range(33): + t = (index+0.5)/33 + if axis == "x": + fixed = a["x1"] + varying = a["y0"]+(a["y1"]-a["y0"])*t + za = height_at(a["ceiling"],fixed-epsilon,varying,root_z) + zb = height_at(b["ceiling"],fixed+epsilon,varying,root_z) + else: + fixed = a["y1"] + varying = a["x0"]+(a["x1"]-a["x0"])*t + za = height_at(a["ceiling"],varying,fixed-epsilon,root_z) + zb = height_at(b["ceiling"],varying,fixed+epsilon,root_z) + if za is not None and zb is not None: + edge_deltas.append(abs(za-zb)*100.0) + matched += 1 + if matched == 0: + edge_gaps += 1 + missing = len(target)-len(cap_tiles) + max_root = max(deltas) if deltas else math.nan + print(f"{lod} {len(target)} {len(cap_tiles)} {missing} " + f"{sum(len(tile['ceiling']) for tile in cap_tiles.values())} " + f"{quantile(face_z,.05):.6f}/{quantile(face_z,.5):.6f}/{quantile(face_z,.95):.6f} " + f"{sample_count} {hit_count} {max_root:.3f} {edge_count} {len(edge_deltas)} " + f"{edge_gaps} {quantile(edge_deltas,.5):.3f}/{quantile(edge_deltas,.95):.3f}/" + f"{max(edge_deltas) if edge_deltas else math.nan:.3f}") + if lod >= 4 and target and (missing or hit_count != sample_count or edge_gaps): + all_pass = False +print(f"[CeilingContinuity] result={'PASS' if all_pass else 'FAIL'} " + "criteria=LOD4-8 requested z-band tiles emit an upper-boundary ceiling; 16x16 ray samples hit; " + "shared same-LOD tile edges have paired hits") +raise SystemExit(0 if all_pass else 1) diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/CheckCrossingHashes.py b/Standalone/Research/WorldAssemblerM3/Linux18/CheckCrossingHashes.py new file mode 100644 index 0000000..51e13e4 --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/CheckCrossingHashes.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +"""Compare all L18 crossing configurations to the L14 24 m crossing hashes.""" +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[4] +RUNS = ROOT / "Saved/Linux/l18-crossing" +PATTERN = re.compile( + r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M) +failed = [] +logs = sorted(RUNS.glob("*-w*-r*.log")) +for path in logs: + parts = path.stem.split("-") + compiler = parts[0] + reference_compiler = "clang" if compiler == "clang" else "gcc" + reference_path = ROOT / f"Saved/Linux/l14-final-crossing-24m-{reference_compiler}-w12.log" + expected = PATTERN.findall(reference_path.read_text(encoding="utf-8")) + actual = PATTERN.findall(path.read_text(encoding="utf-8", errors="replace")) + if actual != expected: + failed.append(path.name) + print(f"[CrossingReferenceMismatch] {path.name} expected_rows={len(expected)} " + f"actual_rows={len(actual)}") +print(f"[CrossingSurfaceHashGate] reference=L14-final-crossing-24m-W12 rows={len(logs)} " + f"result={'FAIL' if failed else 'PASS'}") +raise SystemExit(1 if failed or len(logs) != 14 else 0) diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/CheckSurfaceHashes.py b/Standalone/Research/WorldAssemblerM3/Linux18/CheckSurfaceHashes.py new file mode 100644 index 0000000..82f5708 --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/CheckSurfaceHashes.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +"""Compare every L18 SurfaceWorld matrix hash row with the approved L14 reference.""" +import re +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[4] +RUNS = ROOT / "Saved/Linux/l18-matrix" +REFERENCE = ROOT / "Saved/Linux/l14-final-hash-sw-clang-off-w12-r5.log" +PATTERN = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M) +expected = PATTERN.findall(REFERENCE.read_text(encoding="utf-8")) +if not expected or len(expected) != 12: + raise SystemExit(f"invalid L14 reference hash rows: {len(expected)}") +logs = sorted(RUNS.glob("surface-world-*.log")) +if len(logs) != 14: + raise SystemExit(f"expected 14 SurfaceWorld matrix logs, found {len(logs)}") +failed = [] +for path in logs: + actual = PATTERN.findall(path.read_text(encoding="utf-8", errors="replace")) + if actual != expected: + failed.append(path.name) + print(f"[SurfaceHashMismatch] {path.name} expected={len(expected)} actual={len(actual)}") +print(f"[SurfaceHashGate] reference={REFERENCE.name} rows={len(logs)} expected_rows=14 " + f"result={'FAIL' if failed else 'PASS'}") +raise SystemExit(1 if failed else 0) diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/FloatingIslandDensityProbe.cpp b/Standalone/Research/WorldAssemblerM3/Linux18/FloatingIslandDensityProbe.cpp new file mode 100644 index 0000000..60b761b --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/FloatingIslandDensityProbe.cpp @@ -0,0 +1,149 @@ +#include "Json.h" +#include "OwnerWorldLoader.h" +#include "StandaloneCoreScheduler.h" +#include "WorldAssemblyPrototype.h" +#include "StandaloneSnapshotAdapter.h" + +#include +#include +#include +#include +#include +#include + +namespace +{ + constexpr double CoreVoxelsPerMeter=4.0; + constexpr std::int64_t SubvoxelsPerCoreVoxel= + VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel; + + void PrintDensity(VoxelForgeCore::World& World,const char* Label,double X,double Y,double Z) + { + const VoxelForgeCore::Vec3d Point{X*CoreVoxelsPerMeter,Y*CoreVoxelsPerMeter, + Z*CoreVoxelsPerMeter}; + const double Density=World.densityAt(Point); + const double Raw=World.unclampedDensityAt(Point); + std::printf("[DensitySample] label=%s xyz_m=%.6f,%.6f,%.6f density_core_vox=%.9f " + "density_cm=%.4f unclamped_core_vox=%.9f sign=%s\n",Label,X,Y,Z,Density, + Density*25.0,Raw,Density<0.0?"solid":"air"); + } + + void PrintCrossing(VoxelForgeCore::World& World,const char* Label,double X,double Y, + double BottomM,double TopM) + { + const auto DensityAt=[&](double Z) + { + return World.densityAt({X*CoreVoxelsPerMeter,Y*CoreVoxelsPerMeter, + Z*CoreVoxelsPerMeter}); + }; + double Lo=BottomM,Hi=TopM; + double LoDensity=DensityAt(Lo),HiDensity=DensityAt(Hi); + if((LoDensity<0.0)==(HiDensity<0.0)) + { + std::printf("[DensityCrossing] label=%s bracket_m=%.6f..%.6f signs=%s/%s result=none\n", + Label,Lo,Hi,LoDensity<0.0?"solid":"air",HiDensity<0.0?"solid":"air"); + return; + } + for(int Iteration=0;Iteration<64;++Iteration) + { + const double Mid=(Lo+Hi)*0.5; + const double MidDensity=DensityAt(Mid); + if((MidDensity<0.0)==(LoDensity<0.0)) + {Lo=Mid;LoDensity=MidDensity;} + else + {Hi=Mid;HiDensity=MidDensity;} + } + std::printf("[DensityCrossing] label=%s z_m=%.9f bracket_m=%.6f..%.6f " + "density_core_vox=%.9f/%.9f\n",Label,(Lo+Hi)*0.5,BottomM,TopM, + LoDensity,HiDensity); + } +} + +int main(int argc,char** argv) +{ + if(argc!=2) + { + std::fprintf(stderr,"usage: %s owner-world.json\n",argv[0]); + return 2; + } + VFJson::Value Root; + std::string Error; + { + std::ifstream Input(argv[1],std::ios::binary); + if(!Input){std::fprintf(stderr,"owner JSON open failed\n");return 2;} + std::string Text{std::istreambuf_iterator(Input),std::istreambuf_iterator{}}; + if(!VFJson::Parser(std::move(Text)).Parse(Root,Error)) + {std::fprintf(stderr,"owner JSON parse failed: %s\n",Error.c_str());return 2;} + } + if(!StandaloneWorldAssemblyPrototype::SelectTopStrateAsFloatingIslands(Root,Error)) + {std::fprintf(stderr,"FI selection failed: %s\n",Error.c_str());return 2;} + auto Owner=std::make_shared(); + if(!StandaloneOwnerLoader::Resolve(Root,*Owner,Error)) + {std::fprintf(stderr,"owner resolve failed: %s\n",Error.c_str());return 2;} + VoxelForgeCore::WorldAssemblyManifest Assembly; + if(!StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype( + *Owner,Root,Error,{},&Assembly) + ||!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly( + *Owner,Root,Assembly,Error)) + {std::fprintf(stderr,"plan construction failed: %s\n",Error.c_str());return 2;} + auto Snapshot=VoxelForgeCore::MakeStandaloneSnapshotFromParsedJson(Root,Owner->Seed,3,8, + false,false,Error); + if(!Snapshot) + {std::fprintf(stderr,"snapshot resolve failed: %s\n",Error.c_str());return 2;} + const auto* ResolvedAssembly=Snapshot.worldAssembly(); + if(!ResolvedAssembly||ResolvedAssembly->floatingIslands.empty()) + {std::fprintf(stderr,"resolved FloatingIslands plan missing\n");return 2;} + + VoxelForgeCore::World World(std::move(Snapshot)); + VoxelForgeCore::ShapeBuildRequest Request; + Request.minVoxel={-96,-512,-288}; + Request.maxVoxel={96,96,64}; + Request.clipMinVoxel=Request.minVoxel; + Request.clipMaxVoxel=Request.maxVoxel; + Request.workerLimit=12; + Request.includeFarWorld=false; + FStandaloneCoreScheduler Scheduler; + if(!World.compile(Request,Scheduler,Error)) + {std::fprintf(stderr,"shape compile failed: %s\n",Error.c_str());return 2;} + + const auto& Plan=ResolvedAssembly->floatingIslands.front(); + const auto& Recipe=Plan.manifest.recipe; + std::printf("[FloatingIslandBounds] geometry_version=%u owner_voxel_um=%u core_voxel_um=%u " + "owner_to_core=%u/%u chunks=%d..%d layout_z_m=%.6f..%.6f ceiling_start_m=%.6f " + "seal_m=%.6f bottom_cap=%s\n",Recipe.geometryVersion,Recipe.ownerVoxelSizeMicrons, + Recipe.coreVoxelSizeMicrons,Recipe.ownerToCoreScaleNumerator, + Recipe.ownerToCoreScaleDenominator,Plan.topChunkZ,Plan.bottomChunkZ, + static_cast(Recipe.layoutMinimumZSubvoxels)/SubvoxelsPerCoreVoxel/4.0, + static_cast(Recipe.layoutMaximumZSubvoxels)/SubvoxelsPerCoreVoxel/4.0, + static_cast(Recipe.layoutMaximumZSubvoxels-Recipe.boundarySealSubvoxels) + /SubvoxelsPerCoreVoxel/4.0, + static_cast(Recipe.boundarySealSubvoxels)/SubvoxelsPerCoreVoxel/4.0, + Recipe.geometryVersion<3?"legacy":"removed"); + std::printf("[DensityProbe] flat_square_xy_m=-11.612444,-118.221237 " + "compiled=%d core_voxel_size_cm=25\n",World.isCompiled()?1:0); + constexpr double X=-11.612443923950195; + constexpr double Y=-118.22123718261719; + for(double Z:{2.75,2.99,3.00,3.01,3.25,3.49,3.50,3.51,3.75,3.99,4.00,4.01, + 4.05,4.125,4.25,4.50,5.00, + 7.75,8.00,8.25,-60.25,-60.00,-59.75,-59.50,-59.25}) + PrintDensity(World,"flat-square",X,Y,Z); + PrintCrossing(World,"shared-upper-ceiling",X,Y,3.50,3.75); + PrintCrossing(World,"upper-boundary-cap",X,Y,4.00,4.25); + PrintCrossing(World,"old-eight-metre-wrapper",X,Y,7.75,8.25); + PrintCrossing(World,"removed-lower-boundary-seal",X,Y,-60.25,-59.75); + for(const auto& Probe:std::array,3>{{ + {{-66.3,-38.7}},{{-62.3,-54.6}},{{-53.34,-22.84}}}}) + { + std::printf("[DensityProbeXY] xy_m=%.3f,%.3f\n",Probe[0],Probe[1]); + for(double Z:{3.49,3.50,3.51,3.75,3.875,3.99,4.00,4.01,4.05,4.125}) + PrintDensity(World,"boundary-ray",Probe[0],Probe[1],Z); + PrintCrossing(World,"boundary-ray",Probe[0],Probe[1],3.49,4.125); + } + for(const auto& Probe:std::array,4>{{ + {{-67.0,-39.0}},{{-66.0,-39.0}},{{-67.0,-38.0}},{{-66.0,-38.0}}}}) + { + PrintDensity(World,"boundary-grid-node",Probe[0],Probe[1],3.875); + PrintDensity(World,"boundary-grid-node",Probe[0],Probe[1],4.125); + } + return 0; +} diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/MeasureBuild.py b/Standalone/Research/WorldAssemblerM3/Linux18/MeasureBuild.py new file mode 100644 index 0000000..a1b28e3 --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/MeasureBuild.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""Measure peak per-process RSS for a build process tree under the L17 limits.""" +import os +import subprocess +import sys +import time +from pathlib import Path + + +def descendants(root): + pending = [root] + seen = set() + while pending: + pid = pending.pop() + if pid in seen: + continue + seen.add(pid) + try: + children = Path(f"/proc/{pid}/task/{pid}/children").read_text().split() + pending.extend(int(child) for child in children) + except (FileNotFoundError, PermissionError, ProcessLookupError): + pass + return seen + + +def status(pid): + try: + fields = {} + for line in Path(f"/proc/{pid}/status").read_text().splitlines(): + if line.startswith(("Name:", "VmRSS:", "VmSize:")): + key, *value = line.split() + fields[key[:-1]] = value[0] if value else "" + return (int(fields.get("VmRSS", "0")), int(fields.get("VmSize", "0")), + fields.get("Name", "")) + except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError): + return None + + +if len(sys.argv) < 2: + raise SystemExit("usage: MeasureBuild.py command [arguments ...]") +if not os.sched_getaffinity(0).issubset(set(range(12))): + raise SystemExit("run under taskset -c 0-11") + +started = time.monotonic() +process = subprocess.Popen(sys.argv[1:], start_new_session=True) +peak_rss = (0, 0, "") +peak_vms = (0, 0, "") +while process.poll() is None: + for pid in descendants(process.pid): + measured = status(pid) + if measured is None: + continue + rss, vms, name = measured + if rss > peak_rss[0]: + peak_rss = (rss, pid, name) + if vms > peak_vms[0]: + peak_vms = (vms, pid, name) + time.sleep(0.1) + +exit_code = process.wait() +elapsed = time.monotonic() - started +print(f"[BuildTreeResources] exit_code={exit_code} wall_s={elapsed:.3f} " + f"peak_process_rss_kib={peak_rss[0]} peak_rss_pid={peak_rss[1]} " + f"peak_rss_name={peak_rss[2]} peak_process_vms_kib={peak_vms[0]} " + f"peak_vms_pid={peak_vms[1]} peak_vms_name={peak_vms[2]} " + "monitor_interval_s=0.1", flush=True) +raise SystemExit(exit_code) diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/MeshProbe.py b/Standalone/Research/WorldAssemblerM3/Linux18/MeshProbe.py new file mode 100644 index 0000000..414062b --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/MeshProbe.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +"""Summarize exported tile geometry and upward-facing ground for L17.""" +import array +import collections +import math +import struct +import sys + + +def read_exact(stream, size): + data = stream.read(size) + if len(data) != size: + raise EOFError(f"wanted {size} bytes, got {len(data)}") + return data + + +path = sys.argv[1] +with open(path, "rb") as stream: + if read_exact(stream, 8) != b"VFMSH001": + raise SystemExit("bad VFMSH001 header") + version, voxel_um, tile_count = struct.unpack("<3I", read_exact(stream, 12)) + camera = struct.unpack("<3d", read_exact(stream, 24)) + yaw, pitch = struct.unpack("<2d", read_exact(stream, 16)) + per_lod = collections.defaultdict(lambda: {"tiles": 0, "vertices": 0, + "triangles": 0, "surface_triangles": 0, "up_triangles": 0, + "up_centroids": [], "tile_spans": [], "empty": 0}) + tile_rows = [] + for _ in range(tile_count): + key = struct.unpack("<4i", read_exact(stream, 16)) + surf_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack( + "<5I", read_exact(stream, 20)) + p = array.array("f") + p.frombytes(read_exact(stream, vertex_count * 12)) + n = array.array("f") + n.frombytes(read_exact(stream, vertex_count * 12)) + if sys.byteorder != "little": + p.byteswap(); n.byteswap() + indices = array.array("I") + indices.frombytes(read_exact(stream, index_count * 4)) + masks = read_exact(stream, mask_count) + if sys.byteorder != "little": + indices.byteswap() + lod = key[3] + row = per_lod[lod] + row["tiles"] += 1 + row["vertices"] += vertex_count + row["triangles"] += index_count // 3 + row["surface_triangles"] += index_count // 3 - skirt_count + up = [] + for tri in range(index_count // 3): + if masks and masks[tri] != 0: + continue + a, b, c = indices[tri * 3:tri * 3 + 3] + if max(a, b, c) >= surf_vertices: + continue + if (n[a * 3 + 2] + n[b * 3 + 2] + n[c * 3 + 2]) / 3.0 < 0.65: + continue + up.append((p[a * 3 + 2] + p[b * 3 + 2] + p[c * 3 + 2]) / 3.0) + row["up_triangles"] += len(up) + row["up_centroids"].extend(up) + if up: + up.sort() + span = up[math.floor(0.95 * (len(up) - 1))] - up[math.floor(0.05 * (len(up) - 1))] + row["tile_spans"].append(span) + tile_rows.append((key, vertex_count, index_count // 3, skirt_count, + len(up), up[0], up[len(up) // 2], up[-1], span)) + else: + row["empty"] += 1 + tile_rows.append((key, vertex_count, index_count // 3, skirt_count, + 0, math.nan, math.nan, math.nan, math.nan)) + +print(f"version={version} voxel_um={voxel_um} tiles={tile_count} camera_m={camera} yaw={yaw} pitch={pitch}") +print("lod tiles mesh_tiles vertices triangles skirt_triangles upward_surface_triangles " + "upward_centroid_z_m_p05/median/p95 tile_up_z_span_m_p50/p95/max") +for lod in sorted(per_lod): + r = per_lod[lod] + z = sorted(r["up_centroids"]) + s = sorted(r["tile_spans"]) + def q(values, fraction): + return values[math.floor(fraction * (len(values) - 1))] if values else math.nan + print(f"{lod} {r['tiles']} {r['tiles']-r['empty']} {r['vertices']} {r['triangles']} " + f"{sum(row[3] for row in tile_rows if row[0][3] == lod)} {r['up_triangles']} " + f"{q(z,.05):.4f}/{q(z,.5):.4f}/{q(z,.95):.4f} " + f"{q(s,.5):.4f}/{q(s,.95):.4f}/{max(s) if s else math.nan:.4f}") + +print("near_camera_up_tiles (sorted by XY tile-centre distance):") +near = [] +for row in tile_rows: + key = row[0] + lod = key[3] + extent = 32 * (1 << lod) * voxel_um / 1_000_000.0 + cx = (key[0] + 0.5) * extent + cy = (key[1] + 0.5) * extent + near.append((math.hypot(cx-camera[0], cy-camera[1]), row)) +for distance, row in sorted(near)[:30]: + key, verts, tris, skirts, ups, lo, med, hi, span = row + if ups: + print(f"key={key} xy_distance_m={distance:.2f} vertices={verts} triangles={tris} " + f"skirt_triangles={skirts} upward_triangles={ups} z_m={lo:.3f}/{med:.3f}/{hi:.3f} " + f"tile_span_p05_p95_m={span:.3f}") diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/ProbeCaptureRays.py b/Standalone/Research/WorldAssemblerM3/Linux18/ProbeCaptureRays.py new file mode 100755 index 0000000..2bfe969 --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/ProbeCaptureRays.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python3 +"""Trace review-image pixels through the exported clipmap mesh.""" +import array +import math +import struct +import sys + + +def read_exact(f, count): + data = f.read(count) + if len(data) != count: + raise EOFError((len(data), count)) + return data + + +def floor_div(n, d): + q, r = divmod(n, d) + return q - (r < 0) + + +def visible_mask(key, desired): + x, y, z, lod = key + extent = 32 << lod + origin = (x * extent, y * extent, z * extent) + mask = 0 + for axis in range(3): + for side in range(2): + probe = [origin[i] + extent // 2 for i in range(3)] + probe[axis] = origin[axis] + (extent if side else -1) + neighbor = None + for level in range(9): + neighbor_extent = 32 << level + coord = tuple(floor_div(probe[i], neighbor_extent) for i in range(3)) + (level,) + if coord in desired: + neighbor = level + break + if neighbor is None or neighbor != lod: + mask |= 1 << (axis * 2 + side) + return mask + + +def ray_box(origin, direction, low, high): + lo, hi = 0.1, 20000.0 + for axis in range(3): + if abs(direction[axis]) < 1e-12: + if origin[axis] < low[axis] or origin[axis] > high[axis]: + return None + else: + a = (low[axis] - origin[axis]) / direction[axis] + b = (high[axis] - origin[axis]) / direction[axis] + if a > b: + a, b = b, a + lo, hi = max(lo, a), min(hi, b) + if lo > hi: + return None + return lo, hi + + +def ray_tri(origin, direction, a, b, c): + e1 = tuple(b[i] - a[i] for i in range(3)) + e2 = tuple(c[i] - a[i] for i in range(3)) + p = (direction[1]*e2[2]-direction[2]*e2[1], + direction[2]*e2[0]-direction[0]*e2[2], + direction[0]*e2[1]-direction[1]*e2[0]) + det = sum(e1[i]*p[i] for i in range(3)) + if abs(det) < 1e-10: + return None + inv = 1.0/det + tvec = tuple(origin[i]-a[i] for i in range(3)) + u = sum(tvec[i]*p[i] for i in range(3))*inv + if u < 0 or u > 1: + return None + q = (tvec[1]*e1[2]-tvec[2]*e1[1], + tvec[2]*e1[0]-tvec[0]*e1[2], + tvec[0]*e1[1]-tvec[1]*e1[0]) + v = sum(direction[i]*q[i] for i in range(3))*inv + if v < 0 or u+v > 1: + return None + t = sum(e2[i]*q[i] for i in range(3))*inv + return t if t >= 0.1 else None + + +if len(sys.argv) < 8 or len(sys.argv) % 2 != 1: + raise SystemExit("usage: ProbeCaptureRays.py scene.vfmesh camX camY camZ yaw pitch pixelX pixelY [pixelX pixelY ...]") +scene_path = sys.argv[1] +cam = tuple(map(float, sys.argv[2:5])) +yaw, pitch = map(math.radians, map(float, sys.argv[5:7])) +pixels = [(int(sys.argv[i]), int(sys.argv[i+1])) for i in range(7, len(sys.argv), 2)] +width, height, fov = 1600, 900, math.radians(90) +tan_h = math.tan(fov/2) +tan_v = tan_h / (width/height) +forward = (math.sin(yaw)*math.cos(pitch), math.cos(yaw)*math.cos(pitch), math.sin(pitch)) +right = (math.cos(yaw), -math.sin(yaw), 0.0) +up = (right[1]*forward[2]-right[2]*forward[1], right[2]*forward[0]-right[0]*forward[2], right[0]*forward[1]-right[1]*forward[0]) + +with open(scene_path, "rb") as f: + if read_exact(f, 8) != b"VFMSH001": + raise SystemExit("bad scene") + version, voxel_um, count = struct.unpack("<3I", read_exact(f, 12)) + scene_cam = struct.unpack("<3d", read_exact(f, 24)) + scene_yaw, scene_pitch = struct.unpack("<2d", read_exact(f, 16)) + voxel_m = voxel_um / 1_000_000.0 + tiles = [] + desired = set() + for _ in range(count): + key = struct.unpack("<4i", read_exact(f, 16)) + surface_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack("<5I", read_exact(f, 20)) + positions = array.array("f"); positions.frombytes(read_exact(f, vertex_count*12)) + normals = array.array("f"); normals.frombytes(read_exact(f, vertex_count*12)) + indices = array.array("I"); indices.frombytes(read_exact(f, index_count*4)) + masks = read_exact(f, mask_count) + if sys.byteorder != "little": + positions.byteswap(); normals.byteswap(); indices.byteswap() + desired.add(key) + tiles.append((key, surface_vertices, skirt_count, positions, normals, indices, masks)) + +print(f"scene={scene_path} tiles={count} camera={cam} yaw={math.degrees(yaw):.3f} pitch={math.degrees(pitch):.3f}") +for px, py in pixels: + nx = 2*px/width - 1 + ny = 1 - 2*py/height + direction0 = tuple(forward[i] + nx*tan_h*right[i] + ny*tan_v*up[i] for i in range(3)) + length = math.sqrt(sum(v*v for v in direction0)) + direction = tuple(v/length for v in direction0) + hits = [] + candidate_tiles = 0 + for key, surface_vertices, skirt_count, positions, normals, indices, masks in tiles: + x,y,z,lod = key + extent = 32*(1<=surface_vertices or ib>=surface_vertices or ic>=surface_vertices)) + hits.sort(key=lambda h:h[0]) + print(f"pixel=({px},{py}) ray={direction} candidate_tiles={candidate_tiles} hits={len(hits)}") + for t,key,tri,m,p,nz,skirt in hits[:12]: + print(f" t={t:.3f}m key={key} tri={tri} mask={m} skirt={skirt} z={p[2]:.3f} normal_z={nz:.3f} xyz=({p[0]:.3f},{p[1]:.3f},{p[2]:.3f})") diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md b/Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md new file mode 100644 index 0000000..bdd42e6 --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/REPORT.md @@ -0,0 +1,132 @@ +# Linux18 — FloatingIslands stratum boundaries + +**Result:** FloatingIslands geometry v3 removes its false lower all-XY seal, keeps the ceiling from the shared upper-boundary seal, and projects missing ceiling cells for every generator. SurfaceWorld hashes match the approved L14 baseline at `8704129` in every checked configuration. + +## Scale in the Unreal route + +`AVoxelWorld::CoreVoxelSizeCm` defaults to 25 cm, and `GetActiveVoxelSizeCm()` resolves the runtime value ([VoxelWorld.h:300](../../../../Source/VoxelForge/Public/VoxelWorld.h), [VoxelWorld.cpp:7495](../../../../Source/VoxelForge/Private/VoxelWorld.cpp)). The adapter writes the resolved size to the snapshot ([VoxelForgeCoreAdapter.cpp:1019](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp)); `AVoxelWorld` imports it with `ResolvedWorldSnapshot::FromJson` ([VoxelWorld.cpp:7597](../../../../Source/VoxelForge/Private/VoxelWorld.cpp), [VoxelForgeCore.cpp:916](../../../../Standalone/Core/src/VoxelForgeCore.cpp)). S1 records this single active size source and the 32-Core-voxel tile rule ([Round5 REPORT.md](../Round5/REPORT.md#1-one-core-voxel-size-source)). + +At the current 25 cm setting, **SurfaceWorld strata use 8 m per slot chunk**: the Unreal surface plan multiplies the slot range by 32 Core voxels ([VoxelForgeCoreAdapter.cpp:280](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp); `CHUNK_SIZE=32` in [VoxelTypes.h:211](../../../../Source/VoxelForge/Public/VoxelTypes.h)). **FloatingIslands uses 4 m per owner-authored chunk**: the adapter’s owner size is `VOXEL_SIZE` ([VoxelForgeCoreAdapter.cpp:33](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp); 12.5 cm in [VoxelTypes.h:213](../../../../Source/VoxelForge/Public/VoxelTypes.h)), and its plan multiplies 32 owner voxels by the serialized owner/Core ratio, currently 12.5/25 = 1/2, or 16 Core voxels ([VoxelForgeCoreAdapter.cpp:441](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp)). For chunks 0…−15 that gives z bounds −60…+4 m. This is the two explicit coordinate conventions in the game route, not a global change from 8 m to 4 m. + +Standalone uses the same owner/Core ratio and chunk formula ([OwnerWorldLoader.h:302](../../../../Standalone/Source/OwnerWorldLoader.h), [WorldAssemblyPrototype.h:488](../../../../Standalone/Source/WorldAssemblyPrototype.h)); no current Unreal/standalone scale disagreement was found. L18 also removed the standalone-only two-Core-voxel bounds inset so recipe bounds match the Unreal plan. The owner decides whether either authored scale changes. + +## Fix and ceiling + +Geometry version 3 preserves the island shapes and removes only the lower all-XY seal. The upper seal calls the shared `VF_ApplyUpperBoundarySeal` density primitive; the shared two-sided seal uses the same upper-band math ([VoxelDensityPrimitives.h:44](../../../../Source/VoxelForge/Public/VoxelDensityPrimitives.h)). Resolved bounds come from each strate’s own range. The shared `AppendStratumBoundaryCeilings` mesh path runs for every generator and LOD, adding a plane at the resolved upper boundary where the mesh lacks coverage. It suppresses an existing plane only when nine probes show full cell coverage ([ShapeWorldInternal.h:36](../../../../Standalone/Core/src/ShapeWorldInternal.h), [FarShellsInternal.h:894](../../../../Standalone/Core/src/FarShellsInternal.h), [VoxelForgeCore.cpp:2207](../../../../Standalone/Core/src/VoxelForgeCore.cpp)). The underside normal points into the room, so the existing material lighting renders the interior face. This adds no FloatingIslands-specific height. + +For the captured FloatingIslands strate, the upper bound is **z=+4 m** and its configured 0.5 m seal gives an interior-facing ceiling surface beginning around **z=+3.5 m**. The density probe crosses into the seal at 3.5 m and exits at z=4.019 m; z=7.75, 8.0, and 8.25 m remain air with no crossing. The lower all-XY seal is removed; remaining geometry below −60 m belongs to the lower world and is visible in the ray traces. Thus the apparent 3.5 m “floor” is the retained ceiling when viewed from inside; the 8 m floor is absent. No chunk size changed. + +The owner’s decision and version-3 recipe say an underground strate has a ceiling at its configured upper boundary. “Farther to breathe” comes from a taller configured range. I updated the stale architecture-table wording “open void” to say the islands sit beneath the shared ceiling. + +## Ceiling continuity + +The final audit used 16×16 interior samples per tile and paired samples along same-LOD tile edges. Far LODs pass continuously: + +| LOD | Tiles with cap | Interior hits | Max root delta | Edge gaps | +|---:|---:|---:|---:|---:| +| 4 | 48/48 | 12,288/12,288 | 0 cm | 0 | +| 5 | 48/48 | 12,288/12,288 | 0 cm | 0 | +| 6 | 48/48 | 12,288/12,288 | 0 cm | 0 | +| 7 | 48/48 | 12,288/12,288 | 0 cm | 0 | +| 8 | 153/153 | 39,168/39,168 | 0 cm | 0 | + +LOD0, 2, and 3 also hit all tested samples. LOD1 missed 3 of 12,288 interior samples (0.387 cm maximum root delta) and had no shared-edge gaps. The readable upward view is `captures/floating-islands-ceiling-up.jpg`. + +## Dark tile-aligned patches + +They are lower SurfaceWorld triangles visible below the removed false lower cap, not empty rays and not a viewer dark-square overlay. Traces in the final island export found: + +- Pixel (700,720): first hit at 104.924 m on non-skirt LOD2 tile `(-2,2,-2,2)`, z=−62.925 m, normal-z 0.266; another LOD2 tile hits z=−69.942 m. +- Pixel (1050,650): first hit at 168.051 m on non-skirt LOD3 tile `(0,2,-2,3)`, z=−72.594 m, normal-z 0.895; lower LOD4 geometry is also hit at z=−112.229 m and −120 m. + +The ring probe measures real LOD height steps on those lower surfaces. I left them visible: suppressing those triangles would hide valid lower-stratum geometry, while changing the lower strata or SurfaceWorld would exceed this local fix. The sampled rectangles are not missing tiles or floor holes. + +## Cross-LOD ring steps + +Entries are median / p95 / maximum absolute edge-height difference in centimetres, then gap count. The L18 column is the final matched island camera. The large remaining steps are lower-stratum terrain, not the upper ceiling. + +| LOD edge | L17 before | L17 after | L18 final | +|---|---:|---:|---:| +| 0→1 | 3.451 / 8.920 / 449.158; 14 | —; 0 samples | —; 0 samples | +| 1→2 | 26.642 / 148.262 / 149.862; 0 | 0 / 0 / 0; 0 | 147.141 / 148.403 / 149.862; 0 | +| 2→3 | 0.134 / 198.730 / 773.318; 8 | 0 / 0 / 0; 0 | 128.603 / 200.789 / 773.318; 8 | +| 3→4 | 3.269 / 47.875 / 188.531; 27 | 0 / 0 / 0; 0 | 3.269 / 47.774 / 188.531; 27 | +| 4→5 | 29.975 / 130.496 / 445.444; 6 | 0 / 0 / 30.957; 1 | 29.992 / 124.373 / 443.482; 6 | +| 5→6 | 12.234 / 127.224 / 536.573; 32 | 12.234 / 127.224 / 536.573; 32 | 12.234 / 127.224 / 536.573; 21 | +| 6→7 | 29.013 / 301.752 / 42,624.479; 0 | 28.892 / 291.861 / 945.477; 0 | 29.013 / 301.752 / 42,624.479; 0 | +| 7→8 | 83.843 / 1,225.416 / 3,755.407; 32 | 83.843 / 1,225.416 / 3,755.407; 0 | 83.843 / 1,225.416 / 3,755.407; 0 | + +## SurfaceWorld regression hashes + +The 14-run check compared each final output to `Saved/Linux/l14-final-hash-sw-clang-off-w12-r5.log` from the L14/`8704129` baseline: Clang `-ffp-contract=off` and GCC default, W1/W8/W12, with five W12 repeats. All 14 matched the whole-view, full-detail, LOD0–8, and exact-query rows. The 24 m crossing check likewise passed all 14 compiler/worker configurations against their L14 compiler-specific references. + +Whole view D/M/P/T: `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724`. + +Full detail D/M/P/T: `0ee0579bd15cbbe4 / 32e5d4964d610fee / 1932b96ee4b1d910 / 69743c6bad3447dc`. + +| LOD | Density | Mesh | Payload | Topology | +|---:|---|---|---|---| +| 0 | `769f2a706d585a72` | `33eeeb39fa443816` | `645621a1d968983f` | `c2457ed905036c9d` | +| 1 | `69cc5a5c0a2c60af` | `b48335f5410c57d5` | `d15c5480162ab8ba` | `feca1bd025823604` | +| 2 | `85deed5683a77202` | `53469895987aeea2` | `e55f8ae7e1532033` | `d5feb12a0e85c09b` | +| 3 | `6518caefb3be7e7f` | `ec513c90b853a614` | `f62fa1137ff17f82` | `ccf1dcf681965816` | +| 4 | `62d4be96021992f4` | `f1e4c6efcc2615a9` | `9dc5f9c88be02f33` | `fe6f55125a07c3bf` | +| 5 | `5e4a8c38b8cea6fc` | `08ee56998aaf21e5` | `541eea8558f26cc8` | `6539374a8b3336d8` | +| 6 | `e036e95b9006945b` | `624a33f941a99b02` | `81b73e14f68bdf86` | `4de4c63ce1f80a56` | +| 7 | `8ee358af56a30d8d` | `46ab3c6184048b7c` | `0a6164b7e68e80c5` | `0c26b85bb03bc831` | +| 8 | `c3458e1cbdb9c471` | `46c03d0994d75192` | `8f89fc5bde12d230` | `d16dc0cf62031898` | + +Exact query: 9 probes; density/unclamped `e4d4a8eb95b35933`, detail `efcba20c0c70c415`, collision `e604823a249029bf`. + +The 24 m crossing W12×5 hashes match those same aggregate whole-view, full-detail, and exact-query values on both compiler references; the full check compared all 12 rows per run. + +FloatingIslands’ representative W12×5 whole-view D/M/P/T is `ca7f375cded78f1d / da003331c554f8f3 / 0d2e74862b4ee500 / b7a7177af8915a21`; full-detail is `fc71abf85f5b9373 / e139b32d42ecfa29 / 28a2414e41de59bd / d61ca68ca64f74ca`. Exact query is `4ef614485815ee30` density/unclamped, `efcba20c0c70c415` detail, `e604823a249029bf` collision. Clang and GCC representative hashes agree, and all nine LOD rows stayed stable across the 28-run matrix. + +## Other invariants and Unreal edits + +- Final matrix: 28/28 rows passed; repeated runs were stable within each compiler. Route parity had 0 mismatches across 782,026 FI and 910,651 SurfaceWorld exact samples. Proof audits had 0 violations: FI 9,048 blocks / 12,042,888 samples; SurfaceWorld 27,479 / 36,574,549. Readiness negative controls were caught; walkability passed 4,000/4,000 FI and 5,642/5,642 SurfaceWorld samples. +- L3 FP-contract preamble/self-test, L4 `FLazy`, L7 shared cache, L9/L12 proofs, L11 readiness/crash handling, L13 route binding, ARCHITECTURE §8.10, and async/MPSC/Epoch paths remain intact. Both final compiler runs started without the Core FP-contract self-test refusing the build. No async route was added. +- Unreal-side edits are limited to [VoxelForgeCoreAdapter.cpp](../../../../Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp:453), bumping FI geometry version 2→3 so serialized recipes pick up the lower-seal removal, and the shared [VoxelDensityPrimitives.h](../../../../Source/VoxelForge/Public/VoxelDensityPrimitives.h:44), extracting the common upper-seal math used by v3. The Unreal target could not be compiled on this Linux host. + +## Captures + +All JPEGs are below 300 KB. Before/after pairs use matched cameras: FI flat square `(-11.6124,-118.2212,-19.8452), yaw/pitch 0/0`; FI island `(-22,-19,-22.8), 0/−4`; SurfaceWorld spawn `(0,-35,-487.94), 0/−22`; horizon uses the same spawn camera with pitch 0. The ceiling view uses the island camera with pitch 80. The SurfaceWorld pairs look the same; the exact hash checks certify its output bit-for-bit. + +- FI flat square: `captures/floating-islands-flat-square-before.jpg`, `captures/floating-islands-flat-square-after.jpg`. +- FI low island: `captures/floating-islands-island-view-before.jpg`, `captures/floating-islands-island-view-after.jpg`. +- FI upward ceiling: `captures/floating-islands-ceiling-up.jpg`. +- SurfaceWorld L1 spawn: `captures/surface-world-l1-spawn-before.jpg`, `captures/surface-world-l1-spawn-after.jpg`. +- SurfaceWorld horizon: `captures/surface-world-horizon-before.jpg`, `captures/surface-world-horizon-after.jpg`. +- Flat-square diagnostic without tile edges: `captures/floating-islands-flat-square-no-edges.jpg`. + +## Failed or retried runs + +- The first density-probe link omitted legacy compatibility objects and failed with undefined references. Relinking with the legacy implementation objects succeeded; both boundary probes then ran. +- The initial 4×4 continuity audit failed at far LODs 4–6 and found edge gaps. The shared all-LOD boundary cap and final full-cell coverage check replaced the center-only deduplication; final 16×16 LOD4–8 continuity passed with zero edge gaps. +- An early matrix checker compared Clang contraction-off hashes directly with GCC default hashes and reported FI mismatches. The checker was corrected to test repeated runs within each compiler and the L14 compiler-specific references; the final 28-row matrix passed. +- An early offscreen capture drew all skirts and showed an artificial slab. The capture now applies the viewer’s hidden-skirt mask; final matched captures were regenerated. +- A GCC build interrupted by owner steering produced no binary and was rerun. A pre-correction Clang build was superseded by the final build. No final build or matrix run failed or exceeded the runtime limits. + +## Resources and owner note + +Final builds: Clang 19 exit 0 in 31.689 s, peak RSS 436,088 KiB; GCC 14 exit 0 in 48.648 s, peak RSS 903,168 KiB. The largest measured runtime process was 897,276 KiB RSS. All processes stayed below the 6 GiB address-space cap; CPU affinity was 0–11, worker maximum 12, normal priority, and governor `powersave`. No run exceeded 30 minutes or stalled for 15 minutes. See [BuildResources.md](BuildResources.md). + +**Owner note:** SurfaceWorld stayed bit-identical to L14. FloatingIslands now retains a ceiling at its configured upper strate boundary while removing the false lower all-XY floor. At the current plan that is a z=+4 m boundary with a 0.5 m seal; its distance above the islands comes from the configured range. The small Unreal edits are listed above and need an owner-machine UBT compile. + +## Orchestrator review (Claude) + +- **Merged.** SurfaceWorld is bit-identical (14 configs plus the 24 m crossing); the FI false all-XY lower seal + is removed; the ceiling comes from the shared, strate-parameter upper-boundary seal and ceiling path + (owner rule: every strate has a ceiling, height from its own parameters). The Unreal edits are a pure + extraction of the existing upper-seal math plus the FI `geometryVersion` 2→3; they need a UBT compile on + the owner PC. +- **The scale answer:** both conventions are deliberate and agree between Unreal and the standalone + (SurfaceWorld 32 Core voxels per chunk; FloatingIslands 32 owner voxels = 16 Core voxels). Nothing + rescaled. +- **Still open (L19):** + 1. Small black holes in the FI ceiling, visible near the top of `floating-islands-flat-square-after.jpg`; + compare LOD1 missing 3/12,288 continuity samples. + 2. The owner's ledges are most likely the LOWER stratum's terrain seen through the floorless FI void: + ring steps of 147 cm median at LOD1→2 and 129 cm at 2→3 remain in that terrain. "Valid lower-stratum + geometry" with metre-scale cross-LOD steps is still a bug the owner can see. +- Exports (229 MB `.vfmesh`) are not committed. diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/RingProbe.py b/Standalone/Research/WorldAssemblerM3/Linux18/RingProbe.py new file mode 100644 index 0000000..b722a3a --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/RingProbe.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +"""Compare upward mesh heights on shared XY edges between adjacent LOD rings.""" +import array +import collections +import math +import struct +import sys + + +def read_scene(path): + tiles = [] + with open(path, "rb") as f: + if f.read(8) != b"VFMSH001": + raise SystemExit(f"{path}: invalid mesh header") + version, voxel_um, count = struct.unpack("<3I", f.read(12)) + camera = struct.unpack("<3d", f.read(24)) + yaw, pitch = struct.unpack("<2d", f.read(16)) + voxel_m = voxel_um / 1_000_000.0 + for _ in range(count): + key = struct.unpack("<4i", f.read(16)) + surface_vertices, skirt_count, vertex_count, index_count, mask_count = struct.unpack( + "<5I", f.read(20)) + positions = array.array("f") + positions.frombytes(f.read(vertex_count * 12)) + normals = array.array("f") + normals.frombytes(f.read(vertex_count * 12)) + indices = array.array("I") + indices.frombytes(f.read(index_count * 4)) + masks = f.read(mask_count) + if sys.byteorder != "little": + positions.byteswap(); normals.byteswap(); indices.byteswap() + triangles = [] + for i in range(0, index_count, 3): + if masks and masks[i // 3] != 0: + continue + a, b, c = indices[i:i + 3] + if max(a, b, c) >= surface_vertices: + continue + nz = (normals[a * 3 + 2] + normals[b * 3 + 2] + normals[c * 3 + 2]) / 3.0 + if nz < 0.65: + continue + tri = tuple((positions[j * 3], positions[j * 3 + 1], positions[j * 3 + 2]) + for j in (a, b, c)) + triangles.append(tri) + if triangles: + lod = key[3] + extent = 32 * (1 << lod) * voxel_m + tiles.append({"key": key, "lod": lod, "extent": extent, + "x0": key[0] * extent, "y0": key[1] * extent, + "x1": (key[0] + 1) * extent, "y1": (key[1] + 1) * extent, + "z0": key[2] * extent, "z1": (key[2] + 1) * extent, + "triangles": triangles}) + return camera, yaw, pitch, tiles + + +def height_at(tile, x, y): + best = None + for tri in tile["triangles"]: + (x0, y0, z0), (x1, y1, z1), (x2, y2, z2) = tri + den = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2) + if abs(den) < 1.0e-10: + continue + a = ((y1 - y2) * (x - x2) + (x2 - x1) * (y - y2)) / den + b = ((y2 - y0) * (x - x2) + (x0 - x2) * (y - y2)) / den + c = 1.0 - a - b + if min(a, b, c) >= -1.0e-5: + z = a * z0 + b * z1 + c * z2 + if best is None or z > best: + best = z + return best + + +path = sys.argv[1] +camera, yaw, pitch, tiles = read_scene(path) +by_lod = collections.defaultdict(list) +for tile in tiles: + by_lod[tile["lod"]].append(tile) +print(f"scene={path} camera_m={camera} yaw={yaw} pitch={pitch} nonempty_mesh_tiles={len(tiles)}") +print("lod_pair shared_edges samples_both median_abs_cm p95_abs_cm max_abs_cm median_delta_cm gaps") +for lod in range(8): + fine = by_lod[lod] + coarse = by_lod[lod + 1] + deltas = [] + edge_rows = [] + edge_count = 0 + gap_count = 0 + # Shared XY edges occur only where tile extents touch and overlap on the other axis. + for a in fine: + for b in coarse: + zlo, zhi = max(a["z0"], b["z0"]), min(a["z1"], b["z1"]) + if zhi - zlo <= 1.0e-4: + continue + edge = None + if abs(a["x1"] - b["x0"]) < 1.0e-4 or abs(b["x1"] - a["x0"]) < 1.0e-4: + lo, hi = max(a["y0"], b["y0"]), min(a["y1"], b["y1"]) + if hi - lo > 1.0e-4: + edge = ("x", a["x1"] if abs(a["x1"] - b["x0"]) < 1.0e-4 else a["x0"], lo, hi) + if edge is None and (abs(a["y1"] - b["y0"]) < 1.0e-4 or abs(b["y1"] - a["y0"]) < 1.0e-4): + lo, hi = max(a["x0"], b["x0"]), min(a["x1"], b["x1"]) + if hi - lo > 1.0e-4: + edge = ("y", a["y1"] if abs(a["y1"] - b["y0"]) < 1.0e-4 else a["y0"], lo, hi) + if edge is None: + continue + edge_count += 1 + axis, fixed, lo, hi = edge + epsilon = min(0.02, a["extent"] * 0.001, b["extent"] * 0.001) + samples = 9 + matched = 0 + edge_deltas = [] + for i in range(samples): + t = (i + 0.5) / samples + varying = lo + (hi - lo) * t + if axis == "x": + side_a = 1.0 if abs(a["x1"] - fixed) < 1.0e-4 else -1.0 + side_b = 1.0 if abs(b["x1"] - fixed) < 1.0e-4 else -1.0 + za = height_at(a, fixed - side_a * epsilon, varying) + zb = height_at(b, fixed - side_b * epsilon, varying) + else: + side_a = 1.0 if abs(a["y1"] - fixed) < 1.0e-4 else -1.0 + side_b = 1.0 if abs(b["y1"] - fixed) < 1.0e-4 else -1.0 + za = height_at(a, varying, fixed - side_a * epsilon) + zb = height_at(b, varying, fixed - side_b * epsilon) + if za is not None and not zlo - 1.0e-3 <= za <= zhi + 1.0e-3: + za = None + if zb is not None and not zlo - 1.0e-3 <= zb <= zhi + 1.0e-3: + zb = None + if za is not None and zb is not None: + delta = (za - zb) * 100.0 + deltas.append(delta) + edge_deltas.append((delta, za, zb, varying)) + matched += 1 + if matched == 0: + gap_count += 1 + elif edge_deltas: + edge_rows.append((max(abs(row[0]) for row in edge_deltas), + a["key"], b["key"], edge, edge_deltas)) + if deltas: + absolute = sorted(abs(x) for x in deltas) + signed = sorted(deltas) + p95 = absolute[math.floor(0.95 * (len(absolute) - 1))] + median_abs = absolute[len(absolute) // 2] + median_delta = signed[len(signed) // 2] + print(f"{lod}->{lod+1} {edge_count} {len(deltas)} {median_abs:.3f} {p95:.3f} {max(absolute):.3f} {median_delta:.3f} {gap_count}") + for worst, fine_key, coarse_key, edge, rows in sorted(edge_rows, reverse=True)[:2]: + row = max(rows, key=lambda item: abs(item[0])) + print(f" worst_edge max_abs_cm={worst:.3f} fine={fine_key} coarse={coarse_key} " + f"axis={edge[0]} fixed_m={edge[1]:.3f} span_m={edge[2]:.3f}..{edge[3]:.3f} " + f"sample_v_m={row[3]:.3f} fine_z_m={row[1]:.3f} " + f"coarse_z_m={row[2]:.3f} delta_cm={row[0]:.3f}") + else: + print(f"{lod}->{lod+1} {edge_count} 0 n/a n/a n/a n/a {gap_count}") diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/RunCrossing.py b/Standalone/Research/WorldAssemblerM3/Linux18/RunCrossing.py new file mode 100644 index 0000000..e5f0aef --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/RunCrossing.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +"""Run the L18 24 m SurfaceWorld crossing hash matrix.""" +import os +import re +import signal +import subprocess +import time +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[4] +OUT = ROOT / "Saved/Linux/l18-crossing" +OUT.mkdir(parents=True, exist_ok=True) +if not os.sched_getaffinity(0).issubset(set(range(12))): + raise SystemExit("run under taskset -c 0-11") +BINARIES = { + "clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-clang", + "gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-gcc", +} +PATTERN = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M) +rows = [] +passed = True +for compiler, binary in BINARIES.items(): + for workers, repeat in [(1, 1), (8, 1), (12, 1), (12, 2), (12, 3), (12, 4), (12, 5)]: + name = f"{compiler}-w{workers}-r{repeat}" + logfile = OUT / f"{name}.log" + command = ["prlimit", "--as=6442450944", "--", str(binary), + str(ROOT / "Standalone/data/owner_world.json"), + "--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline", + "--stream-hash", "--force-generate", "--clip-radius=3", "--max-clip-level=8", + f"--workers={workers}", "--camera=0,-35,-487.94,0,-22", + "--camera-step=24,0,0", "--region-crossing", "--recipe=surface-world"] + started = time.monotonic() + peak_rss = 0 + with logfile.open("w", encoding="utf-8") as stream: + process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT, + start_new_session=True) + while process.poll() is None: + pending = [process.pid] + seen = set() + while pending: + pid = pending.pop() + if pid in seen: + continue + seen.add(pid) + try: + pending.extend(int(value) for value in + Path(f"/proc/{pid}/task/{pid}/children").read_text().split()) + for line in Path(f"/proc/{pid}/status").read_text().splitlines(): + if line.startswith("VmRSS:"): + peak_rss = max(peak_rss, int(line.split()[1])) + break + except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError): + pass + if time.monotonic() - started > 900: + os.killpg(process.pid, signal.SIGTERM) + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + os.killpg(process.pid, signal.SIGKILL) + process.wait() + passed = False + break + time.sleep(0.1) + code = process.wait() + elapsed = time.monotonic() - started + actual = PATTERN.findall(logfile.read_text(encoding="utf-8", errors="replace")) + ok = code == 0 and len(actual) == 12 + passed &= ok + rows.append((compiler, workers, repeat, code, elapsed, peak_rss, ok, actual)) + print(f"[CrossingRun] {name} exit={code} seconds={elapsed:.3f} " + f"peak_rss_kib={peak_rss} hash_rows={len(actual)} status={'PASS' if ok else 'FAIL'}", + flush=True) +reference = None +for compiler, workers, repeat, code, elapsed, peak_rss, ok, hashes in rows: + if reference is None: + reference = hashes + elif hashes != reference: + passed = False + print(f"[CrossingHashMismatch] {compiler} workers={workers} repeat={repeat}", flush=True) +print(f"[CrossingSummary] rows={len(rows)} expected=14 result={'PASS' if passed else 'FAIL'} " + f"path={OUT}", flush=True) +raise SystemExit(0 if passed and len(rows) == 14 else 1) diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/RunMatrix.py b/Standalone/Research/WorldAssemblerM3/Linux18/RunMatrix.py new file mode 100644 index 0000000..24efb7d --- /dev/null +++ b/Standalone/Research/WorldAssemblerM3/Linux18/RunMatrix.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Run the L18 deterministic W1/W8/W12 x5 matrix on both supported Linux builds.""" +import os +import re +import signal +import subprocess +import sys +import time +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[4] +OUT = ROOT / "Saved/Linux/l18-matrix" +OUT.mkdir(parents=True, exist_ok=True) +if not os.sched_getaffinity(0).issubset(set(range(12))): + raise SystemExit("run under taskset -c 0-11") + +BINARIES = { + "clang-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-clang", + "gcc-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-linux18-gcc", +} +RECIPES = { + "floating-islands": "-10,-31,-22,0,-8", + "surface-world": "0,-35,-487.94,0,-22", +} +HASH_PATTERNS = { + "full": re.compile(r"^\[PipelineFullDetailHash\].*$", re.M), + "whole": re.compile(r"^\[PipelineWholeViewHash\].*$", re.M), + "lod": re.compile(r"^\[PipelineLODHash\].*$", re.M), + "exact": re.compile(r"^\[PipelineExactQueryHash\].*$", re.M), +} +rows = [] +all_pass = True + +for recipe, camera in RECIPES.items(): + for compiler, binary in BINARIES.items(): + if not binary.exists(): + raise SystemExit(f"missing binary: {binary}") + for workers, repeat in [(1, 1), (8, 1), (12, 1), (12, 2), (12, 3), (12, 4), (12, 5)]: + name = f"{recipe}-{compiler}-w{workers}-r{repeat}" + logfile = OUT / f"{name}.log" + command = ["prlimit", "--as=6442450944", "--", str(binary), + str(ROOT / "Standalone/data/owner_world.json"), + "--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline", + "--stream-hash", "--force-generate", "--clip-radius=3", + "--max-clip-level=8", f"--workers={workers}", f"--camera={camera}", + f"--recipe={recipe}"] + started = time.monotonic() + peak_rss_kib = 0 + with logfile.open("w", encoding="utf-8") as stream: + process = subprocess.Popen(command, stdout=stream, stderr=subprocess.STDOUT, + start_new_session=True) + while process.poll() is None: + pending = [process.pid] + seen = set() + while pending: + pid = pending.pop() + if pid in seen: + continue + seen.add(pid) + try: + children = Path(f"/proc/{pid}/task/{pid}/children").read_text().split() + pending.extend(int(value) for value in children) + for line in Path(f"/proc/{pid}/status").read_text().splitlines(): + if line.startswith("VmRSS:"): + peak_rss_kib = max(peak_rss_kib, int(line.split()[1])) + break + except (FileNotFoundError, PermissionError, ProcessLookupError, ValueError): + pass + if time.monotonic() - started > 900: + os.killpg(process.pid, signal.SIGTERM) + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + os.killpg(process.pid, signal.SIGKILL) + process.wait() + all_pass = False + break + time.sleep(0.1) + code = process.wait() + elapsed = time.monotonic() - started + output = logfile.read_text(encoding="utf-8", errors="replace") + matched = {key: pattern.findall(output) for key, pattern in HASH_PATTERNS.items()} + ok = code == 0 and all(matched.values()) and len(matched["lod"]) == 9 + if not ok: + all_pass = False + row = {"recipe": recipe, "compiler": compiler, "workers": workers, + "repeat": repeat, "exit": code, "seconds": elapsed, + "peak_rss_kib": peak_rss_kib, "ok": ok, + "full": matched["full"][-1] if matched["full"] else "", + "whole": matched["whole"][-1] if matched["whole"] else "", + "lod": " || ".join(matched["lod"]), + "exact": matched["exact"][-1] if matched["exact"] else ""} + rows.append(row) + print(f"[MatrixRun] {name} exit={code} seconds={elapsed:.3f} " + f"peak_rss_kib={peak_rss_kib} hash_rows={sum(map(len,matched.values()))} " + f"status={'PASS' if ok else 'FAIL'}", flush=True) + +summary = OUT / "summary.tsv" +columns = ["recipe", "compiler", "workers", "repeat", "exit", "seconds", "peak_rss_kib", + "ok", "full", "whole", "lod", "exact"] +with summary.open("w", encoding="utf-8") as f: + f.write("\t".join(columns) + "\n") + for row in rows: + f.write("\t".join(str(row[key]) for key in columns) + "\n") + +for recipe in RECIPES: + for compiler in BINARIES: + reference = None + for row in rows: + if row["recipe"] != recipe or row["compiler"] != compiler: + continue + signature = (row["full"], row["whole"], row["lod"], row["exact"]) + if reference is None: + reference = signature + elif signature != reference: + print(f"[MatrixMismatch] recipe={recipe} workers={row['workers']} " + f"compiler={compiler} repeat={row['repeat']}", flush=True) + all_pass = False + # Compiler defaults are intentionally recorded separately: Clang uses contraction off, + # while GCC default is the owner-requested control. Report rather than hide any cross-build + # difference; worker/repeat determinism is asserted within each compiler above. + compiler_signatures = {} + for row in rows: + if row["recipe"] == recipe: + compiler_signatures.setdefault(row["compiler"], + (row["full"], row["whole"], row["lod"], row["exact"])) + if len(set(compiler_signatures.values())) > 1: + print(f"[MatrixCompilerDifference] recipe={recipe} compilers=" + f"{','.join(compiler_signatures)}", flush=True) +print(f"[MatrixSummary] rows={len(rows)} expected=28 result={'PASS' if all_pass else 'FAIL'} " + f"path={summary}", flush=True) +raise SystemExit(0 if all_pass and len(rows) == 28 else 1) diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-ceiling-up.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-ceiling-up.jpg new file mode 100644 index 0000000000000000000000000000000000000000..38b7028248f6ea3612e195848910778ee338cb94 GIT binary patch literal 34570 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 Yl7O}Q1r4GI{1&NCxLw5LlEFLw2R}J{rT_o{ literal 0 HcmV?d00001 diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-flat-square-after.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-flat-square-after.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a88fef2418de4ce57e300d9dc529940a6f2e520c GIT binary patch literal 47962 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 Q43;fMYv=RV7kqjCe_7~~e*gdg literal 0 HcmV?d00001 diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-flat-square-no-edges.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-flat-square-no-edges.jpg new file mode 100644 index 0000000000000000000000000000000000000000..706d72d42fcc69a2798908e6a01d3b9e76d4a77a GIT binary patch literal 32606 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 literal 0 HcmV?d00001 diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-island-view-after.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/floating-islands-island-view-after.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c42dcd36a618b16c67fbe928e4eda6badfe881dd GIT binary patch literal 44687 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 qi(?nO!(<8}SP_6)RV+1mB_`;Pc5RpUho| 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 KbV|~%1pfznFhIrt literal 0 HcmV?d00001 diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-horizon-after.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-horizon-after.jpg new file mode 100644 index 0000000000000000000000000000000000000000..896ba4ecc550444a8902bdecfc18b90829db8eeb GIT binary patch literal 33609 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 SimnKJHZE>W&0_h#x&H^3>w*~o literal 0 HcmV?d00001 diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-horizon-before.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-horizon-before.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4f639c82089074d7bd72bb554097f7feeaeba702 GIT binary patch literal 34039 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 UbkB+h3*=>(WFE)A|KHvJ2cI7eQvd(} literal 0 HcmV?d00001 diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-l1-spawn-after.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-l1-spawn-after.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bffdac32e74affcbb307ad2227919f7cd070a3ff GIT binary patch literal 33389 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 z zO_0F(eIKlYGNwb%6knXOiHH}oW1`DP}Zqn71>Q#Rx zgpsv!rHk0b*U~o^(D5V3?R$QbkIBaiUy)jHp@VW(__t@ z+!qg0kS=<2*U7hQ$dxk)w<_f~L_)bqIi31QvFU5>3KXbK`rr3+QE8v6WJ!LtQNv0? zsC)c)%&O+elz+Cp5$s-@?oaqtrM5bz4N0jB0&0fBn2>W8QyW~W^6p$l0kyxs5Hl%b zKYI-Z)GIDl)W(x1Ij!(`Uel6;hi>Otqz0P+IXG{Ioc5<9MdxWE-_bS7#-4O2l(3=04 zVjAx6wt-h)0Rkw4eT3do_*RzphW(frivG^zTX8s)nmG`p&>R%(4IY9Fx#nZeXh4X^Hn+g|G6CsdYDe@HKh>@LC7 zg1;v-bE2@bd)k$H4Hnq2)?c61-v*kE7fWHNH0K`RP#ok*wn!St2er!G19f@1L0?8Q z-2fK1*Dfof8fcpEiZh1FPrAbStp)EUjt#bDM)FOpZEia13dy;W4LZ!g3t=%3#HvPoDtK(rpcG~KSyxsa^+1!%3dp_DQE%U6S-M%_rir{WYwAhRk z-hJTs$>CW2OF9oNmk?4b4!RVV+likzLBsB@Rm644j&rd(ySt3^EiP6Q_%SR_v0V&- z&p_^#uW>lFY|$FkcGpv>QWV+sikt*}9!5@YHR=3RzV>mRka$JmvI^i2@^pYvqv_S$ z!0uLSj55?IZ@?s6X`$O)ez#C16OP(DbJ4{ae1`JncRv(PYY{iF|xV>mR# z9;*hff@x4Wbr6vbP7IrVnL1;qh9h`zU6jL$>(APkp>Z*MbIY2f^Gnzl1E3lTdVV;>3;<=&L!NT-cWg&>@_W%lTB|@1$Z<;C1`k|Ihy}gQH8+Eh())Y(b47hHpu#NAAbkL%s%_CS}$TX^Gq{ zc@V3&27@|;D_V!%E(lF;kMN=vvx^%MWt_ylns@4=mlVGZyy;q(K^dYV)gXJ*3ZrZh Pp1VYfG5_-a{KfwTaxz=^ literal 0 HcmV?d00001 diff --git a/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-l1-spawn-before.jpg b/Standalone/Research/WorldAssemblerM3/Linux18/captures/surface-world-l1-spawn-before.jpg new file mode 100644 index 0000000000000000000000000000000000000000..07710f4f64e19dbc0018d0a507067ec13f5b72ac GIT binary patch literal 33489 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 #include #include +#include #include namespace @@ -38,10 +39,69 @@ namespace float MaximumHeight=-std::numeric_limits::infinity(); std::vector Vertices; std::vector Indices; + struct FTileRange + { + std::array Key{}; + std::size_t IndexBegin=0; + std::uint32_t IndexCount=0; + std::vector FaceMasks; + }; + std::vector Tiles; std::uint64_t Triangles=0,SkirtTriangles=0; + std::uint64_t VisibleSkirtTriangles=0,HiddenSameLodSkirtTriangles=0; + std::uint64_t DrawnTriangles=0; std::uint32_t TileCount=0; }; + struct FTileKeyHash + { + std::size_t operator()(const std::array& Key) const noexcept + { + std::size_t Hash=0xcbf29ce484222325ull; + for(const std::int32_t Value:Key) + { + Hash^=static_cast(Value); + Hash*=0x100000001b3ull; + } + return Hash; + } + }; + + std::int32_t FloorDiv(std::int64_t Value,std::int64_t Divisor) + { + const std::int64_t Quotient=Value/Divisor, Remainder=Value%Divisor; + return static_cast(Quotient-((Remainder<0)?1:0)); + } + + std::uint8_t ComputeVisibleSkirtFaceMask( + const std::array& Tile, + const std::unordered_set,FTileKeyHash>& Desired) + { + const std::int64_t Extent=static_cast(32)<(Tile[0])*Extent, + static_cast(Tile[1])*Extent,static_cast(Tile[2])*Extent}; + std::uint8_t Mask=0; + for(std::int32_t Axis=0;Axis<3;++Axis)for(std::int32_t Side=0;Side<2;++Side) + { + std::int64_t Probe[3]={Origin[0]+Extent/2,Origin[1]+Extent/2, + Origin[2]+Extent/2}; + Probe[Axis]=Side?Origin[Axis]+Extent:Origin[Axis]-1; + std::int32_t NeighborLevel=-1; + for(std::int32_t Level=0;Level<=8;++Level) + { + const std::int64_t NeighborExtent=static_cast(32)< Neighbor={ + FloorDiv(Probe[0],NeighborExtent),FloorDiv(Probe[1],NeighborExtent), + FloorDiv(Probe[2],NeighborExtent),Level}; + if(Desired.contains(Neighbor)) + {NeighborLevel=Level;break;} + } + if(NeighborLevel<0||NeighborLevel!=Tile[3]) + Mask|=static_cast(1u<<(Axis*2+Side)); + } + return Mask; + } + template bool Read(std::ifstream& File,T& Value) { File.read(reinterpret_cast(&Value),sizeof(Value)); @@ -126,11 +186,36 @@ namespace } Scene.Triangles+=IndexCount/3; Scene.SkirtTriangles+=SkirtCount; + Scene.Tiles.push_back({{Key[0],Key[1],Key[2],Key[3]},IndexOffset, + IndexCount,std::move(Masks)}); TotalVertices+=VertexCount;TotalIndices+=IndexCount; } if(File.peek()!=std::char_traits::eof()) {Error="mesh scene has trailing bytes";return false;} if(Scene.Indices.empty()){Error="mesh scene contains no triangles";return false;} + std::unordered_set,FTileKeyHash> Desired; + Desired.reserve(Scene.Tiles.size()); + for(const auto& Tile:Scene.Tiles)Desired.insert(Tile.Key); + std::vector VisibleIndices; + VisibleIndices.reserve(Scene.Indices.size()); + for(const auto& Tile:Scene.Tiles) + { + const std::uint8_t VisibleMask=ComputeVisibleSkirtFaceMask(Tile.Key,Desired); + for(std::uint32_t Triangle=0;Triangle(Triangle)*3; + VisibleIndices.insert(VisibleIndices.end(),Scene.Indices.begin()+Index, + Scene.Indices.begin()+Index+3); + } + } + Scene.Indices=std::move(VisibleIndices); + Scene.DrawnTriangles=Scene.Indices.size()/3; return true; } @@ -399,9 +484,14 @@ void main() { std::error_code SizeError; const auto Bytes=std::filesystem::file_size(Output,SizeError); - std::printf("[OffscreenCapture] triangles=%llu tiles=%u skirts=%llu shading=%s tile_edges=%s edge_width_m=%.3f png_bytes=%llu status=PASS path=%s\n", - static_cast(Scene.Triangles),Scene.TileCount, + std::printf("[OffscreenCapture] source_triangles=%llu drawn_triangles=%llu tiles=%u " + "skirts=%llu visible_skirt_triangles=%llu hidden_same_lod_skirt_triangles=%llu " + "shading=%s tile_edges=%s edge_width_m=%.3f png_bytes=%llu status=PASS path=%s\n", + static_cast(Scene.Triangles), + static_cast(Scene.DrawnTriangles),Scene.TileCount, static_cast(Scene.SkirtTriangles), + static_cast(Scene.VisibleSkirtTriangles), + static_cast(Scene.HiddenSameLodSkirtTriangles), ReadableMode?"readable":"normal",TileEdges?"on":"off",TileEdgeWidthMeters, static_cast(SizeError?0:Bytes),Output.string().c_str()); } diff --git a/Standalone/Source/VoxelForge/Public/VoxelDensityPrimitives.h b/Standalone/Source/VoxelForge/Public/VoxelDensityPrimitives.h index 7fb17f4..8e2c4c3 100644 --- a/Standalone/Source/VoxelForge/Public/VoxelDensityPrimitives.h +++ b/Standalone/Source/VoxelForge/Public/VoxelDensityPrimitives.h @@ -41,21 +41,27 @@ // SealFactor > 0 et BaseDensity > 0, le résultat est solide GARANTI quelle qu'ait été l'entrée. // C'est exactement ce qu'encode `IVoxelDensityOp::ClassifyBox` (voir VoxelDensityOp.h), et la // raison pour laquelle cette méthode existe. -FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ, - float StrateTopZ, float StrateBottomZ, - float Thickness, float BaseDensity) +FORCEINLINE void VF_ApplyUpperBoundarySealValue(float& Density, float WorldZ, + float StrateTopZ, float Thickness, float BaseDensity) { - if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return; - - const float DistTop = StrateTopZ - WorldZ; // + si on est sous le plafond - const float DistBot = WorldZ - StrateBottomZ; // + si on est au-dessus du sol - + const float DistTop = StrateTopZ - WorldZ; if (DistTop >= 0.0f && DistTop < Thickness) { float SealFactor = 1.0f - (DistTop / Thickness); SealFactor = SmoothStep01(SealFactor); Density = FMath::Max(Density, SealFactor * BaseDensity); } +} + +FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ, + float StrateTopZ, float StrateBottomZ, + float Thickness, float BaseDensity) +{ + if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return; + + const float DistBot = WorldZ - StrateBottomZ; // + si on est au-dessus du sol + + VF_ApplyUpperBoundarySealValue(Density, WorldZ, StrateTopZ, Thickness, BaseDensity); if (DistBot >= 0.0f && DistBot < Thickness) { float SealFactor = 1.0f - (DistBot / Thickness); @@ -64,6 +70,16 @@ FORCEINLINE void VF_ApplyBoundarySeal(float& Density, float WorldZ, } } +// The same structural seal, limited to a strate's upper boundary. Native finite fields use this +// when their lower boundary intentionally has no seal; keeping the math here makes that ceiling +// use the same shared density primitive as every two-sided strate seal. +FORCEINLINE void VF_ApplyUpperBoundarySeal(float& Density, float WorldZ, + float StrateTopZ, float Thickness, float BaseDensity) +{ + if (VoxelDensityAblation::IsBoundarySealOff() || Thickness <= 0.0f) return; + VF_ApplyUpperBoundarySealValue(Density, WorldZ, StrateTopZ, Thickness, BaseDensity); +} + //============================================================================= // CARVE DE PASSAGE / PASSAGE CARVING //============================================================================= diff --git a/Standalone/Source/WorldAssemblyPrototype.h b/Standalone/Source/WorldAssemblyPrototype.h index 90c6cdd..e581ccf 100644 --- a/Standalone/Source/WorldAssemblyPrototype.h +++ b/Standalone/Source/WorldAssemblyPrototype.h @@ -494,11 +494,9 @@ namespace StandaloneWorldAssemblyPrototype const std::int64_t coreVoxelsPerOwnerChunk=static_cast(CHUNK_SIZE) *recipe.ownerToCoreScaleNumerator/recipe.ownerToCoreScaleDenominator; const std::int64_t minimumZ=static_cast(islandSlot->BottomChunkZ) - *coreVoxelsPerOwnerChunk*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel - +2*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel; + *coreVoxelsPerOwnerChunk*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel; const std::int64_t maximumZ=static_cast(islandSlot->TopChunkZ+1) - *coreVoxelsPerOwnerChunk*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel - -2*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel; + *coreVoxelsPerOwnerChunk*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel; if(maximumZ<=minimumZ) {error="FloatingIslands strate is too short for a bounded Core recipe";return false;} recipe.layoutMinimumZSubvoxels=minimumZ;