core: Tunnel Network cave planner with a continuous backbone floor (L134, evaluator v230)

Backbone rooms and edges share one floor profile h(s); side branches keep flat floors; overlap backing capped at the
lower floor. Default seed: route audit 0 blocked / 0 unsupported / 0 grade over 51,975 capsule samples; passages
open; fast tier, seams, Clang/GCC W1/W8/W12 green. Open: seed 1 (24 blocked at the 2-3 arrival mouth) and seed 2
(22 unsupported at passage 1-2) fail composed audits; near-ready +6..+14% on layers 1-3. Not for merge.

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-31 14:03:35 +01:00
1 parent 4a97023b24
commit a3c8e3687d
23 files changed
+338 -53

No files matched your search

+22 -15
View File
@@ -1247,7 +1247,7 @@ bool ResolvedLayoutSnapshotV3::validate(ResolvedLayoutValidationModeV3 mode,
else if(cavernGraphVocabularyVersion!=ResolvedLayoutCavernGraphVocabularyVersionV1
&&cavernGraphVocabularyVersion!=ResolvedLayoutCavernGraphVocabularyVersionV2)
add("cavern_graph_vocabulary_version",
"cavern graph records require vocabulary version 1");
"cavern graph records require a supported vocabulary version");
if(cavernGraphVocabularyVersion!=0)
{
if(cavernRooms.empty()||cavernEdges.empty())
@@ -1447,9 +1447,13 @@ bool ResolvedLayoutSnapshotV3::validate(ResolvedLayoutValidationModeV3 mode,
previous->floorProfileEndDistanceMicrometres);
if(low!=previousHigh
||std::abs(endpointZ(*previous,false)-endpointZ(*edge,true))>1000
||std::abs(endpointSlope(*previous,false)-slope0)>0.000001)
add("cavern_floor_profile_joint",profileId+
" has a gap, height step, or slope step between adjacent edges");
||std::abs(endpointSlope(*previous,false)-slope0)>0.00001)
add("cavern_floor_profile_joint",profileId+" between "+previous->stableId
+" and "+edge->stableId+" has distance gap="
+std::to_string(low-previousHigh)+" um height step="
+std::to_string(endpointZ(*previous,false)-endpointZ(*edge,true))
+" um slope step="
+std::to_string(endpointSlope(*previous,false)-slope0));
}
previous=edge;
(void)high;
@@ -2320,7 +2324,9 @@ bool PlanResolvedCavernNetworkV1(const ResolvedLayoutSnapshotV3& layout,
points[2][axis]=routeStart[axis]+(delta*2)/3;
}
points[1][0]+=perpX;points[1][1]+=perpY;
points[2][0]-=perpX;points[2][1]-=perpY;
// Keep both control points on the same side of the mouth axis. Opposite
// offsets create a tight hairpin whose descending bores overlap in XY.
points[2][0]+=perpX;points[2][1]+=perpY;
return points;
};
const auto routeLength=[&](const std::array<FPoint,4>& points)
@@ -2545,8 +2551,15 @@ bool PlanResolvedCavernNetworkV1(const ResolvedLayoutSnapshotV3& layout,
room.floorGradientQ16=node.floorGradientQ16;
room.halfExtentsMicrometres={halfX,halfY,halfZ};
room.centerMicrometres={node.point[0]+(-pathAxisY)*centerOffset/routeLengthXY,
node.point[1]+pathAxisX*centerOffset/routeLengthXY,
node.point[2]+fractional(halfZ,floorCut)};
node.point[1]+pathAxisX*centerOffset/routeLengthXY,0};
// Keep the local floor plane on the backbone profile at the route point,
// then place each offset primitive from that plane at its own XY centre.
room.floorMicrometres=node.point[2]
+(static_cast<std::int64_t>(room.floorGradientQ16[0])
*(room.centerMicrometres[0]-node.point[0])
+static_cast<std::int64_t>(room.floorGradientQ16[1])
*(room.centerMicrometres[1]-node.point[1]))/65536;
room.centerMicrometres[2]=room.floorMicrometres+fractional(halfZ,floorCut);
if(component>0)
{
const std::int64_t headroom=std::max<std::int64_t>(0,
@@ -2557,11 +2570,6 @@ bool PlanResolvedCavernNetworkV1(const ResolvedLayoutSnapshotV3& layout,
%static_cast<std::uint64_t>(jitterRange+1)):0;
room.centerMicrometres[2]+=ceilingJitter;
}
room.floorMicrometres=node.point[2]
-(static_cast<std::int64_t>(room.floorGradientQ16[0])
*(room.centerMicrometres[0]-node.point[0])
+static_cast<std::int64_t>(room.floorGradientQ16[1])
*(room.centerMicrometres[1]-node.point[1]))/65536;
room.smoothWidthMicrometres=smooth;
room.irregularityAmplitudeMicrometres=irregularity;
room.irregularityWavelengthMicrometres=settings.irregularityWavelengthMicrometres;
@@ -2665,9 +2673,8 @@ bool PlanResolvedCavernNetworkV1(const ResolvedLayoutSnapshotV3& layout,
branch.point={parent.point[0]+(-pathAxisY)*branchLength/pathAxisLength*direction,
parent.point[1]+pathAxisX*branchLength/pathAxisLength*direction,
parent.point[2]};
branch.floorProfileStableId=parent.floorProfileStableId;
branch.floorProfileDistanceMicrometres=parent.floorProfileDistanceMicrometres;
branch.floorGradientQ16=parent.floorGradientQ16;
// A side branch leaves the backbone laterally, so it has its own local flat
// floor and must not reference the parent's one-dimensional h(s) profile.
makeCompound(branch,false,rooms);
const std::string branchEdgeId="tunnel-network/strate-"
+std::to_string(strateIndex)+"/side-edge-"+std::to_string(branchCount);