wip(assembler): round L31 -- FI recipe column audit corrected; recipe-stamped audit runner

On the real FloatingIslands recipe, column caps sit inside anchor-island rock and native bedrock;
the old check sampled the route foot. The audit now samples each planned cap against the native
field (negative control: a cap moved into air is detected). The audit runner records requested vs
actual recipe and exits on mismatch. All 16 passage rows (4 styles x 2 recipes x 2 compilers) pass.
The readable shader uses a smooth tint. Interim: FI Gradient displacement capped at width/256
(flat floor, no contour rings); restoring real undulation is L32. Evaluator 19.

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 14:13:18 +02:00
1 parent 103d8b471e
commit 28069f0d98
23 files changed
+1235 -19

No files matched your search

+23 -9
View File
@@ -290,6 +290,7 @@ in vec4 vTileData;
out vec4 outColor;
uniform int uReadableMode;
uniform int uTileEdges;
uniform int uHeightTint;
uniform float uHeightCenter;
uniform float uHeightRange;
uniform float uTileEdgeWidth;
@@ -312,7 +313,10 @@ void main()
else
{
float heightT=clamp(0.5+(vHeight-uHeightCenter)/max(uHeightRange,0.001),0.0,1.0);
vec3 heightTint=mix(vec3(0.80,0.91,1.0),vec3(1.0,0.91,0.77),heightT);
float smoothHeightT=heightT*heightT*(3.0-2.0*heightT);
vec3 heightTint=uHeightTint!=0
?mix(vec3(0.80,0.91,1.0),vec3(1.0,0.91,0.77),smoothHeightT)
:vec3(1.0);
float diffuse=max(dot(n,normalize(uLightDirection)),0.0);
float illumination=uHeadlamp!=0?0.78+0.34*diffuse:0.62+0.38*diffuse;
color=vec3(0.64,0.62,0.56)*heightTint*illumination;
@@ -376,7 +380,7 @@ void main()
}
bool Render(FScene& Scene,const std::filesystem::path& Output,int Width,int Height,
double HorizontalFovDegrees,bool ReadableMode,bool Headlamp,bool TileEdges,
double HorizontalFovDegrees,bool ReadableMode,bool HeightTint,bool Headlamp,bool TileEdges,
double TileEdgeWidthMeters,bool ClipPlaneEnabled,
const std::array<double,4>& ClipPlane)
{
@@ -472,6 +476,7 @@ void main()
glUniform1f(glGetUniformLocation(Program,"uFar"),static_cast<float>(Far));
glUniform1i(glGetUniformLocation(Program,"uReadableMode"),ReadableMode?1:0);
glUniform1i(glGetUniformLocation(Program,"uTileEdges"),TileEdges?1:0);
glUniform1i(glGetUniformLocation(Program,"uHeightTint"),HeightTint?1:0);
glUniform1f(glGetUniformLocation(Program,"uHeightCenter"),
static_cast<float>(Scene.CameraMeters[2]));
glUniform1f(glGetUniformLocation(Program,"uHeightRange"),64.0f);
@@ -499,13 +504,14 @@ void main()
const auto Bytes=std::filesystem::file_size(Output,SizeError);
std::printf("[OffscreenCapture] source_triangles=%llu drawn_triangles=%llu tiles=%u "
"skirts=%llu visible_skirt_triangles=%llu hidden_same_lod_skirt_triangles=%llu "
"shading=%s tile_edges=%s edge_width_m=%.3f png_bytes=%llu status=PASS path=%s\n",
"shading=%s height_tint=%s tile_edges=%s edge_width_m=%.3f png_bytes=%llu status=PASS path=%s\n",
static_cast<unsigned long long>(Scene.Triangles),
static_cast<unsigned long long>(Scene.DrawnTriangles),Scene.TileCount,
static_cast<unsigned long long>(Scene.SkirtTriangles),
static_cast<unsigned long long>(Scene.VisibleSkirtTriangles),
static_cast<unsigned long long>(Scene.HiddenSameLodSkirtTriangles),
ReadableMode?"readable":"normal",TileEdges?"on":"off",TileEdgeWidthMeters,
ReadableMode?"readable":"normal",HeightTint?"on":"off",
TileEdges?"on":"off",TileEdgeWidthMeters,
static_cast<unsigned long long>(SizeError?0:Bytes),Output.string().c_str());
}
glDeleteProgram(Program);glDeleteBuffers(1,&Ebo);glDeleteBuffers(1,&Vbo);
@@ -521,13 +527,13 @@ int main(int argc,char** argv)
{
if(argc<3)
{
std::fprintf(stderr,"Usage: %s scene.vfmesh output.png [--size=WIDTHxHEIGHT] [--fov-deg=90] [--camera-m=X,Y,Z] [--yaw-deg=N] [--pitch-deg=N] [--shade=readable|normal] [--headlamp=on|off] [--tile-edges=on|off] [--tile-edge-width-m=N] [--clip-plane=NX,NY,NZ,D]\n",argv[0]);
std::fprintf(stderr,"Usage: %s scene.vfmesh output.png [--size=WIDTHxHEIGHT] [--fov-deg=90] [--camera-m=X,Y,Z] [--yaw-deg=N] [--pitch-deg=N] [--shade=readable|normal] [--height-tint=on|off] [--headlamp=on|off] [--tile-edges=on|off] [--tile-edge-width-m=N] [--clip-plane=NX,NY,NZ,D]\n",argv[0]);
return 2;
}
int Width=2560,Height=1440;double Fov=90.0;
bool HasYaw=false,HasPitch=false;double Yaw=0.0,Pitch=0.0;
bool HasCamera=false;std::array<double,3> Camera{};
bool ReadableMode=true,TileEdges=false,Headlamp=false;double TileEdgeWidthMeters=0.15;
bool ReadableMode=true,HeightTint=true,TileEdges=false,Headlamp=false;double TileEdgeWidthMeters=0.15;
bool ClipPlaneEnabled=false;std::array<double,4> ClipPlane{};
for(int I=3;I<argc;++I)
{
@@ -569,6 +575,13 @@ int main(int argc,char** argv)
else if(Mode=="normal")ReadableMode=false;
else {std::fprintf(stderr,"Invalid shading mode\n");return 2;}
}
else if(Arg.starts_with("--height-tint="))
{
const std::string_view Mode=Arg.substr(14);
if(Mode=="on")HeightTint=true;
else if(Mode=="off")HeightTint=false;
else {std::fprintf(stderr,"Invalid height-tint mode\n");return 2;}
}
else if(Arg.starts_with("--headlamp="))
{
const std::string_view Mode=Arg.substr(11);
@@ -610,12 +623,13 @@ int main(int argc,char** argv)
if(HasCamera)Scene.CameraMeters=Camera;
if(HasYaw)Scene.YawDegrees=Yaw;
if(HasPitch)Scene.PitchDegrees=Pitch;
std::printf("[OffscreenScene] voxels_per_meter=%.6f camera_m=(%.3f,%.3f,%.3f) yaw=%.2f pitch=%.2f height_m=%.3f..%.3f shade=%s tile_edges=%s vertices=%zu triangles=%llu\n",
std::printf("[OffscreenScene] voxels_per_meter=%.6f camera_m=(%.3f,%.3f,%.3f) yaw=%.2f pitch=%.2f height_m=%.3f..%.3f shade=%s height_tint=%s tile_edges=%s vertices=%zu triangles=%llu\n",
1000000.0/Scene.VoxelSizeMicrons,Scene.CameraMeters[0],Scene.CameraMeters[1],Scene.CameraMeters[2],
Scene.YawDegrees,Scene.PitchDegrees,Scene.MinimumHeight,Scene.MaximumHeight,
ReadableMode?"readable":"normal",TileEdges?"on":"off",Scene.Vertices.size(),
ReadableMode?"readable":"normal",HeightTint?"on":"off",
TileEdges?"on":"off",Scene.Vertices.size(),
static_cast<unsigned long long>(Scene.Triangles));
return Render(Scene,argv[2],Width,Height,Fov,ReadableMode,Headlamp,TileEdges,
return Render(Scene,argv[2],Width,Height,Fov,ReadableMode,HeightTint,Headlamp,TileEdges,
TileEdgeWidthMeters,ClipPlaneEnabled,ClipPlane)?0:3;
}
@@ -423,6 +423,35 @@ int main(int argc,char** argv)
VoxelForgeCore::ResolvedLayoutValidationModeV3::strict,strictIssues,strictError);
std::printf("[ResolvedLayoutSnapshot] schema=%u stable_identity=%s strata=%zu bytes=%zu round_trip=PASS\n",
resolvedLayout.schemaVersion,resolvedLayout.stableIdentity.c_str(),resolvedLayout.strates.size(),layoutJson.size());
const auto requestedRecipe=options.FloatingIslandsRecipe
?std::string_view("floating-islands"):std::string_view("surface-world");
const auto topStratum=std::max_element(resolvedLayout.strates.begin(),resolvedLayout.strates.end(),
[](const auto& a,const auto& b)
{return a.interiorTopMicrometres<b.interiorTopMicrometres;});
const bool hasFloatingIslands=std::any_of(resolvedLayout.strates.begin(),resolvedLayout.strates.end(),
[](const auto& stratum){return stratum.generatorKind=="FloatingIslands";});
const bool hasSurfaceWorldPlan=std::any_of(resolvedLayout.strates.begin(),resolvedLayout.strates.end(),
[&](const auto& stratum)
{
return stratum.generatorKind=="SurfaceWorld"
&&stratum.recipeId=="SurfaceWorld.Heightfield2D"
&&std::any_of(worldAssembly.plan.strates.begin(),worldAssembly.plan.strates.end(),
[&](const auto& plan){return plan.strateIndex==stratum.strateIndex;});
});
const auto actualRecipe=hasFloatingIslands?std::string_view("floating-islands")
:hasSurfaceWorldPlan?std::string_view("surface-world")
:std::string_view("missing");
const char* topGenerator=topStratum==resolvedLayout.strates.end()
?"missing":topStratum->generatorKind.c_str();
std::printf("[WorldAssemblerRecipeAudit] requested=%.*s actual=%.*s top_generator=%s surface_world_plan=%s floating_islands_stratum=%s status=%s\n",
static_cast<int>(requestedRecipe.size()),requestedRecipe.data(),
static_cast<int>(actualRecipe.size()),actualRecipe.data(),
topGenerator,hasSurfaceWorldPlan?"present":"absent",hasFloatingIslands?"present":"absent",
actualRecipe==requestedRecipe?"PASS":"FAIL");
if(actualRecipe!=requestedRecipe)
{std::fprintf(stderr,"Requested recipe %.*s resolved to %.*s\n",
static_cast<int>(requestedRecipe.size()),requestedRecipe.data(),
static_cast<int>(actualRecipe.size()),actualRecipe.data());return 2;}
std::printf("[ResolvedLayoutCompatibility] accepted=%s issues=%zu error=%s\n",
compatibilityAccepted?"true":"false",compatibilityIssues.size(),compatibilityError.c_str());
for(const auto& issue:compatibilityIssues)
+128 -6
View File
@@ -1084,6 +1084,8 @@ namespace StandaloneStreamBenchmark
double surfaceRadiusReliefMetres=0.0;
double longestShortSpanMetres=0.0;
bool passed=true;
bool disconnectedEndControlApplicable=false;
bool disconnectedEndControlDetected=false;
};
const auto auditPassageColumns=[&](const VoxelForgeCore::World& Field,
const VoxelForgeCore::World& Native,
@@ -1095,7 +1097,7 @@ namespace StandaloneStreamBenchmark
/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 auto endpointSupportCount=[&](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;
@@ -1109,7 +1111,58 @@ namespace StandaloneStreamBenchmark
{solid=true;break;}
supported+=solid;
}
return supported>=3;
return supported;
};
const auto endpointConnected=[&](const std::array<double,4>& point)
{return endpointSupportCount(point)>=3;};
struct FColumnCapProbe
{
std::uint64_t columnSamples=0,nativeOverlapSamples=0;
double firstOverlapDepthMetres=std::numeric_limits<double>::infinity();
double minimumNativeDensity=std::numeric_limits<double>::infinity();
};
const auto probeColumnCap=[&](const VoxelForgeCore::PassageVoidCrossingAuditV1& crossing,
std::size_t segment,double capZMetres,bool upperCap,double depthLimitMetres)
{
FColumnCapProbe probe;
constexpr double DepthStepMetres=0.25;
constexpr double RadialStepMetres=0.50;
constexpr std::size_t DirectionCount=16;
const double axisX=qToMetres(crossing.columnAxisSubvoxels[0]);
const double axisY=qToMetres(crossing.columnAxisSubvoxels[1]);
for(double depth=DepthStepMetres;depth<=depthLimitMetres+1.0e-6;
depth+=DepthStepMetres)
{
const double z=capZMetres+(upperCap?-depth:depth);
const double maxRadius=qToMetres(crossing.columnMaximumRadiusSubvoxels);
const std::size_t radialSteps=static_cast<std::size_t>(
std::ceil(maxRadius/RadialStepMetres));
for(std::size_t radialStep=0;radialStep<=radialSteps;++radialStep)
{
const double radius=std::min(maxRadius,
radialStep*RadialStepMetres);
for(std::size_t direction=0;direction<DirectionCount;++direction)
{
const double angle=2.0*3.14159265358979323846
*direction/DirectionCount;
const VoxelForgeCore::Vec3d sample{
(axisX+radius*std::cos(angle))/coreMetres,
(axisY+radius*std::sin(angle))/coreMetres,z/coreMetres};
if(!Field.isPassageColumnSample(passageIndex,segment,sample))continue;
++probe.columnSamples;
const double nativeDensity=Native.densityAt(sample);
probe.minimumNativeDensity=std::min(probe.minimumNativeDensity,
nativeDensity);
if(nativeDensity<0.0)
{
++probe.nativeOverlapSamples;
probe.firstOverlapDepthMetres=std::min(
probe.firstOverlapDepthMetres,depth);
}
}
}
}
return probe;
};
const auto columnSolidAt=[&](std::size_t segment,double x,double y,double z)
{
@@ -1122,6 +1175,9 @@ namespace StandaloneStreamBenchmark
{x/coreMetres,y/coreMetres,z/coreMetres});
};
const auto crossings=Field.passageVoidCrossings();
double controlLowestRouteZ=std::numeric_limits<double>::infinity();
bool disconnectedEndControlApplicable=false;
bool disconnectedEndControlDetected=false;
for(const auto& crossing:crossings)
{
if(crossing.passageIndex!=passageIndex)continue;
@@ -1157,8 +1213,63 @@ namespace StandaloneStreamBenchmark
}
if(crossing.lastSegment+1>=passage.controlPoints.size())
{audit.passed=false;continue;}
const double capTopMetres=qToMetres(crossing.columnTopZSubvoxels);
const double capBottomMetres=qToMetres(crossing.columnBottomZSubvoxels);
const auto topCap=probeColumnCap(crossing,crossing.firstSegment,
capTopMetres,true,6.0);
const auto bottomCap=probeColumnCap(crossing,crossing.lastSegment,
capBottomMetres,false,6.0);
const bool topCapConnected=topCap.nativeOverlapSamples>0;
const bool bottomCapConnected=bottomCap.nativeOverlapSamples>0;
const std::uint32_t routeStartSupport=endpointSupportCount(
crossing.startPointSubvoxels);
const std::uint32_t routeEndSupport=endpointSupportCount(
crossing.endPointSubvoxels);
std::printf("[PassageColumnRouteEndpointSupport] id=%s start=%u/5 start_z_m=%.3f end=%u/5 end_z_m=%.3f threshold=3/5\n",
passage.stableId.c_str(),routeStartSupport,
qToMetres(crossing.startPointSubvoxels[2]),routeEndSupport,
qToMetres(crossing.endPointSubvoxels[2]));
const auto printCap=[&](const char* endName,const char* side,double capZ,
const FColumnCapProbe& probe,bool connected)
{
std::printf("[PassageColumnCapAudit] id=%s end=%s side=%s cap_z_m=%.3f column_samples=%llu native_overlap_samples=%llu first_overlap_depth_m=%.3f minimum_native_density=%.6f search_depth_m=6.000 status=%s\n",
passage.stableId.c_str(),endName,side,capZ,
static_cast<unsigned long long>(probe.columnSamples),
static_cast<unsigned long long>(probe.nativeOverlapSamples),
probe.firstOverlapDepthMetres,probe.minimumNativeDensity,
connected?"PASS":"FAIL");
};
printCap("top","upper",capTopMetres,topCap,topCapConnected);
printCap("bottom","lower",capBottomMetres,bottomCap,bottomCapConnected);
const auto upper=std::find_if(ResolvedLayout->strates.begin(),
ResolvedLayout->strates.end(),[&](const auto& value)
{return value.strateIndex==passage.upperStrateIndex;});
const double startRouteZ=qToMetres(crossing.startPointSubvoxels[2]);
const double endRouteZ=qToMetres(crossing.endPointSubvoxels[2]);
const double lowerRouteZ=std::min(startRouteZ,endRouteZ);
if(upper!=ResolvedLayout->strates.end()
&&upper->generatorKind=="FloatingIslands"
&&lowerRouteZ<controlLowestRouteZ)
{
controlLowestRouteZ=lowerRouteZ;
// Move the hypothetical lower cap 20 m upward into the FI air gap.
// Its first 2 m are still inside the original column bounds, but a
// truncated column there has no native substrate to join.
const double hypotheticalBottomZ=lowerRouteZ+20.0;
const auto disconnectedControl=probeColumnCap(crossing,
crossing.lastSegment,hypotheticalBottomZ,false,2.0);
disconnectedEndControlApplicable=disconnectedControl.columnSamples>0;
disconnectedEndControlDetected=disconnectedEndControlApplicable
&&disconnectedControl.nativeOverlapSamples==0;
std::printf("[PassageColumnDisconnectedEndControl] source=air_gap_truncated_lower_cap cap_z_m=%.3f column_samples=%llu native_overlap_samples=%llu minimum_native_density=%.6f detected=%s\n",
hypotheticalBottomZ,
static_cast<unsigned long long>(disconnectedControl.columnSamples),
static_cast<unsigned long long>(disconnectedControl.nativeOverlapSamples),
disconnectedControl.minimumNativeDensity,
disconnectedEndControlDetected?"true":"false");
}
++audit.columns;
audit.connectedEnds+=connectedStart+connectedEnd;
audit.connectedEnds+=topCapConnected+bottomCapConnected;
const double axisX=qToMetres(crossing.columnAxisSubvoxels[0]);
const double axisY=qToMetres(crossing.columnAxisSubvoxels[1]);
const double minimumRadius=qToMetres(crossing.columnMinimumRadiusSubvoxels);
@@ -1262,7 +1373,7 @@ namespace StandaloneStreamBenchmark
crossingSurfaceRelief);
const double measuredWall=crossingMinimumSurfaceRadius
-crossing.maximumRouteOffsetMetres-crossing.maximumBoreRadiusMetres;
const bool columnPass=connectedStart&&connectedEnd
const bool columnPass=topCapConnected&&bottomCapConnected
&&minimumWall>=1.50&&crossingRouteFailures==0
&&crossingWallFailures==0&&std::isfinite(measuredWall)
&&measuredWall>=1.50&&crossingSurfaceRelief>=0.20;
@@ -1270,13 +1381,17 @@ namespace StandaloneStreamBenchmark
std::printf("[PassageRockColumnAudit] id=%s segments=%zu..%zu span_m=%.3f axis_m=(%.3f,%.3f) connected=%d/2 route_support=%llu/%llu wall_margin_m=%.3f threshold_m=1.500 radii_m=%.3f..%.3f relief_p2p_m=%.3f nominal_radius_m=%.3f status=%s\n",
passage.stableId.c_str(),crossing.firstSegment,crossing.lastSegment,
crossing.unsupportedLengthMetres,axisX,axisY,
static_cast<int>(connectedStart)+static_cast<int>(connectedEnd),
static_cast<int>(topCapConnected)+static_cast<int>(bottomCapConnected),
static_cast<unsigned long long>(probeCount-crossingRouteFailures),
static_cast<unsigned long long>(probeCount),measuredWall,
crossingMinimumSurfaceRadius,crossingMaximumSurfaceRadius,
crossingSurfaceRelief,qToMetres(crossing.columnNominalRadiusSubvoxels),
columnPass?"PASS":"FAIL");
}
audit.disconnectedEndControlApplicable|=disconnectedEndControlApplicable;
audit.disconnectedEndControlDetected|=disconnectedEndControlDetected;
if(disconnectedEndControlApplicable&&!disconnectedEndControlDetected)
audit.passed=false;
return audit;
};
if(Assembly)
@@ -1384,6 +1499,8 @@ namespace StandaloneStreamBenchmark
double longestUncolumnedSpanMetres=0.0,longestShortSpanMetres=0.0;
double l26LegacyBridgeSpanMetres=0.0;
bool columnAuditsPassed=true,noLongBridgeAuditPassed=true;
bool columnDisconnectedEndControlApplicable=false;
bool columnDisconnectedEndControlDetected=false;
bool l26NegativeControlApplicable=false;
const auto plannedVoidCrossings=Shape.passageVoidCrossings();
for(const auto& crossing:plannedVoidCrossings)
@@ -1439,6 +1556,8 @@ namespace StandaloneStreamBenchmark
longestShortSpanMetres=std::max(longestShortSpanMetres,
columnAudit.longestShortSpanMetres);
columnAuditsPassed&=columnAudit.passed;
columnDisconnectedEndControlApplicable|=columnAudit.disconnectedEndControlApplicable;
columnDisconnectedEndControlDetected|=columnAudit.disconnectedEndControlDetected;
++openAirAudits;
const auto radialSquared=[](const std::array<std::int64_t,3>& p)
{return p[0]*p[0]+p[1]*p[1];};
@@ -1753,12 +1872,15 @@ namespace StandaloneStreamBenchmark
longestShortSpanMetres,l26NegativeControlApplicable
?(l26NoLongBridgeControlDetected?"DETECTED":"MISSED"):"NOT_APPLICABLE",
noLongBridgeAuditPassed?"PASS":"FAIL");
std::printf("[PassageRockColumnAuditSummary] columns=%llu connected_ends=%llu/%llu short_spans=%llu wall_or_support_failures=%llu status=%s\n",
std::printf("[PassageRockColumnAuditSummary] columns=%llu connected_ends=%llu/%llu short_spans=%llu wall_or_support_failures=%llu disconnected_end_control=%s status=%s\n",
static_cast<unsigned long long>(columnCrossings),
static_cast<unsigned long long>(columnConnectedEnds),
static_cast<unsigned long long>(columnCrossings*2),
static_cast<unsigned long long>(shortGroundedSpans),
static_cast<unsigned long long>(columnRouteFailures+columnWallFailures),
columnDisconnectedEndControlApplicable
?(columnDisconnectedEndControlDetected?"DETECTED":"MISSED")
:"NOT_APPLICABLE",
columnAuditsPassed?"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",