wip: L175 fix tile seams - passage-affected X8 lanes use the composed path (v241, RED)

Seam audit: 0 mismatches over 16 seeds (99,269 pairs, 121.6M shared samples),
injected control detected. Step-2 overlap/turn failures remain. Mainline has the
same dispatch structure (not changed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011g9Ez42ZNqQGjigc4FWDih
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-11-04 14:05:01 +01:00
1 parent 0ff8d98786
commit 72f2609507
10 files changed
+605 -6

No files matched your search

@@ -516,7 +516,8 @@ namespace VoxelForgeCore
// v238 plans one resolved passage spline with explicit landing chambers.
// v239 plans their floor planes as the passage's continuous floor profile.
// v240 adds level end runs and rejects passage tube overlaps and hairpins.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 240;
// v241 keeps passage composition sample-local and out of base-only X8 lanes.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 241;
enum class FieldChannel : std::uint32_t
{
+85 -1
View File
@@ -228,6 +228,17 @@ public:
FSurfaceWorldFieldAdapter,FFloatingIslandFieldAdapter,
FCavesFieldAdapter,FLegacyGeneratorFieldAdapter>;
inline static thread_local std::uint32_t PassageX8OutsideProofDepth=0;
class FScopedPassageX8OutsideProof
{
public:
FScopedPassageX8OutsideProof(){++PassageX8OutsideProofDepth;}
~FScopedPassageX8OutsideProof(){--PassageX8OutsideProofDepth;}
FScopedPassageX8OutsideProof(const FScopedPassageX8OutsideProof&)=delete;
FScopedPassageX8OutsideProof& operator=(const FScopedPassageX8OutsideProof&)=delete;
static bool IsActive() noexcept{return PassageX8OutsideProofDepth!=0;}
};
struct FBoundStratumField
{
enum class EKind : uint8 { Legacy, SurfaceWorld, FloatingIslands, Caves };
@@ -1298,6 +1309,14 @@ public:
{
const std::size_t passageIndex=passageTileScopeMatches
?(*routePassageIndices)[routeOffset]:routeOffset;
// A passage can be in this tile's list because a different route segment
// overlaps the tile. Check the sample before its landing chamber is composed.
if(passageTileScopeMatches
&&!passageTileQueries->routeFeatureMayAffect(passageIndex,qx,qy,qz))
{
passageTileQueries->recordFeatureBoundSkip();
continue;
}
const auto& passage=ResolvedLayout->passages[passageIndex];
if(passage.controlPoints.size()<2)continue;
const bool surfaceDepartureLanding=queryStratum&&queryStratum->Resolved
@@ -3710,7 +3729,50 @@ public:
static_cast<uint64>(Count));
FScopedRoute l77Route(ERoute::SharedSource);
FScopedPhase l77Phase(EPhase::BaseField);
SharedDensitySource->DensityAtLatticeX8(XStart,XStep,Y,Z,Count,OutDensity);
const int32 ActiveCount=std::clamp(Count,0,8);
const auto* TileQueries=FScopedPassageTileQueries::CurrentFor(*this);
const auto& Source=*SharedDensitySource;
const bool bOldFastEligible=Source.EditBrushes.empty()
&&Y>=Source.Min[1]&&Y<=Source.Max[1]
&&Z>=Source.Min[2]&&Z<=Source.Max[2]
&&XStart>=Source.Min[0]
&&XStart+static_cast<int64>(ActiveCount-1)*XStep<=Source.Max[0];
const bool bHasResolvedPassages=ResolvedLayout
&&!ResolvedLayout->passages.empty();
std::array<bool,8> LaneMayBeAffected{};
const auto mayBeAffected=[&](int32 Lane)
{
if(!TileQueries)return bHasResolvedPassages;
const double Q=static_cast<double>(
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double X=static_cast<double>(XStart+Lane*XStep)*Q;
const double QY=static_cast<double>(Y)*Q;
const double QZ=static_cast<double>(Z)*Q;
for(const std::size_t passageIndex:TileQueries->routePassageIndices())
if(TileQueries->routeFeatureMayAffect(passageIndex,X,QY,QZ))
return true;
return false;
};
for(int32 Lane=0;Lane<ActiveCount;++Lane)
LaneMayBeAffected[static_cast<std::size_t>(Lane)]=mayBeAffected(Lane);
// The shared X8 source contains only the base field. Route-bound lanes
// use the composed scalar path; only unaffected runs delegate to X8.
for(int32 Lane=0;Lane<ActiveCount;)
{
if(LaneMayBeAffected[static_cast<std::size_t>(Lane)])
{
OutDensity[Lane]=DensityAtLattice(XStart+Lane*XStep,Y,Z);
++Lane;
continue;
}
const int32 RunStart=Lane;
while(Lane<ActiveCount
&&!LaneMayBeAffected[static_cast<std::size_t>(Lane)])++Lane;
FScopedPassageX8OutsideProof outsideProof;
SharedDensitySource->DensityAtLatticeX8(
XStart+RunStart*XStep,XStep,Y,Z,Lane-RunStart,
OutDensity+RunStart);
}
return;
}
Count=std::clamp(Count,0,8);
@@ -3782,6 +3844,10 @@ public:
&&Z>=Min[2]&&Z<=Max[2]
&&XStart>=Min[0]
&&XStart+static_cast<int64>(Count-1)*XStep<=Max[0];
const bool bOldFastEligible=bFast;
const auto* TileQueries=FScopedPassageTileQueries::CurrentFor(*this);
if(!TileQueries&&ResolvedLayout&&!ResolvedLayout->passages.empty()
&&!FScopedPassageX8OutsideProof::IsActive())bFast=false;
if(!bFast)
{
for(int32 Lane=0;Lane<Count;++Lane)
@@ -3802,6 +3868,24 @@ public:
constexpr float ProxyBandEdge=DetailSupremum+0.125f;
for(int32 Lane=0;Lane<Count;++Lane)
{
bool bPassageMayAffectLane=false;
if(TileQueries)
{
const double Q=static_cast<double>(
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double SampleX=static_cast<double>(XStart+Lane*XStep)*Q;
const double SampleY=static_cast<double>(Y)*Q;
const double SampleZ=static_cast<double>(Z)*Q;
for(const std::size_t passageIndex:TileQueries->routePassageIndices())
if(TileQueries->routeFeatureMayAffect(passageIndex,
SampleX,SampleY,SampleZ))
{bPassageMayAffectLane=true;break;}
}
if(bPassageMayAffectLane)
{
OutDensity[Lane]=DensityAtLattice(XStart+Lane*XStep,Y,Z);
continue;
}
const size_t Column=ColumnStart+static_cast<size_t>(Lane*XStep);
const size_t Word=Column*WordsPerZ+WordOffset;
const bool bRock=(RockWords[Word]&Mask)!=0;