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

+92 -2
View File
@@ -16,6 +16,7 @@
#include <limits>
#include <string>
#include <string_view>
#include <unordered_set>
#include <vector>
namespace
@@ -38,10 +39,69 @@ namespace
float MaximumHeight=-std::numeric_limits<float>::infinity();
std::vector<FVertex> Vertices;
std::vector<std::uint32_t> Indices;
struct FTileRange
{
std::array<std::int32_t,4> Key{};
std::size_t IndexBegin=0;
std::uint32_t IndexCount=0;
std::vector<std::uint8_t> FaceMasks;
};
std::vector<FTileRange> Tiles;
std::uint64_t Triangles=0,SkirtTriangles=0;
std::uint64_t VisibleSkirtTriangles=0,HiddenSameLodSkirtTriangles=0;
std::uint64_t DrawnTriangles=0;
std::uint32_t TileCount=0;
};
struct FTileKeyHash
{
std::size_t operator()(const std::array<std::int32_t,4>& Key) const noexcept
{
std::size_t Hash=0xcbf29ce484222325ull;
for(const std::int32_t Value:Key)
{
Hash^=static_cast<std::uint32_t>(Value);
Hash*=0x100000001b3ull;
}
return Hash;
}
};
std::int32_t FloorDiv(std::int64_t Value,std::int64_t Divisor)
{
const std::int64_t Quotient=Value/Divisor, Remainder=Value%Divisor;
return static_cast<std::int32_t>(Quotient-((Remainder<0)?1:0));
}
std::uint8_t ComputeVisibleSkirtFaceMask(
const std::array<std::int32_t,4>& Tile,
const std::unordered_set<std::array<std::int32_t,4>,FTileKeyHash>& Desired)
{
const std::int64_t Extent=static_cast<std::int64_t>(32)<<Tile[3];
const std::int64_t Origin[3]={static_cast<std::int64_t>(Tile[0])*Extent,
static_cast<std::int64_t>(Tile[1])*Extent,static_cast<std::int64_t>(Tile[2])*Extent};
std::uint8_t Mask=0;
for(std::int32_t Axis=0;Axis<3;++Axis)for(std::int32_t Side=0;Side<2;++Side)
{
std::int64_t Probe[3]={Origin[0]+Extent/2,Origin[1]+Extent/2,
Origin[2]+Extent/2};
Probe[Axis]=Side?Origin[Axis]+Extent:Origin[Axis]-1;
std::int32_t NeighborLevel=-1;
for(std::int32_t Level=0;Level<=8;++Level)
{
const std::int64_t NeighborExtent=static_cast<std::int64_t>(32)<<Level;
const std::array<std::int32_t,4> Neighbor={
FloorDiv(Probe[0],NeighborExtent),FloorDiv(Probe[1],NeighborExtent),
FloorDiv(Probe[2],NeighborExtent),Level};
if(Desired.contains(Neighbor))
{NeighborLevel=Level;break;}
}
if(NeighborLevel<0||NeighborLevel!=Tile[3])
Mask|=static_cast<std::uint8_t>(1u<<(Axis*2+Side));
}
return Mask;
}
template<typename T> bool Read(std::ifstream& File,T& Value)
{
File.read(reinterpret_cast<char*>(&Value),sizeof(Value));
@@ -126,11 +186,36 @@ namespace
}
Scene.Triangles+=IndexCount/3;
Scene.SkirtTriangles+=SkirtCount;
Scene.Tiles.push_back({{Key[0],Key[1],Key[2],Key[3]},IndexOffset,
IndexCount,std::move(Masks)});
TotalVertices+=VertexCount;TotalIndices+=IndexCount;
}
if(File.peek()!=std::char_traits<char>::eof())
{Error="mesh scene has trailing bytes";return false;}
if(Scene.Indices.empty()){Error="mesh scene contains no triangles";return false;}
std::unordered_set<std::array<std::int32_t,4>,FTileKeyHash> Desired;
Desired.reserve(Scene.Tiles.size());
for(const auto& Tile:Scene.Tiles)Desired.insert(Tile.Key);
std::vector<std::uint32_t> VisibleIndices;
VisibleIndices.reserve(Scene.Indices.size());
for(const auto& Tile:Scene.Tiles)
{
const std::uint8_t VisibleMask=ComputeVisibleSkirtFaceMask(Tile.Key,Desired);
for(std::uint32_t Triangle=0;Triangle<Tile.IndexCount/3;++Triangle)
{
const std::size_t MaskIndex=Triangle;
const std::uint8_t FaceMask=MaskIndex<Tile.FaceMasks.size()
?Tile.FaceMasks[MaskIndex]:0;
if(FaceMask!=0&&(FaceMask&VisibleMask)==0)
{++Scene.HiddenSameLodSkirtTriangles;continue;}
if(FaceMask!=0)++Scene.VisibleSkirtTriangles;
const std::size_t Index=Tile.IndexBegin+static_cast<std::size_t>(Triangle)*3;
VisibleIndices.insert(VisibleIndices.end(),Scene.Indices.begin()+Index,
Scene.Indices.begin()+Index+3);
}
}
Scene.Indices=std::move(VisibleIndices);
Scene.DrawnTriangles=Scene.Indices.size()/3;
return true;
}
@@ -399,9 +484,14 @@ void main()
{
std::error_code SizeError;
const auto Bytes=std::filesystem::file_size(Output,SizeError);
std::printf("[OffscreenCapture] triangles=%llu tiles=%u skirts=%llu shading=%s tile_edges=%s edge_width_m=%.3f png_bytes=%llu status=PASS path=%s\n",
static_cast<unsigned long long>(Scene.Triangles),Scene.TileCount,
std::printf("[OffscreenCapture] source_triangles=%llu drawn_triangles=%llu tiles=%u "
"skirts=%llu visible_skirt_triangles=%llu hidden_same_lod_skirt_triangles=%llu "
"shading=%s tile_edges=%s edge_width_m=%.3f png_bytes=%llu status=PASS path=%s\n",
static_cast<unsigned long long>(Scene.Triangles),
static_cast<unsigned long long>(Scene.DrawnTriangles),Scene.TileCount,
static_cast<unsigned long long>(Scene.SkirtTriangles),
static_cast<unsigned long long>(Scene.VisibleSkirtTriangles),
static_cast<unsigned long long>(Scene.HiddenSameLodSkirtTriangles),
ReadableMode?"readable":"normal",TileEdges?"on":"off",TileEdgeWidthMeters,
static_cast<unsigned long long>(SizeError?0:Bytes),Output.string().c_str());
}