passages: floor profile by nearest centreline + metric distance outside voids (L114, v222) - WIP
Floor ribs are present in L109/L112/L113 rock tunnels too: the floor height comes from the nearest segment, so it jumps (up to 5.9-7.3 cm) where the nearest segment switches. v222 reduces them; faint ribs remain. Quiet-machine timing (load 0.64): near-ready 9-17% slower than L109 (FI W12 0.95 -> 1.10 s); candidate totals ~5x L109. Fast tier FAIL: 2 SW wall-shell probes of 31,381 read host air. Walk/grade audits pass; Clang/GCC deterministic; UE builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
36d954cf2f
commit
5e875ae504
45 files changed
+3081
-53
No files matched your search
@@ -3166,6 +3166,74 @@ namespace StandaloneStreamBenchmark
|
||||
std::lerp(a.floorZ,b.floorZ,t),
|
||||
std::lerp(a.radius,b.radius,t),distance,b.segmentIndex};
|
||||
};
|
||||
const char* l114DensityProfile=std::getenv("VOXELFORGE_L114_DENSITY_PROFILE");
|
||||
if(l114DensityProfile&&l114DensityProfile[0]=='1'&&l114DensityProfile[1]=='\0')
|
||||
{
|
||||
for(const char* passageId:{"passage/0-1/0","passage/1-2/0"})
|
||||
{
|
||||
const auto passage=std::find_if(ResolvedLayout->passages.begin(),
|
||||
ResolvedLayout->passages.end(),[&](const auto& candidate)
|
||||
{return candidate.stableId==passageId;});
|
||||
if(passage==ResolvedLayout->passages.end())continue;
|
||||
const std::size_t passageIndex=static_cast<std::size_t>(
|
||||
passage-ResolvedLayout->passages.begin());
|
||||
const auto& route=allPassageSmoothRoutes[passageIndex];
|
||||
const auto densityMetres=[&](double x,double y,double z)
|
||||
{
|
||||
return static_cast<double>(Shape.densityAt({x/coreMetres,
|
||||
y/coreMetres,z/coreMetres}))*coreMetres;
|
||||
};
|
||||
const auto floorRoot=[&](const FPassageAuditRoutePoint& pose)
|
||||
{
|
||||
double low=pose.floorZ-0.75,high=pose.floorZ+0.75;
|
||||
double lowDensity=densityMetres(pose.x,pose.y,low);
|
||||
double highDensity=densityMetres(pose.x,pose.y,high);
|
||||
if(!(lowDensity<0.0&&highDensity>=0.0))
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
for(int iteration=0;iteration<24;++iteration)
|
||||
{
|
||||
const double middle=(low+high)*0.5;
|
||||
if(densityMetres(pose.x,pose.y,middle)<0.0)low=middle;
|
||||
else high=middle;
|
||||
}
|
||||
return (low+high)*0.5;
|
||||
};
|
||||
const std::array<std::pair<const char*,double>,2> targets={{
|
||||
{"rock-station-50",route.empty()?0.0:route.back().distance*0.5},
|
||||
{"open-air-section-3",1265.3425}}};
|
||||
for(const auto& [label,targetDistance]:targets)
|
||||
{
|
||||
if(route.size()<2||targetDistance>route.back().distance)continue;
|
||||
const auto center=interpolatePassageRoute(route,targetDistance);
|
||||
const VoxelForgeCore::Vec3d centerVoxel={center.x/coreMetres,
|
||||
center.y/coreMetres,center.floorZ/coreMetres};
|
||||
std::printf("[L114DensityColumn] passage=%s section=%s x_m=%.6f y_m=%.6f planned_floor_m=%.6f dispatch=%s source_density_m=%.9f unclamped_density_m=%.9f\n",
|
||||
passage->stableId.c_str(),label,center.x,center.y,center.floorZ,
|
||||
Shape.densityDispatchPathAt(centerVoxel).c_str(),
|
||||
static_cast<double>(Shape.passageSourceDensityAt(centerVoxel))*coreMetres,
|
||||
static_cast<double>(Shape.unclampedDensityAt(centerVoxel))*coreMetres);
|
||||
for(int sample=0;sample<=40;++sample)
|
||||
{
|
||||
const double offset=-0.50+sample*0.025;
|
||||
std::printf("[L114DensityColumnSample] section=%s dz_m=%.3f density_m=%.9f\n",
|
||||
label,offset,densityMetres(center.x,center.y,
|
||||
center.floorZ+offset));
|
||||
}
|
||||
for(int sample=-25;sample<=25;++sample)
|
||||
{
|
||||
const double distance=targetDistance+sample*0.10;
|
||||
const auto pose=interpolatePassageRoute(route,distance);
|
||||
const double root=floorRoot(pose);
|
||||
std::printf("[L114DensitySlopeSample] section=%s s_m=%.3f x_m=%.6f y_m=%.6f planned_floor_m=%.6f root_floor_m=%.6f residual_m=%.6f density_minus_0p1_m=%.9f density_plane_m=%.9f density_plus_0p1_m=%.9f\n",
|
||||
label,distance,pose.x,pose.y,pose.floorZ,root,
|
||||
root-pose.floorZ,
|
||||
densityMetres(pose.x,pose.y,pose.floorZ-0.1),
|
||||
densityMetres(pose.x,pose.y,pose.floorZ),
|
||||
densityMetres(pose.x,pose.y,pose.floorZ+0.1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto passageInteriorWinsAt=[&](double xMetres,double yMetres,
|
||||
double zMetres,std::size_t ignoredPassage=std::numeric_limits<std::size_t>::max(),
|
||||
std::size_t ignoredSegment=std::numeric_limits<std::size_t>::max())
|
||||
@@ -3292,6 +3360,8 @@ namespace StandaloneStreamBenchmark
|
||||
std::vector<std::array<double,6>> floorPeakProfile;
|
||||
double floorPeakWindowStartMetres=0.0;
|
||||
std::uint64_t samples=0,expectedSamples=0;
|
||||
std::uint64_t wallWindowSamples=0,wallWindowExpectedSamples=0;
|
||||
std::uint64_t wallQualifiedWindows=0;
|
||||
std::uint64_t floorSamples=0,floorExpectedSamples=0;
|
||||
std::uint64_t floorInteriorWins=0;
|
||||
bool controlDetected=false,passed=false;
|
||||
@@ -3836,6 +3906,9 @@ namespace StandaloneStreamBenchmark
|
||||
const double start=(total-WindowLengthMetres)*fraction;
|
||||
std::vector<double> radii;
|
||||
radii.reserve(static_cast<std::size_t>(WindowLengthMetres/SampleSpacingMetres)+1);
|
||||
std::size_t wallProbeNonfinite=0,wallProbeOutOfBand=0;
|
||||
double wallProbeMinimum=std::numeric_limits<double>::infinity();
|
||||
double wallProbeMaximum=-std::numeric_limits<double>::infinity();
|
||||
std::vector<std::array<double,2>> floorResiduals;
|
||||
floorResiduals.reserve(static_cast<std::size_t>(WindowLengthMetres/
|
||||
SampleSpacingMetres)+1);
|
||||
@@ -3922,8 +3995,12 @@ namespace StandaloneStreamBenchmark
|
||||
{x0+nx*offset,y0+ny*offset,z0}))*coreMetres;
|
||||
const double right=static_cast<double>(Field.densityAt(
|
||||
{x0-nx*offset,y0-ny*offset,z0}))*coreMetres;
|
||||
if(!std::isfinite(left)||!std::isfinite(right)
|
||||
||left< -0.75||left>0.75||right< -0.75||right>0.75)continue;
|
||||
if(!std::isfinite(left)||!std::isfinite(right))
|
||||
{++wallProbeNonfinite;continue;}
|
||||
wallProbeMinimum=std::min({wallProbeMinimum,left,right});
|
||||
wallProbeMaximum=std::max({wallProbeMaximum,left,right});
|
||||
if(left< -0.75||left>0.75||right< -0.75||right>0.75)
|
||||
{++wallProbeOutOfBand;continue;}
|
||||
// The probes sit 0.18 m inside the authored radius. Add that
|
||||
// radius back to the signed wall distance so radius-carried ribs
|
||||
// remain visible; the cubic detrend removes the smooth mouth flare.
|
||||
@@ -3931,7 +4008,22 @@ namespace StandaloneStreamBenchmark
|
||||
++audit.samples;
|
||||
}
|
||||
if(radii.size()<static_cast<std::size_t>(WindowLengthMetres/
|
||||
SampleSpacingMetres)*3/4)continue;
|
||||
SampleSpacingMetres)*3/4)
|
||||
{
|
||||
std::printf("[PassageWallRippleCoverage] id=%s start_m=%.3f "
|
||||
"valid=%zu expected=%zu nonfinite=%zu out_of_band=%zu "
|
||||
"probe_range_m=%.4f..%.4f status=UNDERCOVERED\n",
|
||||
passage.stableId.c_str(),start,radii.size(),
|
||||
static_cast<std::size_t>(WindowLengthMetres/
|
||||
SampleSpacingMetres)+1,
|
||||
wallProbeNonfinite,wallProbeOutOfBand,
|
||||
wallProbeMinimum,wallProbeMaximum);
|
||||
continue;
|
||||
}
|
||||
++audit.wallQualifiedWindows;
|
||||
audit.wallWindowSamples+=radii.size();
|
||||
audit.wallWindowExpectedSamples+=static_cast<std::size_t>(
|
||||
WindowLengthMetres/SampleSpacingMetres)+1;
|
||||
std::vector<std::array<double,2>> windowSamples;
|
||||
appendDetrendedProfile(radii,start,windowSamples);
|
||||
double localPeriod=0.0;
|
||||
@@ -3988,14 +4080,20 @@ namespace StandaloneStreamBenchmark
|
||||
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 wallWindowCoverage=audit.wallWindowExpectedSamples>0
|
||||
?static_cast<double>(audit.wallWindowSamples)
|
||||
/audit.wallWindowExpectedSamples:0.0;
|
||||
const double floorCoverage=audit.floorExpectedSamples>0
|
||||
?static_cast<double>(audit.floorSamples)/audit.floorExpectedSamples:0.0;
|
||||
audit.floorOverlapOnly=audit.expectedSamples>0
|
||||
&&audit.floorExpectedSamples==0
|
||||
&&audit.floorInteriorWins==audit.expectedSamples;
|
||||
audit.passed=audit.controlDetected&&coverage>=0.75
|
||||
// Long passages can include open-air spans where the side-wall
|
||||
// probe has no zero crossing. Judge ripple only in windows with
|
||||
// enough measured wall samples; naturalness separately requires
|
||||
// visible relief on the route as a whole.
|
||||
audit.passed=audit.controlDetected&&audit.wallQualifiedWindows>0
|
||||
&&wallWindowCoverage>=0.75
|
||||
&&audit.localPeakAmplitudeMetres<RippleAmplitudeLimitMetres
|
||||
&&audit.floorControlDetected&&audit.floorStepControlDetected
|
||||
&&(audit.floorOverlapOnly||(floorCoverage>=0.75
|
||||
@@ -4380,7 +4478,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 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_overlap_skips=%llu floor_mode=%s floor_threshold_m=0.025 floor_beaded_control_amplitude_m=%.4f floor_beaded_control_detected=%s floor_step_control_amplitude_m=%.4f floor_step_control_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 wall_windows=%llu/5 wall_window_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_overlap_skips=%llu floor_mode=%s floor_threshold_m=0.025 floor_beaded_control_amplitude_m=%.4f floor_beaded_control_detected=%s floor_step_control_amplitude_m=%.4f floor_step_control_detected=%s status=%s\n",
|
||||
passage.stableId.c_str(),rippleAudit.periodMetres,
|
||||
rippleAudit.amplitudeMetres,rippleAudit.amplitudeMetres*100.0,
|
||||
rippleAudit.coherentPeriodMetres,rippleAudit.coherentAmplitudeMetres,
|
||||
@@ -4388,6 +4486,9 @@ namespace StandaloneStreamBenchmark
|
||||
rippleAudit.localPeakAmplitudeMetres,
|
||||
static_cast<unsigned long long>(rippleAudit.samples),
|
||||
static_cast<unsigned long long>(rippleAudit.expectedSamples),
|
||||
static_cast<unsigned long long>(rippleAudit.wallQualifiedWindows),
|
||||
static_cast<unsigned long long>(rippleAudit.wallWindowSamples),
|
||||
static_cast<unsigned long long>(rippleAudit.wallWindowExpectedSamples),
|
||||
rippleAudit.controlAmplitudeMetres,rippleAudit.controlDetected?"true":"false",
|
||||
rippleAudit.floorPeriodMetres,rippleAudit.floorAmplitudeMetres,
|
||||
rippleAudit.floorAmplitudeMetres*100.0,
|
||||
|
||||
Reference in new issue
Block a user