wip(assembler): M1 round 6 -- owner walk fixes: 25 cm geometry scale, one height datum, carve/fill sign, faster relief meshing

Owner saw content floating above native terrain, spiky triangles, reversed carve/fill and late relief.
Causes: shared mesher placed Core tiles on a 12.5 cm grid; content/atmosphere asked strate ranges in
12.5 cm voxels; Core edits add density where the legacy diff subtracts. Horizon LOD8 bridge edge
5.657 -> 2.265 cells. Relief mesh p95 60.8 -> 42.0 ms (LOD0). New BuildHost checks for scale, height,
blueprint carve/fill and per-kind streaming lag.

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 20:39:24 +02:00
1 parent f67b519e75
commit 61633cb492
18 files changed
+1708 -142

No files matched your search

@@ -119,6 +119,8 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
// Cell size in voxels. No upper clamp: coarse clipmap levels use bigger steps (the EXTENT
// grows). Coarse tiles also use FEWER cells (InCellsPerAxis) for cheaper gen.
Step = FMath::Max(1, Step);
const float GeometryVoxelSize = VoxelMath::IsFinite(GeometryVoxelSizeCm)
? FMath::Max(1.0f, GeometryVoxelSizeCm) : VOXEL_SIZE;
// T2.b — octave bias for THIS tile: drop LODOctaveDrop octaves per Step doubling from
// the generator's per-voxel volumetric noise (sub-cell octaves can't shape a coarse
@@ -130,7 +132,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
TGuardValue<int32> SampleStepGuard(VoxelGenLOD::SampleStep, Step);
// World-cm origin of the tile's min corner (positions are built relative to this).
const FVector ChunkWorldPos = FVector(OriginVoxels) * VOXEL_SIZE;
const FVector ChunkWorldPos = FVector(OriginVoxels) * GeometryVoxelSize;
//=========================================================================
// VERTEX DEDUPLICATION MAP
@@ -1120,7 +1122,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
const int32 GY = cy + CornerOffsets[i].Y;
const int32 GZ = cz + CornerOffsets[i].Z;
Positions[i] = ChunkWorldPos
+ FVector(GX * Step, GY * Step, GZ * Step) * VOXEL_SIZE;
+ FVector(GX * Step, GY * Step, GZ * Step) * GeometryVoxelSize;
Gradients[i] = GradAt(GX, GY, GZ);
}
if (bSampleCell)
@@ -1224,10 +1226,10 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
MeshData.NumSurfaceVertices = MeshData.Vertices.Num();
if (bGenerateSkirts && (GroundTris.Num() + CapTris.Num()) > 0)
{
const float ExtentCm = (float)(CellsPerAxis * Step) * VOXEL_SIZE;
const float ExtentCm = (float)(CellsPerAxis * Step) * GeometryVoxelSize;
const float MinX = ChunkWorldPos.X, MinY = ChunkWorldPos.Y, MinZ = ChunkWorldPos.Z;
const float MaxX = MinX + ExtentCm, MaxY = MinY + ExtentCm, MaxZ = MinZ + ExtentCm;
const float SkirtDepth = FMath::Max(1.0f, SkirtCells) * (float)Step * VOXEL_SIZE;
const float SkirtDepth = FMath::Max(1.0f, SkirtCells) * (float)Step * GeometryVoxelSize;
auto OnBoundaryPlane = [&](const FVector& A, const FVector& B) -> bool
{