perf(generation): per-tile reach test skips landing and structural posts -- ~12% less worker CPU

The remove-one ablation put landing posts at ~10% and passage structural posts at ~6% of worker
time, though landings exist only near passage ends and the origin. The parked exact-cull round's
per-SAMPLE post bounds had been a net loss. This round decides reach once per TILE (Codex;
reviewed by me).

- VoxelTilePostReach.h: one per-tile reach mask (thread-local byte), set when the tile is set
  up. The origin landing, passage landing SDF/floors, native floors, tunnel air and passage
  structural posts return their input unchanged on tiles no instance can reach. Per sample this
  costs an inline flag read.
- Reach proofs come from each post's geometry (origin rooms, landing SDF and floors, native floor
  band, structural support spheres), not from comments.
- voxel.TilePostReachDebug=1 evaluates the skipped posts anyway and compares the FINAL field;
  voxel.TilePostReachScale=0.5 deliberately shrinks the reach and must fail.

Default build: 694 tiles, landing reachable on 4 (skipped on 690), structural posts skipped on 169.
Soundness: 123,958,673 comparisons, 0 differences; shrunk reach: 13,929 differences, FAIL as
required.

Final DEFAULT build vs the committed-tip DLL (same command line, two interleaved runs each):
  static  worker 34.80 -> 30.52 s (-12%)   LOD0 generation p50/p95 67.0/107.6 -> 55.8/95.8 ms
  moving  worker 75.96 -> 66.66 s (-12%)   LOD0 generation p50/p95 66.3/106.0 -> 56.0/95.8 ms
Field exact: 841/841 keyed tiles vs a fresh committed-tip trace (669,902 triangles, which includes
9260775's gap floors), export b3e5f4c3..9b377, capability 20,830 / 10,909; strate-crossing and
sealed-proof tests pass.
Ledger: all launches passed or failed where designed to; early raw-SDF debug attempts failed
until the comparator was corrected to compare the final field. No crash folders.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TaFdXhTdYMkW1xrV6ApT6Y
This commit is contained in:
Fr0zkaandClaude Opus 5 committed 2026-09-15 07:42:13 +02:00
1 parent 92607751b1
commit ce4d8783e9
7 files changed
+785 -15

No files matched your search

@@ -4,6 +4,8 @@
#include "VoxelMarchingCubesMesher.h" #include "VoxelMarchingCubesMesher.h"
#include "MarchingCubesTables.h" #include "MarchingCubesTables.h"
#include "VoxelDensityProfile.h" #include "VoxelDensityProfile.h"
#include "VoxelStrateManager.h"
#include "VoxelTilePostReach.h"
#include "ProfilingDebugging/CpuProfilerTrace.h" #include "ProfilingDebugging/CpuProfilerTrace.h"
#include "HAL/IConsoleManager.h" #include "HAL/IConsoleManager.h"
#include "Misc/CommandLine.h" #include "Misc/CommandLine.h"
@@ -17,6 +19,45 @@ namespace
TEXT("Use the operator-major density block path for non-shared mesher grids.")); TEXT("Use the operator-major density block path for non-shared mesher grids."));
bool GVoxelForgeBlockSwitchParsed = false; bool GVoxelForgeBlockSwitchParsed = false;
int32 GVoxelForgeTilePostReachDebug = 0;
FAutoConsoleVariableRef CVarVoxelForgeTilePostReachDebug(
TEXT("voxel.TilePostReachDebug"),
GVoxelForgeTilePostReachDebug,
TEXT("Run skipped landing/structural posts in a bypass and compare their exact result; "
"a nonzero difference fails the debug run."));
float GVoxelForgeTilePostReachScale = 1.0f;
FAutoConsoleVariableRef CVarVoxelForgeTilePostReachScale(
TEXT("voxel.TilePostReachScale"),
GVoxelForgeTilePostReachScale,
TEXT("Scale the per-tile post reach for deliberate soundness tests. Default 1.0 is exact; "
"values below 1 intentionally shrink the guard."));
bool GVoxelForgeTilePostReachSwitchesParsed = false;
void VF_ParseTilePostReachSwitches()
{
if (GVoxelForgeTilePostReachSwitchesParsed)
{
return;
}
GVoxelForgeTilePostReachSwitchesParsed = true;
int32 DebugValue = GVoxelForgeTilePostReachDebug;
float ScaleValue = GVoxelForgeTilePostReachScale;
FParse::Value(
FCommandLine::Get(), TEXT("voxel.TilePostReachDebug="), DebugValue);
FParse::Value(
FCommandLine::Get(), TEXT("voxel.TilePostReachScale="), ScaleValue);
GVoxelForgeTilePostReachDebug = DebugValue != 0 ? 1 : 0;
if (!VoxelMath::IsFinite(ScaleValue) || ScaleValue <= 0.0f)
{
ScaleValue = 1.0f;
}
GVoxelForgeTilePostReachScale = FMath::Min(ScaleValue, 1.0f);
VoxelGenLOD::GTilePostReachDebugEnabled.store(
GVoxelForgeTilePostReachDebug != 0, std::memory_order_relaxed);
}
void VF_ParseOperatorBlockSwitch() void VF_ParseOperatorBlockSwitch()
{ {
if (GVoxelForgeBlockSwitchParsed) { return; } if (GVoxelForgeBlockSwitchParsed) { return; }
@@ -42,6 +83,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
{ {
TRACE_CPUPROFILER_EVENT_SCOPE(VoxelForge_MesherGenerateMesh); TRACE_CPUPROFILER_EVENT_SCOPE(VoxelForge_MesherGenerateMesh);
VF_ParseOperatorBlockSwitch(); VF_ParseOperatorBlockSwitch();
VF_ParseTilePostReachSwitches();
FVoxelMeshData MeshData; FVoxelMeshData MeshData;
if (OutCaptureGrid) { OutCaptureGrid->Reset(); } if (OutCaptureGrid) { OutCaptureGrid->Reset(); }
if (OutDensitySampleCount) { *OutDensitySampleCount = 0; } if (OutDensitySampleCount) { *OutDensitySampleCount = 0; }
@@ -233,6 +275,49 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
VoxelGenLOD::TileOriginVoxels, OriginVoxels); VoxelGenLOD::TileOriginVoxels, OriginVoxels);
TGuardValue<int32> TileCellsGuard( TGuardValue<int32> TileCellsGuard(
VoxelGenLOD::TileCellsPerAxis, CellsPerAxis); VoxelGenLOD::TileCellsPerAxis, CellsPerAxis);
// Every density sample in this tile sees the same post-reach decision. The one-point halo
// matches the actual grid fill below (gx/gy/gz = -1..GridDim), so a false bit proves that no
// landing or passage structural writer can reach any sample used by meshing or gradients.
TGuardValue<bool> TilePostReachDebugGuard(
VoxelGenLOD::bTilePostReachDebug,
GVoxelForgeTilePostReachDebug != 0);
TGuardValue<bool> TilePostReachBypassGuard(
VoxelGenLOD::bTilePostReachBypass, false);
uint8 TilePostReachFlags = VoxelGenLOD::AllTilePostReach;
if (Generator->StrateManager != nullptr)
{
const int64 Extent = static_cast<int64>(CellsPerAxis + 1) * Step;
const FBox LatticeWithHalo(
FVector(
static_cast<float>(static_cast<int64>(OriginVoxels.X) - Step),
static_cast<float>(static_cast<int64>(OriginVoxels.Y) - Step),
static_cast<float>(static_cast<int64>(OriginVoxels.Z) - Step)),
FVector(
static_cast<float>(static_cast<int64>(OriginVoxels.X) + Extent),
static_cast<float>(static_cast<int64>(OriginVoxels.Y) + Extent),
static_cast<float>(static_cast<int64>(OriginVoxels.Z) + Extent)));
const float ReachScale = GVoxelForgeTilePostReachScale;
TilePostReachFlags = 0;
if (Generator->StrateManager->AnyOriginLandingNearLattice(
LatticeWithHalo, OriginVoxels, Step, ReachScale))
{
TilePostReachFlags |= VoxelGenLOD::OriginLandingReachable;
}
if (Generator->StrateManager->AnyPassageLandingNearLattice(
LatticeWithHalo, OriginVoxels, Step, ReachScale))
{
TilePostReachFlags |= VoxelGenLOD::PassageLandingReachable;
}
if (Generator->StrateManager->AnyPassageStructuralPostNearLattice(
LatticeWithHalo, OriginVoxels, Step, ReachScale))
{
TilePostReachFlags |= VoxelGenLOD::PassageStructuralReachable;
}
}
TGuardValue<uint8> TilePostReachFlagsGuard(
VoxelGenLOD::TilePostReachFlags, TilePostReachFlags);
VoxelGenLOD::RecordTileReachMask(TilePostReachFlags);
// COUPE DE CONTENU PAR STRATE — restreint le maillage (et l'échantillonnage) aux cellules // COUPE DE CONTENU PAR STRATE — restreint le maillage (et l'échantillonnage) aux cellules
// dont l'intervalle Z chevauche la bande [BandZMinVox, BandZMaxVox] (voxels inclusifs). // dont l'intervalle Z chevauche la bande [BandZMinVox, BandZMaxVox] (voxels inclusifs).
// Les tuiles à capture ne sont jamais bandées (niveau 0 — garde-fou ci-dessous). // Les tuiles à capture ne sont jamais bandées (niveau 0 — garde-fou ci-dessous).
+382 -12
View File
@@ -2511,6 +2511,12 @@ float UVoxelStrateManager::EvaluateModifierSDF(float WorldX, float WorldY, float
return FLT_MAX; return FLT_MAX;
} }
// The landing terms are part of the passage modifier, so their reach proof is deliberately
// wider than the direct post's four-voxel blend: SmoothMin can lower a finite term by K/6 at
// each later combine. Outside that padded room domain, omitting the two landing evaluations
// is an identity for VF_ApplyPassageCarving.
const bool bEvaluateLandingSDF = VoxelGenLOD::IsPassageLandingReachable()
|| VoxelGenLOD::IsTilePostReachBypassActive();
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
@@ -2602,11 +2608,14 @@ float UVoxelStrateManager::EvaluateModifierSDF(float WorldX, float WorldY, float
// A landing is a real room with a hard flat-floor half-space, not a sphere around the // A landing is a real room with a hard flat-floor half-space, not a sphere around the
// tube endpoint. It is the same fixed SDF geometry selected during GeneratePassages; it // tube endpoint. It is the same fixed SDF geometry selected during GeneratePassages; it
// never performs a source query here and does not synthesize a radial root connector. // never performs a source query here and does not synthesize a radial root connector.
if (bEvaluateLandingSDF)
{
const float UpperLandingSDF = VF_EvaluatePassageLandingSDF(Pos, P.UpperLanding); const float UpperLandingSDF = VF_EvaluatePassageLandingSDF(Pos, P.UpperLanding);
const float LowerLandingSDF = VF_EvaluatePassageLandingSDF(Pos, P.LowerLanding); const float LowerLandingSDF = VF_EvaluatePassageLandingSDF(Pos, P.LowerLanding);
MinSDF = VoxelSDF::SmoothMin(MinSDF, UpperLandingSDF, BlendK); MinSDF = VoxelSDF::SmoothMin(MinSDF, UpperLandingSDF, BlendK);
MinSDF = VoxelSDF::SmoothMin(MinSDF, LowerLandingSDF, BlendK); MinSDF = VoxelSDF::SmoothMin(MinSDF, LowerLandingSDF, BlendK);
} }
}
return MinSDF; return MinSDF;
} }
@@ -2617,13 +2626,41 @@ void UVoxelStrateManager::ApplyPassageModifier(
{ {
VoxelDensityProfile::FScopedTimer ProfileTimer( VoxelDensityProfile::FScopedTimer ProfileTimer(
VoxelDensityProfile::EBucket::PassageModifier); VoxelDensityProfile::EBucket::PassageModifier);
const bool bBypass = VoxelGenLOD::IsTilePostReachBypassActive();
const bool bCompareLandingModifier = VoxelGenLOD::bTilePostReachDebug
&& !VoxelGenLOD::IsPassageLandingReachable() && !bBypass;
float CanonicalModifierDensity = Density;
if (bCompareLandingModifier)
{
const bool PreviousBypass = VoxelGenLOD::bTilePostReachBypass;
VoxelGenLOD::bTilePostReachBypass = true;
const float CanonicalSDF = EvaluateModifierSDF(WorldX, WorldY, WorldZ);
VF_ApplyPassageCarving(
CanonicalModifierDensity, CanonicalSDF, BaseDensity, SealThickness);
VoxelGenLOD::bTilePostReachBypass = PreviousBypass;
}
if (!VoxelDensityAblation::IsPassageCarvingOff()) if (!VoxelDensityAblation::IsPassageCarvingOff())
{ {
const float ModSDF = EvaluateModifierSDF(WorldX, WorldY, WorldZ); const float ModSDF = EvaluateModifierSDF(WorldX, WorldY, WorldZ);
VF_ApplyPassageCarving(Density, ModSDF, BaseDensity, SealThickness); VF_ApplyPassageCarving(Density, ModSDF, BaseDensity, SealThickness);
} }
if (bCompareLandingModifier)
{
VoxelGenLOD::RecordSkippedPostComparison(
VoxelGenLOD::ETilePostComparisonKind::PassageLandingSDF,
!VoxelGenLOD::SameFloatBits(Density, CanonicalModifierDensity));
}
ApplyPassageLandingAir(Density, WorldX, WorldY, WorldZ, BaseDensity, SealThickness); ApplyPassageLandingAir(Density, WorldX, WorldY, WorldZ, BaseDensity, SealThickness);
const bool bLandingReachable = VoxelGenLOD::IsPassageLandingReachable()
|| VoxelGenLOD::IsTilePostReachBypassActive();
const bool bStructuralReachable = VoxelGenLOD::IsPassageStructuralReachable()
|| VoxelGenLOD::IsTilePostReachBypassActive();
if (!bLandingReachable && !bStructuralReachable)
{
return;
}
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
@@ -2634,10 +2671,12 @@ void UVoxelStrateManager::ApplyPassageModifier(
for (const int32 PassageIndex : Nearby) for (const int32 PassageIndex : Nearby)
{ {
const FVoxelPassage& Passage = PassageData[PassageIndex]; const FVoxelPassage& Passage = PassageData[PassageIndex];
const bool bLandingFloor = !VoxelDensityAblation::IsLandingPostsOff() const bool bLandingFloor = bLandingReachable
&& !VoxelDensityAblation::IsLandingPostsOff()
&& (VF_IsPassageLandingFloor(Position, Passage.UpperLanding) && (VF_IsPassageLandingFloor(Position, Passage.UpperLanding)
|| VF_IsPassageLandingFloor(Position, Passage.LowerLanding)); || VF_IsPassageLandingFloor(Position, Passage.LowerLanding));
const bool bLegacySupportFloor = !VoxelDensityAblation::IsPassageStructuralPostsOff() const bool bLegacySupportFloor = bStructuralReachable
&& !VoxelDensityAblation::IsPassageStructuralPostsOff()
&& bPassageSupportFloorWritesEnabled && bPassageSupportFloorWritesEnabled
&& !Passage.bNativeFloorEnabled && !Passage.bNativeFloorEnabled
&& VF_IsWalkableTunnelFloor(Passage, Position, this, PassageIndex); && VF_IsWalkableTunnelFloor(Passage, Position, this, PassageIndex);
@@ -2656,7 +2695,10 @@ void UVoxelStrateManager::ApplyPassageModifier(
// the current walkable tunnel. Reassert tunnel air after all floor posts so overlap cannot // the current walkable tunnel. Reassert tunnel air after all floor posts so overlap cannot
// turn a valid route into a solid plug. At the tunnel's own floor the air predicate is false, // turn a valid route into a solid plug. At the tunnel's own floor the air predicate is false,
// so the support plane remains solid. // so the support plane remains solid.
if (bStructuralReachable)
{
ApplyPassageTunnelAir(Density, WorldX, WorldY, WorldZ, BaseDensity, SealThickness); ApplyPassageTunnelAir(Density, WorldX, WorldY, WorldZ, BaseDensity, SealThickness);
}
} }
void UVoxelStrateManager::ApplyPassageCarvingOnly( void UVoxelStrateManager::ApplyPassageCarvingOnly(
@@ -2669,8 +2711,27 @@ void UVoxelStrateManager::ApplyPassageCarvingOnly(
} }
VoxelDensityProfile::FScopedTimer ProfileTimer( VoxelDensityProfile::FScopedTimer ProfileTimer(
VoxelDensityProfile::EBucket::PassageModifier); VoxelDensityProfile::EBucket::PassageModifier);
const bool bBypass = VoxelGenLOD::IsTilePostReachBypassActive();
const bool bCompareLandingModifier = VoxelGenLOD::bTilePostReachDebug
&& !VoxelGenLOD::IsPassageLandingReachable() && !bBypass;
float CanonicalModifierDensity = Density;
if (bCompareLandingModifier)
{
const bool PreviousBypass = VoxelGenLOD::bTilePostReachBypass;
VoxelGenLOD::bTilePostReachBypass = true;
const float CanonicalSDF = EvaluateModifierSDF(WorldX, WorldY, WorldZ);
VF_ApplyPassageCarving(
CanonicalModifierDensity, CanonicalSDF, BaseDensity, SealThickness);
VoxelGenLOD::bTilePostReachBypass = PreviousBypass;
}
const float ModSDF = EvaluateModifierSDF(WorldX, WorldY, WorldZ); const float ModSDF = EvaluateModifierSDF(WorldX, WorldY, WorldZ);
VF_ApplyPassageCarving(Density, ModSDF, BaseDensity, SealThickness); VF_ApplyPassageCarving(Density, ModSDF, BaseDensity, SealThickness);
if (bCompareLandingModifier)
{
VoxelGenLOD::RecordSkippedPostComparison(
VoxelGenLOD::ETilePostComparisonKind::PassageLandingSDF,
!VoxelGenLOD::SameFloatBits(Density, CanonicalModifierDensity));
}
} }
void UVoxelStrateManager::ApplyPassageLandingAir( void UVoxelStrateManager::ApplyPassageLandingAir(
@@ -2681,6 +2742,16 @@ void UVoxelStrateManager::ApplyPassageLandingAir(
{ {
return; return;
} }
if (!VoxelGenLOD::IsPassageLandingReachable()
&& !VoxelGenLOD::IsTilePostReachBypassActive())
{
VoxelGenLOD::CompareSkippedPost(Density, [&]()
{
ApplyPassageLandingAir(
Density, WorldX, WorldY, WorldZ, BaseDensity, SealThickness);
}, VoxelGenLOD::ETilePostComparisonKind::PassageLandingAir);
return;
}
VoxelDensityProfile::FScopedTimer ProfileTimer( VoxelDensityProfile::FScopedTimer ProfileTimer(
VoxelDensityProfile::EBucket::PassageLandingAir); VoxelDensityProfile::EBucket::PassageLandingAir);
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
@@ -2749,6 +2820,16 @@ void UVoxelStrateManager::ApplyPassageTunnelAir(
{ {
return; return;
} }
if (!VoxelGenLOD::IsPassageStructuralReachable()
&& !VoxelGenLOD::IsTilePostReachBypassActive())
{
VoxelGenLOD::CompareSkippedPost(Density, [&]()
{
ApplyPassageTunnelAir(
Density, WorldX, WorldY, WorldZ, BaseDensity, SealThickness);
}, VoxelGenLOD::ETilePostComparisonKind::PassageTunnelAir);
return;
}
VoxelDensityProfile::FScopedTimer ProfileTimer( VoxelDensityProfile::FScopedTimer ProfileTimer(
VoxelDensityProfile::EBucket::PassageTunnelAir); VoxelDensityProfile::EBucket::PassageTunnelAir);
const FVector Position(WorldX, WorldY, WorldZ); const FVector Position(WorldX, WorldY, WorldZ);
@@ -2784,6 +2865,30 @@ void UVoxelStrateManager::ApplyPassageLandingFloorMC(
{ {
return; return;
} }
const bool bBypass = VoxelGenLOD::IsTilePostReachBypassActive();
const bool bLandingReachable = VoxelGenLOD::IsPassageLandingReachable() || bBypass;
const bool bStructuralReachable = VoxelGenLOD::IsPassageStructuralReachable() || bBypass;
const bool bCompareLanding = VoxelGenLOD::bTilePostReachDebug
&& !bLandingReachable && !bBypass;
float CanonicalDensity = Density;
if (bCompareLanding)
{
const bool PreviousBypass = VoxelGenLOD::bTilePostReachBypass;
VoxelGenLOD::bTilePostReachBypass = true;
ApplyPassageLandingFloorMC(
CanonicalDensity, WorldX, WorldY, WorldZ, BaseDensity);
VoxelGenLOD::bTilePostReachBypass = PreviousBypass;
}
if (!bLandingReachable && !bStructuralReachable)
{
if (bCompareLanding)
{
VoxelGenLOD::RecordSkippedPostComparison(
VoxelGenLOD::ETilePostComparisonKind::PassageLandingFloor,
!VoxelGenLOD::SameFloatBits(Density, CanonicalDensity));
}
return;
}
VoxelDensityProfile::FScopedTimer ProfileTimer( VoxelDensityProfile::FScopedTimer ProfileTimer(
VoxelDensityProfile::EBucket::PassageLandingFloor); VoxelDensityProfile::EBucket::PassageLandingFloor);
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
@@ -2796,10 +2901,12 @@ void UVoxelStrateManager::ApplyPassageLandingFloorMC(
for (const int32 PassageIndex : Nearby) for (const int32 PassageIndex : Nearby)
{ {
const FVoxelPassage& Passage = PassageData[PassageIndex]; const FVoxelPassage& Passage = PassageData[PassageIndex];
const bool bLandingFloor = !VoxelDensityAblation::IsLandingPostsOff() const bool bLandingFloor = bLandingReachable
&& !VoxelDensityAblation::IsLandingPostsOff()
&& (VF_IsPassageLandingFloor(Position, Passage.UpperLanding) && (VF_IsPassageLandingFloor(Position, Passage.UpperLanding)
|| VF_IsPassageLandingFloor(Position, Passage.LowerLanding)); || VF_IsPassageLandingFloor(Position, Passage.LowerLanding));
const bool bLegacySupportFloor = !VoxelDensityAblation::IsPassageStructuralPostsOff() const bool bLegacySupportFloor = bStructuralReachable
&& !VoxelDensityAblation::IsPassageStructuralPostsOff()
&& bPassageSupportFloorWritesEnabled && bPassageSupportFloorWritesEnabled
&& !Passage.bNativeFloorEnabled && !Passage.bNativeFloorEnabled
&& VF_IsWalkableTunnelFloor(Passage, Position, this, PassageIndex); && VF_IsWalkableTunnelFloor(Passage, Position, this, PassageIndex);
@@ -2812,6 +2919,12 @@ void UVoxelStrateManager::ApplyPassageLandingFloorMC(
break; break;
} }
} }
if (bCompareLanding)
{
VoxelGenLOD::RecordSkippedPostComparison(
VoxelGenLOD::ETilePostComparisonKind::PassageLandingFloor,
!VoxelGenLOD::SameFloatBits(Density, CanonicalDensity));
}
} }
static bool VF_IsPassageRoomFloor( static bool VF_IsPassageRoomFloor(
@@ -2844,6 +2957,32 @@ void UVoxelStrateManager::ApplyPassageStructuralPostsMC(
return; return;
} }
const bool bBypass = VoxelGenLOD::IsTilePostReachBypassActive();
const bool bLandingReachable = VoxelGenLOD::IsPassageLandingReachable() || bBypass;
const bool bStructuralReachable = VoxelGenLOD::IsPassageStructuralReachable() || bBypass;
const bool bCompareLanding = VoxelGenLOD::bTilePostReachDebug
&& !bLandingReachable && !bBypass;
float CanonicalDensity = Density;
if (bCompareLanding)
{
const bool PreviousBypass = VoxelGenLOD::bTilePostReachBypass;
VoxelGenLOD::bTilePostReachBypass = true;
ApplyPassageStructuralPostsMC(
CanonicalDensity, WorldX, WorldY, WorldZ,
BaseDensity, SealThickness, bProtectAuthoredTunnelFloor);
VoxelGenLOD::bTilePostReachBypass = PreviousBypass;
}
if (!bLandingReachable && !bStructuralReachable)
{
if (bCompareLanding)
{
VoxelGenLOD::RecordSkippedPostComparison(
VoxelGenLOD::ETilePostComparisonKind::PassageStructuralPosts,
!VoxelGenLOD::SameFloatBits(Density, CanonicalDensity));
}
return;
}
VoxelDensityProfile::FScopedTimer ProfileTimer( VoxelDensityProfile::FScopedTimer ProfileTimer(
VoxelDensityProfile::EBucket::PassageStructuralPosts); VoxelDensityProfile::EBucket::PassageStructuralPosts);
@@ -2873,36 +3012,37 @@ void UVoxelStrateManager::ApplyPassageStructuralPostsMC(
const FVoxelPassage& Passage = PassageData[PassageIndex]; const FVoxelPassage& Passage = PassageData[PassageIndex];
const bool bTunnelSupportFloor = const bool bTunnelSupportFloor =
!bDisableStructuralPosts bStructuralReachable && !bDisableStructuralPosts
&& bPassageSupportFloorWritesEnabled && bPassageSupportFloorWritesEnabled
&& !Passage.bNativeFloorEnabled && !Passage.bNativeFloorEnabled
&& VF_IsWalkableTunnelFloor(Passage, Position, this, PassageIndex); && VF_IsWalkableTunnelFloor(Passage, Position, this, PassageIndex);
if (!bSuppressFloor && !bDisableLandingPosts if (!bSuppressFloor && bLandingReachable && !bDisableLandingPosts
&& (VF_IsPassageLandingFloor(Position, Passage.UpperLanding) && (VF_IsPassageLandingFloor(Position, Passage.UpperLanding)
|| VF_IsPassageLandingFloor(Position, Passage.LowerLanding))) || VF_IsPassageLandingFloor(Position, Passage.LowerLanding)))
{ {
bAnyLandingFloor = true; bAnyLandingFloor = true;
} }
if (!bSuppressFloor && !bDisableStructuralPosts && bTunnelSupportFloor) if (!bSuppressFloor && bStructuralReachable
&& !bDisableStructuralPosts && bTunnelSupportFloor)
{ {
bLegacyTunnelSupportFloor = true; bLegacyTunnelSupportFloor = true;
} }
if (!bSuppressFloor && !bDisableLandingPosts if (!bSuppressFloor && bLandingReachable && !bDisableLandingPosts
&& (VF_IsPassageRoomFloor(Position, Passage.UpperLanding) && (VF_IsPassageRoomFloor(Position, Passage.UpperLanding)
|| VF_IsPassageRoomFloor(Position, Passage.LowerLanding))) || VF_IsPassageRoomFloor(Position, Passage.LowerLanding)))
{ {
bAnyRoomFloor = true; bAnyRoomFloor = true;
} }
if (!bDisableStructuralPosts && !bWalkableAir if (bStructuralReachable && !bDisableStructuralPosts && !bWalkableAir
&& FVector::DistSquared(Position, Passage.BoundCenter) <= Passage.BoundRadiusSq && FVector::DistSquared(Position, Passage.BoundCenter) <= Passage.BoundRadiusSq
&& VF_IsWalkableTunnelAir(Passage, Position, this, PassageIndex)) && VF_IsWalkableTunnelAir(Passage, Position, this, PassageIndex))
{ {
bWalkableAir = true; bWalkableAir = true;
} }
if (!bDisableLandingPosts if (bLandingReachable && !bDisableLandingPosts
&& FVector::DistSquared(Position, Passage.BoundCenter) <= Passage.BoundRadiusSq) && FVector::DistSquared(Position, Passage.BoundCenter) <= Passage.BoundRadiusSq)
{ {
const FVoxelPassageLanding* Landings[] = { const FVoxelPassageLanding* Landings[] = {
@@ -2950,6 +3090,12 @@ void UVoxelStrateManager::ApplyPassageStructuralPostsMC(
VoxelDensityProfile::AddCounter( VoxelDensityProfile::AddCounter(
VoxelDensityProfile::ECounter::PassageSupportFloorBackstopFires); VoxelDensityProfile::ECounter::PassageSupportFloorBackstopFires);
} }
if (bCompareLanding)
{
VoxelGenLOD::RecordSkippedPostComparison(
VoxelGenLOD::ETilePostComparisonKind::PassageStructuralPosts,
!VoxelGenLOD::SameFloatBits(Density, CanonicalDensity));
}
} }
void UVoxelStrateManager::ApplyPassageNativeFloorMC( void UVoxelStrateManager::ApplyPassageNativeFloorMC(
@@ -2960,6 +3106,15 @@ void UVoxelStrateManager::ApplyPassageNativeFloorMC(
{ {
return; return;
} }
if (!VoxelGenLOD::IsPassageStructuralReachable()
&& !VoxelGenLOD::IsTilePostReachBypassActive())
{
VoxelGenLOD::CompareSkippedPost(Density, [&]()
{
ApplyPassageNativeFloorMC(Density, WorldX, WorldY, WorldZ, BaseDensity);
}, VoxelGenLOD::ETilePostComparisonKind::PassageNativeFloor);
return;
}
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
FMath::FloorToInt(WorldX / (float)CHUNK_SIZE), FMath::FloorToInt(WorldX / (float)CHUNK_SIZE),
FMath::FloorToInt(WorldY / (float)CHUNK_SIZE), FMath::FloorToInt(WorldY / (float)CHUNK_SIZE),
@@ -3018,6 +3173,16 @@ void UVoxelStrateManager::ApplyPassageLandingRoomFloorMC(
{ {
return; return;
} }
if (!VoxelGenLOD::IsPassageLandingReachable()
&& !VoxelGenLOD::IsTilePostReachBypassActive())
{
VoxelGenLOD::CompareSkippedPost(Density, [&]()
{
ApplyPassageLandingRoomFloorMC(
Density, WorldX, WorldY, WorldZ, BaseDensity);
}, VoxelGenLOD::ETilePostComparisonKind::PassageLandingRoomFloor);
return;
}
VoxelDensityProfile::FScopedTimer ProfileTimer( VoxelDensityProfile::FScopedTimer ProfileTimer(
VoxelDensityProfile::EBucket::PassageLandingRoomFloor); VoxelDensityProfile::EBucket::PassageLandingRoomFloor);
const FIntVector ChunkCoord( const FIntVector ChunkCoord(
@@ -3912,6 +4077,22 @@ namespace
FMath::Min((float)Box.Max.Z, MaxZ), FMath::Min((float)Box.Max.Z, MaxZ),
(float)Origin.Z, Step); (float)Origin.Z, Step);
} }
static bool VF_LatticeBoxTouchesSphere(
const FBox& Box, const FVector& Center, float Radius)
{
if (!Box.IsValid || !VoxelMath::IsFinite(Center.X)
|| !VoxelMath::IsFinite(Center.Y) || !VoxelMath::IsFinite(Center.Z)
|| !VoxelMath::IsFinite(Radius) || Radius < 0.0f)
{
return true;
}
const FVector Closest(
FMath::Clamp(Center.X, (float)Box.Min.X, (float)Box.Max.X),
FMath::Clamp(Center.Y, (float)Box.Min.Y, (float)Box.Max.Y),
FMath::Clamp(Center.Z, (float)Box.Min.Z, (float)Box.Max.Z));
return FVector::DistSquared(Closest, Center) <= Radius * Radius;
}
} }
bool UVoxelStrateManager::AnyPassageNearLattice( bool UVoxelStrateManager::AnyPassageNearLattice(
@@ -4768,6 +4949,189 @@ bool UVoxelStrateManager::AnyPassageLandingFloorNearLattice(
return false; return false;
} }
bool UVoxelStrateManager::AnyPassageLandingNearLattice(
const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step,
float ReachScale) const
{
if (Step <= 0 || !VoxelBox.IsValid
|| !VoxelMath::IsFinite(ReachScale) || ReachScale <= 0.0f)
{
return true;
}
// VF_ApplyPassageCarving has a hard no-op band at ModSDF >= 4. A landing term outside the
// rounded-room AABB by 4 + K (K=3) is either saturated out of SmoothMin when the tube is
// inside the carve band, or leaves the folded result >= 4 when the tube is outside it. That
// proves the landing term cannot change the field; the direct landing/floor posts use their
// smaller, operation-specific pads below.
for (const FVoxelPassage& Passage : Passages)
{
if (!VoxelMath::IsFinite(Passage.BoundCenter.X)
|| !VoxelMath::IsFinite(Passage.BoundCenter.Y)
|| !VoxelMath::IsFinite(Passage.BoundCenter.Z)
|| !VoxelMath::IsFinite(Passage.BoundRadius)
|| !VoxelMath::IsFinite(Passage.BoundRadiusSq)
|| Passage.BoundRadius < 0.0f || Passage.BoundRadiusSq < 0.0f)
{
return true;
}
if (Passage.ControlPoints.Num() >= 2)
{
if (Passage.ControlPoints.Num() > 4096)
{
return true;
}
const bool bTaper = Passage.ControlRadii.Num() == Passage.ControlPoints.Num();
if (!bTaper && !VoxelMath::IsFinite(Passage.Radius))
{
return true;
}
for (int32 PointIndex = 0;
PointIndex < Passage.ControlPoints.Num(); ++PointIndex)
{
const FVector& Point = Passage.ControlPoints[PointIndex];
if (!VoxelMath::IsFinite(Point.X) || !VoxelMath::IsFinite(Point.Y)
|| !VoxelMath::IsFinite(Point.Z)
|| (bTaper && !VoxelMath::IsFinite(Passage.ControlRadii[PointIndex])))
{
return true;
}
}
}
else
{
if (!VoxelMath::IsFinite(Passage.UpperPoint.X)
|| !VoxelMath::IsFinite(Passage.UpperPoint.Y)
|| !VoxelMath::IsFinite(Passage.UpperPoint.Z)
|| !VoxelMath::IsFinite(Passage.LowerPoint.X)
|| !VoxelMath::IsFinite(Passage.LowerPoint.Y)
|| !VoxelMath::IsFinite(Passage.LowerPoint.Z)
|| !VoxelMath::IsFinite(Passage.Radius))
{
return true;
}
}
const FVoxelPassageLanding* Landings[] = {
&Passage.UpperLanding, &Passage.LowerLanding };
for (const FVoxelPassageLanding* Landing : Landings)
{
if (!VoxelMath::IsFinite(Landing->StandingPoint.X)
|| !VoxelMath::IsFinite(Landing->StandingPoint.Y)
|| !VoxelMath::IsFinite(Landing->FloorZ)
|| !VoxelMath::IsFinite(Landing->CeilingZ)
|| !VoxelMath::IsFinite(Landing->HalfWidth)
|| !VoxelMath::IsFinite(Landing->FloorThickness))
{
return true;
}
if (Landing->HalfWidth > 0.0f
&& Landing->FloorThickness > 0.0f
&& VF_LatticeBoxTouchesAABB(
VoxelBox, LatticeOrigin, Step,
Landing->StandingPoint.X - FMath::Max(Landing->HalfWidth - 1.0f, 0.0f)
- ReachScale,
Landing->StandingPoint.X + FMath::Max(Landing->HalfWidth - 1.0f, 0.0f)
+ ReachScale,
Landing->StandingPoint.Y - FMath::Max(Landing->HalfWidth - 1.0f, 0.0f)
- ReachScale,
Landing->StandingPoint.Y + FMath::Max(Landing->HalfWidth - 1.0f, 0.0f)
+ ReachScale,
Landing->FloorZ - Landing->FloorThickness - ReachScale,
Landing->FloorZ + ReachScale))
{
return true;
}
if (Landing->HalfWidth <= 0.0f || Landing->CeilingZ <= Landing->FloorZ)
{
// VF_EvaluatePassageLandingSDF returns FLT_MAX for this descriptor. The floor
// test above has already handled the only remaining possible writer.
continue;
}
}
}
constexpr float SmoothMinK = 3.0f;
const float RoomPad = (VoxelPassageGeometry::LandingCarveBlendVoxels + SmoothMinK)
* ReachScale;
if (!VoxelMath::IsFinite(RoomPad) || RoomPad < 0.0f)
{
return true;
}
for (const FVoxelPassage& Passage : Passages)
{
const FVoxelPassageLanding* Landings[] = {
&Passage.UpperLanding, &Passage.LowerLanding };
for (const FVoxelPassageLanding* Landing : Landings)
{
if (Landing->HalfWidth <= 0.0f || Landing->CeilingZ <= Landing->FloorZ)
{
continue;
}
constexpr float RoomRounding = 1.5f;
const float Height = Landing->CeilingZ - Landing->FloorZ;
const float HalfX = FMath::Max(Landing->HalfWidth - RoomRounding, 0.25f);
const float HalfZ = FMath::Max(Height * 0.5f - RoomRounding, 0.25f);
const float CenterZ = (Landing->FloorZ + Landing->CeilingZ) * 0.5f;
if (VF_LatticeBoxTouchesAABB(
VoxelBox, LatticeOrigin, Step,
Landing->StandingPoint.X - HalfX - RoomRounding - RoomPad,
Landing->StandingPoint.X + HalfX + RoomRounding + RoomPad,
Landing->StandingPoint.Y - HalfX - RoomRounding - RoomPad,
Landing->StandingPoint.Y + HalfX + RoomRounding + RoomPad,
FMath::Min(Landing->FloorZ,
CenterZ - HalfZ - RoomRounding) - RoomPad,
FMath::Max(Landing->CeilingZ,
CenterZ + HalfZ + RoomRounding) + RoomPad))
{
return true;
}
}
}
return false;
}
bool UVoxelStrateManager::AnyPassageStructuralPostNearLattice(
const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step,
float ReachScale) const
{
(void)LatticeOrigin;
(void)Step;
if (Step <= 0 || !VoxelBox.IsValid
|| !VoxelMath::IsFinite(ReachScale) || ReachScale <= 0.0f)
{
return true;
}
// The construction-time BoundRadius encloses every tube, landing room, floor band, and its
// four-voxel carve margin. All structural writers below are subsets of that sphere, so a
// sphere/AABB miss proves identity without doing a per-sample chunk-shortlist lookup.
for (const FVoxelPassage& Passage : Passages)
{
if (!VoxelMath::IsFinite(Passage.BoundCenter.X)
|| !VoxelMath::IsFinite(Passage.BoundCenter.Y)
|| !VoxelMath::IsFinite(Passage.BoundCenter.Z)
|| !VoxelMath::IsFinite(Passage.BoundRadius)
|| !VoxelMath::IsFinite(Passage.BoundRadiusSq)
|| Passage.BoundRadius < 0.0f || Passage.BoundRadiusSq < 0.0f)
{
return true;
}
const float Reach = (Passage.BoundRadius + 1.0f) * ReachScale;
if (!VoxelMath::IsFinite(Reach)
|| VF_LatticeBoxTouchesSphere(VoxelBox, Passage.BoundCenter, Reach))
{
return true;
}
}
return false;
}
bool UVoxelStrateManager::AnyLandingFloorAtLattice( bool UVoxelStrateManager::AnyLandingFloorAtLattice(
const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step) const const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step) const
{ {
@@ -5013,9 +5377,14 @@ bool UVoxelStrateManager::AnyOriginLandingFloorNearBox(
} }
bool UVoxelStrateManager::AnyOriginLandingNearLattice( bool UVoxelStrateManager::AnyOriginLandingNearLattice(
const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step) const const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step,
float ReachScale) const
{ {
if (OriginSpineRadius <= 0.0f) return false; if (OriginSpineRadius <= 0.0f) return false;
if (!VoxelMath::IsFinite(ReachScale) || ReachScale <= 0.0f)
{
return true;
}
for (const FStrateSlot& Slot : StrateLayout) for (const FStrateSlot& Slot : StrateLayout)
{ {
if (Slot.Definition == nullptr) continue; if (Slot.Definition == nullptr) continue;
@@ -5023,7 +5392,8 @@ bool UVoxelStrateManager::AnyOriginLandingNearLattice(
const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE; const float BottomZ = static_cast<float>(Slot.BottomChunkZ) * CHUNK_SIZE;
const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition); const float Seal = VF_BoundarySealThicknessForDefinition(*Slot.Definition);
if (VoxelPassageGeometry::OriginLandingRoomTouchesLattice( if (VoxelPassageGeometry::OriginLandingRoomTouchesLattice(
VoxelBox, LatticeOrigin, Step, TopZ, BottomZ, Seal, OriginSpineRadius)) VoxelBox, LatticeOrigin, Step, TopZ, BottomZ, Seal, OriginSpineRadius,
ReachScale))
{ {
return true; return true;
} }
+93
View File
@@ -19,6 +19,7 @@
#include "VoxelStats.h" #include "VoxelStats.h"
#include "VoxelCaveMorphology.h" #include "VoxelCaveMorphology.h"
#include "VoxelPassageGeometry.h" #include "VoxelPassageGeometry.h"
#include "VoxelTilePostReach.h"
// IWYU (FPSemantics = Precise ⇒ plus de PCH partagé) : GetPlayerPosition déréférence le pawn, donc // 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 était // APawn doit être COMPLET — `Casts.h` n'en donne qu'une déclaration avant. APlayerController était
// complet par transitivité seulement : on l'inclut explicitement, c'est exactement la fragilité // complet par transitivité seulement : on l'inclut explicitement, c'est exactement la fragilité
@@ -1132,6 +1133,98 @@ void AVoxelWorld::EndPlay(const EEndPlayReason::Type EndPlayReason)
} }
VoxelCaveMorphology::LogPlayerFitMemoStats(); VoxelCaveMorphology::LogPlayerFitMemoStats();
LogStreamingLatencySummary(); LogStreamingLatencySummary();
const uint64 TilePostReachDifferences =
VoxelGenLOD::GSkippedPostDifferences.load(std::memory_order_relaxed);
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeTilePostReach] tiles=%llu origin_reachable=%llu origin_skipped=%llu "
"passage_landing_reachable=%llu passage_landing_skipped=%llu "
"passage_structural_reachable=%llu passage_structural_skipped=%llu "
"debug=%d comparisons=%llu differences=%llu"),
static_cast<unsigned long long>(
VoxelGenLOD::GTilePostReachTileCount.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(
VoxelGenLOD::GOriginLandingReachableTiles.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(
VoxelGenLOD::GOriginLandingSkippedTiles.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(
VoxelGenLOD::GPassageLandingReachableTiles.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(
VoxelGenLOD::GPassageLandingSkippedTiles.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(
VoxelGenLOD::GPassageStructuralReachableTiles.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(
VoxelGenLOD::GPassageStructuralSkippedTiles.load(std::memory_order_relaxed)),
VoxelGenLOD::GTilePostReachDebugEnabled.load(std::memory_order_relaxed) ? 1 : 0,
static_cast<unsigned long long>(
VoxelGenLOD::GSkippedPostComparisons.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(TilePostReachDifferences));
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeTilePostReachKinds] comparisons="
"origin_air=%llu/origin_floor=%llu/passage_sdf=%llu/landing_air=%llu/"
"tunnel_air=%llu/landing_floor=%llu/structural=%llu/native_floor=%llu/room_floor=%llu "
"differences=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu"),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::OriginAir)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::OriginFloor)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingSDF)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingAir)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageTunnelAir)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingFloor)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageStructuralPosts)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageNativeFloor)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostComparisonsByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingRoomFloor)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::OriginAir)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::OriginFloor)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingSDF)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingAir)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageTunnelAir)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingFloor)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageStructuralPosts)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageNativeFloor)].load(
std::memory_order_relaxed)),
static_cast<unsigned long long>(VoxelGenLOD::GSkippedPostDifferencesByKind[
static_cast<uint8>(VoxelGenLOD::ETilePostComparisonKind::PassageLandingRoomFloor)].load(
std::memory_order_relaxed)));
if (VoxelGenLOD::GTilePostReachDebugEnabled.load(std::memory_order_relaxed)
&& TilePostReachDifferences != 0)
{
UE_LOG(LogTemp, Error,
TEXT("[VoxelForgeTilePostReach] soundness failure: skipped post changed the field."));
FPlatformMisc::RequestExitWithStatus(
false, 1, TEXT("VoxelForge tile post reach soundness failure"));
}
PendingTiles.Empty(); PendingTiles.Empty();
PendingTileCancellation.Empty(); PendingTileCancellation.Empty();
PendingUnload.Empty(); PendingUnload.Empty();
@@ -28,6 +28,7 @@
#include "VoxelTypes.h" // SmoothStep01 #include "VoxelTypes.h" // SmoothStep01
#include "VoxelPassageGeometry.h" // shared body-sized landing/tunnel geometry #include "VoxelPassageGeometry.h" // shared body-sized landing/tunnel geometry
#include "VoxelDensityAblation.h" // development-only world-changing measurements #include "VoxelDensityAblation.h" // development-only world-changing measurements
#include "VoxelTilePostReach.h" // worker-local landing/structural post reach bits
//============================================================================= //=============================================================================
// SEAL DE FRONTIÈRE / BOUNDARY SEAL // SEAL DE FRONTIÈRE / BOUNDARY SEAL
@@ -193,6 +194,17 @@ FORCEINLINE void VF_ApplyOriginLandingAirMC(float& Density,
float WorldX, float WorldY, float WorldZ, float WorldX, float WorldY, float WorldZ,
float StrateTopZ, float StrateBottomZ, float SealThickness, float BaseDensity, float Radius) float StrateTopZ, float StrateBottomZ, float SealThickness, float BaseDensity, float Radius)
{ {
if (!VoxelGenLOD::IsOriginLandingReachable()
&& !VoxelGenLOD::IsTilePostReachBypassActive())
{
VoxelGenLOD::CompareSkippedPost(Density, [&]()
{
VF_ApplyOriginLandingAirMC(
Density, WorldX, WorldY, WorldZ,
StrateTopZ, StrateBottomZ, SealThickness, BaseDensity, Radius);
}, VoxelGenLOD::ETilePostComparisonKind::OriginAir);
return;
}
float InternalDensity = -Density; float InternalDensity = -Density;
VF_ApplyOriginLandingAir(InternalDensity, WorldX, WorldY, WorldZ, VF_ApplyOriginLandingAir(InternalDensity, WorldX, WorldY, WorldZ,
StrateTopZ, StrateBottomZ, SealThickness, BaseDensity, Radius); StrateTopZ, StrateBottomZ, SealThickness, BaseDensity, Radius);
@@ -204,6 +216,17 @@ FORCEINLINE void VF_ApplyOriginLandingFloorMC(float& Density,
float WorldX, float WorldY, float WorldZ, float WorldX, float WorldY, float WorldZ,
float StrateTopZ, float StrateBottomZ, float SealThickness, float BaseDensity, float Radius) float StrateTopZ, float StrateBottomZ, float SealThickness, float BaseDensity, float Radius)
{ {
if (!VoxelGenLOD::IsOriginLandingReachable()
&& !VoxelGenLOD::IsTilePostReachBypassActive())
{
VoxelGenLOD::CompareSkippedPost(Density, [&]()
{
VF_ApplyOriginLandingFloorMC(
Density, WorldX, WorldY, WorldZ,
StrateTopZ, StrateBottomZ, SealThickness, BaseDensity, Radius);
}, VoxelGenLOD::ETilePostComparisonKind::OriginFloor);
return;
}
float InternalDensity = -Density; float InternalDensity = -Density;
VF_ApplyOriginLandingFloor(InternalDensity, WorldX, WorldY, WorldZ, VF_ApplyOriginLandingFloor(InternalDensity, WorldX, WorldY, WorldZ,
StrateTopZ, StrateBottomZ, SealThickness, BaseDensity, Radius); StrateTopZ, StrateBottomZ, SealThickness, BaseDensity, Radius);
@@ -471,13 +471,20 @@ namespace VoxelPassageGeometry
FORCEINLINE bool OriginLandingRoomTouchesLattice( FORCEINLINE bool OriginLandingRoomTouchesLattice(
const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step, const FBox& VoxelBox, const FIntVector& LatticeOrigin, int32 Step,
float StrateTopZ, float StrateBottomZ, float SealThickness, float OriginRadius) float StrateTopZ, float StrateBottomZ, float SealThickness, float OriginRadius,
float ReachScale = 1.0f)
{ {
if (!VoxelBox.IsValid) return false; if (!VoxelBox.IsValid) return false;
if (!VoxelMath::IsFinite(ReachScale) || ReachScale <= 0.0f)
{
// This is an invalid proof request, not an empty room. The manager treats a
// malformed scale as conservative/unknown before calling this helper.
return true;
}
const FOriginLandingGeometry Geometry = BuildOriginLandingGeometry( const FOriginLandingGeometry Geometry = BuildOriginLandingGeometry(
StrateTopZ, StrateBottomZ, SealThickness, OriginRadius); StrateTopZ, StrateBottomZ, SealThickness, OriginRadius);
if (!Geometry.bValid) return false; if (!Geometry.bValid) return false;
const float Pad = LandingCarveBlendVoxels; const float Pad = LandingCarveBlendVoxels * ReachScale;
return LatticeAxisHasSampleInInterval( return LatticeAxisHasSampleInInterval(
FMath::Max((float)VoxelBox.Min.X, -Geometry.HalfWidth - Pad), FMath::Max((float)VoxelBox.Min.X, -Geometry.HalfWidth - Pad),
FMath::Min((float)VoxelBox.Max.X, Geometry.HalfWidth + Pad), FMath::Min((float)VoxelBox.Max.X, Geometry.HalfWidth + Pad),
+10 -1
View File
@@ -472,6 +472,14 @@ public:
float BaseDensity, float SealThickness) const; float BaseDensity, float SealThickness) const;
bool AnyPassageLandingFloorNearLattice(const FBox& VoxelBox, bool AnyPassageLandingFloorNearLattice(const FBox& VoxelBox,
const FIntVector& LatticeOrigin, int32 Step) const; const FIntVector& LatticeOrigin, int32 Step) const;
/** Conservative landing-room plus floor reach for the exact MC lattice and its halo. */
bool AnyPassageLandingNearLattice(const FBox& VoxelBox,
const FIntVector& LatticeOrigin, int32 Step,
float ReachScale = 1.0f) const;
/** Conservative sphere guard for all passage-owned structural posts and native D-floors. */
bool AnyPassageStructuralPostNearLattice(const FBox& VoxelBox,
const FIntVector& LatticeOrigin, int32 Step,
float ReachScale = 1.0f) const;
/** Exact presence test for a structural floor write on the MC lattice. */ /** Exact presence test for a structural floor write on the MC lattice. */
bool AnyLandingFloorAtLattice(const FBox& VoxelBox, bool AnyLandingFloorAtLattice(const FBox& VoxelBox,
const FIntVector& LatticeOrigin, int32 Step) const; const FIntVector& LatticeOrigin, int32 Step) const;
@@ -481,7 +489,8 @@ public:
bool AnyOriginLandingFloorNearBox(const FVector& MinVoxel, const FVector& MaxVoxel) const; bool AnyOriginLandingFloorNearBox(const FVector& MinVoxel, const FVector& MaxVoxel) const;
bool AnyOriginLandingNearLattice(const FBox& VoxelBox, bool AnyOriginLandingNearLattice(const FBox& VoxelBox,
const FIntVector& LatticeOrigin, int32 Step) const; const FIntVector& LatticeOrigin, int32 Step,
float ReachScale = 1.0f) const;
/** Exact conservative candidate for the post-disturbance origin-room air reassertion. */ /** Exact conservative candidate for the post-disturbance origin-room air reassertion. */
bool AnyOriginLandingAirNearLattice(const FBox& VoxelBox, bool AnyOriginLandingAirNearLattice(const FBox& VoxelBox,
const FIntVector& LatticeOrigin, int32 Step, const FIntVector& LatticeOrigin, int32 Step,
@@ -0,0 +1,183 @@
// Per-tile reach state for density posts.
//
// The marching-cubes worker installs this state once for the tile's lattice plus its one-point
// halo. Density helpers only read the bit that owns them. The inline TLS is intentional: the
// runtime hot path must not cross a DLL boundary for a single boolean load.
#pragma once
#include "CoreMinimal.h"
#include <atomic>
namespace VoxelGenLOD
{
enum ETilePostReach : uint8
{
OriginLandingReachable = 1u << 0,
PassageLandingReachable = 1u << 1,
PassageStructuralReachable= 1u << 2,
AllTilePostReach = OriginLandingReachable
| PassageLandingReachable
| PassageStructuralReachable,
};
enum class ETilePostComparisonKind : uint8
{
Other = 0,
OriginAir,
OriginFloor,
PassageLandingSDF,
PassageLandingAir,
PassageTunnelAir,
PassageLandingFloor,
PassageStructuralPosts,
PassageNativeFloor,
PassageLandingRoomFloor,
Count,
};
// A tile that is not being meshed, or a point query outside the mesher, must retain the
// canonical behaviour. GenerateMesh scopes this to its computed mask.
inline thread_local uint8 TilePostReachFlags = AllTilePostReach;
inline thread_local bool bTilePostReachDebug = false;
inline thread_local bool bTilePostReachBypass = false;
// These are diagnostics only. They never participate in a field decision.
inline std::atomic<bool> GTilePostReachDebugEnabled { false };
inline std::atomic<uint64> GTilePostReachTileCount { 0 };
inline std::atomic<uint64> GOriginLandingReachableTiles { 0 };
inline std::atomic<uint64> GPassageLandingReachableTiles { 0 };
inline std::atomic<uint64> GPassageStructuralReachableTiles { 0 };
inline std::atomic<uint64> GOriginLandingSkippedTiles { 0 };
inline std::atomic<uint64> GPassageLandingSkippedTiles { 0 };
inline std::atomic<uint64> GPassageStructuralSkippedTiles { 0 };
inline std::atomic<uint64> GSkippedPostComparisons { 0 };
inline std::atomic<uint64> GSkippedPostDifferences { 0 };
inline std::atomic<uint64> GSkippedPostComparisonsByKind[
static_cast<uint8>(ETilePostComparisonKind::Count)]{};
inline std::atomic<uint64> GSkippedPostDifferencesByKind[
static_cast<uint8>(ETilePostComparisonKind::Count)]{};
FORCEINLINE bool IsTilePostReachable(uint8 Bit)
{
return (TilePostReachFlags & Bit) != 0;
}
FORCEINLINE bool IsOriginLandingReachable()
{
return IsTilePostReachable(OriginLandingReachable);
}
FORCEINLINE bool IsPassageLandingReachable()
{
return IsTilePostReachable(PassageLandingReachable);
}
FORCEINLINE bool IsPassageStructuralReachable()
{
return IsTilePostReachable(PassageStructuralReachable);
}
FORCEINLINE bool IsTilePostReachBypassActive()
{
return bTilePostReachBypass;
}
FORCEINLINE void RecordTileReachMask(uint8 Flags)
{
GTilePostReachTileCount.fetch_add(1, std::memory_order_relaxed);
if ((Flags & OriginLandingReachable) != 0)
{
GOriginLandingReachableTiles.fetch_add(1, std::memory_order_relaxed);
}
else
{
GOriginLandingSkippedTiles.fetch_add(1, std::memory_order_relaxed);
}
if ((Flags & PassageLandingReachable) != 0)
{
GPassageLandingReachableTiles.fetch_add(1, std::memory_order_relaxed);
}
else
{
GPassageLandingSkippedTiles.fetch_add(1, std::memory_order_relaxed);
}
if ((Flags & PassageStructuralReachable) != 0)
{
GPassageStructuralReachableTiles.fetch_add(1, std::memory_order_relaxed);
}
else
{
GPassageStructuralSkippedTiles.fetch_add(1, std::memory_order_relaxed);
}
}
FORCEINLINE bool SameFloatBits(float A, float B)
{
uint32 ABits = 0;
uint32 BBits = 0;
FMemory::Memcpy(&ABits, &A, sizeof(float));
FMemory::Memcpy(&BBits, &B, sizeof(float));
return ABits == BBits;
}
FORCEINLINE void RecordSkippedPostComparison(
ETilePostComparisonKind Kind, bool bDifferent)
{
GSkippedPostComparisons.fetch_add(1, std::memory_order_relaxed);
const uint8 KindIndex = static_cast<uint8>(Kind);
if (KindIndex < static_cast<uint8>(ETilePostComparisonKind::Count))
{
GSkippedPostComparisonsByKind[KindIndex].fetch_add(
1, std::memory_order_relaxed);
}
if (bDifferent)
{
GSkippedPostDifferences.fetch_add(1, std::memory_order_relaxed);
if (KindIndex < static_cast<uint8>(ETilePostComparisonKind::Count))
{
GSkippedPostDifferencesByKind[KindIndex].fetch_add(
1, std::memory_order_relaxed);
}
}
}
FORCEINLINE void RecordSkippedPostComparison(bool bDifferent)
{
RecordSkippedPostComparison(ETilePostComparisonKind::Other, bDifferent);
}
/** Run one skipped float post through its canonical body, then restore the fast-path value. */
template <typename CallableType>
FORCEINLINE void CompareSkippedPost(
float& Density, CallableType Callable,
ETilePostComparisonKind Kind = ETilePostComparisonKind::Other)
{
if (!bTilePostReachDebug || bTilePostReachBypass)
{
return;
}
const float Before = Density;
{
const bool PreviousBypass = bTilePostReachBypass;
bTilePostReachBypass = true;
Callable();
bTilePostReachBypass = PreviousBypass;
}
RecordSkippedPostComparison(Kind, !SameFloatBits(Before, Density));
Density = Before;
}
/** Compare a scalar proof input such as EvaluateModifierSDF without changing the field. */
FORCEINLINE void CompareSkippedPostValue(
float Candidate, float Canonical,
ETilePostComparisonKind Kind = ETilePostComparisonKind::Other)
{
if (bTilePostReachDebug && !bTilePostReachBypass)
{
RecordSkippedPostComparison(Kind, !SameFloatBits(Candidate, Canonical));
}
}
}