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

+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;