perf(streaming): prove sealed rock solid instead of sampling it -- crossing fix's cost recovered

4c8d06f stopped content-cutting LOD0 so the player can cross strates, at a cost of +29% static
worker CPU: LOD0 tiles in the sealed rock between strates, which the old cut skipped by accident,
were sampled in full and found solid. This proves those tiles solid instead (Codex; reviewed by me).

- UVoxelGenerator::TryProveSealedSolidTile: AllSolid only for a tile whose whole lattice lies in a
  gap/seal region. It rejects player mods (HasAnyModInChunkRange), passages plus carve pads, the
  origin spine/landing, disturbances, recipes and overrides. It is narrower than the old
  ClassifyTile, which stays off in streaming. CollisionSolidTiles / CollisionNotRequiredTiles
  bookkeeping is preserved, so the collision gate's support search still resolves.
- TryProveOutOfLayoutAirTile: a separate fail-closed constant-air proof for the zero-triangle tiles
  outside the strate layout. It never supplies collision support.
- voxel.SealedSolidProof (default 1). Mining a proven tile invalidates and re-meshes it.
- A soundness test that can fail (VoxelForgeSealedSolidProofTest): 22 candidates, 22 skips, 0
  non-solid lattice samples; a deliberately weakened diff guard produces 437 non-solid samples
  and fails.

Verified: mining tile (14,-18,-8) went from proof=1 / 0 triangles to proof=0 / 8 triangles and
re-meshed; strate-crossing test PASS (max gate 0.098 s); off/on trace 899/899 identical; export
b3e5f4c3..9b377; capability 20,830 / 10,909.

Two interleaved rounds, serialized (owner-editor count 0 before each launch):
                        baseline   crossing-fixed   + proof
  static  worker        35.5 s     41.9 s           36.0 s   (+1.4% vs baseline)
  moving  worker        78.1 s     93.2 s           78.2 s   (+0.1%)
  mesher calls static   18.078M    22.280M          18.078M
Applied triangles identical: 669,834 static / 1,331,482 moving.
Runs: one early automation probe exited 3 with no log (the corrected harness passed); one
exploratory moving run was interrupted and excluded.

Note: HasAnyModInChunkRange scans every modified chunk per candidate (cold audit #21). That is cheap
today (~20 candidates), but it grows with mining; it is queued in the correctness round.

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-14 22:08:24 +02:00
1 parent 481e7bbaee
commit 39c306b524
7 files changed
+1067 -15

No files matched your search

+196 -12
View File
@@ -97,6 +97,15 @@ namespace
GVoxelForgeOuterClassifierMode,
TEXT("Outer tile classifier mode: 0 off, 1 discarded exact validation."));
// Cheap structural proofs for LOD tiles whose exact core lattice lies entirely in a gap/seal
// (AllSolid) or constant out-of-layout air (AllAir). They are independent of the discarded
// full classifier and default on; 0 is retained for per-tile identity/A-B traces.
int32 GVoxelForgeSealedSolidProof = 1;
FAutoConsoleVariableRef CVarVoxelForgeSealedSolidProof(
TEXT("voxel.SealedSolidProof"),
GVoxelForgeSealedSolidProof,
TEXT("Skip meshing only when an exact gap/seal or constant-air proof holds: 0 off, 1 on."));
// Startup command-line cvars can arrive before the game world has spawned AVoxelWorld (or
// before its first tiles have become visible). Keep the diagnostic edit pending until Tick has
// a loaded tile; otherwise a startup measurement silently becomes a no-op or edits the wrong
@@ -104,6 +113,7 @@ namespace
int32 GVoxelForgePendingTestModification = 0;
float GVoxelForgePendingModificationRadius = 3.0f;
float GVoxelForgePendingModificationStrength = 10.0f;
bool GVoxelForgeTestModificationLoadedProofTarget = false;
bool GVoxelForgeTestModificationCommandLineConsumed = false;
bool GVoxelForgeStreamingBudgetReported = false;
bool GVoxelForgeGenerationCapHitReported = false;
@@ -1105,6 +1115,9 @@ void AVoxelWorld::BeginPlay()
TotalObsoleteWorkerTasks.store(0, std::memory_order_relaxed);
TotalValidationDensityCalls.store(0, std::memory_order_relaxed);
TotalMesherDensityCalls.store(0, std::memory_order_relaxed);
TotalSealedSolidProofCandidates.store(0, std::memory_order_relaxed);
TotalSealedSolidProofSkips.store(0, std::memory_order_relaxed);
TotalOutOfLayoutAirProofSkips.store(0, std::memory_order_relaxed);
AppliedTileCount = 0;
AppliedVisibleTileCount = 0;
AppliedTriangleCount = 0;
@@ -1133,6 +1146,7 @@ void AVoxelWorld::BeginPlay()
int32 CommandLineProfileTileGeneration = GVoxelForgeProfileTileGeneration;
int32 CommandLineUseBlockEarlyOut = GVoxelForgeUseBlockEarlyOut;
int32 CommandLineOuterClassifierMode = GVoxelForgeOuterClassifierMode;
int32 CommandLineSealedSolidProof = GVoxelForgeSealedSolidProof;
int32 CommandLineSampleStacks = GVoxelForgeSampleStacks;
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.ProfileDensity="), CommandLineProfile))
{
@@ -1161,6 +1175,10 @@ void AVoxelWorld::BeginPlay()
{
GVoxelForgeOuterClassifierMode = CommandLineOuterClassifierMode;
}
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.SealedSolidProof="), CommandLineSealedSolidProof))
{
GVoxelForgeSealedSolidProof = CommandLineSealedSolidProof;
}
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.SampleStacks="), CommandLineSampleStacks))
{
GVoxelForgeSampleStacks = CommandLineSampleStacks;
@@ -1168,6 +1186,7 @@ void AVoxelWorld::BeginPlay()
GVoxelForgeProfileTileGeneration = GVoxelForgeProfileTileGeneration != 0 ? 1 : 0;
GVoxelForgeUseBlockEarlyOut = GVoxelForgeUseBlockEarlyOut != 0 ? 1 : 0;
GVoxelForgeOuterClassifierMode = FMath::Clamp(GVoxelForgeOuterClassifierMode, 0, 1);
GVoxelForgeSealedSolidProof = GVoxelForgeSealedSolidProof != 0 ? 1 : 0;
GVoxelForgeSampleStacks = FMath::Clamp(
GVoxelForgeSampleStacks,
0,
@@ -1281,8 +1300,9 @@ void AVoxelWorld::BeginPlay()
Mesher->bUseBlockEarlyOut = GVoxelForgeUseBlockEarlyOut != 0;
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeClassifierConfig] outer_mode=%d nested_block_early_out=%d"),
GVoxelForgeOuterClassifierMode, Mesher->bUseBlockEarlyOut ? 1 : 0);
TEXT("[VoxelForgeClassifierConfig] outer_mode=%d sealed_solid_proof=%d nested_block_early_out=%d"),
GVoxelForgeOuterClassifierMode, GVoxelForgeSealedSolidProof,
Mesher->bUseBlockEarlyOut ? 1 : 0);
VoxelForgeStartupTrace::RecordEvent(TEXT("generator_mesher_constructed"), FString::Printf(
TEXT("\"generator\":1,\"mesher\":1,\"generate_skirts\":%d,\"full_res_clip_levels\":%d,\"coarse_tile_cells\":%d"),
@@ -1377,6 +1397,9 @@ void AVoxelWorld::ConfigureHeadlessStreamingTest()
{
bHeadlessStreamingTestMovement = false;
bHeadlessStreamingTestExitRequested = false;
bStartupTraceThroughCrossing = false;
bHeadlessStreamingTestCenterOverride = false;
HeadlessStreamingTestCenterVoxel = FVector::ZeroVector;
HeadlessStreamingTestMoveAttempts = 0;
HeadlessStreamingTestDistanceCm = 0.0;
HeadlessStreamingTestSpeedCmPerSecond = 0.0f;
@@ -1472,6 +1495,33 @@ void AVoxelWorld::ConfigureHeadlessStreamingTest()
HeadlessStrateCrossingTestRequestedPassageIndex);
}
int32 TraceThroughCrossingValue = 0;
if (FParse::Value(
CommandLine,
TEXT("voxel.StartupTraceThroughCrossing="),
TraceThroughCrossingValue))
{
bStartupTraceThroughCrossing = TraceThroughCrossingValue != 0;
}
float CenterX = 0.0f;
float CenterY = 0.0f;
float CenterZ = 0.0f;
const bool bCenterX = FParse::Value(CommandLine, TEXT("voxel.StreamingTestCenterX="), CenterX);
const bool bCenterY = FParse::Value(CommandLine, TEXT("voxel.StreamingTestCenterY="), CenterY);
const bool bCenterZ = FParse::Value(CommandLine, TEXT("voxel.StreamingTestCenterZ="), CenterZ);
if (bCenterX && bCenterY && bCenterZ
&& VoxelMath::IsFinite(CenterX)
&& VoxelMath::IsFinite(CenterY)
&& VoxelMath::IsFinite(CenterZ))
{
bHeadlessStreamingTestCenterOverride = true;
HeadlessStreamingTestCenterVoxel = FVector(CenterX, CenterY, CenterZ);
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeStreamingTest] center_override=1 local_vox=(%.2f,%.2f,%.2f)"),
CenterX, CenterY, CenterZ);
}
if (bMoveRequested && !bHeadlessStrateCrossingTest)
{
FString DirectionText;
@@ -2000,6 +2050,11 @@ void AVoxelWorld::MaybeFinishHeadlessStrateCrossingTest()
HeadlessStrateCrossingTestLastActualPosition.X,
HeadlessStrateCrossingTestLastActualPosition.Y,
HeadlessStrateCrossingTestLastActualPosition.Z);
if (bStartupTraceThroughCrossing && VoxelForgeStartupTrace::IsActive())
{
VoxelForgeStartupTrace::Finish(
bPassed ? TEXT("strate_crossing_passed") : TEXT("strate_crossing_failed"));
}
FPlatformMisc::RequestExitWithStatus(
false, bPassed ? 0 : 1, TEXT("VoxelForge strate crossing test complete"));
}
@@ -2110,7 +2165,10 @@ void AVoxelWorld::Tick(float DeltaTime)
PeakObservedPawnSpeedCmPerSecond, PlayerHeading.Size2D());
UpdatePawnCollisionGate(PlayerPawn, PlayerLastPos, DeltaTime);
ObserveHeadlessStrateCrossingTest(PlayerLastPos, PlayerPawn);
UpdateChunksAroundPosition(PlayerLastPos, PlayerPawn, PlayerHeading);
const FVector StreamingCenterPosition = bHeadlessStreamingTestCenterOverride
? LocalVoxelToWorld(HeadlessStreamingTestCenterVoxel)
: PlayerLastPos;
UpdateChunksAroundPosition(StreamingCenterPosition, PlayerPawn, PlayerHeading);
if (AtmosphereManager)
{
AtmosphereManager->UpdateForPlayer(PlayerLastPos);
@@ -2165,10 +2223,20 @@ void AVoxelWorld::Tick(float DeltaTime)
{
GVoxelForgePendingModificationRadius = 3.0f;
GVoxelForgePendingModificationStrength = 10.0f;
FString ModificationTarget;
if (FParse::Value(
*CommandLine,
TEXT("voxel.TestModificationTarget="),
ModificationTarget)
&& ModificationTarget.Equals(TEXT("loaded-proof"), ESearchCase::IgnoreCase))
{
GVoxelForgeTestModificationLoadedProofTarget = true;
}
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeTestModification] queued radius=%.2f strength=%.2f"),
TEXT("[VoxelForgeTestModification] queued radius=%.2f strength=%.2f target=%s"),
GVoxelForgePendingModificationRadius,
GVoxelForgePendingModificationStrength);
GVoxelForgePendingModificationStrength,
GVoxelForgeTestModificationLoadedProofTarget ? TEXT("loaded-proof") : TEXT("player"));
GVoxelForgePendingTestModification = 1;
}
}
@@ -2183,10 +2251,16 @@ void AVoxelWorld::Tick(float DeltaTime)
&& PendingTiles.Num() == 0
&& bStartupTraceDesiredRecorded
&& PendingCollisionCooks.Num() == 0
&& (!bStartupTraceThroughCrossing
|| !bHeadlessStrateCrossingTest
|| bHeadlessStrateCrossingTestPassed
|| bHeadlessStrateCrossingTestFailed)
// The desired set being applied is not the player-ready point: the feet tile must have
// received its completed LOD0 RMC body first. If no pawn exists, there is no gate to wait
// for and the headless trace keeps its old completion behavior.
&& (!bHasPlayer || IsPlayerSupportCollisionReady(PlayerPawn, PlayerLastPos)))
&& (!bHasPlayer
|| bHeadlessStreamingTestCenterOverride
|| IsPlayerSupportCollisionReady(PlayerPawn, PlayerLastPos)))
{
TMap<int32, int32> SteadyLevelCounts;
TMap<int32, FIntVector> SteadyLevelMins;
@@ -2244,22 +2318,75 @@ void AVoxelWorld::Tick(float DeltaTime)
// No pawn is a distinct state from a pawn at (0,0,0); keep the diagnostic fallback for
// headless/editor use without making the world-origin pawn skip streaming.
FVector ModificationPosition = bHasPlayer ? PlayerLastPos : GetActorLocation();
const FVoxelTileKey ModificationCenterTile(
FVoxelTileKey ModificationCenterTile(
WorldToChunkCoord(WorldToLocalCm(ModificationPosition)), 0);
bool bModificationTargetSelected = false;
if (GVoxelForgePendingTestModification != 0
&& GVoxelForgeTestModificationLoadedProofTarget
&& Generator)
{
// The diagnostic target is deliberately selected from the applied set. That makes the
// edit exercise the normal loaded-tile synchronous remesh, while the proof query here is
// the same public predicate used by GenerateTileResult before the diff exists.
for (const FVoxelTileKey& CandidateTile : LoadedTiles)
{
if (CandidateTile.Level != 0
|| PendingTiles.Contains(CandidateTile))
{
continue;
}
const FIntVector CandidateOrigin(
CandidateTile.Coord.X * CHUNK_SIZE,
CandidateTile.Coord.Y * CHUNK_SIZE,
CandidateTile.Coord.Z * CHUNK_SIZE);
if (!Generator->TryProveSealedSolidTile(CandidateOrigin, 1, CHUNK_SIZE))
{
continue;
}
const FIntVector CandidateCenter(
CandidateOrigin.X + CHUNK_SIZE / 2,
CandidateOrigin.Y + CHUNK_SIZE / 2,
CandidateOrigin.Z + CHUNK_SIZE / 2);
ModificationPosition = LocalVoxelToWorld(FVector(CandidateCenter));
ModificationCenterTile = CandidateTile;
bModificationTargetSelected = true;
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeTestModification] player_mine_target tile=(%d,%d,%d) "
"local_center=(%d,%d,%d) before_proof=1"),
CandidateTile.Coord.X, CandidateTile.Coord.Y, CandidateTile.Coord.Z,
CandidateCenter.X, CandidateCenter.Y, CandidateCenter.Z);
break;
}
}
if (GVoxelForgePendingTestModification != 0
&& DiffLayer
&& (!GVoxelForgeTestModificationLoadedProofTarget || bModificationTargetSelected)
&& LoadedTiles.Contains(ModificationCenterTile)
&& !PendingTiles.Contains(ModificationCenterTile))
{
GVoxelForgePendingTestModification = 0;
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeTestModification] applying position=(%.2f,%.2f,%.2f) radius=%.2f strength=%.2f"),
TEXT("[VoxelForgeTestModification] applying player_mine=1 tile=(%d,%d,%d) "
"position=(%.2f,%.2f,%.2f) radius=%.2f strength=%.2f"),
ModificationCenterTile.Coord.X, ModificationCenterTile.Coord.Y, ModificationCenterTile.Coord.Z,
ModificationPosition.X, ModificationPosition.Y, ModificationPosition.Z,
GVoxelForgePendingModificationRadius, GVoxelForgePendingModificationStrength);
CarveAtPosition(
ModificationPosition,
GVoxelForgePendingModificationRadius,
GVoxelForgePendingModificationStrength);
const FIntVector ModifiedOrigin(
ModificationCenterTile.Coord.X * CHUNK_SIZE,
ModificationCenterTile.Coord.Y * CHUNK_SIZE,
ModificationCenterTile.Coord.Z * CHUNK_SIZE);
const bool bProofSurvivedCarve = Generator
&& Generator->TryProveSealedSolidTile(ModifiedOrigin, 1, CHUNK_SIZE);
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeTestModification] player_mine_complete tile=(%d,%d,%d) "
"after_proof=%d"),
ModificationCenterTile.Coord.X, ModificationCenterTile.Coord.Y,
ModificationCenterTile.Coord.Z, bProofSurvivedCarve ? 1 : 0);
}
ProcessUnloadQueue();
MaybeFinishHeadlessStreamingTest();
@@ -2849,6 +2976,12 @@ void AVoxelWorld::LogStreamingLatencySummary() const
TotalWorkerGenerationCycles.load(std::memory_order_relaxed);
const uint64 ObsoleteWorkerCycles =
TotalObsoleteWorkerCycles.load(std::memory_order_relaxed);
const uint64 SealedSolidProofCandidates =
TotalSealedSolidProofCandidates.load(std::memory_order_relaxed);
const uint64 SealedSolidProofSkips =
TotalSealedSolidProofSkips.load(std::memory_order_relaxed);
const uint64 OutOfLayoutAirProofSkips =
TotalOutOfLayoutAirProofSkips.load(std::memory_order_relaxed);
const bool bDiagnosticsEnabled = GVoxelForgeProfileTileGeneration != 0
|| VoxelForgeStartupTrace::IsActive()
|| VoxelDensityProfile::GetMode() != VoxelDensityProfile::EMode::Disabled;
@@ -2863,6 +2996,8 @@ void AVoxelWorld::LogStreamingLatencySummary() const
"applied_tiles=%llu applied_visible_tiles=%llu applied_triangles=%llu "
"worker_generation_tasks=%llu worker_generation_sum_s=%.6f "
"validation_density_calls=%llu mesher_density_calls=%llu "
"sealed_solid_proof_candidates=%llu sealed_solid_proof_skips=%llu "
"out_of_layout_air_proof_skips=%llu "
"obsolete_worker_tasks=%llu obsolete_worker_sum_s=%.6f "
"outer_classifier_verdicts=%s applied_level_summary=%s band_level_summary=%s"),
bDiagnosticsEnabled ? TEXT("profiled") : TEXT("clean"),
@@ -2881,6 +3016,9 @@ void AVoxelWorld::LogStreamingLatencySummary() const
FPlatformTime::ToSeconds64(WorkerGenerationCycles),
static_cast<unsigned long long>(TotalValidationDensityCalls.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(TotalMesherDensityCalls.load(std::memory_order_relaxed)),
static_cast<unsigned long long>(SealedSolidProofCandidates),
static_cast<unsigned long long>(SealedSolidProofSkips),
static_cast<unsigned long long>(OutOfLayoutAirProofSkips),
static_cast<unsigned long long>(TotalObsoleteWorkerTasks.load(std::memory_order_relaxed)),
FPlatformTime::ToSeconds64(ObsoleteWorkerCycles),
*ClassifierVerdictSummary,
@@ -3191,6 +3329,7 @@ bool AVoxelWorld::ApplyTileResult(FChunkResult& Result)
Sample.TileZ = Result.Tile.Coord.Z;
Sample.Level = Result.Tile.Level;
Sample.Verdict = Result.ClassifyVerdict;
Sample.bSealedSolidProof = Result.bSealedSolidProof;
Sample.bEmpty = bResultEmpty;
Sample.Triangles = Result.NumTriangles;
Sample.RequestToApplySeconds = RequestToApply;
@@ -4523,7 +4662,7 @@ void AVoxelWorld::GenerateTileResult(const FVoxelTileKey& Tile, const FIntVector
UE_LOG(LogTemp, Display,
TEXT("[VoxelForgeTileProfile] tile=(%d,%d,%d) level=%d step=%d cells=%d sheet=%d aborted=%d empty=%d triangles=%d "
"band=(%d,%d) "
"verdict=%d classify=%.6f mesh=%.6f streams=%.6f seconds=%.6f "
"verdict=%d proof=%d air_proof=%d classify=%.6f mesh=%.6f streams=%.6f seconds=%.6f "
"cache_build=%.6f evaluation=%.6f "
"refine=%u stack=%u core_samples=%u final_samples=%u core_hits=%u final_hits=%u "
"core_leaves=%u final_leaves=%u tail_queries=%u tail_eval=%u "
@@ -4543,7 +4682,9 @@ void AVoxelWorld::GenerateTileResult(const FVoxelTileKey& Tile, const FIntVector
Tile.Coord.X, Tile.Coord.Y, Tile.Coord.Z, Tile.Level, Step, Cells,
bSheetTile ? 1 : 0, Result.bAborted ? 1 : 0,
Result.bEmpty ? 1 : 0, Result.NumTriangles, BandChunkLo, BandChunkHi,
ClassifyVerdict, ClassifySeconds, MeshSeconds, StreamSeconds,
ClassifyVerdict, Result.bSealedSolidProof ? 1 : 0,
Result.bOutOfLayoutAirProof ? 1 : 0,
ClassifySeconds, MeshSeconds, StreamSeconds,
TileSeconds, CacheBuildSeconds, EvaluationSeconds,
ClassifierStats.RefineNodes, ClassifierStats.StackBoxCalls,
ClassifierStats.ExactCoreSamples, ClassifierStats.ExactFinalSamples,
@@ -4637,6 +4778,8 @@ void AVoxelWorld::GenerateTileResult(const FVoxelTileKey& Tile, const FIntVector
Result.bObsolete = false;
Result.bEmpty = true;
Result.ClassifyVerdict = -1;
Result.bSealedSolidProof = false;
Result.bOutOfLayoutAirProof = false;
Result.ClassifySeconds = 0.0;
Result.MeshSeconds = 0.0;
Result.StreamSeconds = 0.0;
@@ -4674,8 +4817,49 @@ void AVoxelWorld::GenerateTileResult(const FVoxelTileKey& Tile, const FIntVector
// même pour les cellules uniformes, et ces tuiles sont rares (fenêtre d'ombre).
// (Gate IsoLevel == 0 : les verdicts du classifieur supposent l'iso MC à zéro exactement.)
bool bTrivialEmpty = false;
if (GVoxelForgeSealedSolidProof != 0
&& !bSheetTile && !bWantCapture && Generator && Mesher
&& Mesher->IsoLevel == 0.0f)
{
TotalSealedSolidProofCandidates.fetch_add(1, std::memory_order_relaxed);
const double ProofStartSeconds = bMeasureTile ? FPlatformTime::Seconds() : 0.0;
if (Generator->TryProveSealedSolidTile(OriginVoxels, Step, Cells))
{
ClassifySeconds = bMeasureTile
? FPlatformTime::Seconds() - ProofStartSeconds : 0.0;
ClassifyVerdict = static_cast<int32>(EVoxelTileClass::AllSolid);
Result.ClassifyVerdict = ClassifyVerdict;
Result.bSealedSolidProof = true;
TotalSealedSolidProofSkips.fetch_add(1, std::memory_order_relaxed);
INC_DWORD_STAT(STAT_VoxelForgeTilesSkippedAllSolid);
bTrivialEmpty = true;
}
else if (Generator->TryProveOutOfLayoutAirTile(OriginVoxels, Step, Cells))
{
ClassifySeconds = bMeasureTile
? FPlatformTime::Seconds() - ProofStartSeconds : 0.0;
ClassifyVerdict = static_cast<int32>(EVoxelTileClass::AllAir);
Result.ClassifyVerdict = ClassifyVerdict;
Result.bOutOfLayoutAirProof = true;
TotalOutOfLayoutAirProofSkips.fetch_add(1, std::memory_order_relaxed);
INC_DWORD_STAT(STAT_VoxelForgeTilesSkippedAllAir);
bTrivialEmpty = true;
}
else if (bMeasureTile)
{
// Keep the measured proof cost visible on a tile that continues through the normal
// path. The clean summary remains counter-only and pays no timer overhead.
ClassifySeconds = FPlatformTime::Seconds() - ProofStartSeconds;
}
}
if (ShouldAbortWork(ObsoleteFlag))
{
AbortResult();
EmitTileProfile();
return;
}
const int32 OuterClassifierMode = FMath::Clamp(GVoxelForgeOuterClassifierMode, 0, 1);
if (OuterClassifierMode != 0
if (!bTrivialEmpty && OuterClassifierMode != 0
&& !bSheetTile && !bWantCapture && Generator && Mesher && Mesher->IsoLevel == 0.0f)
{
TRACE_CPUPROFILER_EVENT_SCOPE(VoxelForge_ClassifyTile);
@@ -4754,7 +4938,7 @@ void AVoxelWorld::GenerateTileResult(const FVoxelTileKey& Tile, const FIntVector
EmitTileProfile();
return;
}
ClassifySeconds = bMeasureTile ? FPlatformTime::Seconds() - ClassifyStartSeconds : 0.0;
ClassifySeconds += bMeasureTile ? FPlatformTime::Seconds() - ClassifyStartSeconds : 0.0;
ClassifyVerdict = static_cast<int32>(ValidatedVerdict);
Result.ClassifyVerdict = ClassifyVerdict;
const int32 TrackedLOD = FMath::Clamp(Tile.Level, 0, TrackedClassifierLODCount - 1);