wip(L25, side branch): FI helix enclosed in a 13 m rock root; support never created in open air

Fixes the L24 ribbon (owner request). NOT merged: the open-air support gate leaves ~4,000 unsupported
samples on every SurfaceWorld-recipe passage style (TN -> SW), a walkability regression. L26 fixes that
on this branch. See Linux25/REPORT.md.

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 00:38:57 +02:00
1 parent cb9236c265
commit ef789aaa00
14 files changed
+662 -110

No files matched your search

+352 -41
View File
@@ -453,6 +453,9 @@ namespace StandaloneStreamBenchmark
std::array<std::array<double,4>,8> firstUnsupported{};
std::array<std::array<bool,5>,8> firstSupportMasks{};
std::size_t firstBlockedCount=0,firstUnsupportedCount=0;
std::array<double,4> firstDeepUnsupported{};
std::array<bool,5> firstDeepSupportMask{};
bool hasDeepUnsupported=false;
bool passed=false;
};
const double coreMetres=static_cast<double>(World.CoreVoxelSizeMicrons)/1000000.0;
@@ -547,6 +550,13 @@ namespace StandaloneStreamBenchmark
if(supportedProbes<minimumSupportProbes)
{
++audit.unsupported;
if(!audit.hasDeepUnsupported&&footZ<-80.0)
{
audit.hasDeepUnsupported=true;
audit.firstDeepUnsupported={firstUnsupportedX,firstUnsupportedY,
footZ,lastUnsupportedDensity};
audit.firstDeepSupportMask=supportMask;
}
if(audit.firstUnsupportedCount<audit.firstUnsupported.size())
{
const std::size_t sample=audit.firstUnsupportedCount++;
@@ -658,6 +668,267 @@ namespace StandaloneStreamBenchmark
[index](const auto& s){return s.strateIndex==index;});
return it==ResolvedLayout->strates.end()?nullptr:&*it;
};
const auto controlSnapshot=CoreSnapshot.withoutResolvedLayoutPassages();
VoxelForgeCore::World blockedWorld(controlSnapshot);
std::string blockedCompileError;
const bool blockedCompiled=controlSnapshot
&&blockedWorld.compile(ShapeRequest,Scheduler,blockedCompileError);
if(!blockedCompiled)
{
Streamer.Stop();
std::fprintf(stderr,"[ResolvedPassageBlockedControl] compile_failed=%s\n",
blockedCompileError.c_str());
return 10;
}
struct FPassageOpenAirAudit
{
std::uint64_t supportSamples=0,violations=0,legacyViolations=0;
std::uint64_t routeSupportSamples=0,routeSupportViolations=0;
std::array<std::array<double,4>,8> firstViolations{};
std::size_t firstViolationCount=0;
};
constexpr double PassageSupportAuditSpacingMetres=0.25;
constexpr std::array<double,2> PassageSupportAuditDepthsMetres{{0.125,0.375}};
constexpr std::array<std::array<double,2>,16> PassageSupportAuditDirections{{
{{1.0000000000000000,0.0000000000000000}},
{{0.9238795325112867,0.3826834323650898}},
{{0.7071067811865476,0.7071067811865476}},
{{0.3826834323650898,0.9238795325112867}},
{{0.0000000000000000,1.0000000000000000}},
{{-0.3826834323650898,0.9238795325112867}},
{{-0.7071067811865476,0.7071067811865476}},
{{-0.9238795325112867,0.3826834323650898}},
{{-1.0000000000000000,0.0000000000000000}},
{{-0.9238795325112867,-0.3826834323650898}},
{{-0.7071067811865476,-0.7071067811865476}},
{{-0.3826834323650898,-0.9238795325112867}},
{{0.0000000000000000,-1.0000000000000000}},
{{0.3826834323650898,-0.9238795325112867}},
{{0.7071067811865476,-0.7071067811865476}},
{{0.9238795325112867,-0.3826834323650898}}}};
const auto auditPassageOpenAir=[&](const VoxelForgeCore::World& Field,
const VoxelForgeCore::World& Native,
const VoxelForgeCore::ResolvedLayoutPassageV1& passage)
{
FPassageOpenAirAudit audit;
const auto inspect=[&](double xMetres,double yMetres,double floorMetres,
double depthMetres,double supportThicknessMetres,bool routeSupport=false)
{
if(depthMetres<=0.0||depthMetres>supportThicknessMetres+1.0e-6)return;
++audit.supportSamples;
audit.routeSupportSamples+=routeSupport;
const VoxelForgeCore::Vec3d sample{xMetres/coreMetres,yMetres/coreMetres,
(floorMetres-depthMetres)/coreMetres};
const float nativeDensity=Native.densityAt(sample);
const float passageDensity=Field.densityAt(sample);
const float legacySupportDensity=std::min(nativeDensity,
static_cast<float>(-depthMetres/coreMetres));
if(nativeDensity>=0.0f&&legacySupportDensity<0.0f)
++audit.legacyViolations;
if(nativeDensity>=0.0f&&passageDensity<0.0f)
{
audit.routeSupportViolations+=routeSupport;
if(audit.firstViolationCount<audit.firstViolations.size())
audit.firstViolations[audit.firstViolationCount++]={xMetres,yMetres,
floorMetres-depthMetres,passageDensity};
++audit.violations;
}
};
const auto inspectFloorDisc=[&](double xMetres,double yMetres,double floorMetres,
double supportRadiusMetres,double depthMetres,double supportThicknessMetres,
bool routeSupport=false)
{
const std::size_t radialSteps=static_cast<std::size_t>(std::ceil(
supportRadiusMetres/PassageSupportAuditSpacingMetres));
for(std::size_t radialStep=0;radialStep<=radialSteps;++radialStep)
{
const double radial=std::min(supportRadiusMetres,
radialStep*PassageSupportAuditSpacingMetres);
for(const auto& direction:PassageSupportAuditDirections)
inspect(xMetres+direction[0]*radial,yMetres+direction[1]*radial,
floorMetres,depthMetres,supportThicknessMetres,routeSupport);
}
};
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 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 length=std::sqrt((bx-ax)*(bx-ax)+(by-ay)*(by-ay)+(bz-az)*(bz-az));
const std::size_t intervals=std::max<std::size_t>(1,static_cast<std::size_t>(
std::ceil(length/PassageSupportAuditSpacingMetres)));
for(std::size_t sample=0;sample<=intervals;++sample)
{
if(segment>1&&sample==0)continue;
const double t=static_cast<double>(sample)/intervals;
const double centerX=ax+(bx-ax)*t,centerY=ay+(by-ay)*t;
const double centerZ=az+(bz-az)*t;
const double radius=qToMetres(a.radiusSubvoxels)
+(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);
}
}
const auto upperStratum=std::find_if(ResolvedLayout->strates.begin(),
ResolvedLayout->strates.end(),[&](const auto& value)
{return value.strateIndex==passage.upperStrateIndex;});
if(upperStratum!=ResolvedLayout->strates.end())
{
std::array<const VoxelForgeCore::ResolvedLayoutAnchorV2*,5> route{};
std::size_t routeCount=0;
for(const auto& anchor:upperStratum->anchors)
if(anchor.kind=="route_point"&&anchor.values.size()>=3)
{
if(routeCount<route.size())route[routeCount++]=&anchor;
else
{
std::move(route.begin()+1,route.end(),route.begin());
route.back()=&anchor;
}
}
const double mouthX=qToMetres(passage.upperMouthSubvoxels[0]);
const double mouthY=qToMetres(passage.upperMouthSubvoxels[1]);
constexpr double RouteSupportReachMetres=13.0;
constexpr double RouteFloorOffsetMetres=1.20;
constexpr double RouteSupportThicknessMetres=1.0;
constexpr double RouteSupportDepthStepMetres=0.125;
for(std::size_t segment=1;segment<routeCount;++segment)
{
const auto& a=*route[segment-1];
const auto& b=*route[segment];
const double ax=qToMetres(a.values[0]),ay=qToMetres(a.values[1]);
const double az=qToMetres(a.values[2]);
const double bx=qToMetres(b.values[0]),by=qToMetres(b.values[1]);
const double bz=qToMetres(b.values[2]);
const double dx=bx-ax,dy=by-ay,dz=bz-az;
const double length=std::sqrt(dx*dx+dy*dy+dz*dz);
const std::size_t intervals=std::max<std::size_t>(1,
static_cast<std::size_t>(std::ceil(length
/PassageSupportAuditSpacingMetres)));
const double routeRadius=a.values.size()>=4
?std::max(0.75,qToMetres(a.values[3])):0.75;
for(std::size_t sample=0;sample<=intervals;++sample)
{
if(segment>1&&sample==0)continue;
const double t=static_cast<double>(sample)/intervals;
const double centerX=ax+dx*t,centerY=ay+dy*t;
const double centerZ=az+dz*t;
for(std::size_t radialStep=0;radialStep<=static_cast<std::size_t>(
std::ceil(routeRadius/PassageSupportAuditSpacingMetres));++radialStep)
{
const double radial=std::min(routeRadius,
radialStep*PassageSupportAuditSpacingMetres);
for(const auto& direction:PassageSupportAuditDirections)
{
const double x=centerX+direction[0]*radial;
const double y=centerY+direction[1]*radial;
if(std::hypot(x-mouthX,y-mouthY)>RouteSupportReachMetres)continue;
const double floorZ=centerZ-RouteFloorOffsetMetres;
for(double depth=RouteSupportDepthStepMetres;
depth<=RouteSupportThicknessMetres+1.0e-6;
depth+=RouteSupportDepthStepMetres)
inspect(x,y,floorZ,depth,RouteSupportThicknessMetres,true);
}
}
}
}
}
return audit;
};
if(Assembly)
for(const auto& stratum:ResolvedLayout->strates)
{
if(stratum.generatorKind!="FloatingIslands")continue;
const auto anchor=std::find_if(stratum.anchors.begin(),stratum.anchors.end(),
[](const auto& value){return value.kind=="passage_anchor"&&value.values.size()>=7;});
const auto islandPlan=std::find_if(Assembly->floatingIslands.begin(),
Assembly->floatingIslands.end(),[&](const auto& value)
{return value.strateIndex==stratum.strateIndex;});
if(anchor==stratum.anchors.end()||islandPlan==Assembly->floatingIslands.end())continue;
const auto ordinal=islandPlan->manifest.recipe.anchorIslandOrdinal;
if(ordinal>=islandPlan->manifest.plan.islands.size())continue;
const auto& anchorIsland=islandPlan->manifest.plan.islands[ordinal];
const double axisX=qToMetres(anchor->values[0]);
const double axisY=qToMetres(anchor->values[1]);
const double rootBottom=qToMetres(anchor->values[5]);
const auto& islandRecipe=islandPlan->manifest.recipe;
const std::int64_t crustRatioQ16=islandRecipe.thicknessRatioQ16
+islandRecipe.crustDepthBonusQ16;
const std::int64_t crustDepthQ=(anchorIsland.radiusSubvoxels*crustRatioQ16
+32768)/65536;
const double rootTop=qToMetres(anchorIsland.topZSubvoxels-crustDepthQ);
const double nominalRootRadius=qToMetres(anchor->values[2]);
double helixMinimumRadius=std::numeric_limits<double>::infinity();
double helixMaximumRadius=0.0;
for(const auto& passage:ResolvedLayout->passages)
if(passage.upperStrateIndex==stratum.strateIndex)
for(const auto& point:passage.controlPoints)
{
const double z=qToMetres(point.positionSubvoxels[2]);
if(z<rootBottom||z>rootTop)continue;
const double radial=std::hypot(
qToMetres(point.positionSubvoxels[0]-anchor->values[0]),
qToMetres(point.positionSubvoxels[1]-anchor->values[1]));
helixMinimumRadius=std::min(helixMinimumRadius,radial);
helixMaximumRadius=std::max(helixMaximumRadius,radial);
}
if(!std::isfinite(helixMinimumRadius))continue;
double minimumMeasuredRootRadius=std::numeric_limits<double>::infinity();
std::uint64_t rootRaySamples=0;
constexpr std::array<double,5> RootHeightFractions{{0.01,0.25,0.5,0.75,0.99}};
for(const double fraction:RootHeightFractions)
{
const double z=rootTop+(rootBottom-rootTop)*fraction;
double minimumRadius=std::numeric_limits<double>::infinity();
double maximumRadius=0.0,meanRadius=0.0;
constexpr std::size_t DirectionCount=32;
constexpr double RayStepMetres=0.125;
const std::size_t raySteps=static_cast<std::size_t>(std::ceil(
(nominalRootRadius+2.0)/RayStepMetres));
for(std::size_t direction=0;direction<DirectionCount;++direction)
{
const double angle=2.0*3.14159265358979323846*direction/DirectionCount;
double radius=0.0;
for(std::size_t step=0;step<=raySteps;++step)
{
const double probeRadius=step*RayStepMetres;
const VoxelForgeCore::Vec3d probe{
(axisX+probeRadius*std::cos(angle))/coreMetres,
(axisY+probeRadius*std::sin(angle))/coreMetres,z/coreMetres};
if(blockedWorld.densityAt(probe)>=0.0f)break;
radius=probeRadius;
}
minimumRadius=std::min(minimumRadius,radius);
maximumRadius=std::max(maximumRadius,radius);
meanRadius+=radius;
++rootRaySamples;
}
meanRadius/=DirectionCount;
minimumMeasuredRootRadius=std::min(minimumMeasuredRootRadius,minimumRadius);
std::printf("[PassageRootRadiusMeasure] strate=%d z_m=%.3f solid_radius_min_m=%.3f mean_m=%.3f max_m=%.3f nominal_root_m=%.3f rays=%zu\n",
stratum.strateIndex,z,minimumRadius,meanRadius,maximumRadius,
nominalRootRadius,DirectionCount);
}
const auto firstRootPassage=std::find_if(ResolvedLayout->passages.begin(),
ResolvedLayout->passages.end(),[&](const auto& passage)
{return passage.upperStrateIndex==stratum.strateIndex;});
const double mouthBoreRadius=firstRootPassage==ResolvedLayout->passages.end()?0.0
:qToMetres(firstRootPassage->mouthRadiusSubvoxels);
const double midBoreRadius=firstRootPassage==ResolvedLayout->passages.end()?0.0
:qToMetres(firstRootPassage->midRadiusSubvoxels);
const double maximumBoreRadius=std::max(mouthBoreRadius,midBoreRadius);
std::printf("[PassageRootMeasure] strate=%d axis_m=(%.3f,%.3f) helix_centerline_radius_min_m=%.3f max_m=%.3f mouth_bore_radius_m=%.3f mid_bore_radius_m=%.3f nominal_root_m=%.3f measured_min_root_m=%.3f minimum_wall_m=%.3f samples=%llu\n",
stratum.strateIndex,axisX,axisY,helixMinimumRadius,helixMaximumRadius,
mouthBoreRadius,midBoreRadius,nominalRootRadius,minimumMeasuredRootRadius,
minimumMeasuredRootRadius-helixMaximumRadius-maximumBoreRadius,
static_cast<unsigned long long>(rootRaySamples));
}
const auto mouthInContent=[&](std::int32_t index,const std::array<std::int64_t,3>& mouth)
{
const auto* stratum=findStratum(index);if(!stratum)return false;
@@ -667,6 +938,8 @@ namespace StandaloneStreamBenchmark
return zUm>=stratum->content.bottomMicrometres&&zUm<stratum->content.topMicrometres;
};
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::vector<std::array<double,3>> path;path.reserve(passage.controlPoints.size());
@@ -680,6 +953,11 @@ namespace StandaloneStreamBenchmark
}
const FWalkAudit passageAudit=auditPlayerPath(Shape,path,0.125,0.125,0.25,3,0.45);
const FPassageNaturalnessAudit naturalAudit=auditPassageNaturalness(Shape,passage);
const FPassageOpenAirAudit openAirAudit=auditPassageOpenAir(Shape,blockedWorld,passage);
openAirSamples+=openAirAudit.supportSamples;
openAirViolations+=openAirAudit.violations;
openAirLegacyViolations+=openAirAudit.legacyViolations;
++openAirAudits;
const auto radialSquared=[](const std::array<std::int64_t,3>& p)
{return p[0]*p[0]+p[1]*p[1];};
const bool mouthsInRadius=radialSquared(passage.upperMouthSubvoxels)
@@ -706,15 +984,32 @@ 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",
passage.stableId.c_str(),static_cast<unsigned long long>(openAirAudit.supportSamples),
static_cast<unsigned long long>(openAirAudit.violations),
static_cast<unsigned long long>(openAirAudit.legacyViolations),
static_cast<unsigned long long>(openAirAudit.routeSupportSamples),
static_cast<unsigned long long>(openAirAudit.routeSupportViolations),
PassageSupportAuditSpacingMetres,
openAirAudit.violations==0?"PASS":"FAIL");
for(std::size_t i=0;i<openAirAudit.firstViolationCount;++i)
std::printf("[PassageOpenAirAuditSample] id=%s kind=unsupported_support xyz_m=(%.3f,%.3f,%.3f) density=%.6f\n",
passage.stableId.c_str(),openAirAudit.firstViolations[i][0],
openAirAudit.firstViolations[i][1],openAirAudit.firstViolations[i][2],
openAirAudit.firstViolations[i][3]);
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(),passageAudit.firstBlocked[i][0],passageAudit.firstBlocked[i][1],
passageAudit.firstBlocked[i][2],passageAudit.firstBlocked[i][3]);
passage.stableId.c_str(),sample[0],sample[1],sample[2],sample[3]);
}
for(std::size_t i=0;i<passageAudit.firstUnsupportedCount;++i)
{
std::printf("[ResolvedPassageAuditSample] id=%s kind=unsupported xyz_m=(%.3f,%.3f,%.3f) density=%.6f\n",
passage.stableId.c_str(),passageAudit.firstUnsupported[i][0],
passageAudit.firstUnsupported[i][1],passageAudit.firstUnsupported[i][2],
passageAudit.firstUnsupported[i][3]);
}
}
std::uint64_t routePoints=0,routePasses=0,routeWalkPasses=0,routeBindings=0,routeBindingFailures=0;
struct FRouteAuditInput
@@ -798,15 +1093,28 @@ namespace StandaloneStreamBenchmark
{return a[0]==b[0]&&a[1]==b[1]&&a[2]==b[2];};
if(passage.upperStrateIndex==stratum.strateIndex)
{
const std::array<std::int64_t,3> departure{{anchors.back()->values[0],
anchors.back()->values[1],anchors.back()->values[2]}};
const auto rootedMouth=std::find_if(stratum.anchors.begin(),
stratum.anchors.end(),[](const auto& anchor)
{return anchor.kind=="passage_anchor"&&anchor.values.size()>=10;});
const std::array<std::int64_t,3> departure=
rootedMouth!=stratum.anchors.end()
?std::array<std::int64_t,3>{{rootedMouth->values[7],
rootedMouth->values[8],rootedMouth->values[9]}}
:std::array<std::int64_t,3>{{anchors.back()->values[0],
anchors.back()->values[1],anchors.back()->values[2]}};
binding&=equalPosition(passage.upperMouthSubvoxels,
departure);
}
if(passage.lowerStrateIndex==stratum.strateIndex)
{
const std::array<std::int64_t,3> arrival{{anchors.front()->values[0],
anchors.front()->values[1],anchors.front()->values[2]}};
const auto passageArrival=std::find_if(stratum.anchors.begin(),
stratum.anchors.end(),[](const auto& anchor)
{return anchor.kind=="passage_arrival"&&anchor.values.size()>=3;});
const std::array<std::int64_t,3> arrival=passageArrival!=stratum.anchors.end()
?std::array<std::int64_t,3>{{passageArrival->values[0],
passageArrival->values[1],passageArrival->values[2]}}
:std::array<std::int64_t,3>{{anchors.front()->values[0],
anchors.front()->values[1],anchors.front()->values[2]}};
binding&=equalPosition(passage.lowerMouthSubvoxels,
arrival);
}
@@ -831,43 +1139,45 @@ namespace StandaloneStreamBenchmark
routeAudit.firstUnsupported[i][1],routeAudit.firstUnsupported[i][2],
routeAudit.firstUnsupported[i][3]);
}
const auto controlSnapshot=CoreSnapshot.withoutResolvedLayoutPassages();
VoxelForgeCore::World blockedWorld(controlSnapshot);
std::string blockedCompileError;
const bool blockedCompiled=controlSnapshot
&&blockedWorld.compile(ShapeRequest,Scheduler,blockedCompileError);
if(blockedCompiled)
for(const auto& passage:ResolvedLayout->passages)
for(const auto& passage:ResolvedLayout->passages)
{
std::vector<std::array<double,3>> path;path.reserve(passage.controlPoints.size());
for(const auto& point:passage.controlPoints)
{
std::vector<std::array<double,3>> path;path.reserve(passage.controlPoints.size());
for(const auto& point:passage.controlPoints)
{
const double playerZ=static_cast<double>(point.positionSubvoxels[2]
-point.radiusSubvoxels)+1.13*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel
*1000000.0/World.CoreVoxelSizeMicrons;
path.push_back({qToMetres(point.positionSubvoxels[0])/coreMetres,
qToMetres(point.positionSubvoxels[1])/coreMetres,playerZ/256.0});
}
const FWalkAudit blockedAudit=auditPlayerPath(blockedWorld,path,
0.125,0.125,0.25,3,0.45);
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),
blockedAudit.blocked>0&&!blockedAudit.passed?"true":"false");
}
else
std::fprintf(stderr,"[ResolvedPassageBlockedControl] compile_failed=%s\n",blockedCompileError.c_str());
if(blockedCompiled)
for(const auto& input:routeAuditInputs)
{
const FWalkAudit controlRoute=auditPlayerPath(blockedWorld,input.path,
input.supportStart,input.supportStep,input.supportMaximum,
input.minimumSupportProbes,input.supportProbeRadius);
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),
controlRoute.passed?"PASS":"FAIL");
const double playerZ=static_cast<double>(point.positionSubvoxels[2]
-point.radiusSubvoxels)+1.13*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel
*1000000.0/World.CoreVoxelSizeMicrons;
path.push_back({qToMetres(point.positionSubvoxels[0])/coreMetres,
qToMetres(point.positionSubvoxels[1])/coreMetres,playerZ/256.0});
}
const FWalkAudit blockedAudit=auditPlayerPath(blockedWorld,path,
0.125,0.125,0.25,3,0.45);
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),
blockedAudit.blocked>0&&!blockedAudit.passed?"true":"false");
}
for(const auto& input:routeAuditInputs)
{
const FWalkAudit controlRoute=auditPlayerPath(blockedWorld,input.path,
input.supportStart,input.supportStep,input.supportMaximum,
input.minimumSupportProbes,input.supportProbeRadius);
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),
controlRoute.passed?"PASS":"FAIL");
}
const bool l24OpenAirControlDetected=openAirLegacyViolations>0;
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",
static_cast<unsigned long long>(openAirAudits),
static_cast<unsigned long long>(openAirSamples),
static_cast<unsigned long long>(openAirViolations),
l24OpenAirControlDetected?"DETECTED":"MISSED",
openAirAudits==passageCount&&openAirViolations==0&&l24OpenAirControlDetected
?"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");
@@ -877,6 +1187,7 @@ namespace StandaloneStreamBenchmark
MinimumWallReliefMetres,naturalPasses==passageCount&&l23SmoothWallDetected?"PASS":"FAIL");
const bool auditPassed=passageCount>0&&passagePasses==passageCount
&&naturalPasses==passageCount&&l23SmoothWallDetected
&&openAirAudits==passageCount&&openAirViolations==0&&l24OpenAirControlDetected
&&routePasses>0&&routePasses==routeWalkPasses&&routePasses==routeBindings
&&routeBindingFailures==0
&&blockedCompiled&&blockedControls==passageCount;
+84 -13
View File
@@ -540,7 +540,7 @@ namespace StandaloneWorldAssemblyPrototype
FIntVector(0,0,islandSlot->TopChunkZ));
const FStratePassageConfig& passage=islandSlot->Definition->PassageConfig;
recipe.seed=static_cast<std::uint32_t>(owner.Seed);
recipe.geometryVersion=5;
recipe.geometryVersion=7;
recipe.ownerVoxelSizeMicrons=owner.OwnerVoxelSizeMicrons;
recipe.coreVoxelSizeMicrons=owner.CoreVoxelSizeMicrons;
recipe.ownerToCoreScaleNumerator=owner.OwnerVoxelSizeMicrons/static_cast<std::uint32_t>(divisor);
@@ -573,17 +573,22 @@ namespace StandaloneWorldAssemblyPrototype
recipe.anchorPlacementRadiusSubvoxels=ownerVoxelsToCoreQ(passage.DistanceMax);
const std::int64_t spiralRadius=ownerVoxelsToCoreQ(passage.SpiralRadius);
const std::int64_t mouthBore=std::max(ownerVoxelsToCoreQ(passage.MouthRadius),
ownerVoxelsToCoreQ(12.0));
ownerVoxelsToCoreQ(36.0));
const std::int64_t bore=std::max(ownerVoxelsToCoreQ(passage.MidRadius),
ownerVoxelsToCoreQ(12.0));
const std::int64_t wallReserve=ownerVoxelsToCoreQ(12.0);
// Put the mouth near the island rim, with enough island and root around the
// first coil to read as a cave entrance instead of a hole in open air.
recipe.anchorMouthOffsetSubvoxels=spiralRadius+mouthBore+ownerVoxelsToCoreQ(4.0);
const std::int64_t excursion=std::max(ownerVoxelsToCoreQ(passage.Wander),spiralRadius);
recipe.anchorRootRadiusSubvoxels=excursion+bore+wallReserve;
ownerVoxelsToCoreQ(24.0));
const std::int64_t wallReserve=ownerVoxelsToCoreQ(20.0);
// Retain a 4.5-metre mouth for capsule clearance while keeping the long
// ramp at three metres to leave more rock around the first coil.
recipe.anchorMouthOffsetSubvoxels=ownerVoxelsToCoreQ(40.0);
const std::int64_t supportOverhang=ownerVoxelsToCoreQ(16.0);
const std::int64_t rootTaperReserve=ownerVoxelsToCoreQ(10.0);
const std::int64_t mouthEnvelope=recipe.anchorMouthOffsetSubvoxels+mouthBore;
const std::int64_t treadEnvelope=spiralRadius+bore+supportOverhang;
recipe.anchorRootRadiusSubvoxels=std::max(mouthEnvelope,treadEnvelope)
+wallReserve+rootTaperReserve;
recipe.anchorIslandMinimumRadiusSubvoxels=std::max(recipe.minimumRadiusSubvoxels,
recipe.anchorMouthOffsetSubvoxels+mouthBore+ownerVoxelsToCoreQ(4.0));
std::max(recipe.anchorMouthOffsetSubvoxels+mouthBore+ownerVoxelsToCoreQ(4.0),
recipe.anchorRootRadiusSubvoxels+wallReserve));
recipe.anchorRootBottomZSubvoxels=recipe.layoutMinimumZSubvoxels
+recipe.boundarySealSubvoxels;
@@ -713,6 +718,39 @@ namespace StandaloneWorldAssemblyPrototype
[&](const auto& p){return p.strateIndex==slot.StrateIndex;});
if(it!=assembly.floatingIslands.end())
{
std::size_t passageMouthRouteIndex=it->manifest.plan.route.empty()?0
:it->manifest.plan.route.size()-1;
std::size_t resolvedRoutePointCount=it->manifest.plan.route.size();
if(it->manifest.recipe.geometryVersion>=5
&&!it->manifest.plan.route.empty()
&&it->manifest.recipe.anchorIslandOrdinal<it->manifest.plan.islands.size())
{
const auto& rootedIsland=it->manifest.plan.islands[
it->manifest.recipe.anchorIslandOrdinal];
const double qPerMetre=static_cast<double>(
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel)*1000000.0
/owner.CoreVoxelSizeMicrons;
const double thresholdQ=static_cast<double>(
it->manifest.recipe.anchorMouthOffsetSubvoxels)+qPerMetre;
for(std::size_t reverse=it->manifest.plan.route.size();reverse>1;--reverse)
{
const std::size_t index=reverse-1;
const auto& point=it->manifest.plan.route[index].positionSubvoxels;
const double dx=static_cast<double>(point[0]-rootedIsland.centerSubvoxels[0]);
const double dy=static_cast<double>(point[1]-rootedIsland.centerSubvoxels[1]);
if(std::hypot(dx,dy)>thresholdQ)
{
passageMouthRouteIndex=std::min(index+1,
it->manifest.plan.route.size()-1);
break;
}
}
// Stop the island surface route immediately before it enters
// the outer coil. The helical passage owns the walkable path
// from its mouth inward.
resolvedRoutePointCount=passageMouthRouteIndex>1
?passageMouthRouteIndex-1:passageMouthRouteIndex;
}
const auto recipeBottom=fixedToMicrons(it->manifest.recipe.layoutMinimumZSubvoxels);
const auto recipeTop=fixedToMicrons(it->manifest.recipe.layoutMaximumZSubvoxels);
if(recipeBottom!=bottom||recipeTop!=top)
@@ -737,10 +775,17 @@ namespace StandaloneWorldAssemblyPrototype
it->manifest.recipe.anchorPlacementRadiusSubvoxels,
it->manifest.recipe.anchorRootBottomZSubvoxels,
a.radiusSubvoxels};
if(!it->manifest.plan.route.empty())
{
const auto& routeMouth=it->manifest.plan.route[
passageMouthRouteIndex].positionSubvoxels;
passageAnchor.values.insert(passageAnchor.values.end(),
{routeMouth[0],routeMouth[1],routeMouth[2]});
}
s.anchors.push_back(std::move(passageAnchor));
}
}
for(std::size_t n=0;n<it->manifest.plan.route.size();++n)
for(std::size_t n=0;n<resolvedRoutePointCount;++n)
{
const auto& p=it->manifest.plan.route[n];ResolvedLayoutAnchorV2 anchor;
anchor.kind="route_point";anchor.stableId="route/"+std::to_string(n);
@@ -788,6 +833,32 @@ namespace StandaloneWorldAssemblyPrototype
{const auto& p=plan->route[n];ResolvedLayoutAnchorV2 a;a.kind="route_point";a.stableId="route/"+std::to_string(n);
a.units="1/256 Core voxel";a.values={p.positionSubvoxels[0],p.positionSubvoxels[1],p.positionSubvoxels[2],p.radiusSubvoxels};
s.anchors.push_back(std::move(a));}
const auto upperAnchorStratum=std::find_if(out.strates.begin(),out.strates.end(),
[](const auto& candidate)
{return candidate.generatorKind=="FloatingIslands"
&&std::any_of(candidate.anchors.begin(),candidate.anchors.end(),
[](const auto& anchor){return anchor.kind=="passage_anchor"
&&anchor.values.size()>=7;});});
if(upperAnchorStratum!=out.strates.end())
{
const auto rootAnchor=std::find_if(upperAnchorStratum->anchors.begin(),
upperAnchorStratum->anchors.end(),[](const auto& anchor)
{return anchor.kind=="passage_anchor"&&anchor.values.size()>=7;});
const std::int64_t arrivalZMicrometres=top-seal-1250000;
if(rootAnchor!=upperAnchorStratum->anchors.end()
&&arrivalZMicrometres>=bottom+seal&&arrivalZMicrometres<top-seal)
{
ResolvedLayoutAnchorV2 arrival;arrival.kind="passage_arrival";
arrival.stableId="passage-arrival/from-strate/"
+std::to_string(upperAnchorStratum->strateIndex);
arrival.units="1/256 Core voxel";
arrival.values={rootAnchor->values[0],rootAnchor->values[1],
static_cast<std::int64_t>(std::llround(
static_cast<double>(arrivalZMicrometres)
*WorldAssemblySubvoxelsPerVoxel/owner.CoreVoxelSizeMicrons))};
s.anchors.push_back(std::move(arrival));
}
}
}
out.strates.push_back(std::move(s));
}
@@ -803,9 +874,9 @@ namespace StandaloneWorldAssemblyPrototype
config.connections=authored.Connections;
config.style=static_cast<std::uint32_t>(authored.Style);
config.mouthRadiusSubvoxels=std::max(ownerVoxelsToCoreQ(authored.MouthRadius),
ownerVoxelsToCoreQ(12.0));
ownerVoxelsToCoreQ(36.0));
config.midRadiusSubvoxels=std::max(ownerVoxelsToCoreQ(authored.MidRadius),
ownerVoxelsToCoreQ(12.0));
ownerVoxelsToCoreQ(24.0));
config.reachMinimumSubvoxels=ownerVoxelsToCoreQ(authored.ReachMin);
config.reachMaximumSubvoxels=ownerVoxelsToCoreQ(authored.ReachMax);
config.distanceMinimumSubvoxels=ownerVoxelsToCoreQ(authored.DistanceMin);