wip(assembler): M1 repair round -- raised block and cliff fixed; native 7x faster than legacy

Luna, M1 repair round: the rectangular raised block and the broken cliff shared one cause,
a type-2 solid AABB in the generated plan; it is now a tapered, terrain-following shelf, and
a negative-control audit catches the old box behaviour; seam classification check passes.
Bound audit 298 boxes / 8,046 samples, 0 misses. Evaluator and 120-tile density/mesh/payload/
topology hashes identical at W1/W8/W16. Cave regression: walkability 5,642/5,642, 64/64 tiles.
Legacy mismatch unchanged (0 biome mismatches, 18.14% signs).
Speed (matched workloads): 120-tile full detail 0.089 s native vs 0.625 s legacy; 529-tile
clipmap 3.858 s vs 11.687 s -- 2.29 s above the ~1.57 s aim; LOD8 dominates (165 unknown
tiles, 13.27 M field calls, 10.88 M column-cache misses).
My capture review: coast matches legacy closely; surface clean but a dark flat slab on the far
horizon; cliff shelf renders as a stack of thin plates with back faces showing (sub-voxel
shelf thickness suspected).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-09 01:22:30 +02:00
1 parent fcb16fd265
commit 2c20f9eaea
61 files changed
+4308 -165

No files matched your search

+68 -14
View File
@@ -33,6 +33,21 @@ class FStandaloneShapeWorld
{
public:
enum class EDetailVariant : uint8 { Coherent, Smooth, PerVoxel };
struct FBoxClassification
{
EVoxelTileClass Verdict=EVoxelTileClass::Mixed;
bool bNativeSurface=false;
bool bUnknown=false;
};
struct FClassificationThreadStats
{
uint64 SolidBoxes=0,AirBoxes=0,MixedBoxes=0,UnknownBoxes=0;
uint64 NativeFloatFieldCalls=0,NativeLatticeFieldCalls=0,NativeUnclampedFieldCalls=0;
double Milliseconds=0.0;
};
static void ResetThreadClassificationStats() { ThreadClassificationStats()={}; }
static FClassificationThreadStats GetThreadClassificationStats()
{ return ThreadClassificationStats(); }
struct FFarConnectorSegment
{
FVector Start=FVector::ZeroVector;
@@ -923,7 +938,10 @@ public:
{
float NativeDensity=0.0f;
if(NativeSurfaceDensityAt(X,Y,Z,NativeDensity))
{
++ThreadClassificationStats().NativeFloatFieldCalls;
return ApplyEditBrushes(NativeDensity,X,Y,Z);
}
if(UsesLegacySurfaceField(X,Y,Z))
return LegacySurfaceDensityAt(X,Y,Z);
int32 IX=0,IY=0,IZ=0;
@@ -939,7 +957,10 @@ public:
float NativeDensity=0.0f;
if(NativeSurfaceDensityAt(static_cast<float>(X),static_cast<float>(Y),
static_cast<float>(Z),NativeDensity))
{
++ThreadClassificationStats().NativeLatticeFieldCalls;
return ApplyEditBrushes(NativeDensity,X,Y,Z);
}
if(UsesLegacySurfaceField(static_cast<float>(X),static_cast<float>(Y),
static_cast<float>(Z)))
return LegacySurfaceDensityAt(static_cast<float>(X),static_cast<float>(Y),
@@ -956,7 +977,10 @@ public:
{
float NativeDensity=0.0f;
if(NativeSurfaceDensityAt(X,Y,Z,NativeDensity))
{
++ThreadClassificationStats().NativeUnclampedFieldCalls;
return ApplyEditBrushes(NativeDensity,X,Y,Z);
}
if(UsesLegacySurfaceField(X,Y,Z))
return LegacySurfaceDensityAt(X,Y,Z);
return AnalyticDensityAt(X,Y,Z,false);
@@ -1130,12 +1154,17 @@ private:
public:
EVoxelTileClass ClassifyBox(const FIntVector& Origin,int32 Step,int32 Cells) const
{ return ClassifyBoxDetailed(Origin,Step,Cells).Verdict; }
FBoxClassification ClassifyBoxDetailed(const FIntVector& Origin,int32 Step,int32 Cells) const
{
using Clock=std::chrono::steady_clock;
const auto Start=Clock::now();
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};
const VoxelForgeCore::WorldAssemblyStratumPlanV1* SurfacePlan=nullptr;
bool bSurfaceOverlap=false,bOtherStrateOverlap=false;
bool bSurfaceOverlap=false,bOtherStrateOverlap=false,bBadPlan=false;
if(Owner&&Owner->Manager)
{
const int32 FirstChunk=FMath::FloorToInt(static_cast<float>(BMin[2])
@@ -1152,19 +1181,31 @@ public:
static_cast<float>((static_cast<double>(ChunkZ*CHUNK_SIZE+CHUNK_SIZE/2))*VOXEL_SIZE));
const auto* Candidate=FindWorldAssemblyStratum(StrateIndex,ChunkZ);
if(!Candidate||(SurfacePlan&&SurfacePlan!=Candidate))
return EVoxelTileClass::Mixed;
bBadPlan=true;
SurfacePlan=Candidate;
}
else bOtherStrateOverlap=true;
}
}
const auto Finish=[&](EVoxelTileClass Verdict,bool bUnknown=false)
{
FBoxClassification Result{Verdict,bSurfaceOverlap&&!bOtherStrateOverlap,bUnknown};
auto& Counts=ThreadClassificationStats();
Counts.Milliseconds+=std::chrono::duration<double,std::milli>(Clock::now()-Start).count();
if(!Result.bNativeSurface||bUnknown)++Counts.UnknownBoxes;
else if(Verdict==EVoxelTileClass::AllSolid)++Counts.SolidBoxes;
else if(Verdict==EVoxelTileClass::AllAir)++Counts.AirBoxes;
else ++Counts.MixedBoxes;
return Result;
};
// A box crossing recipes cannot use one field interval; unknown composition stays Mixed.
// Une boite qui traverse plusieurs recettes reste Mixed, car l'intervalle d'un seul champ ne suffit pas.
if(bSurfaceOverlap&&bOtherStrateOverlap)return EVoxelTileClass::Mixed;
if(bBadPlan|| (bSurfaceOverlap&&bOtherStrateOverlap))
return Finish(EVoxelTileClass::Mixed,true);
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])
return EVoxelTileClass::Mixed;
return Finish(EVoxelTileClass::Mixed,true);
for(int32 BZ=FloorDiv(BMin[2],ActiveSpatialBinSize);BZ<=FloorDiv(BMax[2],ActiveSpatialBinSize);++BZ)
for(int32 BY=FloorDiv(BMin[1],ActiveSpatialBinSize);BY<=FloorDiv(BMax[1],ActiveSpatialBinSize);++BY)
for(int32 BX=FloorDiv(BMin[0],ActiveSpatialBinSize);BX<=FloorDiv(BMax[0],ActiveSpatialBinSize);++BX)
@@ -1175,32 +1216,39 @@ public:
const FPrimitive& P=Primitives[Id];bool Overlap=true;
for(int32 A=0;A<3;++A)
Overlap &= P.Max[A]+DetailBand>=BMin[A]&&P.Min[A]-DetailBand<=BMax[A];
if(Overlap)return EVoxelTileClass::Mixed;
if(Overlap)return Finish(EVoxelTileClass::Mixed);
}
}
for(const FInterval& R:LayerRanges)
if(R.Lo<=BMax[2]&&R.Hi>=BMin[2]
&&(R.Lo>=BMin[2]||R.Hi<=BMax[2]))
return EVoxelTileClass::Mixed;
return Finish(EVoxelTileClass::Mixed);
if(bSurfaceOverlap)
{
if(!WorldAssembly||!SurfacePlan)return EVoxelTileClass::Mixed;
if(!WorldAssembly||!SurfacePlan)return Finish(EVoxelTileClass::Mixed,true);
const VoxelForgeCore::Heightfield2D Block(WorldAssembly->recipe,*SurfacePlan);
const auto Bounds=Block.interval(
const auto Verdict=Block.classifyLatticeBox(
static_cast<int64>(BMin[0])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
static_cast<int64>(BMin[1])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
static_cast<int64>(BMin[2])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
static_cast<int64>(BMax[0])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
static_cast<int64>(BMax[1])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
static_cast<int64>(BMax[2])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel);
if(!Bounds.known)return EVoxelTileClass::Mixed;
if(Bounds.minimumDensitySubvoxels>0)return EVoxelTileClass::AllAir;
if(Bounds.maximumDensitySubvoxels<0)return EVoxelTileClass::AllSolid;
return EVoxelTileClass::Mixed;
static_cast<int64>(BMax[2])*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel,
std::max(Step,1));
switch(Verdict)
{
case VoxelForgeCore::HeightfieldBoxClass::allAir:
return Finish(EVoxelTileClass::AllAir);
case VoxelForgeCore::HeightfieldBoxClass::allSolid:
return Finish(EVoxelTileClass::AllSolid);
case VoxelForgeCore::HeightfieldBoxClass::mixed:
return Finish(EVoxelTileClass::Mixed);
default:return Finish(EVoxelTileClass::Mixed,true);
}
}
const bool bRock=EvaluateFast((BMin[0]+BMax[0])*0.5,
(BMin[1]+BMax[1])*0.5,(BMin[2]+BMax[2])*0.5);
return bRock?EVoxelTileClass::AllSolid:EVoxelTileClass::AllAir;
return Finish(bRock?EVoxelTileClass::AllSolid:EVoxelTileClass::AllAir);
}
bool IsRock(int32 X,int32 Y,int32 Z) const
@@ -1662,6 +1710,12 @@ public:
}
private:
static FClassificationThreadStats& ThreadClassificationStats()
{
static thread_local FClassificationThreadStats Stats;
return Stats;
}
const VoxelForgeCore::WorldAssemblyStratumPlanV1* FindWorldAssemblyStratum(
int32 StrateIndex,int32 ChunkZ) const
{