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:
1 parent
0ff8d98786
commit
72f2609507
10 files changed
+605
-6
No files matched your search
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user