feat(core): native Core caves generator, slice 1 -- spine + room, whole view 0.73 s (L54); research R23

Core.Caves.PrimitiveField v1, opt-in per strate (legacy TunnelNetwork assets stay legacy): solid host rock
and one smooth union of two elliptical spine tubes and an ellipsoid room, each intersected with its rising
floor by cubic smooth-max (W 2.4 m, measured fillet 0.70 m, no trailing floor cap). Bound in the L40 field
table and L42 capabilities, BVH feature candidates, isTileShapeFree aware, exact interval boxes (0 misses).
Capsule flood fill arrival -> departure passes (headroom >= 0.3 m, grade <= 15 deg); the generalized
whole-surface audit passes with its controls failing. Cold whole view 0.727 s, near ring 0.19 s. Graph
ordering/serialization changes are scoped to native caves (the flagged L47 demo is unchanged); verify
tiers write captures under --out only. fast/medium/full PASS, Clang and GCC.
Research R23 (deepened): per-tile LOD0 kernel speed plan.

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-25 04:10:19 +01:00
1 parent 20f6c98ec5
commit 9458217d34
24 files changed
+471136 -59

No files matched your search

+106 -1
View File
@@ -621,7 +621,18 @@ namespace
if(point)out<<',';const auto& p=edge.controlPointsMicrometres[point];
out<<'['<<p[0]<<','<<p[1]<<','<<p[2]<<']';
}
out<<"],\"bore_radius_um\":"<<edge.boreRadiusMicrometres
out<<']';
if(!edge.polylineMicrometres.empty())
{
out<<",\"polyline_um\":[";
for(std::size_t point=0;point<edge.polylineMicrometres.size();++point)
{
if(point)out<<',';const auto& p=edge.polylineMicrometres[point];
out<<'['<<p[0]<<','<<p[1]<<','<<p[2]<<']';
}
out<<']';
}
out<<",\"bore_radius_um\":"<<edge.boreRadiusMicrometres
<<",\"bore_height_um\":"<<edge.boreHeightMicrometres
<<",\"floor_support_depth_um\":"<<edge.floorSupportDepthMicrometres
<<",\"smooth_width_um\":"<<edge.smoothWidthMicrometres
@@ -845,6 +856,8 @@ bool ResolvedLayoutSnapshotV3::finalize(std::string& error)
x.lowerInterfaceCapabilities={};
if(x.generatorKind=="SurfaceWorld")
x.passageCapabilities.hasSurfaceLanding=true;
else if(x.generatorKind=="Caves")
x.passageCapabilities.hasNativeCaveField=true;
else if(x.generatorKind=="FloatingIslands")
{
x.passageCapabilities.hasFloatingIslandLanding=true;
@@ -1235,6 +1248,15 @@ bool ResolvedLayoutSnapshotV3::validate(ResolvedLayoutValidationModeV3 mode,
||std::abs(endpoint[2]-room->floorMicrometres)>500000)
add("cavern_edge_portal",edge.stableId+" endpoint does not meet its room floor portal");
}
const auto* edgeStratum=findStratum(edge.strateIndex);
if(edgeStratum&&edgeStratum->generatorKind=="Caves"
&&edgeStratum->recipeId=="Core.Caves.PrimitiveField"
&&edgeStratum->recipeVersion==1
&&(edge.polylineMicrometres.size()<2
||edge.polylineMicrometres.front()!=edge.controlPointsMicrometres.front()
||edge.polylineMicrometres.back()!=edge.controlPointsMicrometres.back()))
add("cavern_edge_polyline",edge.stableId+
" has no resolve-time polyline with the cubic endpoints");
}
}
if(oreVeins.empty())
@@ -1409,6 +1431,13 @@ std::optional<ResolvedLayoutSnapshotV3> ResolvedLayoutSnapshotV3::FromJson(
for(std::size_t axis=0;axis<3&&axis<point.size();++axis)
edge.controlPointsMicrometres[i][axis]=point[axis].Integer();
}
for(const auto& item:v.Get("polyline_um").AsArray())
{
const auto& point=item.AsArray();
if(point.size()!=3)continue;
edge.polylineMicrometres.push_back({point[0].Integer(),
point[1].Integer(),point[2].Integer()});
}
const auto readTriplet=[&](std::string_view key,std::array<std::int64_t,3>& target)
{
const auto& values=v.Get(key).AsArray();
@@ -1594,6 +1623,13 @@ bool ResolveResolvedCavernGraphV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
candidate.cavernGraphVocabularyVersion=ResolvedLayoutCavernGraphVocabularyVersionV1;
candidate.cavernRooms.assign(rooms.begin(),rooms.end());
candidate.cavernEdges.assign(edges.begin(),edges.end());
const auto isNativeCavesStrate=[&candidate](std::int32_t strateIndex)
{
const auto found=std::find_if(candidate.strates.begin(),candidate.strates.end(),
[strateIndex](const auto& stratum){return stratum.strateIndex==strateIndex;});
return found!=candidate.strates.end()&&found->generatorKind=="Caves"
&&found->recipeId=="Core.Caves.PrimitiveField"&&found->recipeVersion==1;
};
for(auto& room:candidate.cavernRooms)
{
// The shared JSON value type stores numbers as IEEE-754 doubles. Keep the
@@ -1614,6 +1650,75 @@ bool ResolveResolvedCavernGraphV1(ResolvedLayoutSnapshotV3& layout,std::int32_t
{
edge.irregularitySeed=LayoutStampSeed(seed,edge.strateIndex,edge.stableId)
&0x001fffffffffffffull;
using FCurvePoint=std::array<double,3>;
std::array<FCurvePoint,4> curve{};
for(std::size_t point=0;point<curve.size();++point)
for(std::size_t axis=0;axis<3;++axis)
curve[point][axis]=static_cast<double>(edge.controlPointsMicrometres[point][axis]);
const auto pointSegmentDistance=[](const FCurvePoint& point,
const FCurvePoint& a,const FCurvePoint& b)
{
double lengthSquared=0.0,dot=0.0;
for(std::size_t axis=0;axis<3;++axis)
{
const double delta=b[axis]-a[axis];
lengthSquared+=delta*delta;dot+=(point[axis]-a[axis])*delta;
}
const double t=lengthSquared>0.0
?std::clamp(dot/lengthSquared,0.0,1.0):0.0;
double distanceSquared=0.0;
for(std::size_t axis=0;axis<3;++axis)
{
const double delta=point[axis]-(a[axis]+t*(b[axis]-a[axis]));
distanceSquared+=delta*delta;
}
return std::sqrt(distanceSquared);
};
edge.polylineMicrometres.clear();
if(isNativeCavesStrate(edge.strateIndex))
{
edge.polylineMicrometres.push_back(edge.controlPointsMicrometres.front());
constexpr double MaximumChordErrorMicrometres=10000.0;
bool polylineValid=true;
const auto subdivide=[&](const auto& self,const std::array<FCurvePoint,4>& points,
int depth)->void
{
if(!polylineValid)return;
const double flatness=std::max(pointSegmentDistance(points[1],points[0],points[3]),
pointSegmentDistance(points[2],points[0],points[3]));
if(flatness<=MaximumChordErrorMicrometres)
{
std::array<std::int64_t,3> endpoint{};
for(std::size_t axis=0;axis<3;++axis)
{
if(!std::isfinite(points[3][axis])
||std::abs(points[3][axis])>9.0e15)
{polylineValid=false;return;}
endpoint[axis]=static_cast<std::int64_t>(std::llround(points[3][axis]));
}
edge.polylineMicrometres.push_back(endpoint);
if(edge.polylineMicrometres.size()>65536)polylineValid=false;
return;
}
if(depth>=20){polylineValid=false;return;}
std::array<FCurvePoint,4> left{},right{};
FCurvePoint a{},b{},c{},d{},e{},mid{};
for(std::size_t axis=0;axis<3;++axis)
{
a[axis]=(points[0][axis]+points[1][axis])*0.5;
b[axis]=(points[1][axis]+points[2][axis])*0.5;
c[axis]=(points[2][axis]+points[3][axis])*0.5;
d[axis]=(a[axis]+b[axis])*0.5;
e[axis]=(b[axis]+c[axis])*0.5;
mid[axis]=(d[axis]+e[axis])*0.5;
}
left={points[0],a,d,mid};right={mid,e,c,points[3]};
self(self,left,depth+1);self(self,right,depth+1);
};
subdivide(subdivide,curve,0);
if(!polylineValid)
{error="cavern edge "+edge.stableId+" exceeds the bounded polyline subdivision budget";return false;}
}
std::array<std::int64_t,3> low=edge.controlPointsMicrometres[0];
std::array<std::int64_t,3> high=low;
for(const auto& point:edge.controlPointsMicrometres)