wip(assembler): round L36 -- tunnel floor without washboard; FI mouth without shards (evaluator v23)

The walk tread was built per segment as a one-sided density clamp, so its crossing with the native
field moved at segment joins (L35: 2.25-2.48 cm washboard). Treads now overlap up to 2 m as bounded
signed-distance slabs (0.06 cm residual). The FI mouth's crater detail and tread met without a smooth
join; v23 filters the local field, drops thin isolated solids and smooth-unions the tread with the
terrain. New floor ripple and mouth fragment/crease audits with L35 as failing controls. 24/24
passage rows, 30/30 determinism, 16/16 invariants, LOD0-8 rings; 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 13:01:54 +02:00
1 parent ba017077d1
commit 8be1c4d9ef
27 files changed
+1787 -55

No files matched your search

+135 -4
View File
@@ -817,8 +817,15 @@ namespace StandaloneStreamBenchmark
double periodMetres=0.0,amplitudeMetres=0.0,localPeakAmplitudeMetres=0.0;
double coherentPeriodMetres=0.0,coherentAmplitudeMetres=0.0;
double controlAmplitudeMetres=0.0;
double floorPeriodMetres=0.0,floorAmplitudeMetres=0.0;
double floorControlAmplitudeMetres=0.0;
double floorCoherentPeriodMetres=0.0,floorCoherentAmplitudeMetres=0.0;
std::vector<std::array<double,6>> floorPeakProfile;
double floorPeakWindowStartMetres=0.0;
std::uint64_t samples=0,expectedSamples=0;
std::uint64_t floorSamples=0,floorExpectedSamples=0;
bool controlDetected=false,passed=false;
bool floorControlDetected=false;
};
constexpr double MaximumFlatRunMetres=8.0;
constexpr double MinimumWallReliefMetres=0.20;
@@ -1131,6 +1138,7 @@ namespace StandaloneStreamBenchmark
constexpr double MaximumPeriodMetres=8.0;
constexpr double PeriodStepMetres=0.0625;
constexpr double RippleAmplitudeLimitMetres=0.035;
constexpr double FloorRippleAmplitudeLimitMetres=0.015;
struct FPathPoint
{
double x=0.0,y=0.0,z=0.0,radius=0.0,distance=0.0;
@@ -1218,6 +1226,26 @@ namespace StandaloneStreamBenchmark
values[i]-mean-slope*x});
}
};
const auto appendDetrendedPairs=[](
const std::vector<std::array<double,2>>& values,
std::vector<std::array<double,2>>& output)
{
if(values.size()<64)return;
double meanX=0.0,meanY=0.0;
for(const auto& value:values){meanX+=value[0];meanY+=value[1];}
meanX/=static_cast<double>(values.size());
meanY/=static_cast<double>(values.size());
double xy=0.0,xx=0.0;
for(const auto& value:values)
{
const double x=value[0]-meanX;
xy+=x*(value[1]-meanY);xx+=x*x;
}
const double slope=xx>0.0?xy/xx:0.0;
for(const auto& value:values)
output.push_back({value[0],value[1]-meanY
-slope*(value[0]-meanX)});
};
std::vector<double> beadControl;
beadControl.reserve(static_cast<std::size_t>(WindowLengthMetres/SampleSpacingMetres)+1);
constexpr double BeadSpacingMetres=1.5;
@@ -1234,20 +1262,64 @@ namespace StandaloneStreamBenchmark
double ignoredPeriod=0.0;
audit.controlAmplitudeMetres=sinusoidAmplitude(beadSamples,ignoredPeriod);
audit.controlDetected=audit.controlAmplitudeMetres>=RippleAmplitudeLimitMetres;
const std::array<double,4> windowStarts{{0.03,0.31,0.61,0.91}};
audit.floorControlAmplitudeMetres=audit.controlAmplitudeMetres;
audit.floorControlDetected=audit.floorControlAmplitudeMetres
>=FloorRippleAmplitudeLimitMetres;
const std::array<double,5> windowStarts{{0.03,0.31,0.457,0.61,0.91}};
std::vector<std::array<double,2>> coherentSamples;
std::vector<std::array<double,2>> coherentFloorSamples;
for(const double fraction:windowStarts)
{
const double start=(total-WindowLengthMetres)*fraction;
std::vector<double> radii;
radii.reserve(static_cast<std::size_t>(WindowLengthMetres/SampleSpacingMetres)+1);
std::vector<std::array<double,2>> floorResiduals;
floorResiduals.reserve(static_cast<std::size_t>(WindowLengthMetres/
SampleSpacingMetres)+1);
std::vector<std::array<double,6>> floorDebugSamples;
floorDebugSamples.reserve(static_cast<std::size_t>(WindowLengthMetres/
SampleSpacingMetres)+1);
for(std::size_t sample=0;
sample<=static_cast<std::size_t>(WindowLengthMetres/SampleSpacingMetres);
++sample)
{
++audit.expectedSamples;
++audit.floorExpectedSamples;
const double distance=start+static_cast<double>(sample)*SampleSpacingMetres;
const auto pose=interpolate(distance);
// Recover the composed walk surface from its zero crossing.
// The support strip is segment-built and is not itself a true
// signed-distance field, so a fixed centerline radius misses
// the stepped top that the player actually walks on.
const double expectedFloor=pose.z-pose.radius+0.20;
constexpr double FloorProbeStepMetres=0.25;
constexpr int FloorProbeCount=7;
double previousDensity=0.0,previousZ=0.0;
bool havePrevious=false,haveFloor=false;
double bestFloor=0.0,bestDistance=std::numeric_limits<double>::infinity();
for(int vertical=0;vertical<FloorProbeCount;++vertical)
{
const double z=expectedFloor-1.0+vertical*FloorProbeStepMetres;
const double density=static_cast<double>(Field.densityAt({
pose.x/coreMetres,pose.y/coreMetres,z/coreMetres}))*coreMetres;
if(havePrevious&&previousDensity<0.0&&density>=0.0)
{
const double denominator=density-previousDensity;
const double crossing=denominator>1.0e-12
?previousZ+(z-previousZ)*(-previousDensity)/denominator:z;
const double candidateDistance=std::abs(crossing-expectedFloor);
if(candidateDistance<bestDistance)
{bestDistance=candidateDistance;bestFloor=crossing;haveFloor=true;}
}
previousDensity=density;previousZ=z;havePrevious=true;
}
if(haveFloor)
{
floorResiduals.push_back({distance,bestFloor-expectedFloor});
floorDebugSamples.push_back({distance,expectedFloor,bestFloor,
pose.x,pose.y,pose.z});
++audit.floorSamples;
}
const auto before=interpolate(std::max(0.0,distance-0.25));
const auto after=interpolate(std::min(total,distance+0.25));
const double tangentX=after.x-before.x,tangentY=after.y-before.y;
@@ -1279,14 +1351,54 @@ namespace StandaloneStreamBenchmark
}
coherentSamples.insert(coherentSamples.end(),windowSamples.begin(),
windowSamples.end());
double floorWindowPeriod=0.0,floorWindowAmplitude=0.0;
if(floorResiduals.size()>=static_cast<std::size_t>(WindowLengthMetres/
SampleSpacingMetres)*3/4)
{
std::vector<std::array<double,2>> floorWindowSamples;
appendDetrendedPairs(floorResiduals,floorWindowSamples);
floorWindowAmplitude=sinusoidAmplitude(floorWindowSamples,
floorWindowPeriod);
if(floorWindowAmplitude>audit.floorAmplitudeMetres)
{
audit.floorAmplitudeMetres=floorWindowAmplitude;
audit.floorPeriodMetres=floorWindowPeriod;
audit.floorPeakWindowStartMetres=start;
audit.floorPeakProfile=std::move(floorDebugSamples);
}
coherentFloorSamples.insert(coherentFloorSamples.end(),
floorWindowSamples.begin(),floorWindowSamples.end());
}
const double floorWindowCoverage=static_cast<double>(floorResiduals.size())
/(WindowLengthMetres/SampleSpacingMetres+1.0);
double floorResidualMinimum=0.0,floorResidualMaximum=0.0;
if(!floorResiduals.empty())
{
const auto extrema=std::minmax_element(floorResiduals.begin(),
floorResiduals.end(),[](const auto& a,const auto& b)
{return a[1]<b[1];});
floorResidualMinimum=(*extrema.first)[1];
floorResidualMaximum=(*extrema.second)[1];
}
std::printf("[PassageFloorRippleWindow] id=%s start_m=%.3f "
"period_m=%.3f amplitude_m=%.4f coverage=%.3f "
"residual_range_m=%.4f..%.4f threshold_m=0.015\n",
passage.stableId.c_str(),start,floorWindowPeriod,floorWindowAmplitude,
floorWindowCoverage,floorResidualMinimum,floorResidualMaximum);
}
audit.coherentAmplitudeMetres=sinusoidAmplitude(coherentSamples,
audit.coherentPeriodMetres);
audit.floorCoherentAmplitudeMetres=sinusoidAmplitude(coherentFloorSamples,
audit.floorCoherentPeriodMetres);
audit.amplitudeMetres=audit.localPeakAmplitudeMetres;
const double coverage=audit.expectedSamples>0
?static_cast<double>(audit.samples)/audit.expectedSamples:0.0;
const double floorCoverage=audit.floorExpectedSamples>0
?static_cast<double>(audit.floorSamples)/audit.floorExpectedSamples:0.0;
audit.passed=audit.controlDetected&&coverage>=0.75
&&audit.localPeakAmplitudeMetres<RippleAmplitudeLimitMetres;
&&audit.localPeakAmplitudeMetres<RippleAmplitudeLimitMetres
&&audit.floorControlDetected&&floorCoverage>=0.75
&&audit.floorAmplitudeMetres<FloorRippleAmplitudeLimitMetres;
return audit;
};
const auto looksNatural=[&](double flatRun,double reliefPeakToPeak)
@@ -1908,6 +2020,7 @@ namespace StandaloneStreamBenchmark
};
std::uint64_t passageCount=0,passagePasses=0,blockedControls=0,naturalPasses=0;
std::uint64_t mouthProfilePasses=0,ripplePasses=0,rippleControlsDetected=0;
std::uint64_t floorRippleControlsDetected=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;
@@ -1990,6 +2103,7 @@ namespace StandaloneStreamBenchmark
mouthProfilePasses+=mouthProfileAudit.passed;
ripplePasses+=rippleAudit.passed;
rippleControlsDetected+=rippleAudit.controlDetected;
floorRippleControlsDetected+=rippleAudit.floorControlDetected;
passagePasses+=passageAudit.passed&&mouthsInRadius&&mouthsInContent
&&naturalAudit.passed&&mouthProfileAudit.passed&&rippleAudit.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",
@@ -2016,7 +2130,7 @@ namespace StandaloneStreamBenchmark
mouthProfileAudit.wallFlatStepRunMetres,mouthProfileAudit.wallStepMetres,
PassageProfileSpacingMetres,PassageProfilePlateauMinimumMetres,
PassageProfileStepThresholdMetres,mouthProfileAudit.passed?"PASS":"FAIL");
std::printf("[PassageRippleAudit] id=%s window_m=32.000 spacing_m=0.125 period_m=%.3f amplitude_m=%.4f amplitude_cm=%.2f coherent_period_m=%.3f coherent_amplitude_m=%.4f coherent_amplitude_cm=%.2f local_peak_amplitude_m=%.4f coverage=%llu/%llu threshold_m=0.035 synthetic_spheres_period_m=1.500 synthetic_spheres_amplitude_m=%.4f synthetic_spheres_detected=%s status=%s\n",
std::printf("[PassageRippleAudit] id=%s window_m=32.000 spacing_m=0.125 period_m=%.3f amplitude_m=%.4f amplitude_cm=%.2f coherent_period_m=%.3f coherent_amplitude_m=%.4f coherent_amplitude_cm=%.2f local_peak_amplitude_m=%.4f coverage=%llu/%llu threshold_m=0.035 synthetic_spheres_period_m=1.500 synthetic_spheres_amplitude_m=%.4f synthetic_spheres_detected=%s floor_period_m=%.3f floor_amplitude_m=%.4f floor_amplitude_cm=%.2f floor_coherent_period_m=%.3f floor_coherent_amplitude_m=%.4f floor_coverage=%llu/%llu floor_threshold_m=0.015 floor_beaded_control_amplitude_m=%.4f floor_beaded_control_detected=%s status=%s\n",
passage.stableId.c_str(),rippleAudit.periodMetres,
rippleAudit.amplitudeMetres,rippleAudit.amplitudeMetres*100.0,
rippleAudit.coherentPeriodMetres,rippleAudit.coherentAmplitudeMetres,
@@ -2025,7 +2139,23 @@ namespace StandaloneStreamBenchmark
static_cast<unsigned long long>(rippleAudit.samples),
static_cast<unsigned long long>(rippleAudit.expectedSamples),
rippleAudit.controlAmplitudeMetres,rippleAudit.controlDetected?"true":"false",
rippleAudit.floorPeriodMetres,rippleAudit.floorAmplitudeMetres,
rippleAudit.floorAmplitudeMetres*100.0,
rippleAudit.floorCoherentPeriodMetres,rippleAudit.floorCoherentAmplitudeMetres,
static_cast<unsigned long long>(rippleAudit.floorSamples),
static_cast<unsigned long long>(rippleAudit.floorExpectedSamples),
rippleAudit.floorControlAmplitudeMetres,
rippleAudit.floorControlDetected?"true":"false",
rippleAudit.passed?"PASS":"FAIL");
for(std::size_t sample=0;sample<rippleAudit.floorPeakProfile.size();sample+=4)
{
const auto& value=rippleAudit.floorPeakProfile[sample];
std::printf("[PassageFloorRippleSample] id=%s distance_m=%.3f "
"expected_floor_m=%.4f sampled_floor_m=%.4f residual_m=%.4f "
"route_xyz_m=(%.3f,%.3f,%.3f)\n",
passage.stableId.c_str(),value[0],value[1],value[2],value[2]-value[1],
value[3],value[4],value[5]);
}
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),
@@ -2340,10 +2470,11 @@ namespace StandaloneStreamBenchmark
PassageProfilePlateauMinimumMetres,PassageProfileStepThresholdMetres,
l23TerraceControlDetected?"DETECTED":"MISSED",
mouthProfilePasses==passageCount&&l23TerraceControlDetected?"PASS":"FAIL");
std::printf("[PassageRippleAuditSummary] passed=%llu/%llu synthetic_spheres_negative_control=%s max_amplitude_m=0.035 status=%s\n",
std::printf("[PassageRippleAuditSummary] passed=%llu/%llu synthetic_spheres_negative_control=%s max_amplitude_m=0.035 floor_beaded_negative_control=%s max_floor_amplitude_m=0.015 status=%s\n",
static_cast<unsigned long long>(ripplePasses),
static_cast<unsigned long long>(passageCount),
rippleControlsDetected==passageCount?"DETECTED":"MISSED",
floorRippleControlsDetected==passageCount?"DETECTED":"MISSED",
ripplePasses==passageCount?"PASS":"FAIL");
const bool auditPassed=passageCount>0&&passagePasses==passageCount
&&naturalPasses==passageCount&&l23SmoothWallDetected