wip(assembler): round L18 -- FloatingIslands false floors removed; shared strate ceiling

FI geometry v3 drops the all-XY lower boundary seal that created false floors (3.5/8 m); the
ceiling comes from the shared VF_ApplyUpperBoundarySeal and AppendStratumBoundaryCeilings path
for every generator, at each strate's own configured upper boundary (owner: every strate has a
ceiling). Far-LOD ceiling continuity: 0 gaps at LOD4-8. SurfaceWorld bit-identical to L14
(14 configs + 24 m crossing); FI deterministic (28-row matrix); route parity and proofs pass.
Unreal: FI geometryVersion 2->3 and the shared upper-seal helper extracted (UBT compile needed on
the owner PC). Open: small ceiling holes; lower-stratum LOD ring steps seen through the FI void.

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-20 07:55:53 +02:00
1 parent 87041290dd
commit dcf0763ec5
36 files changed
+1690 -54

No files matched your search

+86 -15
View File
@@ -5,6 +5,7 @@
#include "VoxelCaveMorphology.h"
#include "VoxelNoise.h"
#include "VoxelStrateManager.h"
#include "VoxelDensityPrimitives.h"
#include "VoxelForgeCore/VoxelForgeCore.h"
#include "VoxelForgeFieldShared.h"
@@ -32,6 +33,13 @@
class FStandaloneShapeWorld
{
public:
struct FResolvedStratumBounds
{
double BottomZ=0.0;
double TopZ=0.0;
double SealThickness=0.0;
};
double GetCoreVoxelSizeCm() const
{
return Owner == nullptr || Owner->CoreVoxelSizeMicrons == 0
@@ -47,6 +55,41 @@ public:
return static_cast<double>(CHUNK_SIZE) * OwnerVoxelSizeCm / GetCoreVoxelSizeCm();
}
static bool MakeResolvedStratumBounds(double BottomZ,double TopZ,double SealThickness,
FResolvedStratumBounds& Out)
{
if(!std::isfinite(BottomZ)||!std::isfinite(TopZ)||!std::isfinite(SealThickness)
||TopZ<=BottomZ||SealThickness<0.0)return false;
Out={BottomZ,TopZ,SealThickness};
return true;
}
bool GetResolvedStratumBounds(const FStrateSlot& Slot,FResolvedStratumBounds& Out) const
{
if(!Owner||!Owner->Manager)return false;
const int32 MidChunkZ=(Slot.TopChunkZ+Slot.BottomChunkZ)/2;
if(bUseNativeManifestFields&&WorldAssembly
&&Owner->Manager->GetGeneratorTypeForChunk(FIntVector(0,0,MidChunkZ))
==ECaveGeneratorType::FloatingIslands)
{
const auto* Plan=FindWorldAssemblyFloatingIslandStratum(Slot.StrateIndex,MidChunkZ);
if(Plan&&Plan->manifest.recipe.geometryVersion>=3)
{
constexpr double Scale=static_cast<double>(
VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
return MakeResolvedStratumBounds(
static_cast<double>(Plan->manifest.recipe.layoutMinimumZSubvoxels)/Scale,
static_cast<double>(Plan->manifest.recipe.layoutMaximumZSubvoxels)/Scale,
static_cast<double>(Plan->manifest.recipe.boundarySealSubvoxels)/Scale,Out);
}
}
const FStrateGenerationParams Params=Owner->Manager->GetGenerationParams(
FIntVector(0,0,MidChunkZ));
return MakeResolvedStratumBounds(static_cast<double>(Slot.BottomChunkZ)*CHUNK_SIZE,
static_cast<double>(Slot.TopChunkZ+1)*CHUNK_SIZE,
static_cast<double>(Params.BoundarySealThickness),Out);
}
enum class EDetailVariant : uint8 { Coherent, Smooth, PerVoxel };
struct FBoxClassification
{
@@ -714,12 +757,12 @@ public:
const double TileZ0=Origin.Z,TileZ1=Origin.Z+static_cast<double>(Cells)*Step;
for(const FStrateSlot& Slot:Owner->Manager->GetLayout())
{
const FStrateGenerationParams Params=Owner->Manager->GetGenerationParams(
FIntVector(0,0,(Slot.TopChunkZ+Slot.BottomChunkZ)/2));
FResolvedStratumBounds Bounds;
if(!GetResolvedStratumBounds(Slot,Bounds))continue;
const float HalfWidth=static_cast<float>(std::max(8.0,
static_cast<double>(Params.BoundarySealThickness)+8.0));
const float Boundaries[2]={static_cast<float>(Slot.BottomChunkZ)*CHUNK_SIZE,
static_cast<float>(Slot.TopChunkZ+1)*CHUNK_SIZE};
Bounds.SealThickness+8.0));
const float Boundaries[2]={static_cast<float>(Bounds.BottomZ),
static_cast<float>(Bounds.TopZ)};
for(const float Z:Boundaries)
if(Z+HalfWidth>=TileZ0&&Z-HalfWidth<=TileZ1)
Out.stratumBoundaries.push_back({Z,HalfWidth});
@@ -1549,13 +1592,18 @@ public:
const std::int64_t Seal=IslandPlan->manifest.recipe.boundarySealSubvoxels;
const std::int64_t BoxBottom=static_cast<std::int64_t>(BMin[2])*Scale;
const std::int64_t BoxTop=static_cast<std::int64_t>(BMax[2])*Scale;
const bool bBottomSealOverlap=BoxBottom<Bottom+Seal&&BoxTop>=Bottom;
const bool bTopSealOverlap=BoxBottom<=Top&&BoxTop>Top-Seal;
const bool bSharedTopSealEnabled=IslandPlan->manifest.recipe.geometryVersion<3
||!VoxelDensityAblation::IsBoundarySealOff();
const bool bTopSealOverlap=bSharedTopSealEnabled
&&BoxBottom<=Top&&BoxTop>Top-Seal;
const bool bBottomSealOverlap=IslandPlan->manifest.recipe.geometryVersion<3
&&BoxBottom<Bottom+Seal&&BoxTop>=Bottom;
if(bBottomSealOverlap)
return Finish(BoxBottom>=Bottom&&BoxTop<=Bottom+Seal
?EVoxelTileClass::AllSolid:EVoxelTileClass::Mixed);
if(bTopSealOverlap)
return Finish(BoxBottom>=Top-Seal&&BoxTop<=Top
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);
@@ -2130,9 +2178,28 @@ private:
const std::int64_t Top=Plan->manifest.recipe.layoutMaximumZSubvoxels;
const std::int64_t Seal=Plan->manifest.recipe.boundarySealSubvoxels;
const std::int64_t Zq=ToFixed(Z);
if(Zq>=Bottom&&Zq<Bottom+Seal)Density=std::min(Density,-std::max<std::int64_t>(1,Zq-Bottom));
if(Zq<=Top&&Zq>Top-Seal)Density=std::min(Density,-std::max<std::int64_t>(1,Top-Zq));
OutDensity=static_cast<float>(static_cast<double>(Density)/Scale);
if(Plan->manifest.recipe.geometryVersion<3)
{
if(Zq>=Bottom&&Zq<Bottom+Seal)
Density=std::min(Density,-std::max<std::int64_t>(1,Zq-Bottom));
if(Zq<=Top&&Zq>Top-Seal)
Density=std::min(Density,-std::max<std::int64_t>(1,Top-Zq));
OutDensity=static_cast<float>(static_cast<double>(Density)/Scale);
}
else
{
OutDensity=static_cast<float>(static_cast<double>(Density)/Scale);
FResolvedStratumBounds Bounds;
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));
float InternalDensity=-OutDensity;
VF_ApplyUpperBoundarySeal(InternalDensity,Z,static_cast<float>(Bounds.TopZ),
static_cast<float>(Bounds.SealThickness),Params.BaseDensity);
OutDensity=-InternalDensity;
}
return std::isfinite(OutDensity);
}
@@ -2351,19 +2418,23 @@ private:
int32 Top=MIN_int32,Bottom=MAX_int32;
for(const FStrateSlot& Slot:Layout)
{
Top=std::max(Top,Slot.TopChunkZ);Bottom=std::min(Bottom,Slot.BottomChunkZ);
FResolvedStratumBounds Bounds;
if(!GetResolvedStratumBounds(Slot,Bounds))continue;
const int32 ResolvedBottom=FMath::FloorToInt(static_cast<float>(Bounds.BottomZ));
const int32 ResolvedTop=FMath::CeilToInt(static_cast<float>(Bounds.TopZ));
Top=std::max(Top,ResolvedTop);Bottom=std::min(Bottom,ResolvedBottom);
if(!Slot.Definition)continue;
const int32 MidChunkZ=(Slot.TopChunkZ+Slot.BottomChunkZ)/2;
FLayerField Field;
Field.Lo=Slot.BottomChunkZ*CHUNK_SIZE;
Field.Hi=(Slot.TopChunkZ+1)*CHUNK_SIZE;
Field.Lo=ResolvedBottom;
Field.Hi=ResolvedTop;
Field.StrateIndex=Slot.StrateIndex;
Field.Params=Owner->Manager->GetGenerationParams(FIntVector(0,0,MidChunkZ));
LayerFields.push_back(std::move(Field));
}
if(Top>=Bottom)
{
LayerRanges.push_back({Bottom*CHUNK_SIZE,(Top+1)*CHUNK_SIZE});
LayerRanges.push_back({Bottom,Top});
}
}