refactor(core): bind generator fields once per resolved strate (L40, migration step 2); research R7

SurfaceWorld, FloatingIslands and legacy evaluators sit behind one immutable densityAt adapter held in
a variant (no virtual call per sample); BindResolvedStratumFields builds a sorted strate table at world
setup, so DensityAt, native SW/FI sampling and ClassifyBoxDetailed no longer ask the strate manager per
sample. No arithmetic change: owner hashes identical to L37/L39 at W1/W12. Cost vs L39: FI -0.66%,
SW -1.31% (noise). verify fast/medium/full PASS (full re-run alone: 407 gates).
Research R7: disk cache design for UE5/Windows/multiplayer and a zlib probe (about 1/3 size, 0.1 ms/tile).

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-23 17:15:46 +02:00
1 parent 753cc9c259
commit efa9e89468
8 files changed
+859 -118

No files matched your search

+327 -118
View File
@@ -25,6 +25,7 @@
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>
// Standalone-only world compiler. It compiles the runtime room/tunnel/passages into
@@ -41,6 +42,114 @@ public:
double SealThickness=0.0;
};
// Immutable adapters share densityAt(x,y,z,out) without a virtual call in the sample
// loop. The variant is selected once per resolved strate; callers retain concrete access
// to fixed-point and interval operations where the legacy arithmetic requires them.
struct FSurfaceWorldFieldAdapter
{
VoxelForgeCore::Heightfield2D Evaluator;
FSurfaceWorldFieldAdapter(const VoxelForgeCore::WorldAssemblyRecipeV1& Recipe,
const VoxelForgeCore::WorldAssemblyStratumPlanV1& Plan) noexcept
:Evaluator(Recipe,Plan){}
bool densityAt(float X,float Y,float Z,float& OutDensity) const noexcept
{
if(!std::isfinite(X)||!std::isfinite(Y)||!std::isfinite(Z))return false;
constexpr double Scale=static_cast<double>(
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double MaxVoxel=static_cast<double>(std::numeric_limits<int64>::max())/Scale;
if(std::abs(static_cast<double>(X))>MaxVoxel
||std::abs(static_cast<double>(Y))>MaxVoxel
||std::abs(static_cast<double>(Z))>MaxVoxel)return false;
const auto ToFixed=[](float Value)
{return static_cast<int64>(std::llround(static_cast<double>(Value)
*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));};
if(!Evaluator.isValid())return false;
OutDensity=static_cast<float>(Evaluator.point(ToFixed(X),ToFixed(Y),ToFixed(Z))
.densitySubvoxels/Scale);
return true;
}
};
struct FFloatingIslandFieldAdapter
{
VoxelForgeCore::FloatingIslandFieldV1 Evaluator;
int32 BottomChunkZ=0;
std::vector<FFloatingIslandParams> LegacyBoundaryParams;
FFloatingIslandFieldAdapter(const VoxelForgeCore::FloatingIslandRecipeV1& Recipe,
const VoxelForgeCore::FloatingIslandPlanV1& Plan,int32 InBottomChunkZ,
int32 InTopChunkZ,const UVoxelStrateManager* Manager)
:Evaluator(Recipe,Plan),BottomChunkZ(InBottomChunkZ)
{
if(Manager&&Recipe.geometryVersion<4&&InTopChunkZ>=InBottomChunkZ)
{
LegacyBoundaryParams.reserve(static_cast<std::size_t>(
static_cast<int64>(InTopChunkZ)-InBottomChunkZ+1));
for(int32 ChunkZ=InBottomChunkZ;ChunkZ<=InTopChunkZ;++ChunkZ)
LegacyBoundaryParams.push_back(Manager->GetFloatingIslandParamsForChunk(
FIntVector(0,0,ChunkZ)));
}
}
std::int64_t densitySubvoxelsAt(std::int64_t X,std::int64_t Y,
std::int64_t Z) const noexcept
{return Evaluator.densitySubvoxels(X,Y,Z);}
const FFloatingIslandParams* legacyBoundaryParamsAt(int32 ChunkZ) const noexcept
{
const int64 Index=static_cast<int64>(ChunkZ)-BottomChunkZ;
return Index>=0&&static_cast<std::size_t>(Index)<LegacyBoundaryParams.size()
?&LegacyBoundaryParams[static_cast<std::size_t>(Index)]:nullptr;
}
bool densityAt(float X,float Y,float Z,float& OutDensity) const noexcept
{
if(!Evaluator.isValid()||!std::isfinite(X)||!std::isfinite(Y)
||!std::isfinite(Z))return false;
constexpr double Scale=static_cast<double>(
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
constexpr double Maximum=1000000000000.0/Scale;
if(std::abs(static_cast<double>(X))>Maximum
||std::abs(static_cast<double>(Y))>Maximum
||std::abs(static_cast<double>(Z))>Maximum)return false;
const auto ToFixed=[](float Value)
{return static_cast<int64>(std::llround(static_cast<double>(Value)
*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));};
OutDensity=static_cast<float>(static_cast<double>(densitySubvoxelsAt(
ToFixed(X),ToFixed(Y),ToFixed(Z)))/Scale);
return std::isfinite(OutDensity);
}
};
struct FLegacyGeneratorFieldAdapter
{
const UVoxelGenerator* Generator=nullptr;
bool densityAt(float X,float Y,float Z,float& OutDensity) const
{
if(!Generator)return false;
OutDensity=Generator->GetDensityAt(X,Y,Z);
return std::isfinite(OutDensity);
}
};
using FGeneratorFieldAdapterV1=std::variant<std::monostate,
FSurfaceWorldFieldAdapter,FFloatingIslandFieldAdapter,
FLegacyGeneratorFieldAdapter>;
struct FBoundStratumField
{
enum class EKind : uint8 { Legacy, SurfaceWorld, FloatingIslands };
const VoxelForgeCore::ResolvedLayoutStratumV2* Resolved=nullptr;
const VoxelForgeCore::WorldAssemblyStratumPlanV1* SurfacePlan=nullptr;
const VoxelForgeCore::WorldAssemblyFloatingIslandPlanV1* IslandPlan=nullptr;
FGeneratorFieldAdapterV1 Evaluator;
int32 StrateIndex=-1;
int32 BottomChunkZ=0;
int32 TopChunkZ=-1;
EKind Kind=EKind::Legacy;
};
const std::vector<FStandalonePassageVoidCrossing>& GetPassageVoidCrossings() const
{return PassageVoidCrossings;}
@@ -170,6 +279,117 @@ public:
return it==ResolvedLayout->strates.end()?nullptr:&*it;
}
void BindResolvedStratumFields()
{
BoundStratumFields.clear();
BoundManagerLayoutChunkWidthVoxels=Owner&&Owner->Manager
?Owner->Manager->GetStrateLayoutChunkWidthVoxels():0.0f;
if(!ResolvedLayout||ResolvedLayout->strateLayoutChunkSizeMicrometres<=0)return;
const int64 ChunkWidthMicrometres=ResolvedLayout->strateLayoutChunkSizeMicrometres;
const auto FloorDiv64=[](int64 Value,int64 Divisor)
{
const int64 Quotient=Value/Divisor;
const int64 Remainder=Value%Divisor;
return Remainder<0?Quotient-1:Quotient;
};
BoundStratumFields.reserve(ResolvedLayout->strates.size());
for(const auto& Stratum:ResolvedLayout->strates)
{
if(Stratum.strateIndex<0
||Stratum.interiorTopMicrometres<=Stratum.interiorBottomMicrometres)
continue;
const int64 Bottom=FloorDiv64(Stratum.interiorBottomMicrometres,
ChunkWidthMicrometres);
const int64 Top=FloorDiv64(Stratum.interiorTopMicrometres-1,
ChunkWidthMicrometres);
if(Bottom<std::numeric_limits<int32>::min()
||Bottom>std::numeric_limits<int32>::max()
||Top<std::numeric_limits<int32>::min()
||Top>std::numeric_limits<int32>::max()||Top<Bottom)continue;
FBoundStratumField Bound;
Bound.Resolved=&Stratum;
Bound.StrateIndex=Stratum.strateIndex;
Bound.BottomChunkZ=static_cast<int32>(Bottom);
Bound.TopChunkZ=static_cast<int32>(Top);
if(Stratum.generatorKind=="SurfaceWorld")
{
Bound.Kind=FBoundStratumField::EKind::SurfaceWorld;
if(WorldAssembly)
{
const auto Plan=std::find_if(WorldAssembly->plan.strates.begin(),
WorldAssembly->plan.strates.end(),[&](const auto& Candidate)
{return Candidate.strateIndex==Bound.StrateIndex
&&Candidate.bottomChunkZ==Bound.BottomChunkZ
&&Candidate.topChunkZ==Bound.TopChunkZ;});
if(Plan!=WorldAssembly->plan.strates.end())
{
Bound.SurfacePlan=&*Plan;
FSurfaceWorldFieldAdapter Adapter(WorldAssembly->recipe,*Plan);
if(Adapter.Evaluator.isValid())
Bound.Evaluator.emplace<FSurfaceWorldFieldAdapter>(
std::move(Adapter));
}
}
}
else if(Stratum.generatorKind=="FloatingIslands")
{
Bound.Kind=FBoundStratumField::EKind::FloatingIslands;
if(WorldAssembly)
{
const auto Plan=std::find_if(WorldAssembly->floatingIslands.begin(),
WorldAssembly->floatingIslands.end(),[&](const auto& Candidate)
{return Candidate.strateIndex==Bound.StrateIndex
&&Candidate.bottomChunkZ==Bound.BottomChunkZ
&&Candidate.topChunkZ==Bound.TopChunkZ;});
if(Plan!=WorldAssembly->floatingIslands.end())
{
Bound.IslandPlan=&*Plan;
Bound.Evaluator.emplace<FFloatingIslandFieldAdapter>(
Plan->manifest.recipe,Plan->manifest.plan,
Bound.BottomChunkZ,Bound.TopChunkZ,
Owner?Owner->Manager.get():nullptr);
}
}
}
if(std::holds_alternative<std::monostate>(Bound.Evaluator))
Bound.Evaluator.emplace<FLegacyGeneratorFieldAdapter>(
FLegacyGeneratorFieldAdapter{Owner?Owner->Generator.get():nullptr});
BoundStratumFields.push_back(std::move(Bound));
}
std::sort(BoundStratumFields.begin(),BoundStratumFields.end(),
[](const auto& A,const auto& B){return A.BottomChunkZ<B.BottomChunkZ;});
}
const FBoundStratumField* FindBoundStratumForChunk(int32 ChunkZ) const
{
const auto Upper=std::upper_bound(BoundStratumFields.begin(),
BoundStratumFields.end(),ChunkZ,[](int32 Z,const auto& Field)
{return Z<Field.BottomChunkZ;});
if(Upper==BoundStratumFields.begin())return nullptr;
const auto& Candidate=*std::prev(Upper);
return ChunkZ<=Candidate.TopChunkZ?&Candidate:nullptr;
}
const FBoundStratumField* FindBoundStratumForZ(float Z) const
{
if(!std::isfinite(Z))return nullptr;
const float LayoutWidth=static_cast<float>(GetResolvedLayoutChunkWidthVoxels());
if(!(LayoutWidth>0.0f))return nullptr;
return FindBoundStratumForChunk(FMath::FloorToInt(Z/LayoutWidth));
}
const FBoundStratumField* FindBoundStratumForManagerZ(float Z) const
{
if(!std::isfinite(Z)||!Owner||!(BoundManagerLayoutChunkWidthVoxels>0.0f))
return nullptr;
const float WorldZCentimetres=static_cast<float>(
static_cast<double>(Z)*GetCoreVoxelSizeCm());
const int32 ChunkZ=FMath::FloorToInt((WorldZCentimetres/VOXEL_SIZE)
/BoundManagerLayoutChunkWidthVoxels);
return FindBoundStratumForChunk(ChunkZ);
}
const VoxelForgeCore::ResolvedLayoutStratumV2* FindResolvedLayoutStratumByOrder(int32 Order) const
{
if(!ResolvedLayout||Order<0)return nullptr;
@@ -479,10 +699,9 @@ public:
// samples. The merged intervals are conservative, so a positive is safe.
return true;
}
if(!ResolvedLayout||!Owner||!Owner->Manager||!std::isfinite(Z))return false;
const double worldZCentimetres=static_cast<double>(Z)*GetCoreVoxelSizeCm();
const int32 strateIndex=Owner->Manager->GetStrateIndex(static_cast<float>(worldZCentimetres));
const auto* stratum=FindResolvedLayoutStratum(strateIndex);
if(!ResolvedLayout||!Owner||!std::isfinite(Z))return false;
const FBoundStratumField* bound=FindBoundStratumForManagerZ(Z);
const auto* stratum=bound?FindResolvedLayoutStratum(bound->StrateIndex):nullptr;
if(!stratum)return false;
const double zMicrometres=static_cast<double>(Z)*Owner->CoreVoxelSizeMicrons;
const auto solidAt=[&](const VoxelForgeCore::ResolvedLayoutBandV2& band)
@@ -538,7 +757,7 @@ public:
return density;
}
}
if(!ResolvedLayout||!Owner||!Owner->Manager||Owner->CoreVoxelSizeMicrons==0
if(!ResolvedLayout||!Owner||Owner->CoreVoxelSizeMicrons==0
||!std::isfinite(Z))return density;
const double zMicrometres=static_cast<double>(Z)*Owner->CoreVoxelSizeMicrons;
if(ResolvedLayout->strates.size()==2)
@@ -600,9 +819,8 @@ public:
}
}
}
const double worldZCentimetres=static_cast<double>(Z)*GetCoreVoxelSizeCm();
const int32 strateIndex=Owner->Manager->GetStrateIndex(static_cast<float>(worldZCentimetres));
const auto* stratum=FindResolvedLayoutStratum(strateIndex);
const FBoundStratumField* bound=FindBoundStratumForManagerZ(Z);
const auto* stratum=bound?FindResolvedLayoutStratum(bound->StrateIndex):nullptr;
if(!stratum)return density;
const auto solidAt=[&](const VoxelForgeCore::ResolvedLayoutBandV2& band)
{return band.presentInCurrentField&&zMicrometres>=band.bottomMicrometres
@@ -1665,7 +1883,7 @@ public:
bool GetResolvedStratumBounds(const FStrateSlot& Slot,FResolvedStratumBounds& Out) const
{
if(!Owner||!Owner->Manager)return false;
if(!Owner)return false;
if(const auto* resolved=FindResolvedLayoutStratum(Slot.StrateIndex))
{
const double coreMicrons=std::max<std::uint32_t>(1,Owner->CoreVoxelSizeMicrons);
@@ -1678,11 +1896,11 @@ public:
return MakeResolvedStratumBounds(bottom,top,std::max(ceiling,bedrock),Out);
}
const int32 MidChunkZ=(Slot.TopChunkZ+Slot.BottomChunkZ)/2;
if(bUseNativeManifestFields&&WorldAssembly
&&Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,MidChunkZ))
==ECaveGeneratorType::FloatingIslands)
const FBoundStratumField* Bound=FindBoundStratumForChunk(MidChunkZ);
if(bUseNativeManifestFields&&WorldAssembly&&Bound
&&Bound->Kind==FBoundStratumField::EKind::FloatingIslands)
{
const auto* Plan=FindWorldAssemblyFloatingIslandStratum(Slot.StrateIndex,MidChunkZ);
const auto* Plan=Bound->IslandPlan;
if(Plan&&Plan->manifest.recipe.geometryVersion>=3)
{
constexpr double Scale=static_cast<double>(
@@ -1989,6 +2207,7 @@ public:
WorkerCount=std::clamp(Workers,1,16);DetailVariant=Variant;
Scheduler=InScheduler;RoundTunnelsEnabled=bInRoundTunnels;
bUseNativeManifestFields=true;
BindResolvedStratumFields();
bAnalyticOnly=false;
bProfileDetailBand=bInProfileDetailBand;
for(int32 A=0;A<3;++A)
@@ -2162,6 +2381,7 @@ public:
// Analytic pages retain their bounded owner bins for route bookkeeping. Once published,
// the Core world binds each page to its base shape as the single density evaluator.
bUseNativeManifestFields=true;
BindResolvedStratumFields();
RoundTunnelsEnabled=bInRoundTunnels;bAnalyticOnly=true;bProfileDetailBand=false;
for(int32 A=0;A<3;++A)
{
@@ -2199,6 +2419,7 @@ public:
Owner=&World;WorldAssembly=InWorldAssembly;ResolvedLayout=InResolvedLayout;
NativeOnlyMinimum=InMinimum;NativeOnlyMaximum=InMaximum;
bUseNativeManifestFields=true;bNativeOnly=true;bAnalyticOnly=true;Built=true;
BindResolvedStratumFields();
NativeOnlyViolations.store(0,std::memory_order_relaxed);
}
@@ -2742,23 +2963,13 @@ public:
if(NativeFloatingIslandDensityAt(X,Y,Z,Density))return "FloatingIslands-native";
if(NativeSurfaceDensityAt(X,Y,Z,Density))return "SurfaceWorld-native";
if(UsesLegacySurfaceField(X,Y,Z))return "SurfaceWorld-legacy";
if(Owner&&Owner->Manager)
const FBoundStratumField* Bound=FindBoundStratumForZ(Z);
if(Bound&&Bound->Resolved)
{
const int32 ChunkZ=FMath::FloorToInt(Z/static_cast<float>(GetResolvedLayoutChunkWidthVoxels()));
const ECaveGeneratorType Type=Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ));
switch(Type)
{
case ECaveGeneratorType::TunnelNetwork:return "compiled-analytic/TunnelNetwork";
case ECaveGeneratorType::FlatPlain:return "compiled-analytic/FlatPlain";
case ECaveGeneratorType::CrystalChamber:return "compiled-analytic/CrystalChamber";
case ECaveGeneratorType::Maze:return "compiled-analytic/Maze";
case ECaveGeneratorType::SurfaceWorld:return "compiled-analytic/SurfaceWorld";
case ECaveGeneratorType::VerticalShafts:return "compiled-analytic/VerticalShafts";
case ECaveGeneratorType::FloatingIslands:return "compiled-analytic/FloatingIslands";
case ECaveGeneratorType::Underwater:return "compiled-analytic/Underwater";
}
const std::string& Kind=Bound->Resolved->generatorKind;
return "compiled-analytic/"+Kind;
}
return "compiled-analytic/fallback";
return Owner?"compiled-analytic/TunnelNetwork":"compiled-analytic/fallback";
}
float DensityAtLattice(int32 X,int32 Y,int32 Z) const
@@ -3672,7 +3883,10 @@ private:
&&!NativeSurfaceDensityAt(X,Y,Z,density))
{
if(UsesLegacySurfaceField(X,Y,Z)&&Owner&&Owner->Generator)
density=Owner->Generator->GetDensityAt(X,Y,Z);
{
if(!LegacyGeneratorDensityAt(X,Y,Z,density))
density=Owner->Generator->GetDensityAt(X,Y,Z);
}
else
density=AnalyticDensityAt(X,Y,Z,true,nullptr,nullptr,nullptr,
false,false);
@@ -3961,7 +4175,9 @@ private:
NativeDensity=ApplyResolvedStrateComposition(NativeDensity,X,Y,Z);
return bApplyEdits?ApplyEditBrushes(NativeDensity,X,Y,Z):NativeDensity;
}
const float Density=Owner->Generator->GetDensityAt(X,Y,Z);
float Density=0.0f;
if(!LegacyGeneratorDensityAt(X,Y,Z,Density))
Density=Owner->Generator->GetDensityAt(X,Y,Z);
const float composed=bApplyComposition
?ApplyResolvedStrateComposition(Density,X,Y,Z):Density;
return bApplyEdits?ApplyEditBrushes(composed,X,Y,Z):composed;
@@ -4019,23 +4235,19 @@ public:
{
if(SharedDensitySource)
return SharedDensitySource->GetNativeSurfaceHeightsAt(X,Y,ChunkZ,OutGroundZ,OutCeilingZ);
if(!WorldAssembly||!ResolvedLayout||!Owner||!Owner->Manager||!Owner->Generator
if(!WorldAssembly||!ResolvedLayout||!Owner||!Owner->Generator
||!std::isfinite(X)||!std::isfinite(Y))return false;
const double ChunkWidth=GetResolvedLayoutChunkWidthVoxels();
const std::int64_t chunkMinimum=static_cast<std::int64_t>(std::llround(ChunkZ*ChunkWidth));
const std::int64_t chunkMaximum=static_cast<std::int64_t>(std::llround((ChunkZ+1)*ChunkWidth));
const FBoundStratumField* Bound=FindBoundStratumForChunk(ChunkZ);
const auto* Field=Bound?std::get_if<FSurfaceWorldFieldAdapter>(&Bound->Evaluator):nullptr;
if(bNativeOnly&&(!NativeOnlyContainsColumn(X,Y)
||chunkMaximum<NativeOnlyMinimum.Z||chunkMinimum>NativeOnlyMaximum.Z
||Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ))
!=ECaveGeneratorType::SurfaceWorld))
||!Bound||Bound->Kind!=FBoundStratumField::EKind::SurfaceWorld))
{RecordNativeOnlyViolation();return false;}
if(Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ))
!=ECaveGeneratorType::SurfaceWorld)return false;
const int32 StrateIndex=Owner->Manager->GetStrateIndex(
static_cast<float>((static_cast<double>(ChunkZ)+0.5)
*ResolvedLayout->strateLayoutChunkSizeMicrometres/10000.0));
const auto* Plan=FindWorldAssemblyStratum(StrateIndex,ChunkZ);
if(!Plan)return false;
if(!Bound||Bound->Kind!=FBoundStratumField::EKind::SurfaceWorld
||!Bound->SurfacePlan||!Field||!Field->Evaluator.isValid())return false;
constexpr double Scale=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double MaxVoxel=static_cast<double>(std::numeric_limits<int64>::max())/Scale;
if(std::abs(static_cast<double>(X))>MaxVoxel||std::abs(static_cast<double>(Y))>MaxVoxel)
@@ -4043,9 +4255,7 @@ public:
const auto ToFixed=[](float Value)
{return static_cast<int64>(std::llround(static_cast<double>(Value)
*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));};
const VoxelForgeCore::Heightfield2D Block(WorldAssembly->recipe,*Plan);
if(!Block.isValid())return false;
const auto Column=Block.point(ToFixed(X),ToFixed(Y),
const auto Column=Field->Evaluator.point(ToFixed(X),ToFixed(Y),
static_cast<int64>(ChunkZ)*ResolvedLayout->strateLayoutChunkWidthSubvoxels);
OutGroundZ=static_cast<float>(Column.groundHeightSubvoxels/Scale);
OutCeilingZ=static_cast<float>(Column.capHeightSubvoxels/Scale);
@@ -4058,25 +4268,22 @@ public:
bool IsNativeSurfaceBox(const FIntVector& Origin,int32 Step,int32 Cells) const
{
if(SharedDensitySource)return SharedDensitySource->IsNativeSurfaceBox(Origin,Step,Cells);
if(!WorldAssembly||!Owner||!Owner->Manager||Step<=0||Cells<=0)return false;
if(!WorldAssembly||!ResolvedLayout||!Owner||Step<=0||Cells<=0)return false;
const int32 Pad=std::max(Step,1);
const int32 BMin=Origin.Z-Pad;
const int32 BMax=Origin.Z+(Cells+1)*Step;
const float LayoutWidth=static_cast<float>(GetResolvedLayoutChunkWidthVoxels());
const int32 FirstChunk=FMath::FloorToInt(static_cast<float>(BMin)/LayoutWidth);
const int32 LastChunk=FMath::FloorToInt(static_cast<float>(BMax)/LayoutWidth);
const VoxelForgeCore::WorldAssemblyStratumPlanV1* Plan=nullptr;
const FBoundStratumField* BoundPlan=nullptr;
for(int32 ChunkZ=FirstChunk;ChunkZ<=LastChunk;++ChunkZ)
{
const auto It=std::find_if(WorldAssembly->plan.strates.begin(),
WorldAssembly->plan.strates.end(),[ChunkZ](const auto& Entry)
{return ChunkZ<=Entry.topChunkZ&&ChunkZ>=Entry.bottomChunkZ;});
if(It==WorldAssembly->plan.strates.end())return false;
const auto* Candidate=&*It;
if(Plan&&Plan!=Candidate)return false;
if(Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ))
!=ECaveGeneratorType::SurfaceWorld)return false;
Plan=Candidate;
const auto* Candidate=FindBoundStratumForChunk(ChunkZ);
if(!Candidate||Candidate->Kind!=FBoundStratumField::EKind::SurfaceWorld
||!Candidate->SurfacePlan||ChunkZ<Candidate->SurfacePlan->bottomChunkZ
||ChunkZ>Candidate->SurfacePlan->topChunkZ)return false;
if(BoundPlan&&BoundPlan!=Candidate)return false;
BoundPlan=Candidate;
}
if(bNativeOnly)
{
@@ -4088,8 +4295,8 @@ public:
||BMaxY>NativeOnlyMaximum.Y||BMax>NativeOnlyMaximum.Z)
{RecordNativeOnlyViolation();return false;}
}
if(bNativeOnly&&!Plan)RecordNativeOnlyViolation();
return Plan!=nullptr;
if(bNativeOnly&&!BoundPlan)RecordNativeOnlyViolation();
return BoundPlan!=nullptr;
}
FBoxClassification ClassifyBoxDetailed(const FIntVector& Origin,int32 Step,int32 Cells,
@@ -4104,31 +4311,39 @@ public:
int32 BMax[3]={Origin.X+(Cells+1)*Step,Origin.Y+(Cells+1)*Step,Origin.Z+(Cells+1)*Step};
const VoxelForgeCore::WorldAssemblyStratumPlanV1* SurfacePlan=nullptr;
const VoxelForgeCore::WorldAssemblyFloatingIslandPlanV1* IslandPlan=nullptr;
const FSurfaceWorldFieldAdapter* SurfaceField=nullptr;
const FFloatingIslandFieldAdapter* IslandField=nullptr;
bool bSurfaceOverlap=false,bIslandOverlap=false,bOtherStrateOverlap=false;
bool bIslandOtherStrateOverlap=false,bBadPlan=false;
if(Owner&&Owner->Manager&&ResolvedLayout)
if(Owner&&ResolvedLayout)
{
const float LayoutWidth=static_cast<float>(GetResolvedLayoutChunkWidthVoxels());
const int32 FirstChunk=FMath::FloorToInt(static_cast<float>(BMin[2])/LayoutWidth);
const int32 LastChunk=FMath::FloorToInt(static_cast<float>(BMax[2])/LayoutWidth);
for(int32 ChunkZ=FirstChunk;ChunkZ<=LastChunk;++ChunkZ)
{
const ECaveGeneratorType Type=Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ));
const int32 StrateIndex=Owner->Manager->GetStrateIndex(static_cast<float>(
(static_cast<double>(ChunkZ)+0.5)*ResolvedLayout->strateLayoutChunkSizeMicrometres/10000.0));
if(Type==ECaveGeneratorType::SurfaceWorld)
const FBoundStratumField* Bound=FindBoundStratumForChunk(ChunkZ);
if(Bound&&Bound->Kind==FBoundStratumField::EKind::SurfaceWorld)
{
bSurfaceOverlap=true;bIslandOtherStrateOverlap=true;
const auto* Candidate=FindWorldAssemblyStratum(StrateIndex,ChunkZ);
if(!Candidate||(SurfacePlan&&SurfacePlan!=Candidate))bBadPlan=true;
const auto* Candidate=Bound->SurfacePlan;
if(!Candidate||ChunkZ<Candidate->bottomChunkZ
||ChunkZ>Candidate->topChunkZ
||(SurfacePlan&&SurfacePlan!=Candidate))bBadPlan=true;
SurfacePlan=Candidate;
SurfaceField=std::get_if<FSurfaceWorldFieldAdapter>(
&Bound->Evaluator);
}
else if(Type==ECaveGeneratorType::FloatingIslands)
else if(Bound&&Bound->Kind==FBoundStratumField::EKind::FloatingIslands)
{
bIslandOverlap=true;bOtherStrateOverlap=true;
const auto* Candidate=FindWorldAssemblyFloatingIslandStratum(StrateIndex,ChunkZ);
if(!Candidate||(IslandPlan&&IslandPlan!=Candidate))bBadPlan=true;
const auto* Candidate=Bound->IslandPlan;
if(!Candidate||ChunkZ<Candidate->bottomChunkZ
||ChunkZ>Candidate->topChunkZ
||(IslandPlan&&IslandPlan!=Candidate))bBadPlan=true;
IslandPlan=Candidate;
IslandField=std::get_if<FFloatingIslandFieldAdapter>(
&Bound->Evaluator);
}
else
{bOtherStrateOverlap=true;bIslandOtherStrateOverlap=true;}
@@ -4213,12 +4428,12 @@ public:
}
if(bSurfaceOverlap)
{
if(!WorldAssembly||!SurfacePlan)return Finish(EVoxelTileClass::Mixed,true);
const VoxelForgeCore::Heightfield2D Block(WorldAssembly->recipe,*SurfacePlan);
if(!WorldAssembly||!SurfacePlan||!SurfaceField)
return Finish(EVoxelTileClass::Mixed,true);
// classifyLatticeBox takes the exact extrema of ground/cap columns at every
// MC lattice XY in this box. Since density is min(z-ground, cap-z), those extrema
// bound every lattice sample in Z without a noise amplitude guess.
const auto Verdict=Block.classifyLatticeBox(
const auto Verdict=SurfaceField->Evaluator.classifyLatticeBox(
static_cast<int64>(BMin[0])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
static_cast<int64>(BMin[1])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
static_cast<int64>(BMin[2])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
@@ -4239,7 +4454,7 @@ public:
}
if(bIslandOverlap)
{
if(!IslandPlan)return Finish(EVoxelTileClass::Mixed,true);
if(!IslandPlan||!IslandField)return Finish(EVoxelTileClass::Mixed,true);
constexpr std::int64_t Scale=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
const std::int64_t Bottom=IslandPlan->manifest.recipe.layoutMinimumZSubvoxels;
const std::int64_t Top=IslandPlan->manifest.recipe.layoutMaximumZSubvoxels;
@@ -4259,10 +4474,8 @@ public:
return Finish((IslandPlan->manifest.recipe.geometryVersion<3
?BoxBottom>=Top-Seal:BoxBottom>Top-Seal)&&BoxTop<=Top
?EVoxelTileClass::AllSolid:EVoxelTileClass::Mixed);
const VoxelForgeCore::FloatingIslandFieldV1 Block(
IslandPlan->manifest.recipe,IslandPlan->manifest.plan);
if(!Block.isValid())return Finish(EVoxelTileClass::Mixed,true);
const auto Interval=Block.interval(static_cast<int64>(BMin[0])*Scale,
if(!IslandField->Evaluator.isValid())return Finish(EVoxelTileClass::Mixed,true);
const auto Interval=IslandField->Evaluator.interval(static_cast<int64>(BMin[0])*Scale,
static_cast<int64>(BMin[1])*Scale,static_cast<int64>(BMin[2])*Scale,
static_cast<int64>(BMax[0])*Scale,static_cast<int64>(BMax[1])*Scale,
static_cast<int64>(BMax[2])*Scale);
@@ -4782,30 +4995,18 @@ private:
bool NativeSurfaceDensityAt(float X,float Y,float Z,float& OutDensity) const
{
if(!bUseNativeManifestFields||!WorldAssembly||!ResolvedLayout||!Owner||!Owner->Manager||!Owner->Generator
||!std::isfinite(X)||!std::isfinite(Y)||!std::isfinite(Z))return false;
if(!bUseNativeManifestFields||!WorldAssembly||!ResolvedLayout||!Owner
||!Owner->Manager||!Owner->Generator||!std::isfinite(X)
||!std::isfinite(Y)||!std::isfinite(Z))return false;
const float LayoutWidth=static_cast<float>(GetResolvedLayoutChunkWidthVoxels());
if(!(LayoutWidth>0.0f))return false;
const int32 ChunkZ=FMath::FloorToInt(Z/LayoutWidth);
if(Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ))
!=ECaveGeneratorType::SurfaceWorld)return false;
const int32 StrateIndex=Owner->Manager->GetStrateIndex(
static_cast<float>((static_cast<double>(ChunkZ)+0.5)
*ResolvedLayout->strateLayoutChunkSizeMicrometres/10000.0));
const auto* Plan=FindWorldAssemblyStratum(StrateIndex,ChunkZ);
if(!Plan)return false;
constexpr double Scale=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
const double MaxVoxel=static_cast<double>(std::numeric_limits<int64>::max())/Scale;
if(std::abs(static_cast<double>(X))>MaxVoxel||std::abs(static_cast<double>(Y))>MaxVoxel
||std::abs(static_cast<double>(Z))>MaxVoxel)return false;
const auto ToFixed=[](float Value)
{return static_cast<int64>(std::llround(static_cast<double>(Value)
*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));};
const VoxelForgeCore::Heightfield2D Block(WorldAssembly->recipe,*Plan);
if(!Block.isValid())return false;
OutDensity=static_cast<float>(Block.point(ToFixed(X),ToFixed(Y),ToFixed(Z)).densitySubvoxels
/Scale);
return true;
const FBoundStratumField* Bound=FindBoundStratumForChunk(ChunkZ);
if(!Bound||Bound->Kind!=FBoundStratumField::EKind::SurfaceWorld
||!Bound->SurfacePlan||ChunkZ<Bound->SurfacePlan->bottomChunkZ
||ChunkZ>Bound->SurfacePlan->topChunkZ)return false;
const auto* Field=std::get_if<FSurfaceWorldFieldAdapter>(&Bound->Evaluator);
return Field&&Field->densityAt(X,Y,Z,OutDensity);
}
bool NativeFloatingIslandDensityAt(float X,float Y,float Z,float& OutDensity) const
@@ -4818,13 +5019,15 @@ private:
const double LayoutChunkWidth=GetResolvedLayoutChunkWidthVoxels();
if(!(LayoutChunkWidth>0.0))return false;
const int32 ChunkZ=FMath::FloorToInt(Z/static_cast<float>(LayoutChunkWidth));
if(Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ))
!=ECaveGeneratorType::FloatingIslands)return false;
const int32 StrateIndex=Owner->Manager->GetStrateIndex(
static_cast<float>((static_cast<double>(ChunkZ)+0.5)
*ResolvedLayout->strateLayoutChunkSizeMicrometres/10000.0));
const auto* Plan=FindWorldAssemblyFloatingIslandStratum(StrateIndex,ChunkZ);
if(!Plan)return false;
const FBoundStratumField* Bound=FindBoundStratumForChunk(ChunkZ);
if(!Bound||Bound->Kind!=FBoundStratumField::EKind::FloatingIslands
||!Bound->IslandPlan||ChunkZ<Bound->IslandPlan->bottomChunkZ
||ChunkZ>Bound->IslandPlan->topChunkZ)return false;
const int32 StrateIndex=Bound->StrateIndex;
const auto* Plan=Bound->IslandPlan;
const auto* FieldAdapter=std::get_if<FFloatingIslandFieldAdapter>(
&Bound->Evaluator);
if(!FieldAdapter||!FieldAdapter->Evaluator.isValid())return false;
constexpr double Scale=static_cast<double>(VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
constexpr double Maximum=1000000000000.0/Scale;
if(std::abs(static_cast<double>(X))>Maximum||std::abs(static_cast<double>(Y))>Maximum
@@ -4832,11 +5035,8 @@ private:
const auto ToFixed=[](float Value)
{return static_cast<int64>(std::llround(static_cast<double>(Value)
*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));};
const VoxelForgeCore::FloatingIslandFieldV1 Field(
Plan->manifest.recipe,Plan->manifest.plan);
if(!Field.isValid())return false;
const std::int64_t qx=ToFixed(X),qy=ToFixed(Y),qz=ToFixed(Z);
std::int64_t Density=Field.densitySubvoxels(qx,qy,qz);
std::int64_t Density=FieldAdapter->densitySubvoxelsAt(qx,qy,qz);
const std::int64_t NativeDensity=Density;
// The anchor-root field keeps broad lobes, but its shortest authored noise
// wavelength is below one metre. Filter that detail only around a FloatingIslands
@@ -4963,7 +5163,7 @@ private:
{
const std::int64_t weight=(dx==0?2:1)*(dy==0?2:1)*(dz==0?2:1);
const std::int64_t sample=(dx==0&&dy==0&&dz==0)?Density:
Field.densitySubvoxels(qx+dx*FilterStep,qy+dy*FilterStep,
FieldAdapter->densitySubvoxelsAt(qx+dx*FilterStep,qy+dy*FilterStep,
qz+dz*FilterStep);
weightedSum+=sample*weight;
}
@@ -5000,7 +5200,7 @@ private:
{
std::array<std::int64_t,3> sample{qx,qy,qz};
sample[axis]+=sign*fragmentStep;
const std::int64_t neighbor=Field.densitySubvoxels(
const std::int64_t neighbor=FieldAdapter->densitySubvoxelsAt(
sample[0],sample[1],sample[2]);
if(neighbor<=0)
{
@@ -5031,11 +5231,11 @@ private:
if(!MakeResolvedStratumBounds(static_cast<double>(Bottom)/Scale,
static_cast<double>(Top)/Scale,static_cast<double>(Seal)/Scale,Bounds))
return false;
const FFloatingIslandParams Params=Owner->Manager->GetFloatingIslandParamsForChunk(
FIntVector(0,0,ChunkZ));
const FFloatingIslandParams* Params=FieldAdapter->legacyBoundaryParamsAt(ChunkZ);
if(!Params)return false;
float InternalDensity=-OutDensity;
VF_ApplyUpperBoundarySeal(InternalDensity,Z,static_cast<float>(Bounds.TopZ),
static_cast<float>(Bounds.SealThickness),Params.BaseDensity);
static_cast<float>(Bounds.SealThickness),Params->BaseDensity);
OutDensity=-InternalDensity;
}
else OutDensity=static_cast<float>(static_cast<double>(Density)/Scale);
@@ -5044,12 +5244,16 @@ private:
bool UsesLegacySurfaceField(float X,float Y,float Z) const
{
if(!Owner||!Owner->Manager||!Owner->Generator)return false;
const double LayoutChunkWidth=GetResolvedLayoutChunkWidthVoxels();
if(!(LayoutChunkWidth>0.0))return false;
const FIntVector ChunkCoord(0,0,FMath::FloorToInt(Z/static_cast<float>(LayoutChunkWidth)));
return Owner->Manager->GetGeneratorTypeForChunk(ChunkCoord)
==ECaveGeneratorType::SurfaceWorld;
const FBoundStratumField* Bound=FindBoundStratumForZ(Z);
return Bound&&Bound->Kind==FBoundStratumField::EKind::SurfaceWorld;
}
bool LegacyGeneratorDensityAt(float X,float Y,float Z,float& OutDensity) const
{
const FBoundStratumField* Bound=FindBoundStratumForZ(Z);
const auto* Legacy=Bound?std::get_if<FLegacyGeneratorFieldAdapter>(
&Bound->Evaluator):nullptr;
return Legacy&&Legacy->densityAt(X,Y,Z,OutDensity);
}
float LegacySurfaceDensityAt(float X,float Y,float Z) const
@@ -5057,7 +5261,10 @@ private:
// SurfaceWorld consumes biome overrides, terrain ops, water level and its sky cap in
// the legacy stack. Reuse that immutable evaluator as an exact temporary bridge.
// SurfaceWorld lit biomes, ops de terrain, niveau d'eau et plafond; reutiliser ce champ.
const float density=ApplyResolvedStrateComposition(Owner->Generator->GetDensityAt(X,Y,Z),X,Y,Z);
float density=0.0f;
if(!LegacyGeneratorDensityAt(X,Y,Z,density))
density=Owner->Generator->GetDensityAt(X,Y,Z);
density=ApplyResolvedStrateComposition(density,X,Y,Z);
return ApplyEditBrushes(density,X,Y,Z);
}
@@ -8378,11 +8585,13 @@ private:
bool Built=false;
bool bNativeOnly=false;
bool bUseNativeManifestFields=false;
float BoundManagerLayoutChunkWidthVoxels=0.0f;
FIntVector NativeOnlyMinimum=FIntVector::ZeroValue;
FIntVector NativeOnlyMaximum=FIntVector::ZeroValue;
mutable std::atomic<uint32> NativeOnlyViolations{0};
bool FarBuilt=false;
std::vector<std::array<double,2>> ResolvedBoundaryZIntervalsMicrometres;
std::vector<FBoundStratumField> BoundStratumFields;
std::vector<FInterval> LayerRanges;
std::vector<FLayerField> LayerFields;
std::vector<FPrimitive> Primitives;