wip(assembler): round S4 -- continuous far ceiling at the strate's upper boundary

S3's far cap sat up to 8.2 m above the near roof and read as floating pieces.
The far render cap now projects onto the owning strate's upper boundary
(density unchanged), on a global XY lattice, LOD4 16-voxel grid + LOD5-8
128-voxel. Cap agreement 0.05 cm (100 cm control detected), 2520/2520 upward
rays hit roof on the owner walk. Far recipe v2; LOD0-3 hashes equal S2/S3.
Tile p95 flat; cold clipmap +4.4%. Far-cliff fluting left open (coarse MC step).

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-19 00:41:13 +02:00
1 parent d0f97bf79a
commit 9d3c50ca95
14 files changed
+1376 -34

No files matched your search

+14 -4
View File
@@ -24,6 +24,7 @@
#include "VoxelClipmapDesiredTiles.h"
#include "VoxelCollisionDesiredTiles.h"
#include "VoxelPreEditDensityCache.h"
#include "RealtimeMeshLibrary.h"
// IWYU (FPSemantics = Precise ⇒ plus de PCH partagé) : GetPlayerPosition déréférence le pawn, donc
// APawn doit être COMPLET — `Casts.h` n'en donne qu'une déclaration avant. APlayerController n'est
// complet que par transitivité : on l'inclut explicitement.
@@ -12471,21 +12472,30 @@ bool AVoxelWorld::ApplyMeshToTile(FChunkResult& Result)
// (default config already maps material slot = polygroup index); only config sections that
// exist — the bHas* flags come from the worker. Collision at level 0 only (T1.c), both groups.
const uint64 CollisionConfigStartCycles = bProfileApply ? FPlatformTime::Cycles64() : 0;
const int32 NumIndices = Result.NumTriangles * 3;
const int32 FirstCapIndex = FMath::Clamp(
NumIndices - Result.NumCeilingTriangles * 3, 0, NumIndices);
if (bHasGroundTris)
{
FRealtimeMeshSectionConfig GroundConfig(0);
GroundConfig.bCastsShadow = bCastShadow;
RTMesh->UpdateSectionConfig(
const FRealtimeMeshStreamRange GroundRange =
URealtimeMeshBlueprintFunctionLibrary::MakeStreamRange(
0, Result.NumVertices, 0, FirstCapIndex);
RTMesh->CreateSection(
FRealtimeMeshSectionKey::CreateForPolyGroup(GroupKey, 0),
GroundConfig, /*bShouldCreateCollision*/ bWantsCollision);
GroundConfig, GroundRange, /*bShouldCreateCollision*/ bWantsCollision);
}
if (bHasCeilingTris)
{
FRealtimeMeshSectionConfig CapConfig(1);
CapConfig.bCastsShadow = false; // the cap never casts (see above)
RTMesh->UpdateSectionConfig(
const FRealtimeMeshStreamRange CapRange =
URealtimeMeshBlueprintFunctionLibrary::MakeStreamRange(
0, Result.NumVertices, FirstCapIndex, NumIndices);
RTMesh->CreateSection(
FRealtimeMeshSectionKey::CreateForPolyGroup(GroupKey, 1),
CapConfig, /*bShouldCreateCollision*/ bWantsCollision);
CapConfig, CapRange, /*bShouldCreateCollision*/ bWantsCollision);
}
const double CollisionConfigSeconds = bProfileApply
? FPlatformTime::ToSeconds64(FPlatformTime::Cycles64() - CollisionConfigStartCycles)