wip(unreal): round 4 -- strate-type coverage matrix; SurfaceWorld via exact legacy bridge
Luna, integration round 4 (owner requirement: Core must know every strate type). Coverage, Core vs legacy owner field (one probe per type, 686,000 LOD0 samples): TunnelNetwork approximate (2.17% signs differ); FlatPlain / CrystalChamber native slab fields missing (generic cave, 1.28%); Maze missing (13.3%); VerticalShafts missing (no shaft surface); FloatingIslands missing (95.8%); Underwater approximate + no water. SurfaceWorld: exact density (0 sign changes, LOD0-3 hashes match) through the copied legacy evaluator -- but at legacy cost: full view 23.1 s vs legacy 23.9 s (Core caves without surface 0.785 s). Passages: SlopedTunnel/VerticalShaft/Spiral pass walkability; Cascading (365/1,495) and Worm (109/1,490) FAIL. Transitions approximate (1.2-1.3%). BuildHost UBT + actor validation pass (SurfaceWorld layout: 2,553 visual keys, 448 LOD transitions, biome query). Small owner/Core capture pairs in core_strate_coverage/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
75210e56f3
commit
d696463c68
40 files changed
+373
-11
No files matched your search
@@ -915,6 +915,8 @@ public:
|
||||
// edge interpolation and normals to the existing mesher.
|
||||
float DensityAt(float X,float Y,float Z) const
|
||||
{
|
||||
if(UsesLegacySurfaceField(X,Y,Z))
|
||||
return LegacySurfaceDensityAt(X,Y,Z);
|
||||
int32 IX=0,IY=0,IZ=0;
|
||||
const bool bInteger=NearInteger(X,IX)&&NearInteger(Y,IY)&&NearInteger(Z,IZ);
|
||||
const bool bPacked=!bAnalyticOnly&&bInteger&&Contains(IX,IY,IZ);
|
||||
@@ -925,6 +927,10 @@ public:
|
||||
|
||||
float DensityAtLattice(int32 X,int32 Y,int32 Z) const
|
||||
{
|
||||
if(UsesLegacySurfaceField(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z)))
|
||||
return LegacySurfaceDensityAt(static_cast<float>(X),static_cast<float>(Y),
|
||||
static_cast<float>(Z));
|
||||
const bool bPacked=!bAnalyticOnly&&Contains(X,Y,Z);
|
||||
if(bPacked)
|
||||
return PackedDensityAt(X,Y,Z,IsRock(X,Y,Z),static_cast<float>(X),
|
||||
@@ -935,6 +941,8 @@ public:
|
||||
|
||||
float DensityAtUnclamped(float X,float Y,float Z) const
|
||||
{
|
||||
if(UsesLegacySurfaceField(X,Y,Z))
|
||||
return LegacySurfaceDensityAt(X,Y,Z);
|
||||
return AnalyticDensityAt(X,Y,Z,false);
|
||||
}
|
||||
|
||||
@@ -958,6 +966,17 @@ public:
|
||||
{
|
||||
Count=std::clamp(Count,0,8);
|
||||
if(Count==0)return;
|
||||
bool bHasLegacySurfaceSample=false;
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
bHasLegacySurfaceSample|=UsesLegacySurfaceField(
|
||||
static_cast<float>(XStart+Lane*XStep),static_cast<float>(Y),
|
||||
static_cast<float>(Z));
|
||||
if(bHasLegacySurfaceSample)
|
||||
{
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
OutDensity[Lane]=DensityAtLattice(XStart+Lane*XStep,Y,Z);
|
||||
return;
|
||||
}
|
||||
if(bAnalyticOnly)
|
||||
{
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
@@ -1041,6 +1060,11 @@ private:
|
||||
if(OutDetailDisplacement)*OutDetailDisplacement=0.0f;
|
||||
if(OutCaveInfluence)*OutCaveInfluence=0.0f;
|
||||
if(OutFloorInfluence)*OutFloorInfluence=0.0f;
|
||||
if(UsesLegacySurfaceField(X,Y,Z))
|
||||
{
|
||||
const float Density=Owner->Generator->GetDensityAt(X,Y,Z);
|
||||
return bApplyEdits?ApplyEditBrushes(Density,X,Y,Z):Density;
|
||||
}
|
||||
const bool bInsideFine=X>=Min[0]&&X<=Max[0]&&Y>=Min[1]&&Y<=Max[1]
|
||||
&&Z>=Min[2]&&Z<=Max[2];
|
||||
if(!bInsideFine)
|
||||
@@ -1091,6 +1115,21 @@ public:
|
||||
const int32 Pad=std::max(Step,1);
|
||||
int32 BMin[3]={Origin.X-Pad,Origin.Y-Pad,Origin.Z-Pad};
|
||||
int32 BMax[3]={Origin.X+(Cells+1)*Step,Origin.Y+(Cells+1)*Step,Origin.Z+(Cells+1)*Step};
|
||||
// A primitive-only proof cannot classify the biome heightfield. Keep overlapping
|
||||
// SurfaceWorld boxes mixed so generation samples the exact copied evaluator.
|
||||
// Une preuve fondee sur les primitives ne classe pas la hauteur par biomes; garder les
|
||||
// boites SurfaceWorld en Mixed force l'evaluation exacte lors du maillage.
|
||||
if(Owner&&Owner->Manager)
|
||||
{
|
||||
const int32 FirstChunk=FMath::FloorToInt(static_cast<float>(BMin[2])
|
||||
/static_cast<float>(CHUNK_SIZE));
|
||||
const int32 LastChunk=FMath::FloorToInt(static_cast<float>(BMax[2])
|
||||
/static_cast<float>(CHUNK_SIZE));
|
||||
for(int32 ChunkZ=FirstChunk;ChunkZ<=LastChunk;++ChunkZ)
|
||||
if(Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,ChunkZ))
|
||||
==ECaveGeneratorType::SurfaceWorld)
|
||||
return EVoxelTileClass::Mixed;
|
||||
}
|
||||
if(!EditBrushes.empty()&&EditBoundsMin.X<=BMax[0]&&EditBoundsMax.X>=BMin[0]
|
||||
&&EditBoundsMin.Y<=BMax[1]&&EditBoundsMax.Y>=BMin[1]
|
||||
&&EditBoundsMin.Z<=BMax[2]&&EditBoundsMax.Z>=BMin[2])
|
||||
@@ -1576,6 +1615,24 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool UsesLegacySurfaceField(float X,float Y,float Z) const
|
||||
{
|
||||
if(!Owner||!Owner->Manager||!Owner->Generator)return false;
|
||||
const FIntVector ChunkCoord(FMath::FloorToInt(X/static_cast<float>(CHUNK_SIZE)),
|
||||
FMath::FloorToInt(Y/static_cast<float>(CHUNK_SIZE)),
|
||||
FMath::FloorToInt(Z/static_cast<float>(CHUNK_SIZE)));
|
||||
return Owner->Manager->GetGeneratorTypeForChunk(ChunkCoord)
|
||||
==ECaveGeneratorType::SurfaceWorld;
|
||||
}
|
||||
|
||||
float LegacySurfaceDensityAt(float X,float Y,float Z) const
|
||||
{
|
||||
// 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.
|
||||
return ApplyEditBrushes(Owner->Generator->GetDensityAt(X,Y,Z),X,Y,Z);
|
||||
}
|
||||
|
||||
float ApplyEditBrushes(float Density,double X,double Y,double Z) const
|
||||
{
|
||||
if(EditBrushes.empty()||X<EditBoundsMin.X||X>EditBoundsMax.X
|
||||
@@ -4213,6 +4270,16 @@ public:
|
||||
int32 Count,float* OutDensity) const
|
||||
{
|
||||
if(Count<=0||OutDensity==nullptr)return;
|
||||
bool bHasLegacySurfaceSample=false;
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
bHasLegacySurfaceSample|=UsesLegacySurfaceField(static_cast<float>(X),
|
||||
static_cast<float>(Y),static_cast<float>(ZStart+Lane*ZStep));
|
||||
if(bHasLegacySurfaceSample)
|
||||
{
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
OutDensity[Lane]=DensityAtLattice(X,Y,ZStart+Lane*ZStep);
|
||||
return;
|
||||
}
|
||||
if(!bAnalyticOnly)
|
||||
{
|
||||
for(int32 Lane=0;Lane<Count;++Lane)
|
||||
|
||||
Reference in new issue
Block a user