passages: tunnels own their floor - flat-bottomed tube + solid shell (L109, v217) - pending visual review

Owner design: flat world-horizontal floor (0.50 m corner blend), 0.75 m solid shell written only
where the host field is air (interiors union first and beat every shell), 5 m cubic mouth ramps.
Removed route support restoration, deferred support, support columns, mouth-support restoration
and their capsule checks (-5,129 / +1,641 lines). Near-ready @W12: FI 1.39 -> 0.86, TN 1.29 ->
0.90, VS 0.85 -> 0.74, SW 0.70 -> 0.76 s (more shell/skirt surface). All walk audits pass;
Clang/GCC W1/W8/W12 deterministic; fast tier PASS; Linux UE builds; 6 UE arrival traces pass.
OPEN ISSUE: open-air shell (e.g. passage 0-1, 1037-1489 m route span) shows a regular stepped
banding pattern - not merged into assembler/world until fixed/approved.

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-29 05:54:48 +01:00
1 parent 95cf8de107
commit 5ea01988c4
104 files changed
+7880 -5022

No files matched your search

@@ -137,31 +137,11 @@ namespace VoxelForgeCore
bool passageComposerProfiled = false;
std::uint64_t passageTileFeatureCount = 0;
std::uint64_t passageTileRouteSegmentCandidates = 0;
std::uint64_t passageTileMouthSegmentCandidates = 0;
std::uint64_t resolvedBoundaryBandQueries = 0;
std::uint64_t passageComposerQueries = 0;
std::uint64_t passageIterations = 0;
std::uint64_t passageTileBoundChecks = 0;
std::uint64_t passageTileBoundRejects = 0;
std::uint64_t passageTileBoundSkippedIterations = 0;
std::uint64_t passageUpperMouthFilterChecks = 0;
std::uint64_t passageColumnCandidates = 0;
std::uint64_t passageColumnDistanceCalls = 0;
std::uint64_t passageNegativeBoundChecks = 0;
std::uint64_t passageNegativeBoundRejects = 0;
std::uint64_t passagePositiveBoundChecks = 0;
std::uint64_t passagePositiveBoundRejects = 0;
std::uint64_t passageCarveSegmentVisits = 0;
std::uint64_t passageSmoothCarveJoins = 0;
std::uint64_t passageSupportSegmentVisits = 0;
std::uint64_t passageSmoothSupportJoins = 0;
std::uint64_t passageSupportCapsuleChecks = 0;
std::uint64_t passageLaterBoreChecks = 0;
std::uint64_t passageOtherCapsuleChecks = 0;
std::uint64_t passageMouthSupportCalls = 0;
std::uint64_t passageMouthRouteSegmentChecks = 0;
std::uint64_t passageReliefFieldCalls = 0;
std::uint64_t passageSmoothstepEvaluations = 0;
// L99 tile-local swept-tube base and detail passes. These are populated only
// by the opt-in passage composer profile, except the mesh composition itself.
std::uint64_t passageSweepRouteSegmentCandidates = 0;
@@ -488,7 +468,8 @@ namespace VoxelForgeCore
// Version 210 keeps bulk native-cave sampling on the scalar field path at strata edges.
// Version 211 makes coordinate biasing in the shared cell hash unsigned, removing signed-overflow UB.
// Version 212 balances generated entry routes against existing walk lanes and preserves their shared treads.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 216;
// Version 217 replaces passage supports with flat-floor hollow-shell geometry.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 217;
enum class FieldChannel : std::uint32_t
{
@@ -1041,7 +1022,6 @@ namespace VoxelForgeCore
{
bool hasSurfaceLanding = false;
bool hasFloatingIslandLanding = false;
bool usePassageAnchorForColumns = false;
bool hasNativeCaveField = false;
bool hasNativeLatticeField = false;
};
@@ -1145,28 +1125,6 @@ namespace VoxelForgeCore
std::vector<ResolvedLayoutPassagePointV1> controlPoints;
};
struct PassageVoidCrossingAuditV1
{
std::size_t passageIndex = 0;
std::size_t firstSegment = 0;
std::size_t lastSegment = 0;
std::uint64_t unsupportedSamples = 0;
double unsupportedLengthMetres = 0.0;
std::array<double, 4> startPointSubvoxels{};
std::array<double, 4> endPointSubvoxels{};
bool needsColumn = false;
bool connectedAtStart = false;
bool connectedAtEnd = false;
std::array<std::int64_t, 2> columnAxisSubvoxels{};
std::int64_t columnTopZSubvoxels = 0;
std::int64_t columnBottomZSubvoxels = 0;
std::int64_t columnMinimumRadiusSubvoxels = 0;
std::int64_t columnNominalRadiusSubvoxels = 0;
std::int64_t columnMaximumRadiusSubvoxels = 0;
double maximumRouteOffsetMetres = 0.0;
double maximumBoreRadiusMetres = 0.0;
};
struct ResolvedLayoutPassageConfigV1
{
std::int32_t upperStrateIndex = -1;
@@ -1836,10 +1794,6 @@ namespace VoxelForgeCore
bool profileMesherStages = false;
// Research-only: count passage-composer work per generated tile.
bool profilePassageComposer = false;
// Research-only field comparison. A nonnegative value clamps the source density
// entering passage composition to at least -N voxel units for this tile.
// A negative value leaves the process-level diagnostic override in control.
double diagnosticPassageSourceFloorVoxels = -1.0;
// Research-only field comparison. Zero keeps the unbounded passage carve;
// a positive value bounds its signed-distance reach in metres. A negative
// value leaves the process-level L93 setting in control.
@@ -1932,12 +1886,6 @@ namespace VoxelForgeCore
OreMiningYieldV1 measureOreMiningYieldForSphere(
Vec3d centerVoxel, double radiusMetres,
double sampleSpacingMetres = 0.25) const;
// Audit-only view of density-field columns and short spans supporting passage voids.
std::vector<PassageVoidCrossingAuditV1> passageVoidCrossings() const;
bool isPassageColumnSample(std::size_t passageIndex, std::size_t segmentIndex,
Vec3d voxelPosition) const;
bool isPassageShortSpanSample(std::size_t passageIndex, std::size_t segmentIndex,
Vec3d voxelPosition) const;
// Audit-only selector provenance for the same point evaluator; never used by meshing.
std::string densityDispatchPathAt(Vec3d voxelPosition) const;
// Analytic source distance without the occupancy-preserving near-zero clamp or packed proxy.
@@ -888,10 +888,7 @@ bool ResolvedLayoutSnapshotV3::finalize(std::string& error)
else if(IsNativeLatticeFieldStratum(x))
x.passageCapabilities.hasNativeLatticeField=true;
else if(x.generatorKind=="FloatingIslands")
{
x.passageCapabilities.hasFloatingIslandLanding=true;
x.passageCapabilities.usePassageAnchorForColumns=true;
}
if(i+1<strates.size())
{
const auto& lower=strates[i+1];
File diff suppressed because it is too large. Load diff
+83 -149
View File
@@ -1284,103 +1284,104 @@ namespace VoxelForgeCore
constexpr double Q=static_cast<double>(WorldAssemblySubvoxelsPerVoxel);
const double voxelsPerMetre=coreVoxelSizeMicrons>0
?1000000.0/coreVoxelSizeMicrons:4.0;
const double bridgeHalfWidthVoxels=3.5*voxelsPerMetre;
const double bridgeFootDepthVoxels=(5.0-0.13)*voxelsPerMetre;
constexpr double WallReliefMetres=0.21;
constexpr double ShellThicknessMetres=0.75;
const double tubeExtentMetres=(WallReliefMetres+ShellThicknessMetres)
*voxelsPerMetre;
const double qPerMetre=Q*voxelsPerMetre;
const double tileMinimum[3]={static_cast<double>(minimum.X),
static_cast<double>(minimum.Y),static_cast<double>(minimum.Z)};
const double tileMaximum[3]={static_cast<double>(maximum.X),
static_cast<double>(maximum.Y),static_cast<double>(maximum.Z)};
for(const auto& passage:layout.passages)
{
if(passage.controlPoints.size()<2)continue;
const std::size_t routeEnd=std::clamp<std::size_t>(
passage.lowerMouthControlIndex,1,passage.controlPoints.size()-1);
std::vector<double> routeDistanceMetres(routeEnd+1,0.0);
for(std::size_t pointIndex=1;pointIndex<=routeEnd;++pointIndex)
{
const auto& a=passage.controlPoints[pointIndex-1].positionSubvoxels;
const auto& b=passage.controlPoints[pointIndex].positionSubvoxels;
const double dx=static_cast<double>(b[0]-a[0])/qPerMetre;
const double dy=static_cast<double>(b[1]-a[1])/qPerMetre;
const double dz=static_cast<double>(b[2]-a[2])/qPerMetre;
routeDistanceMetres[pointIndex]=routeDistanceMetres[pointIndex-1]
+std::sqrt(dx*dx+dy*dy+dz*dz);
}
const double totalRouteMetres=routeDistanceMetres[routeEnd];
double minimumRadiusMetres=std::numeric_limits<double>::infinity();
double minimumBodyRadiusMetres=minimumRadiusMetres;
for(std::size_t pointIndex=0;pointIndex<=routeEnd;++pointIndex)
{
const double radius=static_cast<double>(
passage.controlPoints[pointIndex].radiusSubvoxels)/qPerMetre;
minimumRadiusMetres=std::min(minimumRadiusMetres,radius);
if(routeDistanceMetres[pointIndex]>=10.0
&&totalRouteMetres-routeDistanceMetres[pointIndex]>=10.0)
minimumBodyRadiusMetres=std::min(minimumBodyRadiusMetres,radius);
}
if(!std::isfinite(minimumBodyRadiusMetres))
minimumBodyRadiusMetres=minimumRadiusMetres;
const double bodyFloorDepthMetres=std::max(0.5,
minimumBodyRadiusMetres-0.23);
const double upperMouthDepthMetres=std::max(0.0,
static_cast<double>(passage.controlPoints.front().positionSubvoxels[2]
-passage.upperMouthSubvoxels[2])/qPerMetre+0.90);
const double lowerMouthDepthMetres=std::max(0.0,
static_cast<double>(passage.controlPoints[routeEnd].positionSubvoxels[2]
-passage.lowerMouthSubvoxels[2])/qPerMetre+0.90);
const auto routeFloorDepth=[&](double alongMetres,double radiusMetres)
{
const double localRadiusDepth=std::max(0.0,radiusMetres-0.23);
const double mouthDistance=std::max(0.0,std::min(alongMetres,
totalRouteMetres-alongMetres));
const double linear=std::clamp(mouthDistance/5.0,0.0,1.0);
const double ramp=linear*linear*(3.0-2.0*linear);
const double target=alongMetres<=totalRouteMetres*0.5
?upperMouthDepthMetres:lowerMouthDepthMetres;
return std::lerp(std::clamp(target,0.0,localRadiusDepth),
localRadiusDepth,ramp);
};
std::vector<double> effectiveCenterZVoxels(
passage.controlPoints.size(),0.0);
for(std::size_t pointIndex=0;pointIndex<passage.controlPoints.size();
++pointIndex)
{
const std::size_t radiusIndex=std::min(pointIndex,routeEnd);
const double radius=static_cast<double>(
passage.controlPoints[radiusIndex].radiusSubvoxels)/qPerMetre;
const double localTubeDepth=std::min(bodyFloorDepthMetres,
std::max(0.0,radius-0.23));
const double routeDepth=pointIndex<=routeEnd
?routeFloorDepth(routeDistanceMetres[pointIndex],radius)
:std::max(0.0,radius-0.23);
effectiveCenterZVoxels[pointIndex]=
static_cast<double>(passage.controlPoints[pointIndex]
.positionSubvoxels[2])/Q
+(-routeDepth+localTubeDepth)*voxelsPerMetre;
}
for(std::size_t segment=1;segment<passage.controlPoints.size();++segment)
{
const auto& a=passage.controlPoints[segment-1];
const auto& b=passage.controlPoints[segment];
const double radius=static_cast<double>(std::max(
a.radiusSubvoxels,b.radiusSubvoxels))/Q;
const double horizontalExtent=std::max(radius,bridgeHalfWidthVoxels);
const double low[3]={
std::min(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q-horizontalExtent,
std::min(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q-horizontalExtent,
std::min(a.positionSubvoxels[2],b.positionSubvoxels[2])/Q-radius
-bridgeFootDepthVoxels};
const double high[3]={
std::max(a.positionSubvoxels[0],b.positionSubvoxels[0])/Q+horizontalExtent,
std::max(a.positionSubvoxels[1],b.positionSubvoxels[1])/Q+horizontalExtent,
std::max(a.positionSubvoxels[2],b.positionSubvoxels[2])/Q+radius};
const double extent=std::max(static_cast<double>(a.radiusSubvoxels),
static_cast<double>(b.radiusSubvoxels))/Q+tubeExtentMetres;
double low[3]{},high[3]{};
for(int axis=0;axis<3;++axis)
{
const double aPosition=axis==2?effectiveCenterZVoxels[segment-1]
:static_cast<double>(a.positionSubvoxels[axis])/Q;
const double bPosition=axis==2?effectiveCenterZVoxels[segment]
:static_cast<double>(b.positionSubvoxels[axis])/Q;
low[axis]=std::min(aPosition,bPosition)-extent;
high[axis]=std::max(aPosition,bPosition)+extent;
}
bool overlap=true;
for(int axis=0;axis<3;++axis)
overlap&=high[axis]>=tileMinimum[axis]&&low[axis]<=tileMaximum[axis];
if(overlap)return true;
}
// L27 can add a long support column around an unsupported passage span. Its
// radius can exceed the route and bridge bounds above by the column wall and
// flare allowance. The precompile shape-free proof runs before that crossing
// plan exists, so conservatively bound every possible column from the resolved
// route itself. The center is either the passage anchor or an average of route
// samples; in the latter case it lies inside the route's XY bounds.
if(passage.controlPoints.size()>=2)
{
double routeMinimum[3]={std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::infinity()};
double routeMaximum[3]={-std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity(),
-std::numeric_limits<double>::infinity()};
double maximumBoreRadius=0.0;
for(const auto& point:passage.controlPoints)
{
for(int axis=0;axis<3;++axis)
{
const double value=static_cast<double>(point.positionSubvoxels[axis])/Q;
routeMinimum[axis]=std::min(routeMinimum[axis],value);
routeMaximum[axis]=std::max(routeMaximum[axis],value);
}
maximumBoreRadius=std::max(maximumBoreRadius,
static_cast<double>(point.radiusSubvoxels)/Q);
}
double centerMinimumX=routeMinimum[0],centerMaximumX=routeMaximum[0];
double centerMinimumY=routeMinimum[1],centerMaximumY=routeMaximum[1];
double maximumRouteOffset=std::hypot(
routeMaximum[0]-routeMinimum[0],routeMaximum[1]-routeMinimum[1]);
const auto upper=std::find_if(layout.strates.begin(),layout.strates.end(),
[&passage](const auto& stratum)
{return stratum.strateIndex==passage.upperStrateIndex;});
if(upper!=layout.strates.end()
&&upper->passageCapabilities.usePassageAnchorForColumns)
{
const auto anchor=std::find_if(upper->anchors.begin(),upper->anchors.end(),
[](const auto& value)
{return value.kind=="passage_anchor"&&value.values.size()>=2;});
if(anchor!=upper->anchors.end())
{
const double centerX=static_cast<double>(anchor->values[0])/Q;
const double centerY=static_cast<double>(anchor->values[1])/Q;
centerMinimumX=centerMaximumX=centerX;
centerMinimumY=centerMaximumY=centerY;
maximumRouteOffset=0.0;
for(const auto& point:passage.controlPoints)
maximumRouteOffset=std::max(maximumRouteOffset,std::hypot(
static_cast<double>(point.positionSubvoxels[0])/Q-centerX,
static_cast<double>(point.positionSubvoxels[1])/Q-centerY));
}
}
// The generated maximum column radius is the route offset, bore radius,
// and 13.25 m of wall/irregularity/flare allowance.
const double columnRadius=maximumRouteOffset+maximumBoreRadius
+13.25*voxelsPerMetre;
const double columnMinimum[3]={centerMinimumX-columnRadius,
centerMinimumY-columnRadius,routeMinimum[2]-6.0*voxelsPerMetre};
const double columnMaximum[3]={centerMaximumX+columnRadius,
centerMaximumY+columnRadius,routeMaximum[2]+5.0*voxelsPerMetre};
bool overlap=true;
for(int axis=0;axis<3;++axis)
overlap=overlap&&columnMaximum[axis]>=tileMinimum[axis]
&&columnMinimum[axis]<=tileMaximum[axis];
if(overlap)return true;
}
}
return false;
}
@@ -1866,44 +1867,6 @@ namespace VoxelForgeCore
static_cast<double>(weighted)/65535.0*sampleVolume});
return result;
}
std::vector<PassageVoidCrossingAuditV1> World::passageVoidCrossings() const
{
std::vector<PassageVoidCrossingAuditV1> result;
if(!impl_||!impl_->shapeReady.load(std::memory_order_acquire)||!impl_->shape)return result;
const auto& crossings=impl_->shape->GetPassageVoidCrossings();
result.reserve(crossings.size());
for(const auto& crossing:crossings)
{
PassageVoidCrossingAuditV1 value;
value.passageIndex=crossing.passageIndex;value.firstSegment=crossing.firstSegment;
value.lastSegment=crossing.lastSegment;value.unsupportedSamples=crossing.unsupportedSamples;
value.unsupportedLengthMetres=crossing.unsupportedLengthMetres;
value.startPointSubvoxels=crossing.startPoint;value.endPointSubvoxels=crossing.endPoint;
value.needsColumn=crossing.needsColumn;
value.connectedAtStart=crossing.connectedAtStart;
value.connectedAtEnd=crossing.connectedAtEnd;
value.columnAxisSubvoxels={crossing.centerXSubvoxels,crossing.centerYSubvoxels};
value.columnTopZSubvoxels=crossing.topZSubvoxels;
value.columnBottomZSubvoxels=crossing.bottomZSubvoxels;
value.columnMinimumRadiusSubvoxels=crossing.minimumRadiusSubvoxels;
value.columnNominalRadiusSubvoxels=crossing.nominalRadiusSubvoxels;
value.columnMaximumRadiusSubvoxels=crossing.maximumRadiusSubvoxels;
value.maximumRouteOffsetMetres=crossing.maximumRouteOffsetMetres;
value.maximumBoreRadiusMetres=crossing.maximumBoreRadiusMetres;
result.push_back(value);
}
return result;
}
bool World::isPassageColumnSample(std::size_t passageIndex,std::size_t segmentIndex,
Vec3d position) const
{return impl_&&impl_->shapeReady.load(std::memory_order_acquire)&&impl_->shape
&&impl_->shape->IsResolvedPassageColumnSample(passageIndex,segmentIndex,
{position.x,position.y,position.z});}
bool World::isPassageShortSpanSample(std::size_t passageIndex,std::size_t segmentIndex,
Vec3d position) const
{return impl_&&impl_->shapeReady.load(std::memory_order_acquire)&&impl_->shape
&&impl_->shape->IsResolvedPassageShortSpanSample(passageIndex,segmentIndex,
{position.x,position.y,position.z});}
std::string World::densityDispatchPathAt(Vec3d position) const
{ return impl_&&impl_->shapeReady.load(std::memory_order_acquire)&&impl_->shape
?impl_->shape->DensityDispatchPathAt(static_cast<float>(position.x),static_cast<float>(position.y),static_cast<float>(position.z))
@@ -2672,30 +2635,6 @@ namespace VoxelForgeCore
RelevantMinimum=std::min(RelevantMinimum,FeatureMinimum);
RelevantMaximum=std::max(RelevantMaximum,FeatureMaximum);
}
// A resolved passage void column can add solid support above or
// below the native heightfield's local Z range. Its finite radial
// and vertical bounds must participate before the mesh band is clipped.
for(const auto& Crossing:tileShape.GetPassageVoidCrossings())
{
if(!Crossing.needsColumn||Crossing.maximumRadiusSubvoxels<=0
||Crossing.topZSubvoxels<=Crossing.bottomZSubvoxels)continue;
const double Radius=static_cast<double>(Crossing.maximumRadiusSubvoxels)
/static_cast<double>(SubvoxelScale);
const double CenterX=static_cast<double>(Crossing.centerXSubvoxels)
/static_cast<double>(SubvoxelScale);
const double CenterY=static_cast<double>(Crossing.centerYSubvoxels)
/static_cast<double>(SubvoxelScale);
if(CenterX+Radius<TileMinimum[0]/static_cast<double>(SubvoxelScale)
||CenterX-Radius>TileMaximum[0]/static_cast<double>(SubvoxelScale)
||CenterY+Radius<TileMinimum[1]/static_cast<double>(SubvoxelScale)
||CenterY-Radius>TileMaximum[1]/static_cast<double>(SubvoxelScale))continue;
RelevantMinimum=std::min(RelevantMinimum,
static_cast<double>(Crossing.bottomZSubvoxels)
/static_cast<double>(SubvoxelScale));
RelevantMaximum=std::max(RelevantMaximum,
static_cast<double>(Crossing.topZSubvoxels)
/static_cast<double>(SubvoxelScale));
}
// The native heightfield band only covers the owner terrain and its
// manifest features. Resolved SDF stamps can carve below that band or
// add a floor there, so include every overlapping stamp's bounded Z
@@ -2804,7 +2743,6 @@ namespace VoxelForgeCore
FStandaloneShapeWorld::FScopedPassageTileQueries passageFeatureScope(
tileShape,queryMinimum,queryMaximum,
options.profilePassageComposer?&out.diagnostics:nullptr,key.lod,
options.diagnosticPassageSourceFloorVoxels,
options.diagnosticPassageCarveReachMetres);
passageFeatureScope.prepareSweptTubeBase(origin,MeshStep,MeshCells,
static_cast<std::uint32_t>(world.Seed));
@@ -2904,10 +2842,6 @@ namespace VoxelForgeCore
{
out.diagnostics.passageTileRouteSegmentCandidates=
passageFeatureScope.routeSegmentCandidateCount();
for(std::size_t passageIndex=0;
passageIndex<impl_->resolvedLayout->passages.size();++passageIndex)
out.diagnostics.passageTileMouthSegmentCandidates+=
passageFeatureScope.mouthSupportSegments(passageIndex).size();
}
}
FGridFillWorkerContext GridFillWorkerContext;