feat(core): cavern graph v1, one continuous floor-capped tunnel into the landmark chamber (L46); R13

The flagged SW demo's ramp (57 carves + 107 support pillars, visibly ribbed) becomes one cubic-Bezier
sweep: closest point by 17-point seed plus 5 Newton steps, a cubic floor profile, a rounded 2.6 m bore,
and a hard floor cap applied after unions and relief that only adds support where the field is air.
Optional resolved cavern-graph records (one room, one edge) enter canonical identity only when present;
their bounds extend World::isTileShapeFree. Reachability passes (L43 control fails), headroom 2.8 m,
floor ripple 1.8 mm (L45 ramp control fails at 17.9 mm), shape limits met; demo off: owner hashes
identical to L45. fast/medium/full PASS. Research R13 (read-only): continuous SDF sweeps along curves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-24 09:53:06 +02:00
1 parent f13b145f23
commit e016f6a20f
14 files changed
+1753 -48

No files matched your search

+129 -13
View File
@@ -56,6 +56,7 @@ namespace
int RenderDistanceOverride=0;
bool FloatingIslandsRecipe=false;
bool LandmarkChamberDemo=false;
bool LandmarkL45RampControl=false;
bool AuditLandmarkReachability=false;
bool TlsProbeRequested=false;
int TlsProbeWorkers=0;
@@ -115,10 +116,14 @@ namespace
const VoxelForgeCore::WorldAssemblyManifest& worldAssembly,
std::int32_t seed,
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1>& requests,
std::vector<VoxelForgeCore::ResolvedCavernRoomV1>& cavernRooms,
std::vector<VoxelForgeCore::ResolvedCavernEdgeV1>& cavernEdges,
bool legacyRampControl,
std::string& error)
{
using namespace VoxelForgeCore;
requests.clear();
cavernRooms.clear();cavernEdges.clear();
const auto surface=std::find_if(layout.strates.begin(),layout.strates.end(),
[](const auto& value){return value.generatorKind=="SurfaceWorld";});
if(surface==layout.strates.end())
@@ -444,6 +449,100 @@ namespace
return startZ+descent*std::clamp((beforeFirstTurn+afterFirstTurn)
/slopedLength,0.0,1.0);
};
// The resolved edge is one cubic sweep. Its floor controls are independent
// of the curved XY centerline, so the floor remains an explicit profile.
const double startFloor=surfaceHeight;
const double endFloor=chamberCenterZ-0.5;
const double firstLength=std::hypot(firstTurn.x-start.x,firstTurn.y-start.y);
const double lastLength=std::hypot(end.x-firstTurn.x,end.y-firstTurn.y);
const double estimatedLength=firstLength+lastLength;
const double handleLength=estimatedLength/3.0;
const double firstDirX=(firstTurn.x-start.x)/firstLength;
const double firstDirY=(firstTurn.y-start.y)/firstLength;
const double lastDirX=(end.x-firstTurn.x)/lastLength;
const double lastDirY=(end.y-firstTurn.y)/lastLength;
std::array<std::array<double,3>,4> curve={{
{start.x,start.y,startFloor},
{start.x+firstDirX*handleLength,start.y+firstDirY*handleLength,
startFloor+(endFloor-startFloor)/3.0},
{end.x-lastDirX*handleLength,end.y-lastDirY*handleLength,
startFloor+2.0*(endFloor-startFloor)/3.0},
{end.x,end.y,endFloor}}};
ResolvedCavernRoomV1 room;
room.stableId=chamber.stableId;room.strateIndex=surface->strateIndex;
room.centerMicrometres=chamber.anchorPositionMicrometres;
room.halfExtentsMicrometres=chamber.halfExtentsMicrometres;
room.floorMicrometres=static_cast<std::int64_t>(std::llround(endFloor*1000000.0));
room.smoothWidthMicrometres=chamber.smoothWidthMicrometres;
room.irregularityAmplitudeMicrometres=chamber.irregularityAmplitudeMicrometres;
room.irregularityWavelengthMicrometres=chamber.irregularityWavelengthMicrometres;
if(!legacyRampControl)cavernRooms.push_back(room);
ResolvedCavernEdgeV1 edge;
edge.stableId="landmark/sw-arrival-chamber-tunnel-v1";
edge.startAnchorStableId=passage->stableId+"/surface-ground-approach";
edge.endRoomStableId=room.stableId;edge.strateIndex=surface->strateIndex;
edge.boreRadiusMicrometres=2600000;
edge.boreHeightMicrometres=4800000;
edge.floorSupportDepthMicrometres=450000;
edge.smoothWidthMicrometres=300000;
edge.irregularityAmplitudeMicrometres=20000;
edge.irregularityWavelengthMicrometres=3200000;
double measuredCurveLength=0.0,arcAtThird=0.0,arcAtTwoThirds=0.0;
std::array<double,2> previousCurvePoint={curve[0][0],curve[0][1]};
for(int sample=1;sample<=256;++sample)
{
const double t=static_cast<double>(sample)/256.0,one=1.0-t;
std::array<double,3> point{};
for(std::size_t axis=0;axis<3;++axis)
point[axis]=one*one*one*curve[0][axis]
+3.0*one*one*t*curve[1][axis]+3.0*one*t*t*curve[2][axis]
+t*t*t*curve[3][axis];
const double dx=point[0]-previousCurvePoint[0];
const double dy=point[1]-previousCurvePoint[1];
const double horizontal=std::hypot(dx,dy);
measuredCurveLength+=horizontal;
if(sample==85)arcAtThird=measuredCurveLength;
if(sample==171)arcAtTwoThirds=measuredCurveLength;
previousCurvePoint={point[0],point[1]};
}
const double targetFloorThird=startFloor+(endFloor-startFloor)
*(arcAtThird/measuredCurveLength);
const double targetFloorTwoThirds=startFloor+(endFloor-startFloor)
*(arcAtTwoThirds/measuredCurveLength);
const double firstEquation=targetFloorThird
-(8.0*startFloor+endFloor)/27.0;
const double secondEquation=targetFloorTwoThirds
-(startFloor+8.0*endFloor)/27.0;
curve[1][2]=1.5*(2.0*firstEquation-secondEquation);
curve[2][2]=1.5*(2.0*secondEquation-firstEquation);
double maximumCurveGrade=0.0;
std::array<double,3> previousCurvePosition=curve[0];
for(int sample=1;sample<=256;++sample)
{
const double t=static_cast<double>(sample)/256.0,one=1.0-t;
std::array<double,3> point{};
for(std::size_t axis=0;axis<3;++axis)
point[axis]=one*one*one*curve[0][axis]
+3.0*one*one*t*curve[1][axis]+3.0*one*t*t*curve[2][axis]
+t*t*t*curve[3][axis];
const double horizontal=std::hypot(point[0]-previousCurvePosition[0],
point[1]-previousCurvePosition[1]);
maximumCurveGrade=std::max(maximumCurveGrade,std::atan2(
std::abs(point[2]-previousCurvePosition[2]),
std::max(1.0e-6,horizontal))*180.0/3.14159265358979323846);
previousCurvePosition=point;
}
for(std::size_t i=0;i<curve.size();++i)
for(std::size_t axis=0;axis<3;++axis)
edge.controlPointsMicrometres[i][axis]=static_cast<std::int64_t>(
std::llround(curve[i][axis]*1000000.0));
if(!legacyRampControl)cavernEdges.push_back(edge);
std::printf("[CavernGraphPlan] rooms=1 edges=1 room=%s edge=%s curve=cubic-bezier floor=cubic-profile length_m=%.3f max_grade_deg=%.3f bore_radius_m=2.600 bore_height_m=4.800 floor_um=%lld..%lld\n",
room.stableId.c_str(),edge.stableId.c_str(),measuredCurveLength,maximumCurveGrade,
static_cast<long long>(room.floorMicrometres),
static_cast<long long>(edge.controlPointsMicrometres[0][2]));
if(maximumCurveGrade>15.0)
{error="landmark cavern edge exceeds the 15 degree walk grade";return false;}
const double pointSpacing=0.6;
const std::size_t rampCount=static_cast<std::size_t>(std::ceil(totalLength/pointSpacing));
std::vector<ResolvedLayoutStampRequestV1> rampCarves;
@@ -506,12 +605,15 @@ namespace
}
requests.push_back(std::move(mouthStamp));
requests.push_back(std::move(mouthPortal));
requests.insert(requests.end(),std::make_move_iterator(rampCarves.begin()),
std::make_move_iterator(rampCarves.end()));
requests.push_back(std::move(chamber));
requests.insert(requests.end(),std::make_move_iterator(rampSupports.begin()),
std::make_move_iterator(rampSupports.end()));
requests.push_back(std::move(mouthLanding));
if(legacyRampControl)
{
requests.insert(requests.end(),std::make_move_iterator(rampCarves.begin()),
std::make_move_iterator(rampCarves.end()));
requests.push_back(std::move(chamber));
requests.insert(requests.end(),std::make_move_iterator(rampSupports.begin()),
std::make_move_iterator(rampSupports.end()));
}
if(legacyRampControl)requests.push_back(std::move(mouthLanding));
requests.push_back(std::move(chamberFloor));
requests.push_back(std::move(dais));
(void)seed;
@@ -571,7 +673,8 @@ namespace
" --mesh-export=FILE (write the exact generated tile meshes for offline rendering)\n"
" --profile-column-overlap --far-horizon-lod8-step=N --force-generate\n"
" --seed=N --recipe=surface-world|floating-islands\n"
" --landmark-chamber-demo (opt-in natural SW landmark chamber and ramp)\n"
" --landmark-chamber-demo (opt-in SW cavern room and swept tunnel)\n"
" --landmark-l45-ramp-control (use the buried L45 stamp geometry as an audit control)\n"
" --resolved-layout-output=FILE (canonical plan-time layout snapshot)\n"
" --resolved-layout-only (exit after plan and snapshot validation)\n"
" --audit-resolved-layout-boundaries (query Core at each recorded endpoint)\n"
@@ -640,6 +743,7 @@ namespace
else {std::fprintf(stderr,"Invalid --recipe value: %.*s\n",static_cast<int>(recipe.size()),recipe.data());return false;}
}
else if(arg=="--landmark-chamber-demo")options.LandmarkChamberDemo=true;
else if(arg=="--landmark-l45-ramp-control")options.LandmarkL45RampControl=true;
else if(arg.starts_with("--resolved-layout-output="))
options.ResolvedLayoutOutputPath=std::string(arg.substr(std::string_view("--resolved-layout-output=").size()));
else if(arg.starts_with("--seed="))
@@ -722,6 +826,8 @@ namespace
{std::fprintf(stderr,"--tls-probe-touch requires --tls-probe=N\n");return false;}
if(options.RegionCrossing&&!options.HasCameraStep)
{std::fprintf(stderr,"--region-crossing requires --camera-step=X,Y,Z\n");return false;}
if(options.LandmarkL45RampControl&&!options.LandmarkChamberDemo)
{std::fprintf(stderr,"--landmark-l45-ramp-control requires --landmark-chamber-demo\n");return false;}
if(options.TlsProbeRequested)return true;
if(!options.WorldAssemblerPrototype||!options.StreamBenchmark||!options.StreamPipeline)
{
@@ -820,10 +926,15 @@ int main(int argc,char** argv)
if(options.LandmarkChamberDemo)
{
std::vector<VoxelForgeCore::ResolvedLayoutStampRequestV1> requests;
if(!MakeLandmarkChamberDemoRequests(resolvedLayout,worldAssembly,seed,requests,error)
std::vector<VoxelForgeCore::ResolvedCavernRoomV1> rooms;
std::vector<VoxelForgeCore::ResolvedCavernEdgeV1> edges;
if(!MakeLandmarkChamberDemoRequests(resolvedLayout,worldAssembly,seed,
requests,rooms,edges,options.LandmarkL45RampControl,error)
||!VoxelForgeCore::ResolveResolvedLayoutStampsV2(
resolvedLayout,seed,requests,error))
{std::fprintf(stderr,"Landmark chamber stamp resolution failed: %s\n",error.c_str());return 2;}
resolvedLayout,seed,requests,error)
||!VoxelForgeCore::ResolveResolvedCavernGraphV1(
resolvedLayout,seed,rooms,edges,error))
{std::fprintf(stderr,"Landmark cavern graph resolution failed: %s\n",error.c_str());return 2;}
const auto audit=VoxelForgeCore::AuditResolvedLayoutStampPlacementV1(resolvedLayout);
std::printf("[ResolvedStampPlacementAudit] vocabulary=%u records=%zu route_control=rejected band_control=rejected controls=%u/%u status=%s\n",
resolvedLayout.stampVocabularyVersion,resolvedLayout.stamps.size(),
@@ -849,9 +960,14 @@ int main(int argc,char** argv)
stamp.irregularityAmplitudeMicrometres/1000000.0,
stamp.irregularityWavelengthMicrometres/1000000.0,
static_cast<unsigned long long>(stamp.irregularitySeed));
std::printf("[LandmarkStampDemo] enabled=true seed=%d layout_id=%s passage_safe=true walk_route_clear=true version=%u deterministic_hash=seed,strate,stable_id status=PASS\n",
seed,resolvedLayout.stableIdentity.c_str(),
resolvedLayout.stampVocabularyVersion);
if(options.LandmarkL45RampControl)
std::printf("[LandmarkL45RampControl] enabled=true stamps=%zu graph_records=0 expected=segmented status=PASS\n",
resolvedLayout.stamps.size());
else
std::printf("[LandmarkCavernGraphDemo] enabled=true seed=%d layout_id=%s rooms=%zu edges=%zu support_stamps=%zu passage_safe=true deterministic_hash=seed,strate,stable_id version=%u status=PASS\n",
seed,resolvedLayout.stableIdentity.c_str(),
resolvedLayout.cavernRooms.size(),resolvedLayout.cavernEdges.size(),
resolvedLayout.stamps.size(),resolvedLayout.cavernGraphVocabularyVersion);
}
const std::string layoutJson=resolvedLayout.ToJson();
const auto roundTrip=VoxelForgeCore::ResolvedLayoutSnapshotV3::FromJson(layoutJson,error);