wip(assembler): round L29 -- strate transitions honoured at the bedrock/ceiling interface

EVoxelStrateTransition from the upper strate shapes the bedrock(N)/ceiling(N+1) interface in the
shared composition layer: Hard flat; Gradient = smooth 2D hash surface (16 m owner width, about 4 m
measured undulation); Interleaved = 3D domain-warped fingered overlap within the width. Each band
keeps >= 2 Core voxels solid; faces return to the seam near passage mouths. Interface audit over
512 m: 0 hole columns for all modes; wider-than-declared and too-thin controls rejected. All passage,
route, proof and validator audits pass; deterministic Clang = GCC. Evaluator 15. Cost +4% SW,
+1.3% FI vs L28. Open: ring-like artifact on the FI floor capture; transition look unverified.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-21 09:16:12 +02:00
1 parent f23ab7b9fa
commit 63c7e563d0
16 files changed
+794 -42

No files matched your search

+162 -2
View File
@@ -144,11 +144,96 @@ public:
const VoxelForgeCore::ResolvedLayoutStratumV2* FindResolvedLayoutStratum(int32 StrateIndex) const
{
if(!ResolvedLayout)return nullptr;
if(StrateIndex>=0&&static_cast<std::size_t>(StrateIndex)<ResolvedLayout->strates.size())
{
const auto& direct=ResolvedLayout->strates[static_cast<std::size_t>(StrateIndex)];
if(direct.strateIndex==StrateIndex)return &direct;
}
const auto it=std::find_if(ResolvedLayout->strates.begin(),ResolvedLayout->strates.end(),
[StrateIndex](const auto& item){return item.strateIndex==StrateIndex;});
return it==ResolvedLayout->strates.end()?nullptr:&*it;
}
const VoxelForgeCore::ResolvedLayoutStratumV2* FindResolvedLayoutStratumByOrder(int32 Order) const
{
if(!ResolvedLayout||Order<0)return nullptr;
if(static_cast<std::size_t>(Order)<ResolvedLayout->strates.size())
{
const auto& direct=ResolvedLayout->strates[static_cast<std::size_t>(Order)];
if(direct.order==Order)return &direct;
}
const auto it=std::find_if(ResolvedLayout->strates.begin(),ResolvedLayout->strates.end(),
[Order](const auto& item){return item.order==Order;});
return it==ResolvedLayout->strates.end()?nullptr:&*it;
}
bool IsResolvedLayoutTransitionActive(const VoxelForgeCore::ResolvedLayoutStratumV2& Upper) const
{
return Upper.transitionMode!="Hard"&&!Upper.transitionFallsBackToHard
&&Upper.transitionWidthMicrometres>0
&&Upper.transitionHonouredInCore;
}
std::int64_t ResolvedTransitionMaximumFaceDisplacementMicrometres(
const VoxelForgeCore::ResolvedLayoutStratumV2& Upper,
const VoxelForgeCore::ResolvedLayoutStratumV2& Lower) const
{
const std::int64_t width=std::max<std::int64_t>(0,Upper.transitionWidthMicrometres);
if(Upper.transitionMode=="Gradient")return width/8;
if(Upper.transitionMode!="Interleaved")return 0;
const std::int64_t upperThickness=std::max<std::int64_t>(0,
Upper.bedrock.topMicrometres-Upper.bedrock.bottomMicrometres);
const std::int64_t lowerThickness=std::max<std::int64_t>(0,
Lower.ceiling.topMicrometres-Lower.ceiling.bottomMicrometres);
const std::int64_t maximumCrossing=std::min(width,upperThickness+lowerThickness);
return (maximumCrossing+1)/2;
}
std::int64_t ResolvedTransitionPassageWeightQ16(
const VoxelForgeCore::ResolvedLayoutStratumV2& Upper,
const VoxelForgeCore::ResolvedLayoutStratumV2& Lower,
std::int64_t XMicrometres,std::int64_t YMicrometres) const
{
constexpr std::int64_t Q16=1ll<<16;
constexpr std::int64_t SupportMarginMicrometres=1000000;
constexpr std::int64_t FadeWidthMicrometres=2000000;
if(!ResolvedLayout||!Owner||Owner->CoreVoxelSizeMicrons==0)return Q16;
const std::int64_t seam=Upper.bedrock.bottomMicrometres;
const std::int64_t coreMicrometres=Owner->CoreVoxelSizeMicrons;
const std::int64_t subvoxelsPerVoxel=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
std::int64_t weight=Q16;
for(const auto& passage:ResolvedLayout->passages)
{
if(passage.upperStrateIndex!=Upper.strateIndex
||passage.lowerStrateIndex!=Lower.strateIndex)continue;
const std::int64_t mouthRadiusMicrometres=std::max<std::int64_t>(0,
passage.mouthRadiusSubvoxels*coreMicrometres/subvoxelsPerVoxel);
const std::int64_t protectedRadius=mouthRadiusMicrometres
+SupportMarginMicrometres;
for(const auto* mouth:{&passage.upperMouthSubvoxels,&passage.lowerMouthSubvoxels})
{
const std::int64_t mouthZMicrometres=mouth->at(2)*coreMicrometres
/subvoxelsPerVoxel;
if(std::abs(mouthZMicrometres-seam)
>Upper.transitionWidthMicrometres/2+mouthRadiusMicrometres)continue;
const double dx=static_cast<double>(XMicrometres-mouth->at(0)*coreMicrometres
/subvoxelsPerVoxel);
const double dy=static_cast<double>(YMicrometres-mouth->at(1)*coreMicrometres
/subvoxelsPerVoxel);
const std::int64_t fadeEnd=protectedRadius+FadeWidthMicrometres;
const double distanceSquared=dx*dx+dy*dy;
if(distanceSquared>=static_cast<double>(fadeEnd)*fadeEnd)continue;
if(distanceSquared<=static_cast<double>(protectedRadius)*protectedRadius)return 0;
const double distance=std::sqrt(distanceSquared);
const double t=static_cast<double>(static_cast<std::int64_t>(distance)
-protectedRadius)/FadeWidthMicrometres;
const double smooth=t*t*(3.0-2.0*t);
weight=std::min(weight,static_cast<std::int64_t>(std::llround(smooth*Q16)));
}
}
return weight;
}
bool IsInsideResolvedStrateBoundaryBand(float Z) const
{
if(!ResolvedLayout||!Owner||!Owner->Manager||!std::isfinite(Z))return false;
@@ -160,6 +245,21 @@ public:
const auto solidAt=[&](const VoxelForgeCore::ResolvedLayoutBandV2& band)
{return band.presentInCurrentField&&zMicrometres>=band.bottomMicrometres
&&zMicrometres<band.topMicrometres;};
const auto mayTouchTransition=[&](const VoxelForgeCore::ResolvedLayoutStratumV2* Upper,
const VoxelForgeCore::ResolvedLayoutStratumV2* Lower)
{
if(!Upper||!Lower||!IsResolvedLayoutTransitionActive(*Upper))return false;
const auto maxDisplacement=ResolvedTransitionMaximumFaceDisplacementMicrometres(
*Upper,*Lower);
const double minimum=std::min(Upper->bedrock.bottomMicrometres,
Lower->ceiling.bottomMicrometres)-maxDisplacement;
const double maximum=std::max(Upper->bedrock.topMicrometres,
Lower->ceiling.topMicrometres)+maxDisplacement;
return zMicrometres>=minimum&&zMicrometres<maximum;
};
const auto* lower=FindResolvedLayoutStratumByOrder(stratum->order+1);
const auto* upper=stratum->order>0?FindResolvedLayoutStratumByOrder(stratum->order-1):nullptr;
if(mayTouchTransition(stratum,lower)||mayTouchTransition(upper,stratum))return true;
return solidAt(stratum->ceiling)||solidAt(stratum->bedrock);
}
@@ -175,8 +275,68 @@ public:
const auto solidAt=[&](const VoxelForgeCore::ResolvedLayoutBandV2& band)
{return band.presentInCurrentField&&zMicrometres>=band.bottomMicrometres
&&zMicrometres<band.topMicrometres;};
const auto* band=solidAt(stratum->ceiling)?&stratum->ceiling
:solidAt(stratum->bedrock)?&stratum->bedrock:nullptr;
bool bCeilingHandledByTransition=false,bBedrockHandledByTransition=false;
const auto applyInterface=[&](const VoxelForgeCore::ResolvedLayoutStratumV2* upper,
const VoxelForgeCore::ResolvedLayoutStratumV2* lower)
{
if(!upper||!lower||!IsResolvedLayoutTransitionActive(*upper))return false;
const auto maxDisplacement=ResolvedTransitionMaximumFaceDisplacementMicrometres(
*upper,*lower);
const double minimum=std::min(upper->bedrock.bottomMicrometres,
lower->ceiling.bottomMicrometres)-maxDisplacement;
const double maximum=std::max(upper->bedrock.topMicrometres,
lower->ceiling.topMicrometres)+maxDisplacement;
if(zMicrometres<minimum||zMicrometres>=maximum)return false;
if(upper==stratum)bBedrockHandledByTransition=true;
if(lower==stratum)bCeilingHandledByTransition=true;
const std::int64_t xMicrometres=static_cast<std::int64_t>(std::llround(
static_cast<double>(X)*Owner->CoreVoxelSizeMicrons));
const std::int64_t yMicrometres=static_cast<std::int64_t>(std::llround(
static_cast<double>(Y)*Owner->CoreVoxelSizeMicrons));
const auto bands=VoxelForgeCore::EvaluateResolvedLayoutTransitionBandsV1(*upper,*lower,
Owner->Seed,ResolvedLayout->strateLayoutChunkSizeMicrometres,
xMicrometres,yMicrometres);
auto resolvedBands=bands;
const std::int64_t transitionWeight=ResolvedTransitionPassageWeightQ16(
*upper,*lower,xMicrometres,yMicrometres);
constexpr std::int64_t TransitionQ16=1ll<<16;
if(transitionWeight<TransitionQ16)
{
const std::int64_t seam=upper->bedrock.bottomMicrometres;
const std::int64_t upperThickness=upper->bedrock.topMicrometres-seam;
const std::int64_t lowerThickness=lower->ceiling.topMicrometres
-lower->ceiling.bottomMicrometres;
const auto scaled=[&](std::int64_t value)
{return (value*transitionWeight)/TransitionQ16;};
resolvedBands.upperBedrockBottomMicrometres=seam+scaled(
bands.upperBedrockBottomMicrometres-seam);
resolvedBands.upperBedrockTopMicrometres=
resolvedBands.upperBedrockBottomMicrometres+upperThickness;
resolvedBands.lowerCeilingTopMicrometres=seam+scaled(
bands.lowerCeilingTopMicrometres-seam);
resolvedBands.lowerCeilingBottomMicrometres=
resolvedBands.lowerCeilingTopMicrometres-lowerThickness;
resolvedBands.crossingDepthMicrometres=std::max<std::int64_t>(0,
resolvedBands.lowerCeilingTopMicrometres
-resolvedBands.upperBedrockBottomMicrometres);
}
const bool upperBedrock=zMicrometres>=resolvedBands.upperBedrockBottomMicrometres
&&zMicrometres<resolvedBands.upperBedrockTopMicrometres;
const bool lowerCeiling=zMicrometres>=resolvedBands.lowerCeilingBottomMicrometres
&&zMicrometres<resolvedBands.lowerCeilingTopMicrometres;
if(!upperBedrock&&!lowerCeiling)return false;
const auto& band=upperBedrock?upper->bedrock:lower->ceiling;
density=-std::max(0.05f,static_cast<float>(band.solidDensityQ16)/65536.0f);
return true;
};
const auto* lower=FindResolvedLayoutStratumByOrder(stratum->order+1);
const auto* upper=stratum->order>0?FindResolvedLayoutStratumByOrder(stratum->order-1):nullptr;
if(applyInterface(stratum,lower)||applyInterface(upper,stratum))return density;
const auto* band=(!bCeilingHandledByTransition&&solidAt(stratum->ceiling))
?&stratum->ceiling:(!bBedrockHandledByTransition&&solidAt(stratum->bedrock))
?&stratum->bedrock:nullptr;
if(!band)return density;
return -std::max(0.05f,static_cast<float>(band->solidDensityQ16)/65536.0f);
}