wip(L26, side branch): every passage style walkable in both recipes (0/0/0); SW bridges look wrong

All 4 styles x both recipes pass capsule, open-air and naturalness audits, and full-view hashes are
deterministic. But the SW passage crosses 355 m of open SurfaceWorld sky as a ~2 km fragmented rock
ramp, which is not natural. L27 replaces long bridges with a shared ceiling-to-ground rock column.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-21 02:39:44 +02:00
1 parent ef789aaa00
commit 37a223046c
13 files changed
+878 -41

No files matched your search

+24
View File
@@ -2010,6 +2010,30 @@ captures, style results, and the single Unreal adapter version edit.
[`Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md)
records the evidence and caveats.
### 8.44 Walkable passages as tunnels in rock — World Assembler L26
L25 correctly stopped support from appearing in native air, but its SurfaceWorld-recipe passages
still crossed a long open volume in the SurfaceWorld arrival strata. The segment map places that gap
inside SurfaceWorld (about `-146` to `-497 m`), after the TunnelNetwork transition; it is not TunnelNetwork
cave air. Both ends meet native rock. The shared Core planner now finds contiguous unsupported ranges
from the native field sign and caches them by resolved-layout identity. It adds a deterministic,
relief-bearing rock span only across those ranges. The span is at least 5 m wide, several metres thick,
and joins native rock at both ends. The passage carve then opens the bore through the added density,
leaving a grounded floor and rock walls/ceiling. SurfaceWorld away from the passage remains unchanged.
Native route support remains gated on pre-passage solid density. Before adding any support density, the
composer also checks the resolved player capsule, so neighboring floor segments cannot restore rock
inside the avatar path. This keeps all four style overrides walkable in both recipes. The bridge audit
measures its authored density field at 256 route sections, checks the 5 m width and connected ends, and
records a relief-bearing thickness range; the open-air audit still runs the L24 negative control.
The shared evaluator is version 13; FloatingIslands geometry remains version 7 and resolved-layout
schema V3 is unchanged. These changes are in Core and the standalone audit/capture path; no Unreal
adapter edit is required. The L26 report contains the eight-style table, hashes, captures and run history.
[`Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md)
records the final evidence.
## 9. Multiplayer model (listen-server first, dedicated-friendly)
> **Status: transport is DESIGN ONLY — nothing is networked in-tree yet** (no `Replicated`/`HasAuthority`/RPCs; a
+14
View File
@@ -1194,6 +1194,20 @@ The shared evaluator is version 12 and FI geometry version is 7; resolved-layout
unchanged. See ARCHITECTURE §8.43 and
[`Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux25/REPORT.md).
### 3.27 Tunnels in native rock with grounded passage bridges — World Assembler L26
| Symbol | Canonical file | Role |
|---|---|---|
| `BuildPassageBridgePlan` / `PassageBridgeSignedDistance` | `Standalone/Core/src/ShapeWorldInternal.h` | Uses native density sign to plan cached, connected rock spans only across unsupported route ranges; shared by both recipes and all passage styles. |
| `PassageBridgeCache` | `Standalone/Source/OwnerWorldLoader.h` | Shares deterministic ranges by resolved-layout identity across shape instances. |
| `ApplyResolvedStratePassageCarves` | `Standalone/Core/src/ShapeWorldInternal.h` | Adds bridge density before carving the bore; gates native floor support on solid input and player-capsule clearance. |
| `auditPassageBridges` / `auditPassageOpenAir` / `--audit-resolved-layout-passages` | `Standalone/Source/StreamBenchmarkPipeline.h` | Measures bridge width, thickness, relief and connected ends; checks capsule support, open air, naturalness, route binding and the L24 negative control. |
| `PassageBridgeRangeAuditV1` / `passageBridgeRanges()` / `isPassageBridgeSample()` | `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`, `Standalone/Core/src/VoxelForgeCore.cpp` | Exposes audit-only bridge ranges and density queries to the standalone validator. |
The shared evaluator is version 13; FloatingIslands geometry remains version 7 and resolved-layout
schema V3 is unchanged. See ARCHITECTURE §8.44 and
[`Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md`](Standalone/Research/WorldAssemblerM3/Linux26/REPORT.md).
## 4. The density pipeline (most-edited hot path)
### 4.1 `GetDensityWithParams` (TunnelNetwork) — VoxelGenerator.cpp:3749
+3 -2
View File
@@ -36,8 +36,9 @@ command -v ar >/dev/null || { printf 'ar not found\n' >&2; exit 2; }
command -v pkg-config >/dev/null || { printf 'pkg-config not found\n' >&2; exit 2; }
pkg-config --exists egl glesv2 libpng || { printf 'EGL, GLESv2, and libpng development files are required\n' >&2; exit 2; }
BUILD_DIR="$ROOT/Build/linux-$VARIANT"
BIN_DIR="$ROOT/bin/linux"
BUILD_ROOT="${VOXELFORGE_BUILD_ROOT:-$ROOT/Build}"
BIN_DIR="${VOXELFORGE_BIN_DIR:-$ROOT/bin/linux}"
BUILD_DIR="$BUILD_ROOT/linux-$VARIANT"
mkdir -p "$BUILD_DIR/wrappers" "$BUILD_DIR/objects" "$BIN_DIR"
INCLUDES=(
@@ -249,8 +249,8 @@ namespace VoxelForgeCore
// L'assembleur v1 encode coordonnees et scalaires en 1/256 de voxel, independamment des tuiles.
inline constexpr std::int64_t WorldAssemblySubvoxelsPerVoxel = 256;
inline constexpr std::uint32_t WorldAssemblySchemaVersion = 2;
// Version 12 gates passage supports on native rock and anchors the FI spiral inside a measured root.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 12;
// Version 13 adds connected relief-bearing rock spans across native open-air passage gaps.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 13;
enum class FieldChannel : std::uint32_t
{
@@ -666,6 +666,17 @@ namespace VoxelForgeCore
std::vector<ResolvedLayoutPassagePointV1> controlPoints;
};
struct PassageBridgeRangeAuditV1
{
std::size_t passageIndex = 0;
std::size_t firstSegment = 0;
std::size_t lastSegment = 0;
std::uint64_t unsupportedSamples = 0;
double unsupportedLengthMetres = 0.0;
std::array<double, 4> startPointSubvoxels{};
std::array<double, 4> endPointSubvoxels{};
};
struct ResolvedLayoutPassageConfigV1
{
std::int32_t upperStrateIndex = -1;
@@ -1314,6 +1325,10 @@ namespace VoxelForgeCore
ShapeBuildStats buildStats() const;
float densityAt(Vec3d voxelPosition) const;
// Audit-only view of connected rock spans planned for passage support.
std::vector<PassageBridgeRangeAuditV1> passageBridgeRanges() const;
bool isPassageBridgeSample(std::size_t passageIndex, std::size_t segmentIndex,
Vec3d voxelPosition) const;
// Audit-only selector provenance for the same point evaluator; never used by meshing.
std::string densityDispatchPathAt(Vec3d voxelPosition) const;
// Analytic source distance without the occupancy-preserving near-zero clamp or packed proxy.
+308 -19
View File
@@ -41,6 +41,27 @@ public:
double SealThickness=0.0;
};
const std::vector<FStandalonePassageBridgeRange>& GetPassageBridgeRanges() const
{return PassageBridgeRanges;}
bool IsResolvedPassageBridgeSample(std::size_t PassageIndex,std::size_t SegmentIndex,
const VoxelForgeCore::Vec3d& Position) const
{
if(IsPassageBridgeSegment(PassageIndex,SegmentIndex)
&&PassageBridgeSignedDistance(PassageIndex,SegmentIndex,
static_cast<float>(Position.x),static_cast<float>(Position.y),
static_cast<float>(Position.z))<=0.0)return true;
for(const auto& range:PassageBridgeRanges)
{
if(range.passageIndex!=PassageIndex)continue;
for(std::size_t segment=range.firstSegment;segment<=range.lastSegment;++segment)
if(segment!=SegmentIndex&&PassageBridgeSignedDistance(PassageIndex,segment,
static_cast<float>(Position.x),static_cast<float>(Position.y),
static_cast<float>(Position.z))<=0.0)return true;
}
return false;
}
double GetCoreVoxelSizeCm() const
{
return Owner == nullptr || Owner->CoreVoxelSizeMicrons == 0
@@ -168,20 +189,19 @@ public:
for(const auto& passage:ResolvedLayout->passages)
composeRouteMouthSupport(passage.upperStrateIndex,
passage.upperMouthSubvoxels,true);
for(const auto& passage:ResolvedLayout->passages)
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();++passageIndex)
{
const auto& passage=ResolvedLayout->passages[passageIndex];
if(passage.controlPoints.size()<2)continue;
const double placementRadiusQ=static_cast<double>(passage.placementRadiusSubvoxels)
+static_cast<double>(passage.midRadiusSubvoxels);
if(qx*qx+qy*qy>placementRadiusQ*placementRadiusQ)
continue;
const double firstFloorQ=passage.controlPoints.front().positionSubvoxels[2]
-passage.controlPoints.front().radiusSubvoxels+playerCenterAboveFloorQ;
const double lastFloorQ=passage.controlPoints.back().positionSubvoxels[2]
-passage.controlPoints.back().radiusSubvoxels+playerCenterAboveFloorQ;
if(qz>firstFloorQ+2.0*passage.mouthRadiusSubvoxels
||qz<lastFloorQ-2.0*passage.mouthRadiusSubvoxels)
{
continue;
}
const auto floorProfile=[&](const auto& point)
{return point.positionSubvoxels[2]-point.radiusSubvoxels+playerCenterAboveFloorQ;};
const std::ptrdiff_t lastIndex=static_cast<std::ptrdiff_t>(passage.controlPoints.size())-1;
@@ -204,8 +224,10 @@ public:
const std::ptrdiff_t carveEnd=std::min<std::ptrdiff_t>(lowerMouthIndex-1,
(carveLow-passage.controlPoints.begin())+1);
double bestSignedDistance=std::numeric_limits<double>::infinity();
double bestPlayerCapsuleSignedDistance=std::numeric_limits<double>::infinity();
double bestT=0.0;
std::ptrdiff_t bestIndex=0;
std::ptrdiff_t bestSupportSegmentIndex=0;
bool hasSupportFloor=false;
double bestSupportDensity=0.0;
const auto considerCarveSegment=[&](std::ptrdiff_t index)
@@ -225,12 +247,37 @@ public:
const double ex=qx-cx,ey=qy-cy,ez=qz-cz;
const double radius=static_cast<double>(a.radiusSubvoxels)
+t*(b.radiusSubvoxels-a.radiusSubvoxels);
const double horizontalLengthSq=dx*dx+dy*dy;
const double playerT=horizontalLengthSq>0.0
?std::clamp(((qx-ax)*dx+(qy-ay)*dy)/horizontalLengthSq,0.0,1.0):t;
const double playerDx=qx-(ax+playerT*dx);
const double playerDy=qy-(ay+playerT*dy);
const double playerRadius=static_cast<double>(a.radiusSubvoxels)
+playerT*(b.radiusSubvoxels-a.radiusSubvoxels);
const double playerCenterZ=az+playerT*dz-playerRadius+playerCenterAboveFloorQ;
const double playerVertical=std::max(0.0,
std::abs(qz-playerCenterZ)-0.54*qPerMetre);
const double playerCapsuleDistance=DeterministicSqrt(
playerDx*playerDx+playerDy*playerDy+playerVertical*playerVertical)
-0.34*qPerMetre;
bestPlayerCapsuleSignedDistance=std::min(bestPlayerCapsuleSignedDistance,
playerCapsuleDistance);
const double signedDistance=DeterministicSqrt(ex*ex+ey*ey+ez*ez)-radius;
if(signedDistance<bestSignedDistance)
{bestSignedDistance=signedDistance;bestT=t;bestIndex=index;}
};
for(std::ptrdiff_t index=carveBegin;index<=carveEnd;++index)
considerCarveSegment(index);
// Alternate styles can bend locally at either mouth, so floorProfile is
// not monotone over those short endpoint runs. Keep the binary search for
// the long descent and inspect both endpoint neighborhoods directly.
for(std::ptrdiff_t index=0;index<std::min<std::ptrdiff_t>(8,lowerMouthIndex);++index)
considerCarveSegment(index);
const std::ptrdiff_t mouthSearchBegin=std::max<std::ptrdiff_t>(0,lowerMouthIndex-8);
const std::ptrdiff_t mouthSearchEnd=std::min<std::ptrdiff_t>(lastIndex,
lowerMouthIndex+8);
for(std::ptrdiff_t index=mouthSearchBegin;index<mouthSearchEnd;++index)
considerCarveSegment(index);
// The route-bound landing can rise and fall after the lower mouth. Scan
// that short tail directly; binary search is only valid on the descent.
for(std::ptrdiff_t index=lowerMouthIndex;index<lastIndex;++index)
@@ -250,6 +297,12 @@ public:
const double wallReliefWeight=1.0-0.80*verticalWallAlignment;
const double roughSignedDistance=bestSignedDistance
+static_cast<double>(std::clamp(relief,-1.0f,1.0f))*0.24*qPerMetre*wallReliefWeight;
if(IsPassageBridgeSegment(passageIndex,static_cast<std::size_t>(bestIndex)))
{
const double bridgeDistance=PassageBridgeSignedDistance(passageIndex,
static_cast<std::size_t>(bestIndex),X,Y,Z);
composed=std::min(composed,static_cast<float>(bridgeDistance/Q));
}
// Positive density is air; rough rock is cut with full side/ceiling detail and
// gentler relief on the gravity-facing wall so the supported tread stays open.
composed=std::max(composed,static_cast<float>(-roughSignedDistance/Q));
@@ -264,7 +317,10 @@ public:
const double radiusB=segmentB.radiusSubvoxels;
// Keep the tread within the probe band and below the capsule's
// lowest sampled point.
const double floorOffset=0.20;
const double floorOffset=IsPassageBridgeSegment(passageIndex,
static_cast<std::size_t>(index))
?PassageBridgeDeckOffsetMetres(passageIndex,static_cast<std::size_t>(index))
:0.20;
const double horizontalLengthSq=dx*dx+dy*dy;
const double supportT=horizontalLengthSq>0.0
?std::clamp(((qx-segmentA.positionSubvoxels[0])*dx
@@ -304,6 +360,7 @@ public:
if(supportDistanceSq>=bestSupportDistanceSquared)return;
bestSupportDistanceSquared=supportDistanceSq;
hasSupportFloor=true;
bestSupportSegmentIndex=index;
bestSupportDensity=std::clamp(Z-floorVoxels,
-supportThicknessVoxels,0.0);
};
@@ -330,7 +387,11 @@ public:
considerSupportSegment(index);
// Keep route treads inside the native rock envelope. Carving may reopen the
// floor above this point, but a support cannot create a new surface in air.
if(hasSupportFloor&&density<0.0f)
const bool bridgeFloorSupport=hasSupportFloor
&&IsPassageBridgeSegment(passageIndex,
static_cast<std::size_t>(bestSupportSegmentIndex));
if(hasSupportFloor&&bestPlayerCapsuleSignedDistance>=0.05*qPerMetre
&&(density<0.0f||bridgeFloorSupport))
composed=std::min(composed,static_cast<float>(bestSupportDensity));
}
return composed;
@@ -343,6 +404,10 @@ public:
{
if(!ResolvedLayout||ResolvedLayout->passages.empty())return false;
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double voxelsPerMetre=Owner&&Owner->CoreVoxelSizeMicrons>0
?1000000.0/Owner->CoreVoxelSizeMicrons:4.0;
const double bridgeHalfWidthVoxels=3.5*voxelsPerMetre;
const double bridgeFootDepthVoxels=(5.0-0.13)*voxelsPerMetre;
for(const auto& passage:ResolvedLayout->passages)
{
for(std::size_t i=1;i<passage.controlPoints.size();++i)
@@ -351,13 +416,18 @@ public:
const double radius=static_cast<double>(std::max(a.radiusSubvoxels,b.radiusSubvoxels))/Q;
const double floorThicknessVoxels=Owner&&Owner->CoreVoxelSizeMicrons>0
?1000000.0/Owner->CoreVoxelSizeMicrons:4.0;
// A resolved passage bridge extends to a 3.5 m half-width and almost 5 m
// below the bore floor. Keep those cells shape-dependent for classification
// and streaming even before its bridge ranges have been compiled.
const double horizontalExtent=std::max(radius,bridgeHalfWidthVoxels);
const double footDepth=std::max(floorThicknessVoxels,bridgeFootDepthVoxels);
const double low[3]={
std::min(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q-radius,
std::min(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q-radius,
std::min(a.positionSubvoxels[2],b.positionSubvoxels[2])/Q-radius-floorThicknessVoxels};
std::min(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q-horizontalExtent,
std::min(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q-horizontalExtent,
std::min(a.positionSubvoxels[2],b.positionSubvoxels[2])/Q-radius-footDepth};
const double high[3]={
std::max(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q+radius,
std::max(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q+radius,
std::max(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q+horizontalExtent,
std::max(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q+horizontalExtent,
std::max(a.positionSubvoxels[2],b.positionSubvoxels[2])/Q+radius};
bool overlap=true;
for(int axis=0;axis<3;++axis)
@@ -715,6 +785,7 @@ public:
if(RoundTunnelsEnabled)
BuildRoundTunnelPrimitives();
BuildSpatialBins(LineBinSize);
BuildPassageBridgePlan();
Stats.LocalLineBinSeconds=std::chrono::duration<double>(Clock::now()-Substage).count();
Stats.ShapeSeconds=std::chrono::duration<double>(Clock::now()-Stage).count();
Stats.PrimitiveCount=Primitives.size();
@@ -1622,6 +1693,218 @@ public:
}
private:
bool IsPassageBridgeSegment(std::size_t PassageIndex,std::size_t SegmentIndex) const
{
return std::any_of(PassageBridgeRanges.begin(),PassageBridgeRanges.end(),
[PassageIndex,SegmentIndex](const auto& range)
{return range.passageIndex==PassageIndex
&&SegmentIndex>=range.firstSegment&&SegmentIndex<=range.lastSegment;});
}
double PassageBridgeDeckOffsetMetres(std::size_t PassageIndex,
std::size_t SegmentIndex) const
{
for(const auto& range:PassageBridgeRanges)
{
if(range.passageIndex!=PassageIndex||SegmentIndex>range.lastSegment)continue;
if(SegmentIndex>=range.firstSegment)return 0.13;
}
return 0.20;
}
double PassageBridgeSignedDistance(std::size_t PassageIndex,std::size_t SegmentIndex,
float X,float Y,float Z) const
{
if(!ResolvedLayout||PassageIndex>=ResolvedLayout->passages.size())
return std::numeric_limits<double>::infinity();
const auto& passage=ResolvedLayout->passages[PassageIndex];
if(SegmentIndex+1>=passage.controlPoints.size())
return std::numeric_limits<double>::infinity();
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double qPerMetre=Q*1000000.0/std::max<std::uint32_t>(1,
ResolvedLayout->coreVoxelSizeMicrometres);
const auto& a=passage.controlPoints[SegmentIndex];
const auto& b=passage.controlPoints[SegmentIndex+1];
const double ax=static_cast<double>(a.positionSubvoxels[0]);
const double ay=static_cast<double>(a.positionSubvoxels[1]);
const double dx=static_cast<double>(b.positionSubvoxels[0])-ax;
const double dy=static_cast<double>(b.positionSubvoxels[1])-ay;
const double horizontalLengthSq=dx*dx+dy*dy;
const double qx=static_cast<double>(X)*Q,qy=static_cast<double>(Y)*Q;
const double qz=static_cast<double>(Z)*Q;
const double t=horizontalLengthSq>0.0
?std::clamp(((qx-ax)*dx+(qy-ay)*dy)/horizontalLengthSq,0.0,1.0):0.0;
const double centerX=ax+t*dx,centerY=ay+t*dy;
const double centerZ=a.positionSubvoxels[2]+t*(
static_cast<double>(b.positionSubvoxels[2])-a.positionSubvoxels[2]);
const double radius=a.radiusSubvoxels+t*(
static_cast<double>(b.radiusSubvoxels)-a.radiusSubvoxels);
// Embed the deck 13 cm above the bore bottom: within the 25 cm support
// probe, while leaving 16 cm between it and the capsule's lowest sample.
const double floorQ=centerZ-radius
+PassageBridgeDeckOffsetMetres(PassageIndex,SegmentIndex)*qPerMetre;
const double relief=std::clamp(static_cast<double>(VF_FieldSurfaceRelief(X,Y,Z,
static_cast<std::uint32_t>(Owner?Owner->Seed:0))),-1.0,1.0);
const double halfWidth=(3.30+0.20*relief)*qPerMetre;
const double thickness=(4.0+1.0*relief)*qPerMetre;
const double horizontalDistance=DeterministicSqrt((qx-centerX)*(qx-centerX)
+(qy-centerY)*(qy-centerY));
const double sideDistance=horizontalDistance-halfWidth;
const double topDistance=qz-floorQ;
const double bottomDistance=floorQ-thickness-qz;
const double verticalDistance=std::max(topDistance,bottomDistance);
const double outside=DeterministicSqrt(
std::max(sideDistance,0.0)*std::max(sideDistance,0.0)
+std::max(verticalDistance,0.0)*std::max(verticalDistance,0.0));
const double inside=std::min(std::max(sideDistance,verticalDistance),0.0);
return outside+inside;
}
float NativePassageDensityAt(float X,float Y,float Z) const
{
float density=0.0f;
if(!NativeFloatingIslandDensityAt(X,Y,Z,density)
&&!NativeSurfaceDensityAt(X,Y,Z,density))
{
if(UsesLegacySurfaceField(X,Y,Z)&&Owner&&Owner->Generator)
density=Owner->Generator->GetDensityAt(X,Y,Z);
else
density=AnalyticDensityAt(X,Y,Z,true,nullptr,nullptr,nullptr,
false,false);
}
return ApplyResolvedStrateBoundaryBand(density,X,Y,Z);
}
void BuildPassageBridgePlan()
{
PassageBridgeRanges.clear();
if(!Owner||!ResolvedLayout||ResolvedLayout->passages.empty()
||!Owner->PassageBridgeCache)return;
auto& cache=*Owner->PassageBridgeCache;
std::lock_guard<std::mutex> lock(cache.mutex);
const auto cached=cache.byLayout.find(ResolvedLayout->stableIdentity);
if(cached!=cache.byLayout.end())
{PassageBridgeRanges=cached->second;return;}
constexpr double Q=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double qPerMetre=Q*1000000.0/std::max<std::uint32_t>(1,
ResolvedLayout->coreVoxelSizeMicrometres);
const auto inSurfaceWorldStratum=[&](double zSubvoxels)
{
const double zMicrometres=zSubvoxels
*ResolvedLayout->coreVoxelSizeMicrometres/Q;
return std::any_of(ResolvedLayout->strates.begin(),ResolvedLayout->strates.end(),
[zMicrometres](const auto& stratum)
{return stratum.generatorKind=="SurfaceWorld"
&&zMicrometres>=stratum.interiorBottomMicrometres
&&zMicrometres<stratum.interiorTopMicrometres;});
};
constexpr std::array<std::array<double,2>,5> supportOffsets{{
{{0.0,0.0}},{{0.45,0.0}},{{-0.45,0.0}},{{0.0,0.45}},{{0.0,-0.45}}}};
constexpr std::array<double,2> supportDepthsMetres{{0.125,0.25}};
struct FPathSample
{
std::size_t segment=0;
std::array<double,4> point{};
bool nativeSupported=false;
};
const auto nativeSupportedAt=[&](const std::array<double,4>& point)
{
const double floorQ=point[2]-point[3]+0.13*qPerMetre;
std::uint32_t supported=0;
for(const auto& offset:supportOffsets)
{
bool hasSolid=false;
for(const double depth:supportDepthsMetres)
{
const double sampleZ=floorQ-depth*qPerMetre;
// Bridge spans address the measured SurfaceWorld void. Other native
// strata retain their own route/cave composition and are excluded here.
if(!inSurfaceWorldStratum(sampleZ)){hasSolid=true;break;}
float density=1.0f;
if(!NativeSurfaceDensityAt(
static_cast<float>((point[0]+offset[0]*qPerMetre)/Q),
static_cast<float>((point[1]+offset[1]*qPerMetre)/Q),
static_cast<float>(sampleZ/Q),density))continue;
if(density<0.0f){hasSolid=true;break;}
}
supported+=hasSolid;
}
return supported>=3;
};
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();
++passageIndex)
{
const auto& passage=ResolvedLayout->passages[passageIndex];
if(passage.controlPoints.size()<2)continue;
std::vector<FPathSample> samples;
samples.reserve(passage.controlPoints.size()*2);
const auto pointAt=[&](std::size_t segment,double t)
{
const auto& a=passage.controlPoints[segment];
const auto& b=passage.controlPoints[segment+1];
FPathSample sample;sample.segment=segment;
for(std::size_t axis=0;axis<3;++axis)
sample.point[axis]=a.positionSubvoxels[axis]+t*(
static_cast<double>(b.positionSubvoxels[axis])
-a.positionSubvoxels[axis]);
sample.point[3]=a.radiusSubvoxels+t*(
static_cast<double>(b.radiusSubvoxels)-a.radiusSubvoxels);
sample.nativeSupported=nativeSupportedAt(sample.point);
return sample;
};
samples.push_back(pointAt(0,0.0));
for(std::size_t segment=0;segment+1<passage.controlPoints.size();++segment)
{
const auto& a=passage.controlPoints[segment];
const auto& b=passage.controlPoints[segment+1];
const double dx=static_cast<double>(b.positionSubvoxels[0])-a.positionSubvoxels[0];
const double dy=static_cast<double>(b.positionSubvoxels[1])-a.positionSubvoxels[1];
const double dz=static_cast<double>(b.positionSubvoxels[2])-a.positionSubvoxels[2];
const double lengthMetres=DeterministicSqrt(dx*dx+dy*dy+dz*dz)/qPerMetre;
const std::size_t intervals=std::max<std::size_t>(1,
static_cast<std::size_t>(std::ceil(lengthMetres/0.5)));
for(std::size_t step=1;step<=intervals;++step)
samples.push_back(pointAt(segment,static_cast<double>(step)/intervals));
}
std::size_t cursor=0;
while(cursor<samples.size())
{
if(samples[cursor].nativeSupported){++cursor;continue;}
const std::size_t gapBegin=cursor;
while(cursor<samples.size()&&!samples[cursor].nativeSupported)++cursor;
const std::size_t gapEnd=cursor-1;
if(gapBegin==0||cursor>=samples.size())continue;
double gapLength=0.0;
for(std::size_t index=gapBegin;index<=gapEnd;++index)
{
const auto& a=samples[index-1].point;
const auto& b=samples[index].point;
const double dx=b[0]-a[0],dy=b[1]-a[1],dz=b[2]-a[2];
gapLength+=DeterministicSqrt(dx*dx+dy*dy+dz*dz)/qPerMetre;
}
if(gapLength<1.0)continue;
FStandalonePassageBridgeRange range;
range.passageIndex=passageIndex;
range.firstSegment=samples[gapBegin-1].segment;
range.lastSegment=samples[cursor].segment;
range.unsupportedSamples=gapEnd-gapBegin+1;
range.unsupportedLengthMetres=gapLength;
range.startPoint=samples[gapBegin-1].point;
range.endPoint=samples[cursor].point;
PassageBridgeRanges.push_back(range);
std::printf("[PassageRockBridgePlan] id=%s first_segment=%zu last_segment=%zu unsupported_samples=%llu gap_length_m=%.3f connected_start=1 connected_end=1 width_m=6.000 thickness_m=3.000..5.000 status=PLANNED\n",
passage.stableId.c_str(),range.firstSegment,range.lastSegment,
static_cast<unsigned long long>(range.unsupportedSamples),gapLength);
}
if(std::none_of(PassageBridgeRanges.begin(),PassageBridgeRanges.end(),
[passageIndex](const auto& range){return range.passageIndex==passageIndex;}))
std::printf("[PassageRockBridgePlan] id=%s spans=0 status=NOT_REQUIRED\n",
passage.stableId.c_str());
}
cache.byLayout.emplace(ResolvedLayout->stableIdentity,PassageBridgeRanges);
}
static uint64 PackLatticeKey(int32 X,int32 Y,int32 Z)
{
constexpr uint64 Mask=0x1FFFFFull;
@@ -1656,17 +1939,19 @@ private:
float* OutDetailDisplacement=nullptr,
float* OutCaveInfluence=nullptr,
float* OutFloorInfluence=nullptr,
bool bApplyEdits=true) const
bool bApplyEdits=true,bool bApplyComposition=true) const
{
if(SharedDensitySource)return SharedDensitySource->AnalyticDensityAt(X,Y,Z,
bClampNearZero,OutDetailDisplacement,OutCaveInfluence,OutFloorInfluence,bApplyEdits);
bClampNearZero,OutDetailDisplacement,OutCaveInfluence,OutFloorInfluence,
bApplyEdits,bApplyComposition);
if(OutDetailDisplacement)*OutDetailDisplacement=0.0f;
if(OutCaveInfluence)*OutCaveInfluence=0.0f;
if(OutFloorInfluence)*OutFloorInfluence=0.0f;
float IslandDensity=0.0f;
if(NativeFloatingIslandDensityAt(X,Y,Z,IslandDensity))
{
const float composed=ApplyResolvedStrateComposition(IslandDensity,X,Y,Z);
const float composed=bApplyComposition
?ApplyResolvedStrateComposition(IslandDensity,X,Y,Z):IslandDensity;
return bApplyEdits?ApplyEditBrushes(composed,X,Y,Z):composed;
}
if(UsesLegacySurfaceField(X,Y,Z))
@@ -1674,11 +1959,13 @@ private:
float NativeDensity=0.0f;
if(NativeSurfaceDensityAt(X,Y,Z,NativeDensity))
{
NativeDensity=ApplyResolvedStrateComposition(NativeDensity,X,Y,Z);
if(bApplyComposition)
NativeDensity=ApplyResolvedStrateComposition(NativeDensity,X,Y,Z);
return bApplyEdits?ApplyEditBrushes(NativeDensity,X,Y,Z):NativeDensity;
}
const float Density=Owner->Generator->GetDensityAt(X,Y,Z);
const float composed=ApplyResolvedStrateComposition(Density,X,Y,Z);
const float composed=bApplyComposition
?ApplyResolvedStrateComposition(Density,X,Y,Z):Density;
return bApplyEdits?ApplyEditBrushes(composed,X,Y,Z):composed;
}
const bool bInsideFine=X>=Min[0]&&X<=Max[0]&&Y>=Min[1]&&Y<=Max[1]
@@ -1693,7 +1980,8 @@ private:
if((Density<0.0f)!=bRock||(bClampNearZero&&std::abs(Density)<0.05f))
Density=(bRock?-1.0f:1.0f)*std::max(std::abs(Density),
bClampNearZero?0.05f:1.0e-7f);
const float composed=ApplyResolvedStrateComposition(Density,X,Y,Z);
const float composed=bApplyComposition
?ApplyResolvedStrateComposition(Density,X,Y,Z):Density;
return bApplyEdits?ApplyEditBrushes(composed,X,Y,Z):composed;
}
ESurfaceFamily SurfaceFamily=ESurfaceFamily::Strata;float SurfaceSDF=100000.0f;
@@ -1723,7 +2011,7 @@ private:
if((Density<0.0f)!=bRock||(bClampNearZero&&std::abs(Density)<0.05f))
Density=(bRock?-1.0f:1.0f)*std::max(std::abs(Density),
bClampNearZero?0.05f:1.0e-7f);
Density=ApplyResolvedStrateComposition(Density,X,Y,Z);
if(bApplyComposition)Density=ApplyResolvedStrateComposition(Density,X,Y,Z);
return bApplyEdits?ApplyEditBrushes(Density,X,Y,Z):Density;
}
@@ -5863,6 +6151,7 @@ private:
std::vector<FFarConnectorSegment> FarConnectorSegments;
std::unordered_map<FBinKey,std::vector<uint32>,FBinHash> FarConnectorSpatialBins;
std::vector<FEditBrush> EditBrushes;
std::vector<FStandalonePassageBridgeRange> PassageBridgeRanges;
std::array<FAxisBins,3> AxisBins;
std::unordered_map<FBinKey,FBinItems,FBinHash> SpatialBins;
std::unordered_map<FBinKey,FBinItems,FBinHash> CriticalAirBins;
+62
View File
@@ -1164,6 +1164,44 @@ namespace VoxelForgeCore
}
return false;
}
bool ResolvedPassageTouchesBox(const ResolvedLayoutSnapshotV3& layout,
const FIntVector& minimum,const FIntVector& maximum,std::uint32_t coreVoxelSizeMicrons)
{
if(layout.passages.empty())return false;
constexpr double Q=static_cast<double>(WorldAssemblySubvoxelsPerVoxel);
const double voxelsPerMetre=coreVoxelSizeMicrons>0
?1000000.0/coreVoxelSizeMicrons:4.0;
const double bridgeHalfWidthVoxels=3.5*voxelsPerMetre;
const double bridgeFootDepthVoxels=(5.0-0.13)*voxelsPerMetre;
const double tileMinimum[3]={static_cast<double>(minimum.X),
static_cast<double>(minimum.Y),static_cast<double>(minimum.Z)};
const double tileMaximum[3]={static_cast<double>(maximum.X),
static_cast<double>(maximum.Y),static_cast<double>(maximum.Z)};
for(const auto& passage:layout.passages)
for(std::size_t segment=1;segment<passage.controlPoints.size();++segment)
{
const auto& a=passage.controlPoints[segment-1];
const auto& b=passage.controlPoints[segment];
const double radius=static_cast<double>(std::max(
a.radiusSubvoxels,b.radiusSubvoxels))/Q;
const double horizontalExtent=std::max(radius,bridgeHalfWidthVoxels);
const double low[3]={
std::min(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q-horizontalExtent,
std::min(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q-horizontalExtent,
std::min(a.positionSubvoxels[2],b.positionSubvoxels[2])/Q-radius
-bridgeFootDepthVoxels};
const double high[3]={
std::max(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q+horizontalExtent,
std::max(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q+horizontalExtent,
std::max(a.positionSubvoxels[2],b.positionSubvoxels[2])/Q+radius};
bool overlap=true;
for(int axis=0;axis<3;++axis)
overlap&=high[axis]>=tileMinimum[axis]&&low[axis]<=tileMaximum[axis];
if(overlap)return true;
}
return false;
}
}
bool World::compile(const ShapeBuildRequest& request,const JobScheduler& scheduler,std::string& error)
@@ -1246,6 +1284,8 @@ namespace VoxelForgeCore
if(IntersectsBox(feature.minimumSubvoxels,feature.maximumSubvoxels,
subMinimum,subMaximum))return false;
if(RouteTouchesBox(*selectedPlan,subMinimum,subMaximum))return false;
if(ResolvedPassageTouchesBox(*impl_->resolvedLayout,boundsMin,boundsMax,
impl_->owner->CoreVoxelSizeMicrons))return false;
if(OwnerPassageTouchesBox(*impl_->owner,boundsMin,boundsMax))return false;
FStandaloneShapeWorld proofGeometry;
if(!proofGeometry.BuildShapeDependencyProof(*impl_->owner,boundsMin,boundsMax,
@@ -1502,6 +1542,28 @@ namespace VoxelForgeCore
float World::densityAt(Vec3d position) const
{ return impl_&&impl_->shapeReady.load(std::memory_order_acquire)&&impl_->shape?impl_->shape->DensityAt(static_cast<float>(position.x),static_cast<float>(position.y),static_cast<float>(position.z)):0.0f; }
std::vector<PassageBridgeRangeAuditV1> World::passageBridgeRanges() const
{
std::vector<PassageBridgeRangeAuditV1> result;
if(!impl_||!impl_->shapeReady.load(std::memory_order_acquire)||!impl_->shape)return result;
const auto& ranges=impl_->shape->GetPassageBridgeRanges();
result.reserve(ranges.size());
for(const auto& range:ranges)
{
PassageBridgeRangeAuditV1 value;
value.passageIndex=range.passageIndex;value.firstSegment=range.firstSegment;
value.lastSegment=range.lastSegment;value.unsupportedSamples=range.unsupportedSamples;
value.unsupportedLengthMetres=range.unsupportedLengthMetres;
value.startPointSubvoxels=range.startPoint;value.endPointSubvoxels=range.endPoint;
result.push_back(value);
}
return result;
}
bool World::isPassageBridgeSample(std::size_t passageIndex,std::size_t segmentIndex,
Vec3d position) const
{return impl_&&impl_->shapeReady.load(std::memory_order_acquire)&&impl_->shape
&&impl_->shape->IsResolvedPassageBridgeSample(passageIndex,segmentIndex,
{position.x,position.y,position.z});}
std::string World::densityDispatchPathAt(Vec3d position) const
{ return impl_&&impl_->shapeReady.load(std::memory_order_acquire)&&impl_->shape
?impl_->shape->DensityDispatchPathAt(static_cast<float>(position.x),static_cast<float>(position.y),static_cast<float>(position.z))
@@ -0,0 +1,144 @@
# World Assembler L26 — passages walkable in rock
**All four styles pass for both recipes.** Clang and GCC report zero blocked capsule samples, zero
unsupported samples, zero grade failures, zero open-air violations, passing naturalness, and passing
route bindings. The L24 open-air control and L23 smooth-wall control were detected.
## Where support was missing
In the owner SurfaceWorld recipe, the default Spiral passage has 1,083 control points. Its unsupported
bridge range is segments 98–1077, a 1,957.395 m gap. Segment 98 is at about `(0,-5,-142.7) m`; segment
1077 is at `(-4.6,-1.9,-497.4) m`. Both are inside the SurfaceWorld stratum (`-632..-120 m`), below
its native terrain. The gap starts after the TunnelNetwork transition; it is neither TunnelNetwork
cave air nor a stratum seam. The first L25 failure sample had only 2/5 native support probes, and
following samples had 0/5. Their dispatch path was `SurfaceWorld-native`.
Core now scans the native field sign and adds a deterministic bridge only over contiguous unsupported
ranges. The shared density field gives the bridge at least 5 m width, 3–5 m planned thickness and
surface relief. The audit measured two connected ends, at least 5 m width, 256/256 cross-sections,
3.5–6 m thickness and 2.5 m relief on the default Spiral. All four SurfaceWorld styles use connected
bridges; Floating Islands already has supporting rock and needs none. The capsule clearance gate also
checks the resolved player capsule, fixing FI styles 0/1/3 at their bent mouth segments.
The first bridge export still contained no passage mesh because tile readiness classified all nearby
tiles as native-only. Resolved passage and bridge bounds now keep those tiles shape-dependent. The final
local export changed `shape_free_desired` from 27/27 to 4/27 and contains the composed bridge density.
## Eight-row audit
Counts are from the Clang W12 run; GCC W12 matched every row. `B/U/G` means blocked, unsupported and
grade failures. Route bindings are required bindings passed / required bindings.
| Recipe | Style | Capsule samples | Support samples | B/U/G | Open-air samples / violations | Wall relief | Bindings | Bridge segments / length |
|---|---:|---:|---:|---:|---:|---:|---:|---|
| SurfaceWorld | 0 | 301,140 | 32,765 | 0/0/0 | 3,887,808 / 0 | 0.472 m | 1/1 | 30–293 / 2,004.318 m |
| SurfaceWorld | 1 | 284,949 | 31,046 | 0/0/0 | 3,707,328 / 0 | 0.449 m | 1/1 | 33–357 / 1,945.857 m |
| SurfaceWorld | 2 | 275,877 | 30,072 | 0/0/0 | 3,664,064 / 0 | 0.410 m | 1/1 | 98–1077 / 1,957.395 m |
| SurfaceWorld | 3 | 287,154 | 31,298 | 0/0/0 | 3,741,792 / 0 | 0.552 m | 1/1 | 34–373 / 1,980.607 m |
| Floating Islands | 0 | 50,589 | 4,407 | 0/0/0 | 695,616 / 0 | 0.779 m | 2/2 | none |
| Floating Islands | 1 | 57,015 | 5,060 | 0/0/0 | 742,016 / 0 | 0.806 m | 2/2 | none |
| Floating Islands | 2 | 61,173 | 5,318 | 0/0/0 | 813,632 / 0 | 0.767 m | 2/2 | none |
| Floating Islands | 3 | 54,369 | 4,325 | 0/0/0 | 743,456 / 0 | 0.681 m | 2/2 | none |
Every row passed naturalness (0 m flat run; relief threshold 0.2 m), route binding and strict layout
validation. The validator accepted with zero issues and rejected its malformed controls 9/9. Each L24
open-air negative control and L23 smooth-wall negative control was detected.
## Captures
All are 16:9 JPEGs below 300 KB in `captures/`:
| Capture | View | Size | SHA-256 |
|---|---|---:|---|
| `sw-passage-outside.jpg` | Midspan from outside, 1920×1080 | 90,937 B | `28378eeee755faf7446c0b2ce0eb8d2368c79b42f7de4c15e8b2f4d58fb7754d` |
| `sw-passage-inside.jpg` | Eye-height at first bridged segment, 1600×900 | 47,519 B | `ccadc33c36366a0ca7b2fcda0a21e4cea67bda107f0e20015171fd620d495249` |
| `sw-natural-bridge-wide.jpg` | Wide midspan view, 1920×1080 | 70,192 B | `f4a66fec1adebfbdf5806bb2e7c5a6470e3e8d9dcd60f495d930bbb1d0c5669e` |
| `fi-pillar-exterior.jpg` | Floating Islands pillar exterior, 1600×900 | 35,857 B | `b977ff34acee1294a24c2465b1c9d3d78014cff4b8eceb667f317a0a0b46cc67` |
## Determinism and regressions
The L25 hash command was rerun with the L26 binaries for both recipes, W1/W8/W12, Clang/GCC:
```sh
timeout 1800s taskset -c 0-11 env LP_NUM_THREADS=12 prlimit --as=6442450944 -- \
Saved/Linux/bin/VoxelForgeCoreHeadless-linux26-<clang|gcc> \
--world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate \
--clip-radius=3 --max-clip-level=8 --far-horizon-lod8-step=0 --workers=N \
--recipe=<surface-world|floating-islands> Standalone/data/owner_world.json
```
All six runs per recipe matched. Hash vectors are density / mesh / payload / topology; full detail is
960 tiles and whole view is 2,370 tiles.
| Recipe | Full detail | Whole view | Exact query: density / unclamped / detail / collision |
|---|---|---|---|
| SurfaceWorld | `ace56c8f205238ad / a9c603a1248de6b8 / ea55f1f4fcc6a894 / 5ea7bc78a1b678ae` | `307d5df80e0165b4 / 1d61f30e5733beca / 3aaef136176c4b12 / aa5ff7c2a821196f` | `c949c4df2ce6f9d9 / c949c4df2ce6f9d9 / 114c501e2d830d94 / e6011d3a248d4849` |
| Floating Islands | `d18e722b37a2479e / 0e410a8e80a3e7f7 / 0751926f0c67d8a4 / f01208bc2f7841ec` | `51decfb71d282506 / 69448ec1c7fc954f / e2ff37c98fe8e494 / 5beeb7f94fdbf3d4` | `7b7c50ac24ccadcc / 7b7c50ac24ccadcc / efcba20c0c70c415 / e604823a249029bf` |
The 24 m crossing passed for both compilers and recipes. Each processed 314 moving tiles, with identical
compiler hashes. Moving-tile vectors (density / mesh / payload / topology): SurfaceWorld
`3561ea23485e359f / e8331620fb0fb908 / 765f7dad67c852aa / 3ccc09ac81c05d71`; Floating Islands
`e3d0ea833bca4215 / 6b3d0f148ed83d93 / d6ed85f16acd895e / 9745683036522461`.
SurfaceWorld away from the passage was compared directly between L25 Clang and final L26 Clang at
`--camera=10000,10000,-100,0,0`. Full detail, whole view, all LOD0–8 rows and exact-query hashes were
identical (12/12). Full-detail vector: `1c6abc5e9c657e98 / a1624a3c19bbe554 / bf98934c9d846f3a /
bbdc2a6b821c66d6`; whole-view vector: `40c2be0c7bbdaf28 / 7d9ac2a85020dc7d / c378e48bab2d194f /
81014ec4b888107a`; exact-query vector: `482500abbe835b11 / c4948c7179963784 / efcba20c0c70c415 /
137e8f6c0b03a624`.
Strict validation passed on both compilers and recipes. L13 route parity passed on both compilers/recipes:
8/8 page pairs, 14 higher-LOD pairs, one edit pair, 782,026 exact-query samples and zero mismatches.
For L9 proofs, the passage-centered view has no eligible native blocks. At the same 10 km away-from-route
view, SurfaceWorld checked 4,848 blocks / 6,452,688 samples with 1,296 fallbacks and zero violations
on both compilers. Floating Islands had its expected 21,504 unknown fallbacks and zero violations.
Final headless binary SHA-256: Clang `fc0a5a74f17566384e094cb2429d8925147dd3eb32fb925417393e00c9bb19d5`; GCC
`54843bef3a64087e55d3eb9a76fb0856162b6ad9aeb03d6e1c204c3e91d21ca5`.
Clang built with FP contraction off; GCC used its default FP mode. Both built and started without the L3
FP-contract self-test rejecting them. Core evaluator version is 13; FI geometry remains 7 and layout
schema V3 is unchanged. Changes are shared Core, standalone audits, Linux build output configuration,
and ARCHITECTURE §8.44 / CODEMAP §3.27. No Unreal files changed, and no async path was added. The L4
`FLazy`, L7 cache, L9/L12 proofs, L11 readiness/crash handling, L13 binding, L18/L19 ceiling,
L21/L22 layout and bands, L23–L25 passage/helix, §8.10 and CLAUDE.md async rules remain intact.
## Failed and retried runs
- The first build command used an invalid `clang` variant; corrected to Clang/GCC variants. Early build
iterations R3–R6 had compiler errors and were corrected before final binaries were produced.
- An unsupported `--world-assembler-audit` option exited 2; the correct option is
`--audit-resolved-layout-passages`. One early invocation omitted that flag and performed no passage
audit. Early bridge probes also segfaulted while crossing stratum dispatch; final audits use bounded
resolved-layout queries.
- Support iterations R22–R30 exposed successive failures: FI style 0 had 767, then 27, then 5 blocked /
33 unsupported samples; an offset experiment caused 746 unsupported samples; a control-point capsule
reference left 7 blocked samples. Correcting the capsule reference cleared those. R30 still had SW
bridge sections 254/255, four SW style-1 mouth blocks, and an invalid SW style-2 bridge thickness
sample. R31 corrected them; final matrix is clean.
- The first final audit batch labeled FI JSON files as Floating Islands but omitted `--recipe`, so those
invocations used SurfaceWorld. All 16 style audits were rerun with explicit recipe flags. An initial
proof run used `--force-generate`, which disables L9 block auditing; it was repeated without that flag.
The validator-only command also exited 2 until the required streaming flags were included; all four
corrected strict-validator runs passed.
- `FloorProfileBlend` still reports its L25 alternate-style failures: SurfaceWorld style 1 is 2.544 vox
over the 2.000 threshold and style 3 is 3.645 vox. Both values are identical in the L25 logs; they are
pre-existing and are not capsule, support, open-air or naturalness failures.
- Initial capture attempts used a wrong yaw and missed/partially missed the FI export volume. After
correcting the view and centering the export, the final captures above were rendered. Several inside
camera placements showed wall-only or void-only views; the selected interior frame is at the first
bridged segment.
No run exceeded 30 minutes or remained stuck for 15 minutes. Exports and logs are under `Saved/Linux/`;
this round added only this report and the four small JPEGs under `Standalone/`. An unrelated pre-existing
untracked `Linux18/exports/` directory was left untouched. No Unreal edits, commit, push or stash were made.
## Orchestrator review (Claude) — side branch, not merged
- The audits pass (8/8 rows at 0/0/0), but the SW "natural bridge" is a ~2 km rock ramp spiralling through the
open SurfaceWorld sky from the ceiling (≈−143 m) to the ground (≈−497 m). `sw-natural-bridge-wide.jpg` and
`sw-passage-outside.jpg` show fragmented floating slabs with thin shard spikes: not natural, and visible
from far away.
- Decision (delegated by the owner): one shared mechanism for every strate. When a passage must cross a large
open void inside a strate, it descends inside a natural rock column (ceiling-to-ground, like a
stalactite/stalagmite pair joined), with the spiral tunnel inside, generalising the L25 FI anchor root.
No long bridges through open air. Implemented in L27 on `wip/l25-helix`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

+23
View File
@@ -10,7 +10,11 @@
#include "VoxelTerrainOpDefinition.h"
#include <cmath>
#include <array>
#include <cstdint>
#include <memory>
#include <mutex>
#include <unordered_map>
struct FStandaloneParitySample
{
@@ -20,6 +24,23 @@ struct FStandaloneParitySample
int32 StrateIndex = INDEX_NONE;
};
struct FStandalonePassageBridgeRange
{
std::size_t passageIndex=0;
std::size_t firstSegment=0;
std::size_t lastSegment=0;
std::uint64_t unsupportedSamples=0;
double unsupportedLengthMetres=0.0;
std::array<double,4> startPoint{};
std::array<double,4> endPoint{};
};
struct FStandalonePassageBridgeCache
{
std::mutex mutex;
std::unordered_map<std::string,std::vector<FStandalonePassageBridgeRange>> byLayout;
};
struct FStandaloneOwnerWorld
{
std::unique_ptr<UVoxelSettings> Settings;
@@ -45,6 +66,8 @@ struct FStandaloneOwnerWorld
std::uint32_t CoreVoxelSizeMicrons = 250000;
std::uint32_t StrateLayoutChunkSizeMicrometres = 8000000;
std::int64_t StrateLayoutChunkWidthSubvoxels = 8192;
std::shared_ptr<FStandalonePassageBridgeCache> PassageBridgeCache =
std::make_shared<FStandalonePassageBridgeCache>();
};
namespace StandaloneOwnerLoader
+283 -18
View File
@@ -458,15 +458,26 @@ namespace StandaloneStreamBenchmark
bool hasDeepUnsupported=false;
bool passed=false;
};
struct FPassageSegmentSupportAudit
{
std::uint64_t centers=0,unsupported=0,nativeUnsupported=0;
std::array<double,3> firstUnsupported{};
std::array<double,4> firstNativeDensities{};
std::uint32_t firstNativeSupportedProbes=0;
bool hasUnsupported=false;
};
const double coreMetres=static_cast<double>(World.CoreVoxelSizeMicrons)/1000000.0;
const auto auditPlayerPath=[&](const VoxelForgeCore::World& Field,
const std::vector<std::array<double,3>>& path,
double supportStartMetres,double supportStepMetres,
double supportMaximumMetres,std::uint32_t minimumSupportProbes,
double supportProbeRadiusMetres)
double supportProbeRadiusMetres,
const VoxelForgeCore::World* nativeField=nullptr,
std::vector<FPassageSegmentSupportAudit>* segmentSupport=nullptr)
{
FWalkAudit audit;
if(path.size()<2)return audit;
if(segmentSupport)segmentSupport->assign(path.size()-1,{});
constexpr std::array<double,7> heights{{-0.84,-0.60,-0.30,0.0,0.30,0.60,0.84}};
constexpr std::array<std::array<double,2>,8> directions{{
{{1.0,0.0}},{{0.7071067811865475,0.7071067811865475}},{{0.0,1.0}},
@@ -510,6 +521,9 @@ namespace StandaloneStreamBenchmark
const double y=(a[1]+dy*t)*coreMetres;
const double z=(a[2]+dz*t)*coreMetres;
++audit.centers;
FPassageSegmentSupportAudit* segmentAudit=segmentSupport
?&(*segmentSupport)[segment-1]:nullptr;
if(segmentAudit)++segmentAudit->centers;
for(const double h:heights)
{
const double capOffset=std::max(0.0,std::abs(h)-0.54);
@@ -526,6 +540,7 @@ namespace StandaloneStreamBenchmark
{{0.0,supportProbeRadiusMetres}},
{{0.0,-supportProbeRadiusMetres}}}};
std::uint32_t supportedProbes=0;
std::uint32_t nativeSupportedProbes=0;
double firstUnsupportedX=x,firstUnsupportedY=y,lastUnsupportedDensity=0.0;
std::array<bool,5> supportMask{};
for(std::size_t offsetIndex=0;offsetIndex<supportOffsets.size();++offsetIndex)
@@ -544,12 +559,41 @@ namespace StandaloneStreamBenchmark
supported=true;break;
}
}
if(nativeField)
{
for(double depth=supportStartMetres;
depth<=supportMaximumMetres+1.0e-6;depth+=supportStepMetres)
if(nativeField->densityAt({supportX/coreMetres,
supportY/coreMetres,(footZ-depth)/coreMetres})<0.0f)
{++nativeSupportedProbes;break;}
}
if(supported){++supportedProbes;supportMask[offsetIndex]=true;}
else{firstUnsupportedX=supportX;firstUnsupportedY=supportY;}
}
if(nativeField&&segmentAudit
&&nativeSupportedProbes<minimumSupportProbes)
++segmentAudit->nativeUnsupported;
if(supportedProbes<minimumSupportProbes)
{
++audit.unsupported;
if(segmentAudit)
{
++segmentAudit->unsupported;
if(!segmentAudit->hasUnsupported)
{
segmentAudit->hasUnsupported=true;
segmentAudit->firstUnsupported={x,y,footZ};
segmentAudit->firstNativeSupportedProbes=nativeSupportedProbes;
if(nativeField)
{
constexpr std::array<double,4> depths{{0.125,1.0,2.0,4.0}};
for(std::size_t depthIndex=0;depthIndex<depths.size();++depthIndex)
segmentAudit->firstNativeDensities[depthIndex]=nativeField->densityAt({
x/coreMetres,y/coreMetres,
(footZ-depths[depthIndex])/coreMetres});
}
}
}
if(!audit.hasDeepUnsupported&&footZ<-80.0)
{
audit.hasDeepUnsupported=true;
@@ -682,7 +726,7 @@ namespace StandaloneStreamBenchmark
}
struct FPassageOpenAirAudit
{
std::uint64_t supportSamples=0,violations=0,legacyViolations=0;
std::uint64_t supportSamples=0,violations=0,legacyViolations=0,bridgeSamples=0;
std::uint64_t routeSupportSamples=0,routeSupportViolations=0;
std::array<std::array<double,4>,8> firstViolations{};
std::size_t firstViolationCount=0;
@@ -708,11 +752,13 @@ namespace StandaloneStreamBenchmark
{{0.9238795325112867,-0.3826834323650898}}}};
const auto auditPassageOpenAir=[&](const VoxelForgeCore::World& Field,
const VoxelForgeCore::World& Native,
const VoxelForgeCore::ResolvedLayoutPassageV1& passage)
const VoxelForgeCore::ResolvedLayoutPassageV1& passage,
std::size_t passageIndex)
{
FPassageOpenAirAudit audit;
const auto inspect=[&](double xMetres,double yMetres,double floorMetres,
double depthMetres,double supportThicknessMetres,bool routeSupport=false)
double depthMetres,double supportThicknessMetres,bool routeSupport=false,
std::size_t passageSegment=std::numeric_limits<std::size_t>::max())
{
if(depthMetres<=0.0||depthMetres>supportThicknessMetres+1.0e-6)return;
++audit.supportSamples;
@@ -727,6 +773,10 @@ namespace StandaloneStreamBenchmark
++audit.legacyViolations;
if(nativeDensity>=0.0f&&passageDensity<0.0f)
{
const bool connectedBridge=!routeSupport
&&passageSegment!=std::numeric_limits<std::size_t>::max()
&&Field.isPassageBridgeSample(passageIndex,passageSegment,sample);
if(connectedBridge){++audit.bridgeSamples;return;}
audit.routeSupportViolations+=routeSupport;
if(audit.firstViolationCount<audit.firstViolations.size())
audit.firstViolations[audit.firstViolationCount++]={xMetres,yMetres,
@@ -736,7 +786,8 @@ namespace StandaloneStreamBenchmark
};
const auto inspectFloorDisc=[&](double xMetres,double yMetres,double floorMetres,
double supportRadiusMetres,double depthMetres,double supportThicknessMetres,
bool routeSupport=false)
bool routeSupport=false,
std::size_t passageSegment=std::numeric_limits<std::size_t>::max())
{
const std::size_t radialSteps=static_cast<std::size_t>(std::ceil(
supportRadiusMetres/PassageSupportAuditSpacingMetres));
@@ -746,7 +797,8 @@ namespace StandaloneStreamBenchmark
radialStep*PassageSupportAuditSpacingMetres);
for(const auto& direction:PassageSupportAuditDirections)
inspect(xMetres+direction[0]*radial,yMetres+direction[1]*radial,
floorMetres,depthMetres,supportThicknessMetres,routeSupport);
floorMetres,depthMetres,supportThicknessMetres,routeSupport,
passageSegment);
}
};
for(std::size_t segment=1;segment<passage.controlPoints.size();++segment)
@@ -772,7 +824,8 @@ namespace StandaloneStreamBenchmark
+(qToMetres(b.radiusSubvoxels)-qToMetres(a.radiusSubvoxels))*t;
const double floorZ=centerZ-radius+0.20;
for(const double depth:PassageSupportAuditDepthsMetres)
inspectFloorDisc(centerX,centerY,floorZ,radius,depth,1.0);
inspectFloorDisc(centerX,centerY,floorZ,radius,depth,1.0,
false,segment-1);
}
}
const auto upperStratum=std::find_if(ResolvedLayout->strates.begin(),
@@ -841,6 +894,124 @@ namespace StandaloneStreamBenchmark
}
return audit;
};
struct FPassageBridgeAudit
{
std::uint64_t spans=0,connectedEnds=0,crossSections=0,crossSectionFailures=0;
double minimumThicknessMetres=std::numeric_limits<double>::infinity();
double maximumThicknessMetres=0.0;
double thicknessReliefPeakToPeakMetres=0.0;
bool passed=true;
};
const auto auditPassageBridges=[&](const VoxelForgeCore::World& Field,
const VoxelForgeCore::World& Native,
const VoxelForgeCore::ResolvedLayoutPassageV1& passage,
std::size_t passageIndex)
{
FPassageBridgeAudit audit;
const double qMetres=coreMetres
/VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
constexpr std::array<std::array<double,2>,5> supportOffsets{{
{{0.0,0.0}},{{0.45,0.0}},{{-0.45,0.0}},{{0.0,0.45}},{{0.0,-0.45}}}};
const auto endpointConnected=[&](const std::array<double,4>& point)
{
const double x=point[0]*qMetres,y=point[1]*qMetres;
const double floor=point[2]*qMetres-point[3]*qMetres+0.13;
std::uint32_t supported=0;
for(const auto& offset:supportOffsets)
{
bool solid=false;
for(const double depth:{0.125,0.25})
if(Native.densityAt({(x+offset[0])/coreMetres,
(y+offset[1])/coreMetres,(floor-depth)/coreMetres})<0.0f)
{solid=true;break;}
supported+=solid;
}
return supported>=3;
};
const auto bridgeSolidAt=[&](std::size_t segment,double x,double y,double z)
{
return Field.isPassageBridgeSample(passageIndex,segment,
{x/coreMetres,y/coreMetres,z/coreMetres});
};
const auto thicknessAt=[&](std::size_t segment,double x,double y,double floor)
{
double thickness=0.0;
for(double depth=0.125;depth<=6.0+1.0e-6;depth+=0.125)
{
if(!bridgeSolidAt(segment,x,y,floor-depth))break;
thickness=depth;
}
return thickness;
};
for(const auto& range:Field.passageBridgeRanges())
{
if(range.passageIndex!=passageIndex
||range.lastSegment+1>=passage.controlPoints.size())continue;
++audit.spans;
const bool connectedStart=endpointConnected(range.startPointSubvoxels);
const bool connectedEnd=endpointConnected(range.endPointSubvoxels);
audit.connectedEnds+=connectedStart+connectedEnd;
const std::size_t segmentCount=range.lastSegment-range.firstSegment+1;
const std::size_t probeCount=std::min<std::size_t>(256,segmentCount);
double spanMinimumThickness=std::numeric_limits<double>::infinity();
double spanMaximumThickness=0.0;
std::uint64_t spanCrossSections=0,spanCrossSectionFailures=0;
for(std::size_t probe=0;probe<probeCount;++probe)
{
const std::size_t segment=range.firstSegment
+std::min(segmentCount-1,(probe*segmentCount)/probeCount);
const auto& a=passage.controlPoints[segment];
const auto& b=passage.controlPoints[segment+1];
const double ax=qToMetres(a.positionSubvoxels[0]);
const double ay=qToMetres(a.positionSubvoxels[1]);
const double az=qToMetres(a.positionSubvoxels[2]);
const double bx=qToMetres(b.positionSubvoxels[0]);
const double by=qToMetres(b.positionSubvoxels[1]);
const double bz=qToMetres(b.positionSubvoxels[2]);
const double x=(ax+bx)*0.5,y=(ay+by)*0.5;
const double z=(az+bz)*0.5;
const double radius=(qToMetres(a.radiusSubvoxels)
+qToMetres(b.radiusSubvoxels))*0.5;
const double floor=z-radius+0.13;
const double thickness=thicknessAt(segment,x,y,floor);
spanMinimumThickness=std::min(spanMinimumThickness,thickness);
spanMaximumThickness=std::max(spanMaximumThickness,thickness);
audit.minimumThicknessMetres=std::min(audit.minimumThicknessMetres,thickness);
audit.maximumThicknessMetres=std::max(audit.maximumThicknessMetres,thickness);
const double dx=bx-ax,dy=by-ay,horizontal=std::hypot(dx,dy);
if(horizontal<=1.0e-6)continue;
const double nx=dy/horizontal,ny=-dx/horizontal;
bool crossSectionSolid=true;
for(const double offset:{-2.5,0.0,2.5})
crossSectionSolid&=bridgeSolidAt(segment,x+nx*offset,
y+ny*offset,floor-2.0);
++audit.crossSections;
++spanCrossSections;
spanCrossSectionFailures+=!crossSectionSolid;
audit.crossSectionFailures+=!crossSectionSolid;
}
const double relief=std::isfinite(spanMinimumThickness)
?spanMaximumThickness-spanMinimumThickness:0.0;
audit.thicknessReliefPeakToPeakMetres=std::max(
audit.thicknessReliefPeakToPeakMetres,relief);
const bool spanPass=connectedStart&&connectedEnd
&&spanCrossSections>=3&&spanCrossSectionFailures==0
&&spanMinimumThickness>=2.75
&&spanMaximumThickness<=6.5
&&audit.thicknessReliefPeakToPeakMetres>=0.20;
audit.passed&=spanPass;
std::printf("[PassageRockBridgeAudit] id=%s segments=%zu..%zu gap_m=%.3f connected_ends=%d/2 width_at_least_m=5.000 cross_sections=%llu/%llu thickness_m=%.3f..%.3f relief_p2p_m=%.3f status=%s\n",
passage.stableId.c_str(),range.firstSegment,range.lastSegment,
range.unsupportedLengthMetres,static_cast<int>(connectedStart)
+static_cast<int>(connectedEnd),
static_cast<unsigned long long>(spanCrossSections-spanCrossSectionFailures),
static_cast<unsigned long long>(spanCrossSections),
std::isfinite(spanMinimumThickness)?spanMinimumThickness:0.0,
spanMaximumThickness,relief,
spanPass?"PASS":"FAIL");
}
return audit;
};
if(Assembly)
for(const auto& stratum:ResolvedLayout->strates)
{
@@ -939,9 +1110,12 @@ namespace StandaloneStreamBenchmark
};
std::uint64_t passageCount=0,passagePasses=0,blockedControls=0,naturalPasses=0;
std::uint64_t openAirViolations=0,openAirLegacyViolations=0,openAirSamples=0;
std::uint64_t openAirAudits=0;
for(const auto& passage:ResolvedLayout->passages)
std::uint64_t openAirAudits=0,openAirBridgeSamples=0,bridgeSpans=0,
bridgeConnectedEnds=0;
bool bridgeAuditsPassed=true;
for(std::size_t passageIndex=0;passageIndex<ResolvedLayout->passages.size();++passageIndex)
{
const auto& passage=ResolvedLayout->passages[passageIndex];
std::vector<std::array<double,3>> path;path.reserve(passage.controlPoints.size());
for(const auto& point:passage.controlPoints)
{
@@ -951,12 +1125,21 @@ namespace StandaloneStreamBenchmark
path.push_back({qToMetres(point.positionSubvoxels[0])/coreMetres,
qToMetres(point.positionSubvoxels[1])/coreMetres,playerZ/256.0});
}
const FWalkAudit passageAudit=auditPlayerPath(Shape,path,0.125,0.125,0.25,3,0.45);
std::vector<FPassageSegmentSupportAudit> segmentSupport;
const FWalkAudit passageAudit=auditPlayerPath(Shape,path,0.125,0.125,0.25,3,0.45,
&blockedWorld,&segmentSupport);
const FPassageNaturalnessAudit naturalAudit=auditPassageNaturalness(Shape,passage);
const FPassageOpenAirAudit openAirAudit=auditPassageOpenAir(Shape,blockedWorld,passage);
const FPassageOpenAirAudit openAirAudit=auditPassageOpenAir(Shape,blockedWorld,
passage,passageIndex);
const FPassageBridgeAudit bridgeAudit=auditPassageBridges(Shape,blockedWorld,
passage,passageIndex);
openAirSamples+=openAirAudit.supportSamples;
openAirViolations+=openAirAudit.violations;
openAirLegacyViolations+=openAirAudit.legacyViolations;
openAirBridgeSamples+=openAirAudit.bridgeSamples;
bridgeSpans+=bridgeAudit.spans;
bridgeConnectedEnds+=bridgeAudit.connectedEnds;
bridgeAuditsPassed&=bridgeAudit.passed;
++openAirAudits;
const auto radialSquared=[](const std::array<std::int64_t,3>& p)
{return p[0]*p[0]+p[1]*p[1];};
@@ -984,9 +1167,10 @@ namespace StandaloneStreamBenchmark
static_cast<unsigned long long>(naturalAudit.wallSamples),
static_cast<unsigned long long>(naturalAudit.missingWallSamples),
naturalAudit.passed?"PASS":"FAIL");
std::printf("[PassageOpenAirAudit] id=%s support_samples=%llu violations=%llu l24_ungated_violations=%llu route_support_samples=%llu route_support_violations=%llu spacing_m=%.3f status=%s\n",
std::printf("[PassageOpenAirAudit] id=%s support_samples=%llu violations=%llu bridge_samples=%llu l24_ungated_violations=%llu route_support_samples=%llu route_support_violations=%llu spacing_m=%.3f status=%s\n",
passage.stableId.c_str(),static_cast<unsigned long long>(openAirAudit.supportSamples),
static_cast<unsigned long long>(openAirAudit.violations),
static_cast<unsigned long long>(openAirAudit.bridgeSamples),
static_cast<unsigned long long>(openAirAudit.legacyViolations),
static_cast<unsigned long long>(openAirAudit.routeSupportSamples),
static_cast<unsigned long long>(openAirAudit.routeSupportViolations),
@@ -1000,8 +1184,58 @@ namespace StandaloneStreamBenchmark
for(std::size_t i=0;i<passageAudit.firstBlockedCount;++i)
{
const auto& sample=passageAudit.firstBlocked[i];
std::printf("[ResolvedPassageAuditSample] id=%s kind=blocked xyz_m=(%.3f,%.3f,%.3f) density=%.6f\n",
passage.stableId.c_str(),sample[0],sample[1],sample[2],sample[3]);
double nearestDistanceSquared=std::numeric_limits<double>::infinity();
std::size_t nearestSegment=0;
double nearestT=0.0;
double nearestPassageSdf=std::numeric_limits<double>::infinity();
std::size_t nearestPassageSegment=0;
for(std::size_t segment=0;segment+1<path.size();++segment)
{
const auto& a=path[segment];const auto& b=path[segment+1];
const double dx=b[0]-a[0],dy=b[1]-a[1],dz=b[2]-a[2];
const double lengthSquared=dx*dx+dy*dy+dz*dz;
const double t=lengthSquared>0.0?std::clamp(
((sample[0]/coreMetres-a[0])*dx+(sample[1]/coreMetres-a[1])*dy
+(sample[2]/coreMetres-a[2])*dz)/lengthSquared,0.0,1.0):0.0;
const double ex=sample[0]/coreMetres-(a[0]+t*dx);
const double ey=sample[1]/coreMetres-(a[1]+t*dy);
const double ez=sample[2]/coreMetres-(a[2]+t*dz);
const double distanceSquared=ex*ex+ey*ey+ez*ez;
if(distanceSquared<nearestDistanceSquared)
{nearestDistanceSquared=distanceSquared;nearestSegment=segment;nearestT=t;}
}
for(std::size_t segment=0;segment+1<passage.controlPoints.size();++segment)
{
const auto& a=passage.controlPoints[segment];
const auto& b=passage.controlPoints[segment+1];
const double ax=qToMetres(a.positionSubvoxels[0]);
const double ay=qToMetres(a.positionSubvoxels[1]);
const double az=qToMetres(a.positionSubvoxels[2]);
const double dx=qToMetres(b.positionSubvoxels[0]-a.positionSubvoxels[0]);
const double dy=qToMetres(b.positionSubvoxels[1]-a.positionSubvoxels[1]);
const double dz=qToMetres(b.positionSubvoxels[2]-a.positionSubvoxels[2]);
const double lengthSquared=dx*dx+dy*dy+dz*dz;
const double t=lengthSquared>0.0?std::clamp(
((sample[0]-ax)*dx+(sample[1]-ay)*dy+(sample[2]-az)*dz)
/lengthSquared,0.0,1.0):0.0;
const double ex=sample[0]-(ax+t*dx),ey=sample[1]-(ay+t*dy),
ez=sample[2]-(az+t*dz);
const double radius=qToMetres(a.radiusSubvoxels)
+(qToMetres(b.radiusSubvoxels)-qToMetres(a.radiusSubvoxels))*t;
const double signedDistance=std::sqrt(ex*ex+ey*ey+ez*ez)-radius;
if(signedDistance<nearestPassageSdf)
{nearestPassageSdf=signedDistance;nearestPassageSegment=segment;}
}
const VoxelForgeCore::Vec3d nativePosition{sample[0]/coreMetres,
sample[1]/coreMetres,sample[2]/coreMetres};
const float nativeDensity=blockedWorld.densityAt(nativePosition);
const bool bridgeVolume=Shape.isPassageBridgeSample(passageIndex,
nearestSegment,nativePosition);
std::printf("[ResolvedPassageAuditSample] id=%s kind=blocked xyz_m=(%.3f,%.3f,%.3f) density=%.6f native_density=%.6f segment=%zu t=%.3f passage_segment=%zu passage_sdf_m=%.3f bridge_volume=%d native_path=%s\n",
passage.stableId.c_str(),sample[0],sample[1],sample[2],sample[3],
nativeDensity,nearestSegment,nearestT,nearestPassageSegment,
nearestPassageSdf,bridgeVolume?1:0,
blockedWorld.densityDispatchPathAt(nativePosition).c_str());
}
for(std::size_t i=0;i<passageAudit.firstUnsupportedCount;++i)
{
@@ -1010,6 +1244,30 @@ namespace StandaloneStreamBenchmark
passageAudit.firstUnsupported[i][1],passageAudit.firstUnsupported[i][2],
passageAudit.firstUnsupported[i][3]);
}
for(std::size_t segment=0;segment<segmentSupport.size();++segment)
{
const auto& item=segmentSupport[segment];
if(!item.hasUnsupported)continue;
const auto& a=path[segment];const auto& b=path[segment+1];
const auto& sample=item.firstUnsupported;
const double firstX=sample[0]/coreMetres;
const double firstY=sample[1]/coreMetres;
const double firstZ=(sample[2]-0.125)/coreMetres;
const VoxelForgeCore::Vec3d bridgeProbe{sample[0]/coreMetres,
sample[1]/coreMetres,(sample[2]-0.25)/coreMetres};
const bool bridgeAtSupport=Shape.isPassageBridgeSample(passageIndex,
segment,bridgeProbe);
std::printf("[ResolvedPassageSupportSegment] id=%s segment=%zu route_z_m=%.3f..%.3f centers=%llu unsupported=%llu native_unsupported=%llu first_foot_m=(%.3f,%.3f,%.3f) bridge_at_d025=%d native_support_probes=%u/5 native_density_d0125_d1_d2_d4=(%.6f,%.6f,%.6f,%.6f) native_path=%s\n",
passage.stableId.c_str(),segment,
std::min(a[2],b[2])*coreMetres,std::max(a[2],b[2])*coreMetres,
static_cast<unsigned long long>(item.centers),
static_cast<unsigned long long>(item.unsupported),
static_cast<unsigned long long>(item.nativeUnsupported),
sample[0],sample[1],sample[2],bridgeAtSupport?1:0,
item.firstNativeSupportedProbes,item.firstNativeDensities[0],item.firstNativeDensities[1],
item.firstNativeDensities[2],item.firstNativeDensities[3],
blockedWorld.densityDispatchPathAt({firstX,firstY,firstZ}).c_str());
}
}
std::uint64_t routePoints=0,routePasses=0,routeWalkPasses=0,routeBindings=0,routeBindingFailures=0;
struct FRouteAuditInput
@@ -1082,7 +1340,7 @@ namespace StandaloneStreamBenchmark
}
const FWalkAudit routeAudit=auditPlayerPath(Shape,route,supportStartMetres,
supportStepMetres,supportMaximumMetres,minimumSupportProbes,
supportProbeRadiusMetres);
supportProbeRadiusMetres,nullptr,nullptr);
routeAuditInputs.push_back({stratum.strateIndex,route,supportStartMetres,
supportStepMetres,supportMaximumMetres,supportProbeRadiusMetres,
minimumSupportProbes});
@@ -1151,7 +1409,7 @@ namespace StandaloneStreamBenchmark
qToMetres(point.positionSubvoxels[1])/coreMetres,playerZ/256.0});
}
const FWalkAudit blockedAudit=auditPlayerPath(blockedWorld,path,
0.125,0.125,0.25,3,0.45);
0.125,0.125,0.25,3,0.45,nullptr,nullptr);
blockedControls+=blockedAudit.blocked>0&&!blockedAudit.passed;
std::printf("[ResolvedPassageBlockedControl] id=%s blocked_capsule_samples=%llu detected=%s\n",
passage.stableId.c_str(),static_cast<unsigned long long>(blockedAudit.blocked),
@@ -1161,7 +1419,7 @@ namespace StandaloneStreamBenchmark
{
const FWalkAudit controlRoute=auditPlayerPath(blockedWorld,input.path,
input.supportStart,input.supportStep,input.supportMaximum,
input.minimumSupportProbes,input.supportProbeRadius);
input.minimumSupportProbes,input.supportProbeRadius,nullptr,nullptr);
std::printf("[ResolvedStrateRouteBlockedControl] strate=%d blocked=%llu unsupported=%llu status=%s\n",
input.strateIndex,static_cast<unsigned long long>(controlRoute.blocked),
static_cast<unsigned long long>(controlRoute.unsupported),
@@ -1171,13 +1429,19 @@ namespace StandaloneStreamBenchmark
std::printf("[PassageOpenAirNegativeControl] source=L24_ungated_support unsupported_samples=%llu detected=%s\n",
static_cast<unsigned long long>(openAirLegacyViolations),
l24OpenAirControlDetected?"true":"false");
std::printf("[PassageOpenAirAuditSummary] interfaces=%llu samples=%llu violations=%llu l24_negative_control=%s status=%s\n",
std::printf("[PassageOpenAirAuditSummary] interfaces=%llu samples=%llu violations=%llu bridge_samples=%llu l24_negative_control=%s status=%s\n",
static_cast<unsigned long long>(openAirAudits),
static_cast<unsigned long long>(openAirSamples),
static_cast<unsigned long long>(openAirViolations),
static_cast<unsigned long long>(openAirBridgeSamples),
l24OpenAirControlDetected?"DETECTED":"MISSED",
openAirAudits==passageCount&&openAirViolations==0&&l24OpenAirControlDetected
?"PASS":"FAIL");
std::printf("[PassageRockBridgeAuditSummary] spans=%llu connected_ends=%llu/%llu status=%s\n",
static_cast<unsigned long long>(bridgeSpans),
static_cast<unsigned long long>(bridgeConnectedEnds),
static_cast<unsigned long long>(bridgeSpans*2),
bridgeAuditsPassed?"PASS":"FAIL");
const bool l23SmoothWallDetected=!looksNatural(0.0,0.0);
std::printf("[PassageNaturalnessNegativeControl] source=L23_smooth_unrelieved_wall relief_p2p_m=0.000 threshold_m=%.3f detected=%s\n",
MinimumWallReliefMetres,l23SmoothWallDetected?"true":"false");
@@ -1188,6 +1452,7 @@ namespace StandaloneStreamBenchmark
const bool auditPassed=passageCount>0&&passagePasses==passageCount
&&naturalPasses==passageCount&&l23SmoothWallDetected
&&openAirAudits==passageCount&&openAirViolations==0&&l24OpenAirControlDetected
&&bridgeAuditsPassed
&&routePasses>0&&routePasses==routeWalkPasses&&routePasses==routeBindings
&&routeBindingFailures==0
&&blockedCompiled&&blockedControls==passageCount;