wip(assembler): round L34 -- passage mouth profile audit and standard capture set

Adds a density-field floor/wall profile audit along passages near mouths (0.125 m spacing; L23
terraced negative control detected) and a reusable 12-view passage capture set (80 deg FOV, eye
height, LOD0, skirts off, capped clip planes). The old blurry mouth shot was camera framing; the
L33 entry ledges were tile skirts. Owner world hashes unchanged; 24/24 passage rows, 30/30
determinism, 16/16 invariants; cost within noise.

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-22 01:12:40 +02:00
1 parent b7a47bef95
commit 49e29fcd36
24 files changed
+1863 -3

No files matched your search

+258 -1
View File
@@ -805,8 +805,241 @@ namespace StandaloneStreamBenchmark
std::uint64_t wallSamples=0,missingWallSamples=0;
bool passed=false;
};
struct FPassageMouthProfileAudit
{
double floorFlatStepRunMetres=0.0,floorStepMetres=0.0;
double wallFlatStepRunMetres=0.0,wallStepMetres=0.0;
std::uint64_t floorSamples=0,wallSamples=0,missingFloorSamples=0,missingWallSamples=0;
bool passed=false;
};
constexpr double MaximumFlatRunMetres=8.0;
constexpr double MinimumWallReliefMetres=0.20;
constexpr double PassageProfileSpacingMetres=0.125;
constexpr double PassageProfilePlateauMinimumMetres=0.50;
constexpr double PassageProfilePlateauEpsilonMetres=0.020;
constexpr double PassageProfileStepThresholdMetres=0.100;
constexpr double PassageMouthProfileReachMetres=12.0;
const auto auditProfilePlateaus=[&](const std::vector<std::array<double,2>>& profile)
{
std::pair<double,double> result{};
if(profile.size()<2)return result;
std::size_t runStart=0;
for(std::size_t i=1;i<profile.size();++i)
{
if(profile[i][0]-profile[i-1][0]
>PassageProfileSpacingMetres*1.5)
{runStart=i;continue;}
if(std::abs(profile[i][1]-profile[runStart][1])
<=PassageProfilePlateauEpsilonMetres)continue;
const double flatLength=profile[i-1][0]-profile[runStart][0];
const double step=std::abs(profile[i][1]-profile[i-1][1]);
if(flatLength>=PassageProfilePlateauMinimumMetres
&&step>=PassageProfileStepThresholdMetres)
{
result.first=std::max(result.first,flatLength);
result.second=std::max(result.second,step);
}
runStart=i;
}
return result;
};
const auto auditPassageMouthProfiles=[&](const VoxelForgeCore::World& Field,
const VoxelForgeCore::ResolvedLayoutPassageV1& passage)
{
FPassageMouthProfileAudit audit;
if(passage.controlPoints.size()<2)return audit;
const std::size_t end=std::min(passage.lowerMouthControlIndex,
passage.controlPoints.size()-1);
if(end<1)return audit;
struct FProfilePose
{
double distance=0.0,x=0.0,y=0.0,z=0.0,radius=0.0;
};
std::vector<FProfilePose> path;
path.reserve(end*8+1);
double distance=0.0;
for(std::size_t segment=0;segment<end;++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 bx=qToMetres(b.positionSubvoxels[0]);
const double by=qToMetres(b.positionSubvoxels[1]);
const double bz=qToMetres(b.positionSubvoxels[2]);
const double ar=qToMetres(a.radiusSubvoxels);
const double br=qToMetres(b.radiusSubvoxels);
const double length=std::sqrt((bx-ax)*(bx-ax)+(by-ay)*(by-ay)+(bz-az)*(bz-az));
if(!(length>1.0e-8))continue;
const std::size_t steps=std::max<std::size_t>(1,
static_cast<std::size_t>(std::ceil(length/PassageProfileSpacingMetres)));
for(std::size_t step=segment==0?0:1;step<=steps;++step)
{
const double t=static_cast<double>(step)/steps;
path.push_back({distance+length*t,std::lerp(ax,bx,t),
std::lerp(ay,by,t),std::lerp(az,bz,t),std::lerp(ar,br,t)});
}
distance+=length;
}
if(path.size()<3)return audit;
const double lowerMouthDistance=distance;
constexpr double DensitySearchStepMetres=0.0625;
const auto densityMetres=[&](double x,double y,double z)
{
const float value=Field.densityAt({x/coreMetres,y/coreMetres,z/coreMetres});
return std::isfinite(value)?static_cast<double>(value)*coreMetres
:std::numeric_limits<double>::quiet_NaN();
};
const auto firstFloorCrossing=[&](const FProfilePose& pose,double x,double y)->double
{
const double expectedFloor=pose.z-pose.radius;
const double maximumRise=std::min(2.0*pose.radius-0.25,
std::max(0.75,pose.radius-1.20+0.50));
double previousZ=expectedFloor-1.50;
double previous=densityMetres(x,y,previousZ);
if(!std::isfinite(previous))return std::numeric_limits<double>::quiet_NaN();
double highestFloor=std::numeric_limits<double>::quiet_NaN();
for(double z=previousZ+DensitySearchStepMetres;
z<=expectedFloor+maximumRise+DensitySearchStepMetres*0.25;
z+=DensitySearchStepMetres)
{
const double current=densityMetres(x,y,z);
if(!std::isfinite(current))return std::numeric_limits<double>::quiet_NaN();
if(previous<=0.0&&current>=0.0)
{
const double denominator=current-previous;
const double t=std::abs(denominator)>1.0e-12
?std::clamp(-previous/denominator,0.0,1.0):0.0;
highestFloor=std::lerp(z-DensitySearchStepMetres,z,t);
}
previous=current;
}
return highestFloor;
};
const auto findWallRadius=[&](const FProfilePose& pose,double nx,double ny)
{
const double maximum=pose.radius+2.0;
double previousRadius=0.0;
double previous=densityMetres(pose.x,pose.y,pose.z);
if(!std::isfinite(previous)||previous<0.0)
return std::numeric_limits<double>::quiet_NaN();
for(double radius=DensitySearchStepMetres;radius<=maximum;
radius+=DensitySearchStepMetres)
{
const double current=densityMetres(pose.x+nx*radius,
pose.y+ny*radius,pose.z);
if(!std::isfinite(current))return std::numeric_limits<double>::quiet_NaN();
if(previous>=0.0&&current<=0.0)
{
const double denominator=previous-current;
const double t=std::abs(denominator)>1.0e-12
?std::clamp(previous/denominator,0.0,1.0):0.0;
return std::lerp(previousRadius,radius,t);
}
previous=current;previousRadius=radius;
}
return std::numeric_limits<double>::quiet_NaN();
};
std::array<std::array<std::vector<std::array<double,2>>,3>,2> floorProfiles;
std::array<std::array<std::vector<std::array<double,2>>,2>,2> wallProfiles;
std::array<double,2> endpointFloorCounts{};
for(std::size_t i=0;i<path.size();++i)
{
const auto& pose=path[i];
const bool inUpperWindow=pose.distance<=PassageMouthProfileReachMetres;
const bool inLowerWindow=lowerMouthDistance-pose.distance
<=PassageMouthProfileReachMetres;
if(!inUpperWindow&&!inLowerWindow)continue;
for(std::size_t endpoint=0;endpoint<2;++endpoint)
{
if((endpoint==0&&!inUpperWindow)||(endpoint==1&&!inLowerWindow))continue;
const double localDistance=endpoint==0?pose.distance
:lowerMouthDistance-pose.distance;
const double tangentX=i==0?path[i+1].x-path[i].x
:i+1>=path.size()?path[i].x-path[i-1].x
:path[i+1].x-path[i-1].x;
const double tangentY=i==0?path[i+1].y-path[i].y
:i+1>=path.size()?path[i].y-path[i-1].y
:path[i+1].y-path[i-1].y;
const double tangentLength=std::hypot(tangentX,tangentY);
if(tangentLength<=1.0e-6)
{audit.missingFloorSamples+=3;audit.missingWallSamples+=2;continue;}
const double nx=-tangentY/tangentLength,ny=tangentX/tangentLength;
for(std::size_t lane=0;lane<3;++lane)
{
const double lateral=lane==0?0.0:lane==1?0.75:-0.75;
const double floor=firstFloorCrossing(pose,
pose.x+nx*lateral,pose.y+ny*lateral);
if(lane!=0&&localDistance>=4.0&&localDistance<=5.5)
std::printf("[PassageMouthProfileProbe] id=%s endpoint=%s d_m=%.3f lane_m=%.2f x_m=%.3f y_m=%.3f route_floor_m=%.3f field_floor_m=%.3f\n",
passage.stableId.c_str(),endpoint==0?"upper":"lower",
localDistance,lateral,pose.x+nx*lateral,
pose.y+ny*lateral,pose.z-pose.radius,floor);
if(std::isfinite(floor))
{
floorProfiles[endpoint][lane].push_back({localDistance,floor});
++endpointFloorCounts[endpoint];++audit.floorSamples;
}
else ++audit.missingFloorSamples;
}
if(i%4!=0)continue;
for(std::size_t side=0;side<2;++side)
{
const double sign=side==0?-1.0:1.0;
const double radius=findWallRadius(pose,sign*nx,sign*ny);
if(std::isfinite(radius))
{
wallProfiles[endpoint][side].push_back({localDistance,radius});
++audit.wallSamples;
}
else ++audit.missingWallSamples;
}
}
}
double worstEndpointFloorCoverage=1.0;
for(std::size_t endpoint=0;endpoint<2;++endpoint)
{
for(std::size_t lane=0;lane<3;++lane)
std::sort(floorProfiles[endpoint][lane].begin(),
floorProfiles[endpoint][lane].end(),
[](const auto& a,const auto& b){return a[0]<b[0];});
for(std::size_t side=0;side<2;++side)
std::sort(wallProfiles[endpoint][side].begin(),
wallProfiles[endpoint][side].end(),
[](const auto& a,const auto& b){return a[0]<b[0];});
const double expectedFloor=std::min<double>(path.size(),
PassageMouthProfileReachMetres/PassageProfileSpacingMetres)+1.0;
worstEndpointFloorCoverage=std::min(worstEndpointFloorCoverage,
expectedFloor>0?endpointFloorCounts[endpoint]/expectedFloor:0.0);
// Lateral probes confirm floor coverage, but do not define a longitudinal
// floor profile: the normal rotates around tight bends and can jump across
// unrelated terrain. The centerline is the stable passage-floor trace.
const auto floorStep=auditProfilePlateaus(floorProfiles[endpoint][0]);
audit.floorFlatStepRunMetres=std::max(audit.floorFlatStepRunMetres,
floorStep.first);
audit.floorStepMetres=std::max(audit.floorStepMetres,floorStep.second);
for(std::size_t side=0;side<2;++side)
{
const auto wallStep=auditProfilePlateaus(wallProfiles[endpoint][side]);
audit.wallFlatStepRunMetres=std::max(audit.wallFlatStepRunMetres,wallStep.first);
audit.wallStepMetres=std::max(audit.wallStepMetres,wallStep.second);
}
}
audit.passed=worstEndpointFloorCoverage>=0.75
&&audit.wallSamples>=8
&&audit.floorFlatStepRunMetres==0.0&&audit.wallFlatStepRunMetres==0.0;
return audit;
};
std::vector<std::array<double,2>> l23TerracedControl;
for(std::size_t tread=0;tread<8;++tread)
for(std::size_t sample=0;sample<=16;++sample)
l23TerracedControl.push_back({(tread*16+sample)*PassageProfileSpacingMetres,
static_cast<double>(tread)*0.25});
const auto l23TerraceControlResult=auditProfilePlateaus(l23TerracedControl);
const bool l23TerraceControlDetected=l23TerraceControlResult.first
>=PassageProfilePlateauMinimumMetres
&&l23TerraceControlResult.second>=PassageProfileStepThresholdMetres;
const auto auditPassageNaturalness=[&](const VoxelForgeCore::World& Field,
const VoxelForgeCore::ResolvedLayoutPassageV1& passage)
{
@@ -1498,6 +1731,7 @@ 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 mouthProfilePasses=0;
std::uint64_t openAirViolations=0,openAirLegacyViolations=0,openAirSamples=0;
std::uint64_t openAirAudits=0,openAirColumnSamples=0,openAirShortSpanSamples=0;
std::uint64_t columnCrossings=0,shortGroundedSpans=0,columnConnectedEnds=0;
@@ -1545,6 +1779,8 @@ namespace StandaloneStreamBenchmark
const FWalkAudit passageAudit=auditPlayerPath(Shape,path,0.125,0.125,0.25,3,0.45,
&blockedWorld,&segmentSupport);
const FPassageNaturalnessAudit naturalAudit=auditPassageNaturalness(Shape,passage);
const FPassageMouthProfileAudit mouthProfileAudit=
auditPassageMouthProfiles(Shape,passage);
const FPassageOpenAirAudit openAirAudit=auditPassageOpenAir(Shape,blockedWorld,
passage,passageIndex);
const FPassageColumnAudit columnAudit=auditPassageColumns(Shape,blockedWorld,
@@ -1574,8 +1810,9 @@ namespace StandaloneStreamBenchmark
const bool mouthsInContent=mouthInContent(passage.upperStrateIndex,passage.upperMouthSubvoxels)
&&mouthInContent(passage.lowerStrateIndex,passage.lowerMouthSubvoxels);
++passageCount;naturalPasses+=naturalAudit.passed;
mouthProfilePasses+=mouthProfileAudit.passed;
passagePasses+=passageAudit.passed&&mouthsInRadius&&mouthsInContent
&&naturalAudit.passed;
&&naturalAudit.passed&&mouthProfileAudit.passed;
std::printf("[ResolvedPassageAudit] id=%s interface=%d-%d control_points=%zu center_samples=%llu capsule_samples=%llu blocked=%llu support_samples=%llu unsupported=%llu grade_failures=%llu mouth_content=%d/2 mouth_radius=%d/2 walkability=%s\n",
passage.stableId.c_str(),passage.upperStrateIndex,passage.lowerStrateIndex,
passage.controlPoints.size(),static_cast<unsigned long long>(passageAudit.centers),
@@ -1591,6 +1828,15 @@ namespace StandaloneStreamBenchmark
static_cast<unsigned long long>(naturalAudit.wallSamples),
static_cast<unsigned long long>(naturalAudit.missingWallSamples),
naturalAudit.passed?"PASS":"FAIL");
std::printf("[PassageMouthProfileAudit] id=%s floor_samples=%llu floor_missing=%llu wall_samples=%llu wall_missing=%llu floor_step_scan=centerline floor_flat_step_run_m=%.3f floor_step_m=%.3f wall_flat_step_run_m=%.3f wall_step_m=%.3f spacing_m=%.3f plateau=(%.3f,%.3f) status=%s\n",
passage.stableId.c_str(),static_cast<unsigned long long>(mouthProfileAudit.floorSamples),
static_cast<unsigned long long>(mouthProfileAudit.missingFloorSamples),
static_cast<unsigned long long>(mouthProfileAudit.wallSamples),
static_cast<unsigned long long>(mouthProfileAudit.missingWallSamples),
mouthProfileAudit.floorFlatStepRunMetres,mouthProfileAudit.floorStepMetres,
mouthProfileAudit.wallFlatStepRunMetres,mouthProfileAudit.wallStepMetres,
PassageProfileSpacingMetres,PassageProfilePlateauMinimumMetres,
PassageProfileStepThresholdMetres,mouthProfileAudit.passed?"PASS":"FAIL");
std::printf("[PassageOpenAirAudit] id=%s support_samples=%llu violations=%llu column_samples=%llu short_span_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),
@@ -1891,12 +2137,23 @@ namespace StandaloneStreamBenchmark
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");
std::printf("[PassageMouthProfileNegativeControl] source=L23_terraced_geometry flat_run_m=%.3f following_step_m=%.3f thresholds=(%.3f,%.3f) detected=%s\n",
l23TerraceControlResult.first,l23TerraceControlResult.second,
PassageProfilePlateauMinimumMetres,PassageProfileStepThresholdMetres,
l23TerraceControlDetected?"true":"false");
std::printf("[PassageNaturalnessSummary] passed=%llu/%llu l23_negative_control=%s flat_run_limit_m=%.3f wall_relief_min_m=%.3f status=%s\n",
static_cast<unsigned long long>(naturalPasses),static_cast<unsigned long long>(passageCount),
l23SmoothWallDetected?"DETECTED":"MISSED",MaximumFlatRunMetres,
MinimumWallReliefMetres,naturalPasses==passageCount&&l23SmoothWallDetected?"PASS":"FAIL");
std::printf("[PassageMouthProfileSummary] passed=%llu/%llu spacing_m=%.3f plateau_min_m=%.3f following_step_min_m=%.3f l23_terrace_negative_control=%s status=%s\n",
static_cast<unsigned long long>(mouthProfilePasses),
static_cast<unsigned long long>(passageCount),PassageProfileSpacingMetres,
PassageProfilePlateauMinimumMetres,PassageProfileStepThresholdMetres,
l23TerraceControlDetected?"DETECTED":"MISSED",
mouthProfilePasses==passageCount&&l23TerraceControlDetected?"PASS":"FAIL");
const bool auditPassed=passageCount>0&&passagePasses==passageCount
&&naturalPasses==passageCount&&l23SmoothWallDetected
&&mouthProfilePasses==passageCount&&l23TerraceControlDetected
&&openAirAudits==passageCount&&openAirViolations==0&&l24OpenAirControlDetected
&&columnAuditsPassed&&noLongBridgeAuditPassed
&&routePasses>0&&routePasses==routeWalkPasses&&routePasses==routeBindings