Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa67bd31f5 | ||
|
|
b21a19d561 | ||
|
|
7770074503 | ||
|
|
046f2af495 | ||
|
|
303b7b9f24 | ||
|
|
1276fd11e3 | ||
|
|
ec2afe9c93 |
No files matched your search
@@ -648,6 +648,7 @@ driven by `EditorBrush*` props.
|
|||||||
two global settings through `FVoxelOpContext` once per chunk, while `ClassifyBox`/`ClassifyTile`
|
two global settings through `FVoxelOpContext` once per chunk, while `ClassifyBox`/`ClassifyTile`
|
||||||
share the radial proof. This adds no cache, state, RNG, or clipmap stream, and does not touch the
|
share the radial proof. This adds no cache, state, RNG, or clipmap stream, and does not touch the
|
||||||
density grid's two-pass MC loop or any existing `thread_local` cache.
|
density grid's two-pass MC loop or any existing `thread_local` cache.
|
||||||
|
- **Large `thread_local` caches are lazy** (`VoxelForgeCoreThreadLocal::FLazy<T>`, `Standalone/Core/include/VoxelForgeCore/ThreadLocalStorage.h`, round Linux4): the per-thread handle is a pointer; the table is heap-allocated on that thread's first use and freed at thread exit. Still worker-private and lock-free. It keeps the static TLS block at ~43 KiB instead of 17.3 MiB (glibc carves static TLS out of each thread's stack, and a Linux server pays it on every thread). New cache tables over a few KiB go through `FLazy`, never a bare `thread_local` array.
|
||||||
- **Biome cache** (`ResolveBiomeSampleAt`/`FChunkBiomeCache`, §8.14): validity is a world-XY BOX +
|
- **Biome cache** (`ResolveBiomeSampleAt`/`FChunkBiomeCache`, §8.14): validity is a world-XY BOX +
|
||||||
ChunkZ + Seed, NOT a chunk key — same reason as the SDF cache. The cell classification is
|
ChunkZ + Seed, NOT a chunk key — same reason as the SDF cache. The cell classification is
|
||||||
noise-heavy; a chunk-key would thrash it on gradient-normal / +X/+Y boundary samples. Keep
|
noise-heavy; a chunk-key would thrash it on gradient-normal / +X/+Y boundary samples. Keep
|
||||||
@@ -694,6 +695,10 @@ driven by `EditorBrush*` props.
|
|||||||
position → seamless across chunk borders (both sides use identical pure samples). NO per-vertex
|
position → seamless across chunk borders (both sides use identical pure samples). NO per-vertex
|
||||||
`GetDensityAt` (was ~6/vertex, often as costly as the whole grid). `ComputeGradientNormal` is now
|
`GetDensityAt` (was ~6/vertex, often as costly as the whole grid). `ComputeGradientNormal` is now
|
||||||
unused. Only NORMALS changed vs the old path; geometry is identical.
|
unused. Only NORMALS changed vs the old path; geometry is identical.
|
||||||
|
Round 18 memoizes these exact central-difference `FVector`s in per-worker scratch arrays for the
|
||||||
|
step-1 ShapeWorld path. Validity is reset for each tile; cache hits return the same vector and do
|
||||||
|
not bypass the density grid, halo, or two-pass cell loop. Keep the cache worker-local and exact;
|
||||||
|
do not move gradient probes above the surface-cell test.
|
||||||
- **Core hybrid sharp mesher (M2)** (`CoreMesherRecipe` / `MesherRecipe`): the property remains
|
- **Core hybrid sharp mesher (M2)** (`CoreMesherRecipe` / `MesherRecipe`): the property remains
|
||||||
opt-in and defaults to `MarchingCubesV1`; `bUseVoxelForgeCore` remains separately default-off.
|
opt-in and defaults to `MarchingCubesV1`; `bUseVoxelForgeCore` remains separately default-off.
|
||||||
V1 preserves the round-3 feature-aware dual-contouring path for repeatability. V2 reuses the
|
V1 preserves the round-3 feature-aware dual-contouring path for repeatability. V2 reuses the
|
||||||
@@ -1778,6 +1783,20 @@ shared-page A/B test, not proof that a shared cache will pay after synchronizati
|
|||||||
costs. Round 17 changed no density, mesh, collision, or recipe output; recipe versions remain
|
costs. Round 17 changed no density, mesh, collision, or recipe output; recipe versions remain
|
||||||
unchanged. See [`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md).
|
unchanged. See [`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md).
|
||||||
|
|
||||||
|
**Round 18 / S14:** the 65,536-entry worker-local XY column cache keeps the legacy direct-map
|
||||||
|
lookup for LOD0–2 (at most 33/28/4 conflict misses in the cold audit) and uses four-way sets for
|
||||||
|
LOD3–8. The deterministic coordinate/hash mixer and round-robin replacement cut LOD4 from 8,224
|
||||||
|
misses / 7,407 conflict misses to 1,437 / 0, and LOD3 from 1,634 / 1,119 to 574 / 0. Exact key
|
||||||
|
validation keeps fill order from affecting samples. `voxel.CoreColumnCacheDirectMapped=1` restores
|
||||||
|
the S13 route as a recorded negative control.
|
||||||
|
|
||||||
|
The step-1 ShapeWorld gradient memo reduced LOD0 fallback density probes from 11,474 to 3,018 at
|
||||||
|
the sampled p95 and gradient-normal cost from 65.10 to 24.16 ns/sample; the two-pass MC invariant
|
||||||
|
is unchanged. `voxel.CoreMCGradientMemoization=0` is its recorded negative control. No shared XY
|
||||||
|
page was added: cross-worker repeats alone do not establish a net page-cache win, and the S8
|
||||||
|
immutable-page lifetime rules would add ownership and memory cost. Round 18 changed no output or
|
||||||
|
recipe version. See [`Standalone/Research/WorldAssemblerM3/Round18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round18/REPORT.md).
|
||||||
|
|
||||||
## 9. Multiplayer model (listen-server first, dedicated-friendly)
|
## 9. Multiplayer model (listen-server first, dedicated-friendly)
|
||||||
|
|
||||||
> **Status: transport is DESIGN ONLY — nothing is networked in-tree yet** (no `Replicated`/`HasAuthority`/RPCs; a
|
> **Status: transport is DESIGN ONLY — nothing is networked in-tree yet** (no `Replicated`/`HasAuthority`/RPCs; a
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ remains `0`, and lateral regions remain gated off.
|
|||||||
| `VoxelForge.Build.cs` | Deps: Core, CoreUObject, Engine, **GameplayTags**, **RealtimeMeshComponent**, `VoxelForgeCore`. `AVoxelWorld::bUseVoxelForgeCore` opts into the Core runtime route; it defaults off. |
|
| `VoxelForge.Build.cs` | Deps: Core, CoreUObject, Engine, **GameplayTags**, **RealtimeMeshComponent**, `VoxelForgeCore`. `AVoxelWorld::bUseVoxelForgeCore` opts into the Core runtime route; it defaults off. |
|
||||||
| `../../VoxelForgeCore/VoxelForgeCore.Build.cs` | C++20 runtime module. Reads `Standalone/Core/core_sources.txt`, validates one include shim per canonical source, and fails UBT on missing, extra, or mismatched shims. No unity/PCH; private copied implementation stays under `vfcore::detail`. |
|
| `../../VoxelForgeCore/VoxelForgeCore.Build.cs` | C++20 runtime module. Reads `Standalone/Core/core_sources.txt`, validates one include shim per canonical source, and fails UBT on missing, extra, or mismatched shims. No unity/PCH; private copied implementation stays under `vfcore::detail`. |
|
||||||
| `../../VoxelForgeCore/Private/Manifest/VFCore_*.cpp` | Eighteen one-source UBT shims that include canonical files under `Standalone/`; they do not copy Core implementation. The API-boundary row includes `Core/src/VoxelForgeCore.cpp` directly. |
|
| `../../VoxelForgeCore/Private/Manifest/VFCore_*.cpp` | Eighteen one-source UBT shims that include canonical files under `Standalone/`; they do not copy Core implementation. The API-boundary row includes `Core/src/VoxelForgeCore.cpp` directly. |
|
||||||
|
| `../../Standalone/Core/include/VoxelForgeCore/ThreadLocalStorage.h` | `VoxelForgeCoreThreadLocal::FLazy<T>`: thread-local handle that heap-allocates a worker-private cache on first use. All large Core and legacy caches use it (HeightfieldColumnCache, IslandColumnCache, GFloorReliefCache, GRoomGraphCache, GSurfColCache, tunnel/diff caches). See ARCHITECTURE §8.10. |
|
||||||
|
| `../../Standalone/Core/src/CoreNamespacePreamble.h` | First include of every Core TU. Forces FP contraction off per compiler (Clang/MSVC/GCC pragmas; unknown compiler = `#error`) and defines `vfcore::fp_contract::selfTest`, which `World::compile` runs before building: a fused multiply-add (e.g. Clang `-ffp-contract=fast`) refuses world generation. The world depends on contraction (Linux2/Linux3 reports), so never remove either. |
|
||||||
| `../../VoxelForgeCore/Private/ModuleEntry/` | Unreal module entry and an isolated `CoreMinimal.h` shim for the actual engine header. |
|
| `../../VoxelForgeCore/Private/ModuleEntry/` | Unreal module entry and an isolated `CoreMinimal.h` shim for the actual engine header. |
|
||||||
| `../../Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` | Standard-library-only public Core API. `VOXELFORGECORE_API` exports the API from the Unreal module and is empty for standalone builds. |
|
| `../../Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h` | Standard-library-only public Core API. `VOXELFORGECORE_API` exports the API from the Unreal module and is empty for standalone builds. |
|
||||||
| `../../Standalone/Core/src/FloatingIslandsInternal.h` | Canonical standalone/Core floating-island planner, geometry-versioned field, manifest serializer, influence bounds, capsule-route checks, and thickness audit. |
|
| `../../Standalone/Core/src/FloatingIslandsInternal.h` | Canonical standalone/Core floating-island planner, geometry-versioned field, manifest serializer, influence bounds, capsule-route checks, and thickness audit. |
|
||||||
@@ -874,8 +876,14 @@ round-2 matched capture source and results are under
|
|||||||
[`Standalone/Research/WorldAssemblerM3/Round2/`](Standalone/Research/WorldAssemblerM3/Round2/).
|
[`Standalone/Research/WorldAssemblerM3/Round2/`](Standalone/Research/WorldAssemblerM3/Round2/).
|
||||||
`RefineLod8NativeCap` in [`Standalone/Core/src/VoxelForgeCore.cpp`](Standalone/Core/src/VoxelForgeCore.cpp)
|
`RefineLod8NativeCap` in [`Standalone/Core/src/VoxelForgeCore.cpp`](Standalone/Core/src/VoxelForgeCore.cpp)
|
||||||
replaces coarse LOD8 ceiling surfaces with the planned 2D cap field while retaining ceiling skirts.
|
replaces coarse LOD8 ceiling surfaces with the planned 2D cap field while retaining ceiling skirts.
|
||||||
The standalone SurfaceWorld plan composer and capture/audit entry point live in
|
The standalone SurfaceWorld plan composer (`AttachRound1WorldAssemblyPrototype`) lives in
|
||||||
[`Standalone/Source/StandaloneViewer.cpp`](Standalone/Source/StandaloneViewer.cpp).
|
[`Standalone/Source/WorldAssemblyPrototype.h`](Standalone/Source/WorldAssemblyPrototype.h), and the
|
||||||
|
streaming benchmark/hash pipeline (`RunPipelinedStreamingBenchmark`, `HashTileRows`) in
|
||||||
|
[`Standalone/Source/StreamBenchmarkPipeline.h`](Standalone/Source/StreamBenchmarkPipeline.h); both are
|
||||||
|
shared by the D3D11 viewer ([`StandaloneViewer.cpp`](Standalone/Source/StandaloneViewer.cpp), which
|
||||||
|
keeps the capture/audit entry points) and the Linux headless tool
|
||||||
|
([`StreamBenchmarkHeadless.cpp`](Standalone/Source/StreamBenchmarkHeadless.cpp), built by
|
||||||
|
`Standalone/BuildLinux.sh`; see `Standalone/Research/WorldAssemblerM3/Linux1/REPORT.md`).
|
||||||
|
|
||||||
`RunStandaloneWorldExport` in `VoxelForgeExploreCommandlet.cpp` serializes owner assets on the game
|
`RunStandaloneWorldExport` in `VoxelForgeExploreCommandlet.cpp` serializes owner assets on the game
|
||||||
thread to schema-v1 JSON. The adapter parses it through `ResolvedWorldSnapshot::FromJson` and keeps
|
thread to schema-v1 JSON. The adapter parses it through `ResolvedWorldSnapshot::FromJson` and keeps
|
||||||
@@ -1095,6 +1103,20 @@ generation output. Measurement-only stride and octave probes are confined to the
|
|||||||
audit and are not runtime controls. The result and limits are recorded in
|
audit and are not runtime controls. The result and limits are recorded in
|
||||||
[`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md).
|
[`Standalone/Research/WorldAssemblerM3/Round17/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round17/REPORT.md).
|
||||||
|
|
||||||
|
### 3.20 MC stage audit and coarse column-cache conflicts — World Assembler S14 / M3 Round 18
|
||||||
|
|
||||||
|
`Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp` records the sampled density
|
||||||
|
grid, cell classification, grid-gradient normals, edge interpolation, and vertex/dedup stream
|
||||||
|
stages for the BuildHost audit. Its exact per-worker gradient memo is controlled and trace-read
|
||||||
|
back through `voxel.CoreMCGradientMemoization`. `Standalone/Core/src/WorldAssemblerInternal.h`
|
||||||
|
keeps the 65,536-entry worker-local column cache, using the S13 direct-map for LOD0–2 and a
|
||||||
|
deterministic four-way set-associative route for LOD3–8; `voxel.CoreColumnCacheDirectMapped=1`
|
||||||
|
restores the S13 path for the negative control. Runtime CVar capture lives in
|
||||||
|
`Source/VoxelForge/Private/VoxelWorld.cpp`; stage and conflict counts are reported by
|
||||||
|
`Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp`. The measurements, controls, and
|
||||||
|
cold-path decision are in
|
||||||
|
[`Standalone/Research/WorldAssemblerM3/Round18/REPORT.md`](Standalone/Research/WorldAssemblerM3/Round18/REPORT.md).
|
||||||
|
|
||||||
## 4. The density pipeline (most-edited hot path)
|
## 4. The density pipeline (most-edited hot path)
|
||||||
|
|
||||||
### 4.1 `GetDensityWithParams` (TunnelNetwork) — VoxelGenerator.cpp:3749
|
### 4.1 `GetDensityWithParams` (TunnelNetwork) — VoxelGenerator.cpp:3749
|
||||||
|
|||||||
@@ -235,6 +235,18 @@ namespace
|
|||||||
GVoxelForgeStreamingBackgroundWorkerCap,
|
GVoxelForgeStreamingBackgroundWorkerCap,
|
||||||
TEXT("Size tile admission slots to the TaskGraph background workers used by tile tasks; 0 restores the logical-core cap."));
|
TEXT("Size tile admission slots to the TaskGraph background workers used by tile tasks; 0 restores the logical-core cap."));
|
||||||
|
|
||||||
|
int32 GVoxelForgeCoreColumnCacheDirectMapped = 0;
|
||||||
|
FAutoConsoleVariableRef CVarVoxelForgeCoreColumnCacheDirectMapped(
|
||||||
|
TEXT("voxel.CoreColumnCacheDirectMapped"),
|
||||||
|
GVoxelForgeCoreColumnCacheDirectMapped,
|
||||||
|
TEXT("Negative control: 0 uses the four-way deterministic XY column cache; 1 restores S13 direct-map indexing."));
|
||||||
|
|
||||||
|
int32 GVoxelForgeCoreMCGradientMemoization = 1;
|
||||||
|
FAutoConsoleVariableRef CVarVoxelForgeCoreMCGradientMemoization(
|
||||||
|
TEXT("voxel.CoreMCGradientMemoization"),
|
||||||
|
GVoxelForgeCoreMCGradientMemoization,
|
||||||
|
TEXT("Negative control: 1 reuses exact LOD0 lattice gradients across adjacent MC cells; 0 restores per-cell gradient probes."));
|
||||||
|
|
||||||
int32 GVoxelForgeProfileTileGeneration = 0;
|
int32 GVoxelForgeProfileTileGeneration = 0;
|
||||||
FAutoConsoleVariableRef CVarVoxelForgeProfileTileGeneration(
|
FAutoConsoleVariableRef CVarVoxelForgeProfileTileGeneration(
|
||||||
TEXT("voxel.ProfileTileGeneration"),
|
TEXT("voxel.ProfileTileGeneration"),
|
||||||
@@ -2080,6 +2092,8 @@ void AVoxelWorld::BeginPlay()
|
|||||||
int32 CommandLineStreamingResultBacklogCap = GVoxelForgeStreamingResultBacklogCap;
|
int32 CommandLineStreamingResultBacklogCap = GVoxelForgeStreamingResultBacklogCap;
|
||||||
int32 CommandLineStreamingReadyQueueDepth = GVoxelForgeStreamingReadyQueueDepth;
|
int32 CommandLineStreamingReadyQueueDepth = GVoxelForgeStreamingReadyQueueDepth;
|
||||||
int32 CommandLineStreamingBackgroundWorkerCap = GVoxelForgeStreamingBackgroundWorkerCap;
|
int32 CommandLineStreamingBackgroundWorkerCap = GVoxelForgeStreamingBackgroundWorkerCap;
|
||||||
|
int32 CommandLineCoreColumnCacheDirectMapped = GVoxelForgeCoreColumnCacheDirectMapped;
|
||||||
|
int32 CommandLineCoreMCGradientMemoization = GVoxelForgeCoreMCGradientMemoization;
|
||||||
int32 CommandLineStep1GenerationCap = GVoxelForgeStep1GenerationCap;
|
int32 CommandLineStep1GenerationCap = GVoxelForgeStep1GenerationCap;
|
||||||
int32 CommandLineStep1ExitAfterFrames = GVoxelForgeStep1ExitAfterFrames;
|
int32 CommandLineStep1ExitAfterFrames = GVoxelForgeStep1ExitAfterFrames;
|
||||||
int32 CommandLineStep1CsvCaptureOnBeginPlay = GVoxelForgeStep1CsvCaptureOnBeginPlay;
|
int32 CommandLineStep1CsvCaptureOnBeginPlay = GVoxelForgeStep1CsvCaptureOnBeginPlay;
|
||||||
@@ -2186,6 +2200,18 @@ void AVoxelWorld::BeginPlay()
|
|||||||
GVoxelForgeStreamingBackgroundWorkerCap =
|
GVoxelForgeStreamingBackgroundWorkerCap =
|
||||||
CommandLineStreamingBackgroundWorkerCap != 0 ? 1 : 0;
|
CommandLineStreamingBackgroundWorkerCap != 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.CoreColumnCacheDirectMapped="),
|
||||||
|
CommandLineCoreColumnCacheDirectMapped))
|
||||||
|
{
|
||||||
|
GVoxelForgeCoreColumnCacheDirectMapped=
|
||||||
|
CommandLineCoreColumnCacheDirectMapped!=0?1:0;
|
||||||
|
}
|
||||||
|
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.CoreMCGradientMemoization="),
|
||||||
|
CommandLineCoreMCGradientMemoization))
|
||||||
|
{
|
||||||
|
GVoxelForgeCoreMCGradientMemoization=
|
||||||
|
CommandLineCoreMCGradientMemoization!=0?1:0;
|
||||||
|
}
|
||||||
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.Step1PrequeueVisibleLOD0="),
|
if (FParse::Value(FCommandLine::Get(), TEXT("voxel.Step1PrequeueVisibleLOD0="),
|
||||||
CommandLineStep1PrequeueVisibleLOD0))
|
CommandLineStep1PrequeueVisibleLOD0))
|
||||||
{
|
{
|
||||||
@@ -2609,7 +2635,9 @@ void AVoxelWorld::BeginPlay()
|
|||||||
"\"streaming_legacy_pending_result_cap\":%d,"
|
"\"streaming_legacy_pending_result_cap\":%d,"
|
||||||
"\"streaming_collision_lookahead\":%d,\"core_region_concurrent_admission\":%d,"
|
"\"streaming_collision_lookahead\":%d,\"core_region_concurrent_admission\":%d,"
|
||||||
"\"collision_gate\":%d,"
|
"\"collision_gate\":%d,"
|
||||||
"\"streaming_result_backlog_cap\":%d,\"streaming_startup_apply_boost\":%d"),
|
"\"streaming_result_backlog_cap\":%d,\"streaming_startup_apply_boost\":%d,"
|
||||||
|
"\"core_column_cache_direct_mapped\":%d,"
|
||||||
|
"\"core_mc_gradient_memoization\":%d"),
|
||||||
FPlatformMisc::NumberOfCoresIncludingHyperthreads(), GetMaxConcurrentStreamingTasks(),
|
FPlatformMisc::NumberOfCoresIncludingHyperthreads(), GetMaxConcurrentStreamingTasks(),
|
||||||
TaskScheduler.GetNumWorkers(), TaskScheduler.GetMaxNumWorkers(),
|
TaskScheduler.GetNumWorkers(), TaskScheduler.GetMaxNumWorkers(),
|
||||||
static_cast<int32>(TaskScheduler.GetWorkerPriority()),
|
static_cast<int32>(TaskScheduler.GetWorkerPriority()),
|
||||||
@@ -2622,7 +2650,9 @@ void AVoxelWorld::BeginPlay()
|
|||||||
GVoxelForgeStreamingLegacyPendingResultCap,
|
GVoxelForgeStreamingLegacyPendingResultCap,
|
||||||
GVoxelForgeStreamingCollisionLookahead, GVoxelForgeCoreRegionConcurrentAdmission,
|
GVoxelForgeStreamingCollisionLookahead, GVoxelForgeCoreRegionConcurrentAdmission,
|
||||||
GVoxelForgeCollisionGate,
|
GVoxelForgeCollisionGate,
|
||||||
GVoxelForgeStreamingResultBacklogCap, GVoxelForgeStreamingStartupApplyBoost));
|
GVoxelForgeStreamingResultBacklogCap, GVoxelForgeStreamingStartupApplyBoost,
|
||||||
|
GVoxelForgeCoreColumnCacheDirectMapped,
|
||||||
|
GVoxelForgeCoreMCGradientMemoization));
|
||||||
VoxelForgeStartupTrace::RecordEvent(TEXT("streaming_worker_cap_readback"), FString::Printf(
|
VoxelForgeStartupTrace::RecordEvent(TEXT("streaming_worker_cap_readback"), FString::Printf(
|
||||||
TEXT("\"streaming_background_worker_cap\":%d,\"background_worker_threads\":%d,"
|
TEXT("\"streaming_background_worker_cap\":%d,\"background_worker_threads\":%d,"
|
||||||
"\"effective_tile_slots\":%d"),
|
"\"effective_tile_slots\":%d"),
|
||||||
@@ -13043,13 +13073,15 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
|
|||||||
VoxelForgeStartupTrace::RecordRequest(RequestSample, TaskEpoch);
|
VoxelForgeStartupTrace::RecordRequest(RequestSample, TaskEpoch);
|
||||||
}
|
}
|
||||||
const bool bCaptureHashes = bCaptureVoxelForgeCoreHashesForValidation;
|
const bool bCaptureHashes = bCaptureVoxelForgeCoreHashesForValidation;
|
||||||
|
const bool bLegacyDirectMappedColumnCache=GVoxelForgeCoreColumnCacheDirectMapped!=0;
|
||||||
|
const bool bMemoizeCoreMCGradients=GVoxelForgeCoreMCGradientMemoization!=0;
|
||||||
const UE::Tasks::ETaskPriority TaskPriority = bNearPriority
|
const UE::Tasks::ETaskPriority TaskPriority = bNearPriority
|
||||||
? UE::Tasks::ETaskPriority::BackgroundHigh
|
? UE::Tasks::ETaskPriority::BackgroundHigh
|
||||||
: UE::Tasks::ETaskPriority::BackgroundNormal;
|
: UE::Tasks::ETaskPriority::BackgroundNormal;
|
||||||
UE::Tasks::Launch(TEXT("VoxelForgeCoreTile"),
|
UE::Tasks::Launch(TEXT("VoxelForgeCoreTile"),
|
||||||
[this, State, Cancellation, Tile, WorkPriority, TaskEpoch, TaskDesiredEpoch,
|
[this, State, Cancellation, Tile, WorkPriority, TaskEpoch, TaskDesiredEpoch,
|
||||||
TaskModificationEpoch, RequestStartCycles, RequestOrdinal, bResidentAtRequest,
|
TaskModificationEpoch, RequestStartCycles, RequestOrdinal, bResidentAtRequest,
|
||||||
bCaptureHashes]()
|
bCaptureHashes,bLegacyDirectMappedColumnCache,bMemoizeCoreMCGradients]()
|
||||||
{
|
{
|
||||||
struct FTaskGuard
|
struct FTaskGuard
|
||||||
{
|
{
|
||||||
@@ -13153,6 +13185,8 @@ void AVoxelWorld::LoadCoreTile(const FVoxelTileKey& Tile, EVoxelTileWorkPriority
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Options.hashDensity = bCaptureHashes;
|
Options.hashDensity = bCaptureHashes;
|
||||||
|
Options.legacyDirectMappedColumnCache=bLegacyDirectMappedColumnCache;
|
||||||
|
Options.memoizeMcGradients=bMemoizeCoreMCGradients;
|
||||||
std::string CoreError;
|
std::string CoreError;
|
||||||
std::optional<VoxelForgeCore::TileMesh> CoreMesh;
|
std::optional<VoxelForgeCore::TileMesh> CoreMesh;
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16204,10 +16204,10 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
|
|||||||
}
|
}
|
||||||
VoxelForgeCore::Heightfield2D::resetThreadColumnCacheStats(false,true,0);
|
VoxelForgeCore::Heightfield2D::resetThreadColumnCacheStats(false,true,0);
|
||||||
}
|
}
|
||||||
for (const int32 LOD : {0,1,3,4,5,8})
|
for (const int32 LOD : {0,1,2,3,4,5,6,7,8})
|
||||||
{
|
{
|
||||||
TArray<double> FullTimes,CandidateTimes,FullShellTimes,CandidateShellTimes,ListTimes;
|
TArray<double> FullTimes,CandidateTimes,FullShellTimes,CandidateShellTimes,ListTimes;
|
||||||
TArray<double> UnknownBoxes,FieldCalls,ColumnMisses,StratumShellTimes,ConnectorShellTimes;
|
TArray<double> UnknownBoxes,FieldCalls,UnclampedFieldCalls,ColumnMisses,ColumnConflictMisses,StratumShellTimes,ConnectorShellTimes;
|
||||||
TArray<double> DensitySamples,ClassificationTimes,ClassificationExclusiveTimes;
|
TArray<double> DensitySamples,ClassificationTimes,ClassificationExclusiveTimes;
|
||||||
TArray<double> ColumnComputeTimes,MeshingTimes,HorizonTimes,RepairSkipped;
|
TArray<double> ColumnComputeTimes,MeshingTimes,HorizonTimes,RepairSkipped;
|
||||||
TArray<double> ColumnEvalExclusiveTimes,MarchingExclusiveTimes,GroundRefineExclusiveTimes;
|
TArray<double> ColumnEvalExclusiveTimes,MarchingExclusiveTimes,GroundRefineExclusiveTimes;
|
||||||
@@ -16216,13 +16216,29 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
|
|||||||
TArray<double> ClassificationNsPerSample,ColumnNsPerSample,MarchingNsPerSample;
|
TArray<double> ClassificationNsPerSample,ColumnNsPerSample,MarchingNsPerSample;
|
||||||
TArray<double> GroundNsPerSample,CapNsPerSample,AssemblyNsPerSample,ListNsPerSample;
|
TArray<double> GroundNsPerSample,CapNsPerSample,AssemblyNsPerSample,ListNsPerSample;
|
||||||
TArray<double> MarchingColumnNsPerSample,GroundColumnNsPerSample,CapColumnNsPerSample;
|
TArray<double> MarchingColumnNsPerSample,GroundColumnNsPerSample,CapColumnNsPerSample;
|
||||||
|
TArray<double> McProfileTotalTimes,McProfileGridTimes,McProfileGridExclusiveTimes;
|
||||||
|
TArray<double> McProfileCellTimes,McProfileNormalTimes,McProfileInterpolationTimes;
|
||||||
|
TArray<double> McProfileStreamTimes,McProfileOtherTimes,McProfileResidualTimes;
|
||||||
|
TArray<double> McProfileGradientFallbackCalls,McProfileEdgeMidpointCalls,McProfileGradientMemoHits;
|
||||||
|
TArray<double> McProfileGridNsPerSample,McProfileGridExclusiveNsPerSample;
|
||||||
|
TArray<double> McProfileCellNsPerSample,McProfileNormalNsPerSample;
|
||||||
|
TArray<double> McProfileInterpolationNsPerSample,McProfileStreamNsPerSample;
|
||||||
|
TArray<double> McProfileOtherNsPerSample,McProfileResidualNsPerSample;
|
||||||
TArray<double> StratumFieldCalls,ConnectorFieldCalls,ShellTriangles,GroundTriangles,GroundRemoved,CapTriangles;
|
TArray<double> StratumFieldCalls,ConnectorFieldCalls,ShellTriangles,GroundTriangles,GroundRemoved,CapTriangles;
|
||||||
|
const bool bMcStageAudit=FParse::Param(FCommandLine::Get(),TEXT("coremcstageaudit"));
|
||||||
|
int32 AuditDirectMappedColumnCache=0,AuditMemoizeMcGradients=1;
|
||||||
|
FParse::Value(FCommandLine::Get(),TEXT("voxel.CoreColumnCacheDirectMapped="),
|
||||||
|
AuditDirectMappedColumnCache);
|
||||||
|
FParse::Value(FCommandLine::Get(),TEXT("voxel.CoreMCGradientMemoization="),
|
||||||
|
AuditMemoizeMcGradients);
|
||||||
for (const auto& Key : Keys)
|
for (const auto& Key : Keys)
|
||||||
{
|
{
|
||||||
if (Key.lod!=LOD || FullTimes.Num()>=8) continue;
|
if (Key.lod!=LOD || FullTimes.Num()>=8) continue;
|
||||||
VoxelForgeCore::TileGenerationOptions Options;
|
VoxelForgeCore::TileGenerationOptions Options;
|
||||||
Options.hashDensity=true;
|
Options.hashDensity=true;
|
||||||
Options.useAssemblyFeatureQueries=false;
|
Options.useAssemblyFeatureQueries=false;
|
||||||
|
Options.legacyDirectMappedColumnCache=AuditDirectMappedColumnCache!=0;
|
||||||
|
Options.memoizeMcGradients=AuditMemoizeMcGradients!=0;
|
||||||
std::string Error;
|
std::string Error;
|
||||||
// Check density and mesh parity with hashes, then time uncached runtime generation.
|
// Check density and mesh parity with hashes, then time uncached runtime generation.
|
||||||
// Verifier la parite avec hashes, puis mesurer la generation sans cache de colonnes.
|
// Verifier la parite avec hashes, puis mesurer la generation sans cache de colonnes.
|
||||||
@@ -16256,7 +16272,9 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
|
|||||||
DensitySamples.Add(static_cast<double>(Candidate->densitySampleCount));
|
DensitySamples.Add(static_cast<double>(Candidate->densitySampleCount));
|
||||||
UnknownBoxes.Add(static_cast<double>(Diagnostics.unknownBoxes));
|
UnknownBoxes.Add(static_cast<double>(Diagnostics.unknownBoxes));
|
||||||
FieldCalls.Add(static_cast<double>(Diagnostics.fieldCalls));
|
FieldCalls.Add(static_cast<double>(Diagnostics.fieldCalls));
|
||||||
|
UnclampedFieldCalls.Add(static_cast<double>(Diagnostics.unclampedFieldCalls));
|
||||||
ColumnMisses.Add(static_cast<double>(Diagnostics.columnCacheMisses));
|
ColumnMisses.Add(static_cast<double>(Diagnostics.columnCacheMisses));
|
||||||
|
ColumnConflictMisses.Add(static_cast<double>(Diagnostics.columnCacheConflictMisses));
|
||||||
ClassificationTimes.Add(Diagnostics.classificationMilliseconds);
|
ClassificationTimes.Add(Diagnostics.classificationMilliseconds);
|
||||||
ClassificationExclusiveTimes.Add(Diagnostics.classificationExclusiveMilliseconds);
|
ClassificationExclusiveTimes.Add(Diagnostics.classificationExclusiveMilliseconds);
|
||||||
ColumnComputeTimes.Add(Diagnostics.columnComputeMilliseconds);
|
ColumnComputeTimes.Add(Diagnostics.columnComputeMilliseconds);
|
||||||
@@ -16301,13 +16319,66 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
|
|||||||
*1000000.0/SampleCount);
|
*1000000.0/SampleCount);
|
||||||
ListNsPerSample.Add(Diagnostics.featureListMilliseconds*1000000.0/SampleCount);
|
ListNsPerSample.Add(Diagnostics.featureListMilliseconds*1000000.0/SampleCount);
|
||||||
}
|
}
|
||||||
|
if(bMcStageAudit)
|
||||||
|
{
|
||||||
|
// Profile a separate cold tile so the audit's ordinary timing rows keep the
|
||||||
|
// uninstrumented path and comparable clock scope.
|
||||||
|
// Profiler une tuile froide separee pour garder les mesures ordinaires sans instrumentation.
|
||||||
|
Options.profileMesherStages=true;
|
||||||
|
VoxelForgeCore::Heightfield2D::resetThreadColumnCacheStats(false,true);
|
||||||
|
auto Profiled=World.generateTile(Key,Options,Error);
|
||||||
|
Options.profileMesherStages=false;
|
||||||
|
if(!Profiled)
|
||||||
|
{ OutError=TEXT("Cold MC stage profile tile generation failed."); return false; }
|
||||||
|
const auto& Mc=Profiled->diagnostics;
|
||||||
|
const double Total=Mc.marchingCubesExclusiveMilliseconds
|
||||||
|
+Mc.marchingCubesColumnComputeMilliseconds;
|
||||||
|
const double Grid=Mc.marchingCubesDensityGridMilliseconds;
|
||||||
|
const double GridExclusive=FMath::Max(0.0,Grid
|
||||||
|
-Mc.marchingCubesColumnComputeMilliseconds);
|
||||||
|
const double Cell=Mc.marchingCubesCellClassificationMilliseconds;
|
||||||
|
const double Normal=Mc.marchingCubesGradientNormalsMilliseconds;
|
||||||
|
const double Interpolation=Mc.marchingCubesEdgeInterpolationMilliseconds;
|
||||||
|
const double Stream=Mc.marchingCubesVertexDedupStreamMilliseconds;
|
||||||
|
const double Other=Mc.marchingCubesOtherMilliseconds;
|
||||||
|
const double Residual=FMath::Max(0.0,Mc.marchingCubesExclusiveMilliseconds
|
||||||
|
-GridExclusive-Cell-Normal-Interpolation-Stream);
|
||||||
|
McProfileTotalTimes.Add(Total);
|
||||||
|
McProfileGridTimes.Add(Grid);
|
||||||
|
McProfileGridExclusiveTimes.Add(GridExclusive);
|
||||||
|
McProfileCellTimes.Add(Cell);
|
||||||
|
McProfileNormalTimes.Add(Normal);
|
||||||
|
McProfileInterpolationTimes.Add(Interpolation);
|
||||||
|
McProfileStreamTimes.Add(Stream);
|
||||||
|
McProfileOtherTimes.Add(Other);
|
||||||
|
McProfileResidualTimes.Add(Residual);
|
||||||
|
McProfileGradientFallbackCalls.Add(static_cast<double>(
|
||||||
|
Mc.marchingCubesGradientFallbackDensityCalls));
|
||||||
|
McProfileEdgeMidpointCalls.Add(static_cast<double>(
|
||||||
|
Mc.marchingCubesEdgeMidpointDensityCalls));
|
||||||
|
McProfileGradientMemoHits.Add(static_cast<double>(
|
||||||
|
Mc.marchingCubesGradientMemoHits));
|
||||||
|
const double ProfileSamples=static_cast<double>(Profiled->densitySampleCount);
|
||||||
|
if(ProfileSamples>0.0)
|
||||||
|
{
|
||||||
|
McProfileGridNsPerSample.Add(Grid*1000000.0/ProfileSamples);
|
||||||
|
McProfileGridExclusiveNsPerSample.Add(GridExclusive*1000000.0/ProfileSamples);
|
||||||
|
McProfileCellNsPerSample.Add(Cell*1000000.0/ProfileSamples);
|
||||||
|
McProfileNormalNsPerSample.Add(Normal*1000000.0/ProfileSamples);
|
||||||
|
McProfileInterpolationNsPerSample.Add(Interpolation*1000000.0/ProfileSamples);
|
||||||
|
McProfileStreamNsPerSample.Add(Stream*1000000.0/ProfileSamples);
|
||||||
|
McProfileOtherNsPerSample.Add(Other*1000000.0/ProfileSamples);
|
||||||
|
McProfileResidualNsPerSample.Add(Residual*1000000.0/ProfileSamples);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const auto P95=[](TArray<double> Values)
|
const auto P95=[](TArray<double> Values)
|
||||||
{ Values.Sort(); return Values.IsEmpty() ? 0.0 : Values[FMath::Clamp(
|
{ Values.Sort(); return Values.IsEmpty() ? 0.0 : Values[FMath::Clamp(
|
||||||
FMath::CeilToInt(Values.Num()*0.95f)-1,0,Values.Num()-1)]; };
|
FMath::CeilToInt(Values.Num()*0.95f)-1,0,Values.Num()-1)]; };
|
||||||
UE_LOG(LogTemp,Display,
|
UE_LOG(LogTemp,Display,
|
||||||
TEXT("[VoxelForgeSharedFeatureCost] label=%s lod=%d tiles=%d hashes_identical=1 full_p95_ms=%.5f candidate_p95_ms=%.5f list_p95_ms=%.5f classification_wall_p95_ms=%.5f classification_exclusive_p95_ms=%.5f column_compute_p95_ms=%.5f column_eval_exclusive_p95_ms=%.5f mc_column_compute_p95_ms=%.5f mc_exclusive_p95_ms=%.5f ground_column_compute_p95_ms=%.5f ground_refine_exclusive_p95_ms=%.5f cap_column_compute_p95_ms=%.5f cap_refine_exclusive_p95_ms=%.5f mesh_assembly_p95_ms=%.5f meshing_p95_ms=%.5f horizon_p95_ms=%.5f samples_p95=%.0f classification_ns_per_sample_p95=%.2f column_ns_per_sample_p95=%.2f mc_column_ns_per_sample_p95=%.2f mc_ns_per_sample_p95=%.2f ground_column_ns_per_sample_p95=%.2f ground_ns_per_sample_p95=%.2f cap_column_ns_per_sample_p95=%.2f cap_ns_per_sample_p95=%.2f assembly_ns_per_sample_p95=%.2f feature_list_ns_per_sample_p95=%.2f full_shell_p95_ms=%.5f candidate_shell_p95_ms=%.5f repair_skipped_p95=%.0f unknown_boxes_p95=%.0f field_calls_p95=%.0f column_misses_p95=%.0f stratum_shell_p95_ms=%.5f stratum_field_calls_p95=%.0f connector_shell_p95_ms=%.5f connector_field_calls_p95=%.0f shell_triangles_p95=%.0f horizon_ground_triangles_p95=%.0f horizon_ground_removed_p95=%.0f horizon_cap_triangles_p95=%.0f"),
|
TEXT("[VoxelForgeSharedFeatureCost] label=%s lod=%d column_cache_direct_mapped=%d gradient_memoization=%d tiles=%d hashes_identical=1 full_p95_ms=%.5f candidate_p95_ms=%.5f list_p95_ms=%.5f classification_wall_p95_ms=%.5f classification_exclusive_p95_ms=%.5f column_compute_p95_ms=%.5f column_eval_exclusive_p95_ms=%.5f mc_column_compute_p95_ms=%.5f mc_exclusive_p95_ms=%.5f ground_column_compute_p95_ms=%.5f ground_refine_exclusive_p95_ms=%.5f cap_column_compute_p95_ms=%.5f cap_refine_exclusive_p95_ms=%.5f mesh_assembly_p95_ms=%.5f meshing_p95_ms=%.5f horizon_p95_ms=%.5f samples_p95=%.0f classification_ns_per_sample_p95=%.2f column_ns_per_sample_p95=%.2f mc_column_ns_per_sample_p95=%.2f mc_ns_per_sample_p95=%.2f ground_column_ns_per_sample_p95=%.2f ground_ns_per_sample_p95=%.2f cap_column_ns_per_sample_p95=%.2f cap_ns_per_sample_p95=%.2f assembly_ns_per_sample_p95=%.2f feature_list_ns_per_sample_p95=%.2f full_shell_p95_ms=%.5f candidate_shell_p95_ms=%.5f repair_skipped_p95=%.0f unknown_boxes_p95=%.0f field_calls_p95=%.0f unclamped_field_calls_p95=%.0f column_misses_p95=%.0f column_conflict_misses_p95=%.0f stratum_shell_p95_ms=%.5f stratum_field_calls_p95=%.0f connector_shell_p95_ms=%.5f connector_field_calls_p95=%.0f shell_triangles_p95=%.0f horizon_ground_triangles_p95=%.0f horizon_ground_removed_p95=%.0f horizon_cap_triangles_p95=%.0f"),
|
||||||
Label,LOD,FullTimes.Num(),P95(FullTimes),P95(CandidateTimes),P95(ListTimes),
|
Label,LOD,AuditDirectMappedColumnCache!=0?1:0,AuditMemoizeMcGradients!=0?1:0,
|
||||||
|
FullTimes.Num(),P95(FullTimes),P95(CandidateTimes),P95(ListTimes),
|
||||||
P95(ClassificationTimes),P95(ClassificationExclusiveTimes),P95(ColumnComputeTimes),
|
P95(ClassificationTimes),P95(ClassificationExclusiveTimes),P95(ColumnComputeTimes),
|
||||||
P95(ColumnEvalExclusiveTimes),P95(MarchingColumnTimes),P95(MarchingExclusiveTimes),
|
P95(ColumnEvalExclusiveTimes),P95(MarchingColumnTimes),P95(MarchingExclusiveTimes),
|
||||||
P95(GroundColumnTimes),P95(GroundRefineExclusiveTimes),P95(CapColumnTimes),
|
P95(GroundColumnTimes),P95(GroundRefineExclusiveTimes),P95(CapColumnTimes),
|
||||||
@@ -16317,9 +16388,24 @@ bool RunCoreSharedFeatureCostAudit(VoxelForgeCore::World& World,
|
|||||||
P95(MarchingNsPerSample),P95(GroundColumnNsPerSample),P95(GroundNsPerSample),
|
P95(MarchingNsPerSample),P95(GroundColumnNsPerSample),P95(GroundNsPerSample),
|
||||||
P95(CapColumnNsPerSample),P95(CapNsPerSample),P95(AssemblyNsPerSample),P95(ListNsPerSample),
|
P95(CapColumnNsPerSample),P95(CapNsPerSample),P95(AssemblyNsPerSample),P95(ListNsPerSample),
|
||||||
P95(FullShellTimes),P95(CandidateShellTimes),P95(RepairSkipped),P95(UnknownBoxes),P95(FieldCalls),
|
P95(FullShellTimes),P95(CandidateShellTimes),P95(RepairSkipped),P95(UnknownBoxes),P95(FieldCalls),
|
||||||
P95(ColumnMisses),P95(StratumShellTimes),P95(StratumFieldCalls),
|
P95(UnclampedFieldCalls),
|
||||||
|
P95(ColumnMisses),P95(ColumnConflictMisses),P95(StratumShellTimes),P95(StratumFieldCalls),
|
||||||
P95(ConnectorShellTimes),P95(ConnectorFieldCalls),P95(ShellTriangles),
|
P95(ConnectorShellTimes),P95(ConnectorFieldCalls),P95(ShellTriangles),
|
||||||
P95(GroundTriangles),P95(GroundRemoved),P95(CapTriangles));
|
P95(GroundTriangles),P95(GroundRemoved),P95(CapTriangles));
|
||||||
|
if(bMcStageAudit)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp,Display,
|
||||||
|
TEXT("[VoxelForgeMCStageCost] label=%s lod=%d tiles=%d sampling=row_total_and_1_of_8_cells total_p95_ms=%.5f density_grid_inclusive_p95_ms=%.5f density_grid_ex_column_p95_ms=%.5f cell_classification_p95_ms=%.5f gradient_normals_p95_ms=%.5f edge_interpolation_p95_ms=%.5f vertex_dedup_stream_p95_ms=%.5f setup_finalization_p95_ms=%.5f unassigned_residual_p95_ms=%.5f grid_ns_per_sample_p95=%.2f grid_ex_column_ns_per_sample_p95=%.2f cell_ns_per_sample_p95=%.2f normals_ns_per_sample_p95=%.2f interpolation_ns_per_sample_p95=%.2f dedup_stream_ns_per_sample_p95=%.2f setup_finalization_ns_per_sample_p95=%.2f residual_ns_per_sample_p95=%.2f gradient_fallback_density_calls_p95=%.0f edge_midpoint_density_probes_p95=%.0f gradient_memo_hits_p95=%.0f"),
|
||||||
|
Label,LOD,McProfileTotalTimes.Num(),P95(McProfileTotalTimes),P95(McProfileGridTimes),
|
||||||
|
P95(McProfileGridExclusiveTimes),P95(McProfileCellTimes),P95(McProfileNormalTimes),
|
||||||
|
P95(McProfileInterpolationTimes),P95(McProfileStreamTimes),P95(McProfileOtherTimes),
|
||||||
|
P95(McProfileResidualTimes),P95(McProfileGridNsPerSample),
|
||||||
|
P95(McProfileGridExclusiveNsPerSample),P95(McProfileCellNsPerSample),
|
||||||
|
P95(McProfileNormalNsPerSample),P95(McProfileInterpolationNsPerSample),
|
||||||
|
P95(McProfileStreamNsPerSample),P95(McProfileOtherNsPerSample),
|
||||||
|
P95(McProfileResidualNsPerSample),P95(McProfileGradientFallbackCalls),
|
||||||
|
P95(McProfileEdgeMidpointCalls),P95(McProfileGradientMemoHits));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(Assembly!=nullptr&&!Assembly->plan.strates.empty())
|
if(Assembly!=nullptr&&!Assembly->plan.strates.empty())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ "${VOXELFORGE_LIMITED_BUILD:-0}" != "1" ]]; then
|
||||||
|
exec taskset -c 0-11 prlimit --as=6442450944 -- env VOXELFORGE_LIMITED_BUILD=1 "$0" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ROOT="$SCRIPT_DIR"
|
||||||
|
COMPILER="clang++-19"
|
||||||
|
VARIANT="clang19"
|
||||||
|
FP_CONTRACT="off"
|
||||||
|
JOBS=12
|
||||||
|
|
||||||
|
while (($#)); do
|
||||||
|
case "$1" in
|
||||||
|
--compiler=*) COMPILER="${1#*=}" ;;
|
||||||
|
--variant=*) VARIANT="${1#*=}" ;;
|
||||||
|
--fp-contract=*) FP_CONTRACT="${1#*=}" ;;
|
||||||
|
--jobs=*) JOBS="${1#*=}" ;;
|
||||||
|
*) printf 'Unknown build option: %s\n' "$1" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ! "$JOBS" =~ ^[0-9]+$ ]] || ((JOBS < 1 || JOBS > 12)); then
|
||||||
|
printf 'jobs must be from 1 to 12\n' >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
if [[ "$FP_CONTRACT" != "default" && "$FP_CONTRACT" != "off" && "$FP_CONTRACT" != "on" && "$FP_CONTRACT" != "fast" ]]; then
|
||||||
|
printf 'fp-contract must be default, off, on, or fast\n' >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
command -v "$COMPILER" >/dev/null || { printf 'Compiler not found: %s\n' "$COMPILER" >&2; exit 2; }
|
||||||
|
command -v ar >/dev/null || { printf 'ar not found\n' >&2; exit 2; }
|
||||||
|
command -v pkg-config >/dev/null || { printf 'pkg-config not found\n' >&2; exit 2; }
|
||||||
|
pkg-config --exists egl glesv2 libpng || { printf 'EGL, GLESv2, and libpng development files are required\n' >&2; exit 2; }
|
||||||
|
|
||||||
|
BUILD_DIR="$ROOT/Build/linux-$VARIANT"
|
||||||
|
BIN_DIR="$ROOT/bin/linux"
|
||||||
|
mkdir -p "$BUILD_DIR/wrappers" "$BUILD_DIR/objects" "$BIN_DIR"
|
||||||
|
|
||||||
|
INCLUDES=(
|
||||||
|
"-I$ROOT/Core/include"
|
||||||
|
"-I$ROOT/Core/src"
|
||||||
|
"-I$ROOT/Compat"
|
||||||
|
"-I$ROOT/Source"
|
||||||
|
"-I$ROOT/Source/VoxelForge/Public"
|
||||||
|
"-I$ROOT/Source/VoxelForge/Private"
|
||||||
|
)
|
||||||
|
FLAGS=(
|
||||||
|
-std=c++20 -O2 -mavx2 -mfma -fno-fast-math
|
||||||
|
-fexceptions -pthread "${INCLUDES[@]}"
|
||||||
|
)
|
||||||
|
if [[ "$FP_CONTRACT" != "default" ]]; then
|
||||||
|
FLAGS+=("-ffp-contract=$FP_CONTRACT")
|
||||||
|
fi
|
||||||
|
if [[ "$($COMPILER --version | head -n 1)" == *clang* ]]; then
|
||||||
|
FLAGS+=(-Wno-c++11-narrowing)
|
||||||
|
else
|
||||||
|
FLAGS+=(-Wno-narrowing)
|
||||||
|
fi
|
||||||
|
|
||||||
|
CORE_OBJECTS=()
|
||||||
|
LEGACY_OBJECTS=()
|
||||||
|
PIDS=()
|
||||||
|
wait_oldest() {
|
||||||
|
local pid="${PIDS[0]}"
|
||||||
|
wait "$pid"
|
||||||
|
PIDS=("${PIDS[@]:1}")
|
||||||
|
}
|
||||||
|
compile_background() {
|
||||||
|
local source="$1" output="$2"
|
||||||
|
"$COMPILER" "${FLAGS[@]}" -c "$source" -o "$output" &
|
||||||
|
PIDS+=("$!")
|
||||||
|
if ((${#PIDS[@]} >= JOBS)); then wait_oldest; fi
|
||||||
|
}
|
||||||
|
|
||||||
|
while IFS= read -r source_name || [[ -n "$source_name" ]]; do
|
||||||
|
source_name="${source_name%%#*}"
|
||||||
|
source_name="${source_name//[[:space:]]/}"
|
||||||
|
[[ -z "$source_name" ]] && continue
|
||||||
|
source_path="$ROOT/$source_name"
|
||||||
|
[[ -f "$source_path" ]] || { printf 'Missing source from core_sources.txt: %s\n' "$source_name" >&2; exit 2; }
|
||||||
|
if [[ "$source_name" == "Core/src/VoxelForgeCore.cpp" ]]; then
|
||||||
|
object="$BUILD_DIR/objects/VoxelForgeCore.o"
|
||||||
|
compile_background "$source_path" "$object"
|
||||||
|
CORE_OBJECTS+=("$object")
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
wrapper_name="vfcore_${source_name//[^A-Za-z0-9]/_}"
|
||||||
|
wrapper="$BUILD_DIR/wrappers/$wrapper_name.cpp"
|
||||||
|
cat > "$wrapper" <<WRAPPER
|
||||||
|
#include "CoreNamespacePreamble.h"
|
||||||
|
namespace vfcore::detail
|
||||||
|
{
|
||||||
|
#include "$source_path"
|
||||||
|
}
|
||||||
|
WRAPPER
|
||||||
|
object="$BUILD_DIR/objects/$wrapper_name.o"
|
||||||
|
compile_background "$wrapper" "$object"
|
||||||
|
CORE_OBJECTS+=("$object")
|
||||||
|
|
||||||
|
# The same copied compatibility implementations are also needed by the standalone owner
|
||||||
|
# loader/mesher host. They are compiled globally for that reference layer, as in Build.ps1.
|
||||||
|
legacy_object="$BUILD_DIR/objects/legacy_${wrapper_name}.o"
|
||||||
|
compile_background "$source_path" "$legacy_object"
|
||||||
|
LEGACY_OBJECTS+=("$legacy_object")
|
||||||
|
done < "$ROOT/Core/core_sources.txt"
|
||||||
|
|
||||||
|
headless_object="$BUILD_DIR/objects/StreamBenchmarkHeadless.o"
|
||||||
|
compile_background "$ROOT/Source/StreamBenchmarkHeadless.cpp" "$headless_object"
|
||||||
|
LEGACY_OBJECTS+=("$headless_object")
|
||||||
|
|
||||||
|
for pid in "${PIDS[@]}"; do wait "$pid"; done
|
||||||
|
PIDS=()
|
||||||
|
|
||||||
|
CORE_LIBRARY="$BUILD_DIR/libVoxelForgeCore.a"
|
||||||
|
"$(command -v ar)" rcs "$CORE_LIBRARY" "${CORE_OBJECTS[@]}"
|
||||||
|
OUTPUT="$BIN_DIR/VoxelForgeCoreHeadless-$VARIANT"
|
||||||
|
"$COMPILER" -pthread "${LEGACY_OBJECTS[@]}" "$CORE_LIBRARY" -o "$OUTPUT"
|
||||||
|
CAPTURE_OUTPUT="$BIN_DIR/VoxelForgeOffscreenCapture-$VARIANT"
|
||||||
|
"$COMPILER" -std=c++20 -O2 -fno-fast-math -pthread \
|
||||||
|
"$ROOT/Source/LinuxOffscreenCapture.cpp" -o "$CAPTURE_OUTPUT" \
|
||||||
|
$(pkg-config --cflags --libs egl glesv2 libpng)
|
||||||
|
printf 'Built Core library: %s\nBuilt headless benchmark: %s\n' "$CORE_LIBRARY" "$OUTPUT"
|
||||||
|
printf 'Built EGL offscreen capture: %s\n' "$CAPTURE_OUTPUT"
|
||||||
|
printf 'Compiler: %s | variant: %s | fp-contract: %s | jobs: %s\n' "$COMPILER" "$VARIANT" "$FP_CONTRACT" "$JOBS"
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <cfloat>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ void UVoxelStrateDefinition::PostLoad()
|
|||||||
GenerationParams.bTunnelFloorEnabled = true;
|
GenerationParams.bTunnelFloorEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FPrimaryAssetId UVoxelSeasonAsset::GetPrimaryAssetId() const
|
||||||
|
{
|
||||||
|
return FPrimaryAssetId(TEXT("VoxelSeason"),GetFName());
|
||||||
|
}
|
||||||
|
|
||||||
bool UVoxelSeasonAsset::LoadManifest(FVoxelSeasonManifest& OutManifest, FString& OutReport) const
|
bool UVoxelSeasonAsset::LoadManifest(FVoxelSeasonManifest& OutManifest, FString& OutReport) const
|
||||||
{
|
{
|
||||||
OutManifest = FVoxelSeasonManifest();
|
OutManifest = FVoxelSeasonManifest();
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Keep large worker caches out of each thread's eager ELF TLS image. Each handle is itself
|
||||||
|
// thread-local; its payload is allocated on the first use by that thread and released when the
|
||||||
|
// thread exits. The payload is never shared and this type has no synchronization.
|
||||||
|
namespace VoxelForgeCoreThreadLocal
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
class FLazy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FLazy() noexcept = default;
|
||||||
|
FLazy(const FLazy&) = delete;
|
||||||
|
FLazy& operator=(const FLazy&) = delete;
|
||||||
|
|
||||||
|
~FLazy()
|
||||||
|
{
|
||||||
|
delete Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& Get()
|
||||||
|
{
|
||||||
|
if (Value == nullptr)
|
||||||
|
{
|
||||||
|
Value = new T{};
|
||||||
|
}
|
||||||
|
return *Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* Value = nullptr;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -123,6 +123,7 @@ namespace VoxelForgeCore
|
|||||||
std::uint64_t unclampedFieldCalls = 0;
|
std::uint64_t unclampedFieldCalls = 0;
|
||||||
std::uint64_t columnCacheHits = 0;
|
std::uint64_t columnCacheHits = 0;
|
||||||
std::uint64_t columnCacheMisses = 0;
|
std::uint64_t columnCacheMisses = 0;
|
||||||
|
std::uint64_t columnCacheConflictMisses = 0;
|
||||||
double classificationMilliseconds = 0.0;
|
double classificationMilliseconds = 0.0;
|
||||||
double columnComputeMilliseconds = 0.0;
|
double columnComputeMilliseconds = 0.0;
|
||||||
double columnEvaluationExclusiveMilliseconds = 0.0;
|
double columnEvaluationExclusiveMilliseconds = 0.0;
|
||||||
@@ -131,6 +132,16 @@ namespace VoxelForgeCore
|
|||||||
double capRefinementColumnComputeMilliseconds = 0.0;
|
double capRefinementColumnComputeMilliseconds = 0.0;
|
||||||
double classificationExclusiveMilliseconds = 0.0;
|
double classificationExclusiveMilliseconds = 0.0;
|
||||||
double marchingCubesExclusiveMilliseconds = 0.0;
|
double marchingCubesExclusiveMilliseconds = 0.0;
|
||||||
|
double marchingCubesDensityGridMilliseconds = 0.0;
|
||||||
|
double marchingCubesCellClassificationMilliseconds = 0.0;
|
||||||
|
double marchingCubesGradientNormalsMilliseconds = 0.0;
|
||||||
|
double marchingCubesEdgeInterpolationMilliseconds = 0.0;
|
||||||
|
double marchingCubesVertexDedupStreamMilliseconds = 0.0;
|
||||||
|
double marchingCubesSkirtMilliseconds = 0.0;
|
||||||
|
double marchingCubesOtherMilliseconds = 0.0;
|
||||||
|
std::uint64_t marchingCubesGradientFallbackDensityCalls = 0;
|
||||||
|
std::uint64_t marchingCubesEdgeMidpointDensityCalls = 0;
|
||||||
|
std::uint64_t marchingCubesGradientMemoHits = 0;
|
||||||
double groundRefinementExclusiveMilliseconds = 0.0;
|
double groundRefinementExclusiveMilliseconds = 0.0;
|
||||||
double capRefinementExclusiveMilliseconds = 0.0;
|
double capRefinementExclusiveMilliseconds = 0.0;
|
||||||
double meshAssemblyMilliseconds = 0.0;
|
double meshAssemblyMilliseconds = 0.0;
|
||||||
@@ -639,6 +650,7 @@ namespace VoxelForgeCore
|
|||||||
std::uint64_t pointCalls = 0;
|
std::uint64_t pointCalls = 0;
|
||||||
std::uint64_t columnHits = 0;
|
std::uint64_t columnHits = 0;
|
||||||
std::uint64_t columnMisses = 0;
|
std::uint64_t columnMisses = 0;
|
||||||
|
std::uint64_t columnConflictMisses = 0;
|
||||||
double columnComputeMilliseconds = 0.0;
|
double columnComputeMilliseconds = 0.0;
|
||||||
bool captureCoordinates = false;
|
bool captureCoordinates = false;
|
||||||
bool coordinateCaptureComplete = true;
|
bool coordinateCaptureComplete = true;
|
||||||
@@ -693,6 +705,11 @@ namespace VoxelForgeCore
|
|||||||
std::int64_t maximumZSubvoxels, std::int32_t stepVoxels) const noexcept;
|
std::int64_t maximumZSubvoxels, std::int32_t stepVoxels) const noexcept;
|
||||||
static void resetThreadColumnCacheStats(bool captureCoordinates = false,
|
static void resetThreadColumnCacheStats(bool captureCoordinates = false,
|
||||||
bool clearCache = false, std::uint32_t octaveDrop = 0) noexcept;
|
bool clearCache = false, std::uint32_t octaveDrop = 0) noexcept;
|
||||||
|
static void setThreadColumnOctaveDrop(std::uint32_t octaveDrop) noexcept;
|
||||||
|
static std::uint32_t threadColumnOctaveDrop() noexcept;
|
||||||
|
static void setThreadColumnInterpolationStrideSubvoxels(std::int64_t stride) noexcept;
|
||||||
|
static std::int64_t threadColumnInterpolationStrideSubvoxels() noexcept;
|
||||||
|
static void setThreadColumnCacheLegacyDirectMapped(bool enabled) noexcept;
|
||||||
static const HeightfieldColumnCacheStats& threadColumnCacheStats() noexcept;
|
static const HeightfieldColumnCacheStats& threadColumnCacheStats() noexcept;
|
||||||
FieldInterval interval(std::int64_t minimumXSubvoxels,
|
FieldInterval interval(std::int64_t minimumXSubvoxels,
|
||||||
std::int64_t minimumYSubvoxels,
|
std::int64_t minimumYSubvoxels,
|
||||||
@@ -1021,6 +1038,15 @@ namespace VoxelForgeCore
|
|||||||
// Opt-in diagnostic only; records XY columns evaluated by this LOD8 tile.
|
// Opt-in diagnostic only; records XY columns evaluated by this LOD8 tile.
|
||||||
// Diagnostic seulement; enregistre les colonnes XY evaluees par cette tuile LOD8.
|
// Diagnostic seulement; enregistre les colonnes XY evaluees par cette tuile LOD8.
|
||||||
bool captureColumnCoordinates = false;
|
bool captureColumnCoordinates = false;
|
||||||
|
// Separate cold pass only; samples the MC inner stages without changing output.
|
||||||
|
// Passe froide separee seulement; mesure les etapes internes MC sans changer la sortie.
|
||||||
|
bool profileMesherStages = false;
|
||||||
|
// Negative control for the shared XY-column cache; 1 restores the old direct-map indexing.
|
||||||
|
// Controle negatif du cache XY partage; 1 restaure l'ancien indexage direct.
|
||||||
|
bool legacyDirectMappedColumnCache = false;
|
||||||
|
// Diagnostic/performance control; memoizes exact MC lattice gradients at LOD0.
|
||||||
|
// Controle de mesure/performance; memorise les gradients MC exacts au LOD0.
|
||||||
|
bool memoizeMcGradients = true;
|
||||||
// LOD8-only planar horizon interior grid; zero follows the MC step, 128 restores S9.
|
// LOD8-only planar horizon interior grid; zero follows the MC step, 128 restores S9.
|
||||||
// Grille interieure LOD8 seulement; zero suit la maille MC, 128 restaure S9.
|
// Grille interieure LOD8 seulement; zero suit la maille MC, 128 restaure S9.
|
||||||
std::int32_t lod8HorizonInteriorStepVoxels = 0;
|
std::int32_t lod8HorizonInteriorStepVoxels = 0;
|
||||||
@@ -1029,6 +1055,10 @@ namespace VoxelForgeCore
|
|||||||
// Incremente quand le plafond lointain change. Les hashes LOD4-8 incluent cette version;
|
// Incremente quand le plafond lointain change. Les hashes LOD4-8 incluent cette version;
|
||||||
// densite et hashes LOD0-3 restent inchanges.
|
// densite et hashes LOD0-3 restent inchanges.
|
||||||
std::uint32_t farHorizonVersion = 3;
|
std::uint32_t farHorizonVersion = 3;
|
||||||
|
// Linux research controls for reproducing L5 negative controls. Defaults preserve output.
|
||||||
|
std::uint32_t diagnosticGlobalOctaveDrop = 0;
|
||||||
|
std::uint32_t diagnosticCellStride = 1;
|
||||||
|
std::uint32_t diagnosticColumnInterpolationStride = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VFCORE_API World
|
class VFCORE_API World
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <charconv>
|
#include <charconv>
|
||||||
|
#include <cfloat>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -53,3 +54,41 @@
|
|||||||
// value tree shared lets the viewer resolve its reference world and Core snapshot from one parse.
|
// value tree shared lets the viewer resolve its reference world and Core snapshot from one parse.
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "VoxelForgeCore/VoxelForgeCore.h"
|
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||||
|
#include "VoxelForgeCore/ThreadLocalStorage.h"
|
||||||
|
|
||||||
|
// Keep Core's expression-level FMA behavior fixed regardless of the toolchain setting.
|
||||||
|
// Clang's "fast" mode ignores the pragma, so Core's runtime self-test rejects that build.
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang fp contract(off)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#pragma fp_contract(off)
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC optimize ("fp-contract=off")
|
||||||
|
#else
|
||||||
|
#error "VoxelForge Core requires a compiler-specific FP contraction control"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace vfcore::fp_contract
|
||||||
|
{
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define VFCORE_FP_PROBE_NOINLINE __declspec(noinline)
|
||||||
|
#else
|
||||||
|
#define VFCORE_FP_PROBE_NOINLINE __attribute__((noinline))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
[[maybe_unused]] static VFCORE_FP_PROBE_NOINLINE double multiplyAddProbe(
|
||||||
|
double a, double b, double c) noexcept
|
||||||
|
{
|
||||||
|
return a * b + c;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] static bool selfTest() noexcept
|
||||||
|
{
|
||||||
|
volatile double a = 1.0 + 0x1p-27;
|
||||||
|
volatile double b = 1.0 - 0x1p-27;
|
||||||
|
volatile double c = -1.0;
|
||||||
|
return multiplyAddProbe(a, b, c) == 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef VFCORE_FP_PROBE_NOINLINE
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "VoxelForgeCore/ThreadLocalStorage.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "VoxelForgeCore/VoxelForgeCore.h"
|
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||||
|
|
||||||
@@ -441,7 +442,9 @@ namespace floating_island_detail
|
|||||||
constexpr std::size_t Ways=4;
|
constexpr std::size_t Ways=4;
|
||||||
constexpr std::size_t SetCount=2048;
|
constexpr std::size_t SetCount=2048;
|
||||||
static_assert((SetCount&(SetCount-1))==0);
|
static_assert((SetCount&(SetCount-1))==0);
|
||||||
static thread_local std::array<FIslandColumnCacheEntry,SetCount*Ways> Cache{};
|
static thread_local VoxelForgeCoreThreadLocal::FLazy<
|
||||||
|
std::array<FIslandColumnCacheEntry,SetCount*Ways>> Cache;
|
||||||
|
auto& cache=Cache.Get();
|
||||||
const std::int64_t SampleX=static_cast<std::int64_t>(x);
|
const std::int64_t SampleX=static_cast<std::int64_t>(x);
|
||||||
const std::int64_t SampleY=static_cast<std::int64_t>(y);
|
const std::int64_t SampleY=static_cast<std::int64_t>(y);
|
||||||
std::uint64_t IndexKey=island.stableId
|
std::uint64_t IndexKey=island.stableId
|
||||||
@@ -452,10 +455,10 @@ namespace floating_island_detail
|
|||||||
IndexKey*=0xff51afd7ed558ccdull;
|
IndexKey*=0xff51afd7ed558ccdull;
|
||||||
IndexKey^=IndexKey>>33;
|
IndexKey^=IndexKey>>33;
|
||||||
const std::size_t Base=static_cast<std::size_t>(IndexKey&(SetCount-1))*Ways;
|
const std::size_t Base=static_cast<std::size_t>(IndexKey&(SetCount-1))*Ways;
|
||||||
FIslandColumnCacheEntry* Replacement=&Cache[Base+((IndexKey>>11)&(Ways-1))];
|
FIslandColumnCacheEntry* Replacement=&cache[Base+((IndexKey>>11)&(Ways-1))];
|
||||||
for(std::size_t Way=0;Way<Ways;++Way)
|
for(std::size_t Way=0;Way<Ways;++Way)
|
||||||
{
|
{
|
||||||
FIslandColumnCacheEntry& Entry=Cache[Base+Way];
|
FIslandColumnCacheEntry& Entry=cache[Base+Way];
|
||||||
const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed
|
const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed
|
||||||
&&Entry.StableId==island.stableId
|
&&Entry.StableId==island.stableId
|
||||||
&&Entry.SampleX==SampleX&&Entry.SampleY==SampleY
|
&&Entry.SampleX==SampleX&&Entry.SampleY==SampleY
|
||||||
@@ -559,11 +562,13 @@ namespace floating_island_detail
|
|||||||
// Mettre en cache les constantes par worker; la cle complete evite tout partage d'etat.
|
// Mettre en cache les constantes par worker; la cle complete evite tout partage d'etat.
|
||||||
constexpr std::size_t CacheSize=1024;
|
constexpr std::size_t CacheSize=1024;
|
||||||
static_assert((CacheSize&(CacheSize-1))==0);
|
static_assert((CacheSize&(CacheSize-1))==0);
|
||||||
static thread_local std::array<FRootLobeCacheEntry,CacheSize> Cache{};
|
static thread_local VoxelForgeCoreThreadLocal::FLazy<
|
||||||
|
std::array<FRootLobeCacheEntry,CacheSize>> Cache;
|
||||||
|
auto& cache=Cache.Get();
|
||||||
const std::uint64_t IndexKey=island.stableId^(island.stableId>>33)
|
const std::uint64_t IndexKey=island.stableId^(island.stableId>>33)
|
||||||
^(static_cast<std::uint64_t>(recipe.seed)<<17)
|
^(static_cast<std::uint64_t>(recipe.seed)<<17)
|
||||||
^(static_cast<std::uint64_t>(static_cast<std::uint32_t>(rootIndex))*0x9e3779b97f4a7c15ull);
|
^(static_cast<std::uint64_t>(static_cast<std::uint32_t>(rootIndex))*0x9e3779b97f4a7c15ull);
|
||||||
FRootLobeCacheEntry& Entry=Cache[static_cast<std::size_t>(IndexKey)&(CacheSize-1)];
|
FRootLobeCacheEntry& Entry=cache[static_cast<std::size_t>(IndexKey)&(CacheSize-1)];
|
||||||
const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed
|
const bool bKeyMatches=Entry.bValid&&Entry.Seed==recipe.seed
|
||||||
&&Entry.StableId==island.stableId&&Entry.RootIndex==rootIndex
|
&&Entry.StableId==island.stableId&&Entry.RootIndex==rootIndex
|
||||||
&&Entry.GeometryVersion==recipe.geometryVersion
|
&&Entry.GeometryVersion==recipe.geometryVersion
|
||||||
|
|||||||
@@ -969,6 +969,11 @@ namespace VoxelForgeCore
|
|||||||
bool World::compile(const ShapeBuildRequest& request,const JobScheduler& scheduler,std::string& error)
|
bool World::compile(const ShapeBuildRequest& request,const JobScheduler& scheduler,std::string& error)
|
||||||
{
|
{
|
||||||
if(!impl_->owner){error="resolved world snapshot is empty";return false;}
|
if(!impl_->owner){error="resolved world snapshot is empty";return false;}
|
||||||
|
if(!::vfcore::fp_contract::selfTest())
|
||||||
|
{
|
||||||
|
error="Core startup refused: floating-point contraction self-test detected a fused multiply-add; this compiler/flag combination is unsupported for world generation";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
auto shape=std::make_unique<FStandaloneShapeWorld>();
|
auto shape=std::make_unique<FStandaloneShapeWorld>();
|
||||||
const bool ok=shape->Build(*impl_->owner,ToNative(request.minVoxel),ToNative(request.maxVoxel),
|
const bool ok=shape->Build(*impl_->owner,ToNative(request.minVoxel),ToNative(request.maxVoxel),
|
||||||
ToNative(request.clipMinVoxel),ToNative(request.clipMaxVoxel),
|
ToNative(request.clipMinVoxel),ToNative(request.clipMaxVoxel),
|
||||||
@@ -1325,6 +1330,11 @@ namespace VoxelForgeCore
|
|||||||
std::optional<TileMesh> World::generateTile(const TileKey& key,const TileGenerationOptions& options,
|
std::optional<TileMesh> World::generateTile(const TileKey& key,const TileGenerationOptions& options,
|
||||||
std::string& error) const
|
std::string& error) const
|
||||||
{
|
{
|
||||||
|
// Fine owner tiles had zero direct-map conflict evictions in the cold audit. Keep their
|
||||||
|
// single-probe path and use associativity for the coarse coordinate families that collide.
|
||||||
|
// Les tuiles proches n'avaient aucun conflit; garder leur acces simple et associer les LOD grossiers.
|
||||||
|
Heightfield2D::setThreadColumnCacheLegacyDirectMapped(
|
||||||
|
options.legacyDirectMappedColumnCache||key.lod<=2);
|
||||||
if(!impl_||!impl_->owner||!impl_->shape||!impl_->shape->IsBuilt())
|
if(!impl_||!impl_->owner||!impl_->shape||!impl_->shape->IsBuilt())
|
||||||
{ error="world must be compiled before generating tiles";return std::nullopt; }
|
{ error="world must be compiled before generating tiles";return std::nullopt; }
|
||||||
const auto& world=*impl_->owner;
|
const auto& world=*impl_->owner;
|
||||||
@@ -1342,6 +1352,7 @@ namespace VoxelForgeCore
|
|||||||
mesher.bStandaloneSkipUvAndColors=options.skipUvAndColors;
|
mesher.bStandaloneSkipUvAndColors=options.skipUvAndColors;
|
||||||
mesher.bStandaloneSkipUV=options.skipUv;mesher.bStandaloneSkipColors=options.skipColors;
|
mesher.bStandaloneSkipUV=options.skipUv;mesher.bStandaloneSkipColors=options.skipColors;
|
||||||
mesher.bStandaloneSkipMaterialGroups=options.skipMaterialGroups;
|
mesher.bStandaloneSkipMaterialGroups=options.skipMaterialGroups;
|
||||||
|
mesher.bStandaloneEnableGradientMemoization=options.memoizeMcGradients;
|
||||||
mesher.bGenerateSkirts=world.bGenerateSkirts;
|
mesher.bGenerateSkirts=world.bGenerateSkirts;
|
||||||
mesher.SkirtCells=static_cast<float>(world.SkirtCells)
|
mesher.SkirtCells=static_cast<float>(world.SkirtCells)
|
||||||
*static_cast<float>(world.OwnerVoxelSizeMicrons)
|
*static_cast<float>(world.OwnerVoxelSizeMicrons)
|
||||||
@@ -1435,7 +1446,16 @@ namespace VoxelForgeCore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int32 MeshCells=cells,MeshStep=step;
|
||||||
|
if(options.diagnosticCellStride>1&&level>=3)
|
||||||
|
{
|
||||||
|
const int32 Stride=static_cast<int32>(std::min<std::uint32_t>(
|
||||||
|
options.diagnosticCellStride,static_cast<std::uint32_t>(std::max(1,cells))));
|
||||||
|
MeshCells=FMath::Max(1,cells/Stride);
|
||||||
|
MeshStep=FMath::Max(1,extent/MeshCells);
|
||||||
|
}
|
||||||
int64 sampleCount=0;std::vector<float> densityValues;
|
int64 sampleCount=0;std::vector<float> densityValues;
|
||||||
|
FVoxelMarchingCubesStageTimings McStageTimings;
|
||||||
TileMesh out;out.key=key;
|
TileMesh out;out.key=key;
|
||||||
out.diagnostics.featureRefinedResolution=bFeatureRefinedResolution;
|
out.diagnostics.featureRefinedResolution=bFeatureRefinedResolution;
|
||||||
const bool bHasWorldAssembly=impl_->worldAssembly!=nullptr;
|
const bool bHasWorldAssembly=impl_->worldAssembly!=nullptr;
|
||||||
@@ -1523,6 +1543,7 @@ namespace VoxelForgeCore
|
|||||||
out.diagnostics.unclampedFieldCalls=Counts.NativeUnclampedFieldCalls;
|
out.diagnostics.unclampedFieldCalls=Counts.NativeUnclampedFieldCalls;
|
||||||
out.diagnostics.columnCacheHits=Columns.columnHits;
|
out.diagnostics.columnCacheHits=Columns.columnHits;
|
||||||
out.diagnostics.columnCacheMisses=Columns.columnMisses;
|
out.diagnostics.columnCacheMisses=Columns.columnMisses;
|
||||||
|
out.diagnostics.columnCacheConflictMisses=Columns.columnConflictMisses;
|
||||||
out.diagnostics.classificationMilliseconds=Counts.Milliseconds;
|
out.diagnostics.classificationMilliseconds=Counts.Milliseconds;
|
||||||
out.diagnostics.classificationExclusiveMilliseconds=std::max(0.0,
|
out.diagnostics.classificationExclusiveMilliseconds=std::max(0.0,
|
||||||
Counts.Milliseconds-classificationColumnComputeMilliseconds);
|
Counts.Milliseconds-classificationColumnComputeMilliseconds);
|
||||||
@@ -1665,12 +1686,32 @@ namespace VoxelForgeCore
|
|||||||
out.diagnostics.featureListMilliseconds=std::chrono::duration<double,std::milli>(
|
out.diagnostics.featureListMilliseconds=std::chrono::duration<double,std::milli>(
|
||||||
std::chrono::steady_clock::now()-FeatureListStart).count();
|
std::chrono::steady_clock::now()-FeatureListStart).count();
|
||||||
const ScopedWorldAssemblyFeatureQueriesV1 featureScope(featureQueries);
|
const ScopedWorldAssemblyFeatureQueriesV1 featureScope(featureQueries);
|
||||||
|
const bool bDiagnosticColumnSampling=options.diagnosticGlobalOctaveDrop!=0
|
||||||
|
||options.diagnosticColumnInterpolationStride>1;
|
||||||
|
const std::uint32_t PreviousOctaveDrop=bDiagnosticColumnSampling
|
||||||
|
?Heightfield2D::threadColumnOctaveDrop():0;
|
||||||
|
const std::int64_t PreviousInterpolationStride=bDiagnosticColumnSampling
|
||||||
|
?Heightfield2D::threadColumnInterpolationStrideSubvoxels():0;
|
||||||
|
if(bDiagnosticColumnSampling)
|
||||||
|
{
|
||||||
|
Heightfield2D::setThreadColumnOctaveDrop(options.diagnosticGlobalOctaveDrop);
|
||||||
|
Heightfield2D::setThreadColumnInterpolationStrideSubvoxels(
|
||||||
|
options.diagnosticColumnInterpolationStride>1&&level>=3
|
||||||
|
?static_cast<std::int64_t>(MeshStep)*WorldAssemblySubvoxelsPerVoxel
|
||||||
|
*options.diagnosticColumnInterpolationStride:0);
|
||||||
|
}
|
||||||
const double ColumnMillisecondsBeforeMeshing=
|
const double ColumnMillisecondsBeforeMeshing=
|
||||||
VoxelForgeCore::Heightfield2D::threadColumnCacheStats().columnComputeMilliseconds;
|
VoxelForgeCore::Heightfield2D::threadColumnCacheStats().columnComputeMilliseconds;
|
||||||
const auto MarchingCubesStart=std::chrono::steady_clock::now();
|
const auto MarchingCubesStart=std::chrono::steady_clock::now();
|
||||||
FVoxelMeshData mesh=mesher.GenerateMesh(origin,step,cells,nullptr,
|
FVoxelMeshData mesh=mesher.GenerateMesh(origin,MeshStep,MeshCells,nullptr,
|
||||||
MeshBandMinZVoxel,MeshBandMaxZVoxel,&sampleCount,nullptr,nullptr,
|
MeshBandMinZVoxel,MeshBandMaxZVoxel,&sampleCount,nullptr,nullptr,
|
||||||
(options.hashDensity||options.captureDensitySamples)?&densityValues:nullptr);
|
(options.hashDensity||options.captureDensitySamples)?&densityValues:nullptr,
|
||||||
|
options.profileMesherStages?&McStageTimings:nullptr);
|
||||||
|
if(bDiagnosticColumnSampling)
|
||||||
|
{
|
||||||
|
Heightfield2D::setThreadColumnOctaveDrop(PreviousOctaveDrop);
|
||||||
|
Heightfield2D::setThreadColumnInterpolationStrideSubvoxels(PreviousInterpolationStride);
|
||||||
|
}
|
||||||
const double MarchingCubesWallMilliseconds=std::chrono::duration<double,std::milli>(
|
const double MarchingCubesWallMilliseconds=std::chrono::duration<double,std::milli>(
|
||||||
std::chrono::steady_clock::now()-MarchingCubesStart).count();
|
std::chrono::steady_clock::now()-MarchingCubesStart).count();
|
||||||
const double ColumnMillisecondsAfterMeshing=
|
const double ColumnMillisecondsAfterMeshing=
|
||||||
@@ -1679,6 +1720,28 @@ namespace VoxelForgeCore
|
|||||||
MarchingCubesWallMilliseconds-(ColumnMillisecondsAfterMeshing-ColumnMillisecondsBeforeMeshing));
|
MarchingCubesWallMilliseconds-(ColumnMillisecondsAfterMeshing-ColumnMillisecondsBeforeMeshing));
|
||||||
out.diagnostics.marchingCubesColumnComputeMilliseconds=std::max(0.0,
|
out.diagnostics.marchingCubesColumnComputeMilliseconds=std::max(0.0,
|
||||||
ColumnMillisecondsAfterMeshing-ColumnMillisecondsBeforeMeshing);
|
ColumnMillisecondsAfterMeshing-ColumnMillisecondsBeforeMeshing);
|
||||||
|
if(options.profileMesherStages)
|
||||||
|
{
|
||||||
|
out.diagnostics.marchingCubesSkirtMilliseconds=McStageTimings.SkirtMilliseconds;
|
||||||
|
out.diagnostics.marchingCubesExclusiveMilliseconds=std::max(0.0,
|
||||||
|
out.diagnostics.marchingCubesExclusiveMilliseconds
|
||||||
|
-out.diagnostics.marchingCubesSkirtMilliseconds);
|
||||||
|
out.diagnostics.marchingCubesDensityGridMilliseconds=McStageTimings.DensityGridMilliseconds;
|
||||||
|
out.diagnostics.marchingCubesCellClassificationMilliseconds=
|
||||||
|
McStageTimings.CellClassificationMilliseconds;
|
||||||
|
out.diagnostics.marchingCubesGradientNormalsMilliseconds=
|
||||||
|
McStageTimings.GradientNormalsMilliseconds;
|
||||||
|
out.diagnostics.marchingCubesEdgeInterpolationMilliseconds=
|
||||||
|
McStageTimings.EdgeInterpolationMilliseconds;
|
||||||
|
out.diagnostics.marchingCubesVertexDedupStreamMilliseconds=
|
||||||
|
McStageTimings.VertexDedupStreamMilliseconds;
|
||||||
|
out.diagnostics.marchingCubesOtherMilliseconds=McStageTimings.OtherMilliseconds;
|
||||||
|
out.diagnostics.marchingCubesGradientFallbackDensityCalls=
|
||||||
|
McStageTimings.GradientFallbackDensityCalls;
|
||||||
|
out.diagnostics.marchingCubesEdgeMidpointDensityCalls=
|
||||||
|
McStageTimings.EdgeMidpointDensityCalls;
|
||||||
|
out.diagnostics.marchingCubesGradientMemoHits=McStageTimings.GradientMemoHits;
|
||||||
|
}
|
||||||
const double MeshingMilliseconds=std::chrono::duration<double,std::milli>(
|
const double MeshingMilliseconds=std::chrono::duration<double,std::milli>(
|
||||||
std::chrono::steady_clock::now()-MeshingStart).count();
|
std::chrono::steady_clock::now()-MeshingStart).count();
|
||||||
out.diagnostics.farHorizonVersion=key.lod>=4?options.farHorizonVersion:0;
|
out.diagnostics.farHorizonVersion=key.lod>=4?options.farHorizonVersion:0;
|
||||||
@@ -1765,6 +1828,7 @@ namespace VoxelForgeCore
|
|||||||
out.diagnostics.unclampedFieldCalls=Counts.NativeUnclampedFieldCalls;
|
out.diagnostics.unclampedFieldCalls=Counts.NativeUnclampedFieldCalls;
|
||||||
out.diagnostics.columnCacheHits=Columns.columnHits;
|
out.diagnostics.columnCacheHits=Columns.columnHits;
|
||||||
out.diagnostics.columnCacheMisses=Columns.columnMisses;
|
out.diagnostics.columnCacheMisses=Columns.columnMisses;
|
||||||
|
out.diagnostics.columnCacheConflictMisses=Columns.columnConflictMisses;
|
||||||
out.diagnostics.columnComputeMilliseconds=Columns.columnComputeMilliseconds;
|
out.diagnostics.columnComputeMilliseconds=Columns.columnComputeMilliseconds;
|
||||||
out.diagnostics.columnEvaluationExclusiveMilliseconds=Columns.columnComputeMilliseconds;
|
out.diagnostics.columnEvaluationExclusiveMilliseconds=Columns.columnComputeMilliseconds;
|
||||||
out.diagnostics.classificationMilliseconds=Counts.Milliseconds;
|
out.diagnostics.classificationMilliseconds=Counts.Milliseconds;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "VoxelForgeCore/ThreadLocalStorage.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "VoxelForgeCore/VoxelForgeCore.h"
|
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||||
|
|
||||||
@@ -1030,6 +1031,7 @@ namespace world_assembly_detail
|
|||||||
// Audit-only override; normal tile generation resets this to zero before evaluating a recipe.
|
// Audit-only override; normal tile generation resets this to zero before evaluating a recipe.
|
||||||
// Surcharge reservee aux mesures; la generation remet zero avant d'evaluer une recette.
|
// Surcharge reservee aux mesures; la generation remet zero avant d'evaluer une recette.
|
||||||
inline thread_local std::uint32_t HeightfieldColumnOctaveDrop = 0;
|
inline thread_local std::uint32_t HeightfieldColumnOctaveDrop = 0;
|
||||||
|
inline thread_local std::int64_t HeightfieldColumnInterpolationStrideSubvoxels = 0;
|
||||||
|
|
||||||
inline std::int32_t FractalNoiseQ16(std::int64_t xQ16, std::int64_t yQ16,
|
inline std::int32_t FractalNoiseQ16(std::int64_t xQ16, std::int64_t yQ16,
|
||||||
std::int64_t zQ16, std::uint32_t octaves, bool ridged = false)
|
std::int64_t zQ16, std::uint32_t octaves, bool ridged = false)
|
||||||
@@ -1361,11 +1363,36 @@ namespace world_assembly_detail
|
|||||||
std::int64_t x = 0, y = 0;
|
std::int64_t x = 0, y = 0;
|
||||||
HeightfieldPointSample column{};
|
HeightfieldPointSample column{};
|
||||||
};
|
};
|
||||||
// Coarse LOD tiles revisit a wider set of gradient-sample columns than the full-resolution
|
// Keep 65,536 entries in each worker cache; four ways tolerate coordinate families that
|
||||||
// band. Keep those columns resident for a complete worker tile so the 3D mesher does not
|
// deliberately share low hash bits at coarse LODs.
|
||||||
// repeat the procedural biome evaluation for every Z sample.
|
// Chaque cache worker garde 65 536 entrees; quatre voies absorbent les coordonnees grossieres
|
||||||
inline thread_local std::array<HeightfieldColumnCacheEntry, 65536> HeightfieldColumnCache{};
|
// qui partagent les bits faibles du hash.
|
||||||
|
constexpr std::size_t HeightfieldColumnCacheWays=4;
|
||||||
|
constexpr std::size_t HeightfieldColumnCacheSetCount=65536/HeightfieldColumnCacheWays;
|
||||||
|
inline thread_local VoxelForgeCoreThreadLocal::FLazy<
|
||||||
|
std::array<HeightfieldColumnCacheEntry, 65536>> HeightfieldColumnCache;
|
||||||
|
inline thread_local VoxelForgeCoreThreadLocal::FLazy<
|
||||||
|
std::array<std::uint8_t, HeightfieldColumnCacheSetCount>> HeightfieldColumnCacheNextWay;
|
||||||
inline thread_local HeightfieldColumnCacheStats HeightfieldColumnStats{};
|
inline thread_local HeightfieldColumnCacheStats HeightfieldColumnStats{};
|
||||||
|
inline thread_local bool HeightfieldColumnCacheLegacyDirectMapped=false;
|
||||||
|
|
||||||
|
inline std::size_t HeightfieldColumnCacheSet(const WorldAssemblyRecipeV1& recipe,
|
||||||
|
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y) noexcept
|
||||||
|
{
|
||||||
|
// Avalanche every coordinate bit before masking. The old direct hash kept too little
|
||||||
|
// entropy from widely spaced coarse LOD coordinates in its low 16 bits.
|
||||||
|
// Melanger tous les bits de coordonnee avant le masque; l'ancien hash perdait de
|
||||||
|
// l'entropie sur les coordonnees espacees des LOD grossiers.
|
||||||
|
std::uint64_t mixed=static_cast<std::uint64_t>(x)*0x9E3779B185EBCA87ull
|
||||||
|
^std::rotl(static_cast<std::uint64_t>(y)*0xC2B2AE3D27D4EB4Full,29)
|
||||||
|
^recipe.contentHash^std::rotl(plan.contentHash,17);
|
||||||
|
mixed^=mixed>>30;
|
||||||
|
mixed*=0xBF58476D1CE4E5B9ull;
|
||||||
|
mixed^=mixed>>27;
|
||||||
|
mixed*=0x94D049BB133111EBull;
|
||||||
|
mixed^=mixed>>31;
|
||||||
|
return static_cast<std::size_t>(mixed)&(HeightfieldColumnCacheSetCount-1);
|
||||||
|
}
|
||||||
|
|
||||||
inline HeightfieldPointSample EvaluateColumn(const WorldAssemblyRecipeV1& recipe,
|
inline HeightfieldPointSample EvaluateColumn(const WorldAssemblyRecipeV1& recipe,
|
||||||
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y)
|
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y)
|
||||||
@@ -1480,15 +1507,86 @@ namespace world_assembly_detail
|
|||||||
inline HeightfieldPointSample CachedColumn(const WorldAssemblyRecipeV1& recipe,
|
inline HeightfieldPointSample CachedColumn(const WorldAssemblyRecipeV1& recipe,
|
||||||
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y)
|
const WorldAssemblyStratumPlanV1& plan,std::int64_t x,std::int64_t y)
|
||||||
{
|
{
|
||||||
const std::uint64_t mixed=(static_cast<std::uint64_t>(x)*0x9E3779B185EBCA87ull)
|
const std::int64_t InterpolationStride=HeightfieldColumnInterpolationStrideSubvoxels;
|
||||||
^std::rotl(static_cast<std::uint64_t>(y)*0xC2B2AE3D27D4EB4Full,23)
|
if(InterpolationStride>0)
|
||||||
^static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe))
|
{
|
||||||
^std::rotl(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),41);
|
const std::int64_t X0=FloorDiv(x,InterpolationStride)*InterpolationStride;
|
||||||
auto& entry=HeightfieldColumnCache[static_cast<std::size_t>(mixed)&
|
const std::int64_t Y0=FloorDiv(y,InterpolationStride)*InterpolationStride;
|
||||||
(HeightfieldColumnCache.size()-1)];
|
const std::int64_t X1=X0+InterpolationStride,Y1=Y0+InterpolationStride;
|
||||||
if(entry.recipe==&recipe&&entry.plan==&plan&&entry.recipeHash==recipe.contentHash
|
const std::int64_t Fx=x-X0,Fy=y-Y0;
|
||||||
&&entry.planHash==plan.contentHash&&entry.x==x&&entry.y==y)
|
struct FScopedInterpolationSampling
|
||||||
{++HeightfieldColumnStats.columnHits;return entry.column;}
|
{
|
||||||
|
std::int64_t Previous=HeightfieldColumnInterpolationStrideSubvoxels;
|
||||||
|
~FScopedInterpolationSampling()
|
||||||
|
{HeightfieldColumnInterpolationStrideSubvoxels=Previous;}
|
||||||
|
} SamplingScope;
|
||||||
|
HeightfieldColumnInterpolationStrideSubvoxels=0;
|
||||||
|
const HeightfieldPointSample C00=CachedColumn(recipe,plan,X0,Y0);
|
||||||
|
const HeightfieldPointSample C10=CachedColumn(recipe,plan,X1,Y0);
|
||||||
|
const HeightfieldPointSample C01=CachedColumn(recipe,plan,X0,Y1);
|
||||||
|
const HeightfieldPointSample C11=CachedColumn(recipe,plan,X1,Y1);
|
||||||
|
const auto Lerp=[&](std::int64_t A,std::int64_t B,std::int64_t T)
|
||||||
|
{return A+((B-A)*T)/InterpolationStride;};
|
||||||
|
const auto Bilinear=[&](std::int64_t A,std::int64_t B,
|
||||||
|
std::int64_t C,std::int64_t D)
|
||||||
|
{
|
||||||
|
const std::int64_t Top=Lerp(A,B,Fx),Bottom=Lerp(C,D,Fx);
|
||||||
|
return Lerp(Top,Bottom,Fy);
|
||||||
|
};
|
||||||
|
HeightfieldPointSample Out=C00;
|
||||||
|
Out.groundHeightSubvoxels=Bilinear(C00.groundHeightSubvoxels,
|
||||||
|
C10.groundHeightSubvoxels,C01.groundHeightSubvoxels,
|
||||||
|
C11.groundHeightSubvoxels);
|
||||||
|
Out.capHeightSubvoxels=Bilinear(C00.capHeightSubvoxels,
|
||||||
|
C10.capHeightSubvoxels,C01.capHeightSubvoxels,
|
||||||
|
C11.capHeightSubvoxels);
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
if(HeightfieldColumnOctaveDrop!=0)
|
||||||
|
return EvaluateColumn(recipe,plan,x,y);
|
||||||
|
auto& cache=HeightfieldColumnCache.Get();
|
||||||
|
auto& nextWay=HeightfieldColumnCacheNextWay.Get();
|
||||||
|
HeightfieldColumnCacheEntry* replacement=nullptr;
|
||||||
|
if(HeightfieldColumnCacheLegacyDirectMapped)
|
||||||
|
{
|
||||||
|
// Preserve S13's exact direct-map index as an in-process negative control.
|
||||||
|
// Conserver l'index direct exact de S13 comme controle negatif en cours d'execution.
|
||||||
|
const std::uint64_t mixed=(static_cast<std::uint64_t>(x)*0x9E3779B185EBCA87ull)
|
||||||
|
^std::rotl(static_cast<std::uint64_t>(y)*0xC2B2AE3D27D4EB4Full,23)
|
||||||
|
^static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&recipe))
|
||||||
|
^std::rotl(static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(&plan)),41);
|
||||||
|
replacement=&cache[static_cast<std::size_t>(mixed)&(cache.size()-1)];
|
||||||
|
if(replacement->recipe==&recipe&&replacement->plan==&plan
|
||||||
|
&&replacement->recipeHash==recipe.contentHash
|
||||||
|
&&replacement->planHash==plan.contentHash&&replacement->x==x&&replacement->y==y)
|
||||||
|
{++HeightfieldColumnStats.columnHits;return replacement->column;}
|
||||||
|
if(replacement->recipe!=nullptr)++HeightfieldColumnStats.columnConflictMisses;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const std::size_t set=HeightfieldColumnCacheSet(recipe,plan,x,y);
|
||||||
|
const std::size_t first=set*HeightfieldColumnCacheWays;
|
||||||
|
std::size_t replacementWay=HeightfieldColumnCacheWays;
|
||||||
|
for(std::size_t way=0;way<HeightfieldColumnCacheWays;++way)
|
||||||
|
{
|
||||||
|
auto& candidate=cache[first+way];
|
||||||
|
if(candidate.recipe==&recipe&&candidate.plan==&plan
|
||||||
|
&&candidate.recipeHash==recipe.contentHash&&candidate.planHash==plan.contentHash
|
||||||
|
&&candidate.x==x&&candidate.y==y)
|
||||||
|
{++HeightfieldColumnStats.columnHits;return candidate.column;}
|
||||||
|
if(candidate.recipe==nullptr&&replacementWay==HeightfieldColumnCacheWays)
|
||||||
|
replacementWay=way;
|
||||||
|
}
|
||||||
|
if(replacementWay==HeightfieldColumnCacheWays)
|
||||||
|
{
|
||||||
|
++HeightfieldColumnStats.columnConflictMisses;
|
||||||
|
replacementWay=nextWay[set];
|
||||||
|
}
|
||||||
|
nextWay[set]=static_cast<std::uint8_t>(
|
||||||
|
(replacementWay+1)%HeightfieldColumnCacheWays);
|
||||||
|
replacement=&cache[first+replacementWay];
|
||||||
|
}
|
||||||
|
auto& entry=*replacement;
|
||||||
const auto start=std::chrono::steady_clock::now();
|
const auto start=std::chrono::steady_clock::now();
|
||||||
HeightfieldPointSample column=EvaluateColumn(recipe,plan,x,y);
|
HeightfieldPointSample column=EvaluateColumn(recipe,plan,x,y);
|
||||||
HeightfieldColumnStats.columnComputeMilliseconds+=std::chrono::duration<double,std::milli>(
|
HeightfieldColumnStats.columnComputeMilliseconds+=std::chrono::duration<double,std::milli>(
|
||||||
@@ -1977,19 +2075,40 @@ void Heightfield2D::resetThreadColumnCacheStats(bool captureCoordinates, bool cl
|
|||||||
{
|
{
|
||||||
// Diagnostic probes may clear old tile entries before comparing isolated sample grids.
|
// Diagnostic probes may clear old tile entries before comparing isolated sample grids.
|
||||||
// Les sondes de mesure peuvent vider les entrees d'une tuile avant de comparer deux grilles.
|
// Les sondes de mesure peuvent vider les entrees d'une tuile avant de comparer deux grilles.
|
||||||
if(clearCache)world_assembly_detail::HeightfieldColumnCache.fill(
|
if(clearCache)
|
||||||
world_assembly_detail::HeightfieldColumnCacheEntry{});
|
{
|
||||||
|
world_assembly_detail::HeightfieldColumnCache.Get().fill(
|
||||||
|
world_assembly_detail::HeightfieldColumnCacheEntry{});
|
||||||
|
world_assembly_detail::HeightfieldColumnCacheNextWay.Get().fill(0);
|
||||||
|
}
|
||||||
auto& Stats=world_assembly_detail::HeightfieldColumnStats;
|
auto& Stats=world_assembly_detail::HeightfieldColumnStats;
|
||||||
world_assembly_detail::HeightfieldColumnOctaveDrop=octaveDrop;
|
world_assembly_detail::HeightfieldColumnOctaveDrop=octaveDrop;
|
||||||
Stats.pointCalls=0;
|
Stats.pointCalls=0;
|
||||||
Stats.columnHits=0;
|
Stats.columnHits=0;
|
||||||
Stats.columnMisses=0;
|
Stats.columnMisses=0;
|
||||||
|
Stats.columnConflictMisses=0;
|
||||||
Stats.columnComputeMilliseconds=0.0;
|
Stats.columnComputeMilliseconds=0.0;
|
||||||
Stats.captureCoordinates=captureCoordinates;
|
Stats.captureCoordinates=captureCoordinates;
|
||||||
Stats.coordinateCaptureComplete=true;
|
Stats.coordinateCaptureComplete=true;
|
||||||
Stats.evaluatedCoordinates.clear();
|
Stats.evaluatedCoordinates.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Heightfield2D::setThreadColumnCacheLegacyDirectMapped(bool enabled) noexcept
|
||||||
|
{ world_assembly_detail::HeightfieldColumnCacheLegacyDirectMapped=enabled; }
|
||||||
|
|
||||||
|
void Heightfield2D::setThreadColumnOctaveDrop(std::uint32_t octaveDrop) noexcept
|
||||||
|
{ world_assembly_detail::HeightfieldColumnOctaveDrop=octaveDrop; }
|
||||||
|
|
||||||
|
std::uint32_t Heightfield2D::threadColumnOctaveDrop() noexcept
|
||||||
|
{ return world_assembly_detail::HeightfieldColumnOctaveDrop; }
|
||||||
|
|
||||||
|
void Heightfield2D::setThreadColumnInterpolationStrideSubvoxels(std::int64_t stride) noexcept
|
||||||
|
{ world_assembly_detail::HeightfieldColumnInterpolationStrideSubvoxels=std::max<std::int64_t>(0,stride); }
|
||||||
|
|
||||||
|
std::int64_t Heightfield2D::threadColumnInterpolationStrideSubvoxels() noexcept
|
||||||
|
{ return world_assembly_detail::HeightfieldColumnInterpolationStrideSubvoxels; }
|
||||||
|
|
||||||
|
|
||||||
const HeightfieldColumnCacheStats& Heightfield2D::threadColumnCacheStats() noexcept
|
const HeightfieldColumnCacheStats& Heightfield2D::threadColumnCacheStats() noexcept
|
||||||
{ return world_assembly_detail::HeightfieldColumnStats; }
|
{ return world_assembly_detail::HeightfieldColumnStats; }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Run one child and report its wait4 peak RSS without /usr/bin/time."""
|
||||||
|
import os
|
||||||
|
import resource
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
raise SystemExit("usage: MeasureProcess.py executable [arguments ...]")
|
||||||
|
|
||||||
|
address_limit, _ = resource.getrlimit(resource.RLIMIT_AS)
|
||||||
|
stack_limit, _ = resource.getrlimit(resource.RLIMIT_STACK)
|
||||||
|
if address_limit in (resource.RLIM_INFINITY, -1) or address_limit > 6 * 1024**3:
|
||||||
|
raise SystemExit("run under prlimit --as=6442450944")
|
||||||
|
if stack_limit in (resource.RLIM_INFINITY, -1) or stack_limit < 64 * 1024**2:
|
||||||
|
raise SystemExit("run under prlimit --stack=67108864:67108864")
|
||||||
|
if not os.sched_getaffinity(0).issubset(set(range(12))):
|
||||||
|
raise SystemExit("run under taskset -c 0-11")
|
||||||
|
print(f"[ProcessLimits] address_limit={address_limit} stack_limit={stack_limit} affinity={sorted(os.sched_getaffinity(0))}", flush=True)
|
||||||
|
|
||||||
|
started = time.monotonic()
|
||||||
|
pid = os.fork()
|
||||||
|
if pid == 0:
|
||||||
|
try:
|
||||||
|
os.execvp(sys.argv[1], sys.argv[1:])
|
||||||
|
except OSError as error:
|
||||||
|
print(f"MeasureProcess: exec failed: {error}", file=sys.stderr, flush=True)
|
||||||
|
os._exit(127)
|
||||||
|
|
||||||
|
_, status, usage = os.wait4(pid, 0)
|
||||||
|
wall = time.monotonic() - started
|
||||||
|
exit_code = os.waitstatus_to_exitcode(status)
|
||||||
|
print(f"[ProcessResources] exit_code={exit_code} wall_s={wall:.6f} peak_rss_kib={usage.ru_maxrss}", flush=True)
|
||||||
|
raise SystemExit(exit_code)
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
# L1 — Linux baseline (abyss)
|
||||||
|
|
||||||
|
## What changed
|
||||||
|
|
||||||
|
- `Standalone/Source/StreamBenchmarkPipeline.h` now holds the S13 streaming benchmark, hash helpers, and per-LOD reporting. The Windows viewer and the headless executable call the same functions.
|
||||||
|
- `Standalone/Source/WorldAssemblyPrototype.h` holds the existing Round 1 plan builder; both executables call it.
|
||||||
|
- `Standalone/Source/StreamBenchmarkHeadless.cpp` is the Linux CLI entry point. It loads the same owner JSON, resolves it through `StandaloneOwnerLoader`, builds the same Core snapshot, and runs the shared pipeline. It has no window, renderer, D3D11, or Win32 setup.
|
||||||
|
- `Standalone/BuildLinux.sh` builds the Core library and headless executable. `Linux1/MeasureProcess.py` checks affinity and memory/stack limits and records child peak RSS.
|
||||||
|
- `Standalone/Source/StandaloneViewer.cpp` now includes and calls the shared headers. `Standalone/Core/src/CoreNamespacePreamble.h` and `Standalone/Compat/CoreMinimal.h` include `<cfloat>` for existing `FLT_MAX` use. `Standalone/Compat/StandaloneDataAssetGlue.cpp` now supplies the standalone `UVoxelSeasonAsset::GetPrimaryAssetId` implementation matching the engine source.
|
||||||
|
|
||||||
|
The headless entry point retains the parsed JSON root for the existing snapshot adapter. The route planner, Core shape compile, tile generator, hash code, and pipeline counters are shared with the viewer, rather than reimplemented. Viewer-only command switches for process affinity, priority, and frame limit are accepted for command-line parity; the Linux runner pins and limits itself externally.
|
||||||
|
|
||||||
|
**Windows compile risk:** MSVC was unavailable here, so the Windows viewer was not compiled. The likely risk spots are the new includes and namespaced calls in `StandaloneViewer.cpp`, and the moved inline bodies in `StreamBenchmarkPipeline.h` and `WorldAssemblyPrototype.h`; `Build.ps1` compiles that viewer with `/std:c++20`. The Linux-only main, script, and RSS helper are not in the explicit Windows source list. The compatibility `GetPrimaryAssetId` mirrors `VoxelSeasonAsset.cpp`; keep the engine `.cpp` out of the Standalone compatibility manifest to avoid a duplicate if that manifest is expanded later. No density formula changed, so no recipe-version bump is needed.
|
||||||
|
|
||||||
|
## Build and run commands
|
||||||
|
|
||||||
|
Run from the repo root. `BuildLinux.sh` enforces CPUs 0–11 and a 6 GiB address-space limit itself; the explicit wrapper below makes those limits visible at the call site too. The build output is under `Standalone/Build/linux-*` and `Standalone/bin/linux/`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
taskset -c 0-11 prlimit --as=6442450944 -- \
|
||||||
|
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19 --jobs=12 --fp-contract=off \
|
||||||
|
> Saved/Linux/build-clang19-final.log 2>&1
|
||||||
|
|
||||||
|
taskset -c 0-11 prlimit --as=6442450944 -- \
|
||||||
|
bash Standalone/BuildLinux.sh --compiler=g++-14 --variant=gcc14 --jobs=12 --fp-contract=off \
|
||||||
|
> Saved/Linux/build-gcc14.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
The measured build flags were `-std=c++20 -O2 -mavx2 -mfma -ffp-contract=off -fno-fast-math`; Clang also suppresses the legacy narrowing diagnostic that MSVC accepts. The benchmark wrapper below enforces the 6 GiB address-space cap, a 64 MiB stack, and CPU affinity, then records `wait4` peak RSS. These are the exact run calls; `yes` adds `--profile-column-overlap`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
run_bench() {
|
||||||
|
local variant="$1" workers="$2" overlap="$3" name="$4"
|
||||||
|
local profile=()
|
||||||
|
if [[ "$overlap" == yes ]]; then profile+=(--profile-column-overlap); fi
|
||||||
|
taskset -c 0-11 prlimit --as=6442450944 --stack=67108864:67108864 -- \
|
||||||
|
python3 Standalone/Research/WorldAssemblerM3/Linux1/MeasureProcess.py \
|
||||||
|
"Standalone/bin/linux/VoxelForgeCoreHeadless-$variant" Standalone/data/owner_world.json \
|
||||||
|
--workers="$workers" --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash \
|
||||||
|
--force-generate --clip-radius=3 --max-clip-level=8 \
|
||||||
|
--camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 \
|
||||||
|
--process-priority=Normal --process-affinity=4095 --frame-limit=60 \
|
||||||
|
"${profile[@]}" > "Saved/Linux/$name.log" 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
run_bench clang19 1 no bench-clang19-w1-r1
|
||||||
|
run_bench clang19 8 no bench-clang19-w8-r1
|
||||||
|
run_bench clang19 12 no bench-clang19-w12-r1
|
||||||
|
run_bench clang19 8 no bench-clang19-w8-r2
|
||||||
|
run_bench clang19 12 no bench-clang19-w12-r2
|
||||||
|
run_bench clang19 1 no bench-clang19-w1-r2
|
||||||
|
run_bench clang19 12 no bench-clang19-w12-r3
|
||||||
|
run_bench clang19 1 no bench-clang19-w1-r3
|
||||||
|
run_bench clang19 8 no bench-clang19-w8-r3
|
||||||
|
run_bench clang19 8 yes bench-clang19-w8-columns-r1
|
||||||
|
run_bench clang19 8 yes bench-clang19-w8-columns-r2
|
||||||
|
run_bench clang19 8 yes bench-clang19-w8-columns-r3
|
||||||
|
run_bench gcc14 8 no bench-gcc14-w8
|
||||||
|
```
|
||||||
|
|
||||||
|
Every run used a fresh process and a newly constructed streamer; the pipeline reported `cache_hits=0`, so no process or thread-local tile/column cache carried over. `--force-generate` was passed for CLI parity, not relied on for isolation. The kernel file cache was not purged: doing so would require a system-wide setting outside the allowed write boundary. Owner JSON load is included in the cold-start timer and took about 5 ms.
|
||||||
|
|
||||||
|
## Hashes and determinism
|
||||||
|
|
||||||
|
Every Linux hash below covers the same 2,553-tile Round17 view. Clang used `-ffp-contract=off`, matching the intended MSVC `/fp:precise` behavior; GCC used the same contraction setting. Both builds enabled AVX2/FMA instructions but disabled contraction.
|
||||||
|
|
||||||
|
| Build / workers | Runs | Density | Mesh | Payload | Topology | Tiles |
|
||||||
|
|---|---:|---|---|---|---|---:|
|
||||||
|
| Windows S13 reference, W1/W8/W12 | S13 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
|
||||||
|
| Linux Clang 19, W1 | 3 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
|
||||||
|
| Linux Clang 19, W8 | 3 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
|
||||||
|
| Linux Clang 19, W12 | 3 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
|
||||||
|
| Linux GCC 14, W8 | 1 | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | 2,553 |
|
||||||
|
|
||||||
|
There was no divergence in this owner seed/view, so there is no first sample or stage to bisect and no density fix to make. The result covers the full hashed view, not every possible seed or platform math-library input. The tested flags show no observable FMA, libm, integer-width, container-order, or SIMD difference here; they do not establish what default Clang contraction would do.
|
||||||
|
|
||||||
|
Clang W1/W8/W12 each produced identical hashes across all three runs. The GCC W8 run agreed too. The overlap-capture counts varied slightly with worker scheduling, while the generated hashes stayed fixed.
|
||||||
|
|
||||||
|
## Linux timing and per-LOD cost
|
||||||
|
|
||||||
|
Machine: Debian 13, Intel i9-12900H, 15 GB RAM, 24 MiB L3. Processes were pinned to logical CPUs 0–11 (the six P-cores and their SMT siblings); CPUs 12–19 remained free. CPUs 0–11 reported `powersave` governor and `balance_performance` EPP. No governor or system setting was changed; priority remained normal. `RLIMIT_AS` was 6 GiB for every build and benchmark process. The benchmark stack was limited to 64 MiB after the default-stack failures below. No run reached the 30-minute limit.
|
||||||
|
|
||||||
|
`whole_view_ready` is the cold-start timer from process start through all 2,553 tiles, including owner load, plan, shape compile, and streamed generation. Values are median `[min–max]` of three interleaved runs. Peak RSS values are the three `wait4` readings in KiB, in run order; the maximum across all successful runs was 604,652 KiB.
|
||||||
|
|
||||||
|
| Workers | `whole_view_ready` median [range] | Peak RSS per run (KiB) |
|
||||||
|
|---:|---:|---|
|
||||||
|
| W1 | 16.555 s [16.069–16.660] | 218,372 / 329,308 / 329,012 |
|
||||||
|
| W8 | 3.562 s [3.558–3.602] | 445,884 / 462,588 / 462,216 |
|
||||||
|
| W12 | 3.512 s [3.482–3.557] | 536,884 / 537,208 / 539,036 |
|
||||||
|
| W8 with overlap capture | 3.718 s [3.638–3.718] | 603,820 / 603,480 / 604,652 |
|
||||||
|
| GCC 14 W8 hash check | 3.789 s (one run) | 463,276 |
|
||||||
|
|
||||||
|
The S13 W8 Windows reference was 3.518 s on the owner’s 5800X3D. The Linux W8 result is 44 ms (about 1.3%) slower for the same source view and timer, but these are different CPUs and this is a baseline comparison, not an optimization result. Round17 documents no corresponding W1/W12 timing for a direct comparison.
|
||||||
|
|
||||||
|
The next table divides S13’s accumulated `worker_sum_s` by tile count. Each cell is median `[min–max]` milliseconds per tile across the three Clang runs. It is average worker time per tile, not a per-tile p95 or whole-pipeline elapsed time.
|
||||||
|
|
||||||
|
| LOD | W1 ms/tile | W8 ms/tile | W12 ms/tile |
|
||||||
|
|---:|---:|---:|---:|
|
||||||
|
| 0 | 2.131 [2.066–2.144] | 4.222 [4.146–4.343] | 6.405 [6.364–6.489] |
|
||||||
|
| 1 | 4.429 [4.281–4.441] | 7.394 [7.335–7.491] | 11.084 [11.000–11.296] |
|
||||||
|
| 2 | 1.319 [1.282–1.319] | 1.871 [1.842–1.943] | 2.771 [2.740–2.813] |
|
||||||
|
| 3 | 5.520 [5.366–5.527] | 7.916 [7.860–8.179] | 11.777 [11.670–11.916] |
|
||||||
|
| 4 | 16.305 [15.787–16.344] | 23.403 [23.382–23.798] | 34.479 [34.229–34.654] |
|
||||||
|
| 5 | 7.389 [7.223–7.443] | 10.714 [10.567–10.926] | 15.520 [15.288–15.605] |
|
||||||
|
| 6 | 15.521 [15.021–15.638] | 22.183 [21.813–22.350] | 32.063 [31.641–32.163] |
|
||||||
|
| 7 | 17.203 [16.495–17.226] | 24.476 [23.925–24.560] | 33.760 [33.085–33.885] |
|
||||||
|
| 8 | 12.087 [11.673–12.228] | 16.591 [16.559–16.617] | 22.738 [22.610–23.673] |
|
||||||
|
|
||||||
|
S13’s exclusive stage counters are also retained per LOD: column evaluation, marching cubes, ground/cap refinement, and mesh assembly. At W8, column evaluation averaged 21.124 ms/tile at LOD4 `[21.083–21.462]`, versus 6.815 ms at LOD3 `[6.761–7.014]`; LOD4 remains the standout cost. Standalone has matching aggregate stage sums, but no BuildHost-style per-tile p95 or per-LOD classify-exclusive p95. It also has no counterpart for full-scan versus candidate feature-list p95, field-point calls p95, column misses p95, or approximate per-LOD hit rate; its field/cache totals are whole-run totals, and its overlap capture measures cross-tile XY reuse instead. BuildHost `UWorld::Tick`, apply, and stationary-ring timings also have no headless equivalent.
|
||||||
|
|
||||||
|
The W8 overlap capture completed for all tiles and all LODs. Each cell is median `[min–max]` across three captures.
|
||||||
|
|
||||||
|
| LOD | Unique XY columns | Repeated tile evaluations | Neighbor repeats | Cross-worker neighbor repeats |
|
||||||
|
|---:|---:|---:|---:|---:|
|
||||||
|
| 0 | 128,240 [128,240–128,240] | 360,764 [359,953–364,225] | 301,491 [300,316–301,913] | 296,573 [294,996–297,862] |
|
||||||
|
| 1 | 103,957 [103,464–104,384] | 300,707 [296,768–312,183] | 243,479 [236,767–246,556] | 238,030 [228,885–241,780] |
|
||||||
|
| 2 | 32,267 [32,263–32,271] | 106,072 [104,091–106,939] | 90,338 [88,410–90,534] | 87,693 [84,976–87,921] |
|
||||||
|
| 3 | 33,286 [33,286–33,286] | 87,531 [87,310–88,408] | 81,853 [79,915–83,171] | 78,814 [76,126–78,903] |
|
||||||
|
| 4 | 91,325 [91,325–91,325] | 231,088 [230,967–231,122] | 228,336 [226,998–228,369] | 207,383 [191,310–207,789] |
|
||||||
|
| 5 | 71,960 [71,960–71,960] | 118,805 [118,676–118,806] | 118,665 [117,782–118,797] | 111,453 [108,197–112,585] |
|
||||||
|
| 6 | 280,336 [280,336–280,336] | 63,463 [63,148–63,624] | 63,463 [63,148–63,624] | 63,204 [62,944–63,579] |
|
||||||
|
| 7 | 71,530 [71,530–71,530] | 7,762 [7,752–7,807] | 7,762 [7,752–7,807] | 7,155 [7,074–7,262] |
|
||||||
|
| 8 | 106,219 [106,219–106,219] | 32,092 [32,013–32,155] | 32,092 [32,013–32,155] | 28,393 [27,959–28,598] |
|
||||||
|
|
||||||
|
## Failed and retried attempts
|
||||||
|
|
||||||
|
- `build-clang19.log` failed because `FLT_MAX` was undeclared; adding `<cfloat>` fixed it.
|
||||||
|
- `build-clang19-retry1.log` failed on existing double-to-float list initializers in `VoxelStrateManager.cpp` and an incorrect dereference in the new runner. The Linux build suppresses that legacy Clang narrowing diagnostic and passes the snapshot value correctly.
|
||||||
|
- `build-clang19-retry2.log` linked with unresolved `typeinfo for UVoxelSeasonAsset`; the compatibility glue now provides the missing `GetPrimaryAssetId`. `build-clang19-retry3.log` and `build-clang19-final.log` succeeded.
|
||||||
|
- A temporary diagnostic relink in `rebuild-headless-crash-handler.log` omitted `main` and failed; `relink-headless-crash-handler.log` corrected it. This was only for diagnosis and is not part of the final source.
|
||||||
|
- `smoke-clang19-w1.log` stopped before launching because `/usr/bin/time` was absent. No package was installed; `MeasureProcess.py` replaced it.
|
||||||
|
- Seven default-stack W1 attempts (`smoke-clang19-w1-r1.log` through `r7.log`) and three instrumented diagnostic runs (`smoke-clang19-direct.log`, `smoke-clang19-entry.log`, `smoke-clang19-stack.log`) exited with SIGSEGV while entering `FStandaloneStreamingGenerator::Generate` under the default 8 MiB stack. Their peak RSS was 211,056–329,008 KiB. A 64 MiB stack completed the diagnostic run (`smoke-clang19-stack64m.log`, 330,288 KiB peak RSS); temporary tracing pointed to worker stack exhaustion. That diagnostic included an extra direct tile and was excluded from the baseline. All clean baseline runs used the 64 MiB stack.
|
||||||
|
|
||||||
|
## Note for the owner
|
||||||
|
|
||||||
|
For this owner seed and view, a Linux server and Windows client generate identical hashed density, mesh, payload, and topology, and the hashes stayed stable across Linux worker counts and compilers. This i9-12900H result is a local Linux speed baseline; the W8 time is close to the S13 Windows number, but the machines differ and it should not be read as a speedup.
|
||||||
|
|
||||||
|
## Orchestrator review (Claude)
|
||||||
|
|
||||||
|
- **The default-stack crash is thread-local storage, not deep recursion.** `-fstack-usage` shows no frame over
|
||||||
|
~4 KB in Core or the headless tool (`Generate` is 8 KB). But the binary's TLS segment is
|
||||||
|
`0x115068d` = **17.3 MiB per thread** (6.1 MiB of it initialised data), and glibc carves static TLS out of
|
||||||
|
each thread's stack, so an 8 MiB default stack overflows before any work runs. Largest pieces:
|
||||||
|
`world_assembly_detail::HeightfieldColumnCache` 6.8 MB, `GFloorReliefCache` 1.3 MB (x2: Core and
|
||||||
|
legacy copies), `IslandColumnCache` 1.1 MB, `GRoomGraphCache` 0.97 MB (x2), `GSurfColCache` 0.83 MB (x2).
|
||||||
|
Windows allocates TLS separately from the 1 MB thread stack, which is why it never showed there.
|
||||||
|
It matters for a Linux dedicated server: every worker thread pays ~17 MB and copies 6 MB on start.
|
||||||
|
Open for a later round (after S14, which reworks the column cache).
|
||||||
|
- **Untested:** the hash match is with `-ffp-contract=off`. Whether the hash would *detect* contraction
|
||||||
|
(`on`/`fast`) has not been shown, so it is not yet proven the flag is load-bearing.
|
||||||
|
- Viewer move checked: of 738 removed viewer lines, all but 12 signature lines (now `inline`/namespaced)
|
||||||
|
reappear verbatim in the two shared headers; every remaining viewer use is qualified or `using`-imported.
|
||||||
|
MSVC compile still unverified.
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Run one child and print its wait4 peak RSS under the Linux2 process limits."""
|
||||||
|
import os
|
||||||
|
import resource
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
raise SystemExit("usage: MeasureProcess.py executable [arguments ...]")
|
||||||
|
|
||||||
|
address_limit, _ = resource.getrlimit(resource.RLIMIT_AS)
|
||||||
|
stack_limit, _ = resource.getrlimit(resource.RLIMIT_STACK)
|
||||||
|
if address_limit in (resource.RLIM_INFINITY, -1) or address_limit > 6 * 1024**3:
|
||||||
|
raise SystemExit("run under prlimit --as=6442450944")
|
||||||
|
if stack_limit in (resource.RLIM_INFINITY, -1) or stack_limit < 8 * 1024**2:
|
||||||
|
raise SystemExit("run with the ordinary process stack limit of at least 8 MiB")
|
||||||
|
if not os.sched_getaffinity(0).issubset(set(range(12))):
|
||||||
|
raise SystemExit("run under taskset -c 0-11")
|
||||||
|
print(f"[ProcessLimits] address_limit={address_limit} stack_limit={stack_limit} affinity={sorted(os.sched_getaffinity(0))}", flush=True)
|
||||||
|
|
||||||
|
started = time.monotonic()
|
||||||
|
pid = os.fork()
|
||||||
|
if pid == 0:
|
||||||
|
try:
|
||||||
|
os.execvp(sys.argv[1], sys.argv[1:])
|
||||||
|
except OSError as error:
|
||||||
|
print(f"MeasureProcess: exec failed: {error}", file=sys.stderr, flush=True)
|
||||||
|
os._exit(127)
|
||||||
|
|
||||||
|
_, status, usage = os.wait4(pid, 0)
|
||||||
|
wall = time.monotonic() - started
|
||||||
|
exit_code = os.waitstatus_to_exitcode(status)
|
||||||
|
print(f"[ProcessResources] exit_code={exit_code} wall_s={wall:.6f} peak_rss_kib={usage.ru_maxrss}")
|
||||||
|
raise SystemExit(exit_code)
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
# WorldAssemblerM3 Linux2
|
||||||
|
|
||||||
|
## Result and changes
|
||||||
|
|
||||||
|
The hash check can go red. `-ffp-contract=on`, `fast`, and GCC's default each change the first stage hash (density) on the L1 view; contraction off still reproduces all four L1 hashes at W1 and W12. No Core cache or density source was changed.
|
||||||
|
|
||||||
|
The standalone now accepts `--seed`, `--recipe`, and `--render-distance-chunks`; the viewer uses those same options for Windows replay. Linux standalone workers use 32 MiB pthread stacks, while the process retains its ordinary 8 MiB stack limit. The build script still defaults to contraction off; `--fp-contract=default` omits that override for the compiler-default probe.
|
||||||
|
|
||||||
|
Environment: i9-12900H, CPUs 0–11, Clang 19.1.7, GCC 14.2.0, governor `powersave`, EPP `balance_performance`. Runs used `taskset -c 0-11`, `RLIMIT_AS=6,442,450,944`, normal priority, and no 64 MiB stack limit. Peak `wait4` RSS was 539,648 KiB on the 2,553-tile checks and 293,460 KiB in the seed sweep.
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
Build variants, with `--fp-contract=off`, `on`, and `fast` as named; `default` leaves the compiler flag unset:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19-l2-off --jobs=12 --fp-contract=off
|
||||||
|
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19-l2-on --jobs=12 --fp-contract=on
|
||||||
|
bash Standalone/BuildLinux.sh --compiler=clang++-19 --variant=clang19-l2-fast --jobs=12 --fp-contract=fast
|
||||||
|
bash Standalone/BuildLinux.sh --compiler=g++-14 --variant=gcc14-l2-off --jobs=12 --fp-contract=off
|
||||||
|
bash Standalone/BuildLinux.sh --compiler=g++-14 --variant=gcc14-l2-default --jobs=12 --fp-contract=default
|
||||||
|
```
|
||||||
|
|
||||||
|
The L1-view call was `taskset -c 0-11 prlimit --as=6442450944 -- python3 Standalone/Research/WorldAssemblerM3/Linux2/MeasureProcess.py <binary> Standalone/data/owner_world.json --workers=<1|12> --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0`. The per-variant commands and resource records are in `Saved/Linux/linux2-contract-final-*.log`.
|
||||||
|
|
||||||
|
The seed matrix ran with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 Standalone/Research/WorldAssemblerM3/Linux2/RunSeedSweep.py 1800
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contraction sensitivity
|
||||||
|
|
||||||
|
All rows cover the same 2,553-tile L1 view, W12. `g++-14 -Q --help=optimizers -O2 -fno-fast-math` reports `-ffp-contract=fast` when no override is given.
|
||||||
|
|
||||||
|
| Build | Density | Mesh | Payload | Topology | First divergence from off |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| Clang 19 off; GCC 14 off | `c10697a8f48380c7` | `e75c9119a1498cd5` | `49a9a8d1835a6c8c` | `edcb23288b5e8724` | — |
|
||||||
|
| Clang 19 on | `acfa7023c3671dd6` | `adacc34b568be881` | `7c1de424738166e3` | `78e77fd29674920f` | density |
|
||||||
|
| Clang 19 fast | `f04bb87094a92a25` | `07596ba1a83f91d5` | `1292f277745a876d` | `b07b82bfb52166f5` | density |
|
||||||
|
| GCC 14 default (effective fast) | `03ed0b826a9ff773` | `07596ba1a83f91d5` | `fb6f82e779be56b2` | `9e5d549138ef2bc0` | density |
|
||||||
|
|
||||||
|
The hashes come from the whole-view pipeline stages in order: density, mesh, payload, topology. The same contraction-off binaries reproduce L1 at W1 as well as W12.
|
||||||
|
|
||||||
|
## Seed sweep
|
||||||
|
|
||||||
|
`seeds.txt` contains seed 0 plus 47 distinct values sampled without replacement from signed int32 using `random.Random(0x564F58454C464F52)`. With no mismatch among the 47 random draws, the one-sided 95% binomial upper bound is 6.18% for a random seed to mismatch on this exact matrix; seed 0 is included as the fixed L1 baseline.
|
||||||
|
|
||||||
|
| Recipe | Seeds | Linux combinations | Coverage per seed |
|
||||||
|
|---|---:|---|---|
|
||||||
|
| SurfaceWorld | 48 | Clang/GCC × W1/W12 (192 rows) | 27 LOD0 tiles; voxels `(-32,-192,-1984)` to `(64,-96,-1888)`, a 96³ cube (24 m per side) |
|
||||||
|
| FloatingIslands | 48 | Clang/GCC × W1/W12 (192 rows) | 27 LOD0 tiles; voxels `(-32,-32,-160)` to `(64,64,-64)`, a 96³ cube (24 m per side) |
|
||||||
|
|
||||||
|
All 384 runs passed. Clang/GCC matched at both worker counts in 192 comparisons; W1/W12 also matched within each compiler in 192 comparisons. The full per-seed, per-stage hashes, tile extents, wall time, and RSS are in [seed_hashes.csv](seed_hashes.csv); the summary is in [seed_sweep_summary.txt](seed_sweep_summary.txt). The sweep took 290.1 seconds; its maximum per-process peak RSS was 293,460 KiB. Coverage is limited to these fixed local cubes.
|
||||||
|
|
||||||
|
For seed 0, SurfaceWorld hashes are `e93491225d0202f9 / 6b2a630951428df2 / fc2798d6a5478b25 / 0c08d7d980a84301`; FloatingIslands hashes are `ea74d3354b5ce671 / 476d49ae2a4ba2a6 / 16078fcd36b68ff0 / cfb6c412b7118172`. Each sequence is density / mesh / payload / topology and matched across both compilers and worker counts.
|
||||||
|
|
||||||
|
The viewer seed override was added in `StandaloneViewer.cpp` and the standalone recipe helper; no Core change is needed. [windows_commands.txt](windows_commands.txt) contains all 192 PowerShell commands. Example from the repository root:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
```
|
||||||
|
|
||||||
|
Build the viewer with `powershell -ExecutionPolicy Bypass -File Standalone\Build.ps1`, then run the full replay with `powershell -ExecutionPolicy Bypass -File Standalone\Research\WorldAssemblerM3\Linux2\WindowsReplay.ps1`; it writes logs under `Saved\Linux`. Windows/MSVC compilation was unavailable here. Portability risk spots are the new C++20 helpers in `WorldAssemblyPrototype.h`, `strtoll` argument parsing in `StandaloneViewer.cpp`, and the `__linux__`/`std::thread` split in `StandaloneWorkerThread.h`; the pthread path is Linux-guarded.
|
||||||
|
|
||||||
|
## TLS cost and follow-up
|
||||||
|
|
||||||
|
`readelf -lW` reports `PT_TLS` FileSiz 6,093,024 bytes (5.81 MiB initialized image) and MemSiz 18,155,149 bytes (17.31 MiB per thread). Three 12-worker probes under the ordinary 8 MiB process stack measured a median spawn-to-ready time of 5.63 ms per thread (5.07–6.44 ms), and a resident increase of 17,736 KiB per worker after the first (17,936 KiB for the first). At 12 workers, `/proc/self/statm` rose by 213,036 KiB (208.0 MiB); the 32 MiB worker stacks reserve a further 32,772 KiB of virtual address space each. The largest wait4 peak across TLS probes was 268,476 KiB.
|
||||||
|
|
||||||
|
The large TLS symbols include `HeightfieldColumnCache` (0x680000 bytes, about 6.8 MB), `IslandColumnCache` (0x110000), plus duplicated `GFloorReliefCache` (0x140000 each), `GRoomGraphCache` (0xed000 each), and `GSurfColCache` (0xc9e78 each). `GPlayerFitMemo` is also duplicated as a process-wide object in ordinary `.bss`. [core_sources.txt](../../../Core/core_sources.txt) has 18 translation units: `VoxelForgeCore.cpp` is compiled once; each other 17 is compiled both as a `vfcore::detail` wrapper for Core and as a global legacy object for the standalone owner loader/mesher. This isolates the Core copy from Unreal-shaped global symbols and preserves the legacy reference path; the duplicate objects also duplicate cache state.
|
||||||
|
|
||||||
|
The L2 executable's static TLS measurement does not establish the Unreal plugin's model. Inference: a runtime-loaded shared object using general-dynamic TLS can obtain per-thread blocks through the dynamic loader, so it may avoid this exact static-TLS-in-stack footprint; the actual UBT `.so` flags and relocations must be inspected. glibc documents the TLS/dlopen compatibility concern for initial-exec TLS and recommends global-dynamic for more general shared-object loading ([glibc Dynamic Linker Hardening](https://www.sourceware.org/glibc/manual/latest/html_node/Dynamic-Linker-Hardening.html)); GCC describes the per-thread storage model and its loader/libc support ([GCC Thread-Local Storage](https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Thread-Local.html)).
|
||||||
|
|
||||||
|
After S14, prototype a small per-thread TLS handle backed by a bounded worker scratch pool or explicit generation context; share immutable initialized data and remove the Core/legacy duplicate cache where practical. This is a proposal only. The standalone stack wrapper already avoids the external 64 MiB process-stack setting: its own Linux workers request 32 MiB, and the L1 hashes stayed unchanged.
|
||||||
|
|
||||||
|
## Failed and retried runs
|
||||||
|
|
||||||
|
- The first Clang-off build failed because one join loop still named `std::thread&`; it was changed to `FStandaloneWorkerThread&` and rebuilt successfully (`linux2-build-clang-off.log`, then the retry logs). One later GCC-off build attempt stopped with `headless_object: unbound variable` (`linux2-build-gcc-off-final2.log`); an immediate identical build under the same CPU/address-space limits succeeded (`linux2-build-gcc-off-debug.log`), and the failure did not recur.
|
||||||
|
- The first FloatingIslands smoke used the default far ring and planned 186,911 tiles; it was stopped after about 10 seconds before generation (`linux2-floating-smoke-clang-w1.log`). With `--render-distance-chunks=0`, a radius-2/max-LOD-4 smoke completed 791 tiles in 18.94 seconds (`linux2-floating-smoke-clang-w1-r2.log`); the sweep uses radius 1/max-LOD 0 (27 tiles).
|
||||||
|
- The first contraction pass omitted the L1 camera and covered 2,370 tiles (`linux2-contract-*-w12.log`), so those hashes were discarded. The exact L1 camera rerun covered 2,553 tiles and produced the table above (`linux2-contract-final-*.log`).
|
||||||
|
- An optional one-ULP diagnostic attempt did not trigger (no injection line and no hash change; `linux2-negative-one-ulp-clang-off-w12.log`), so that switch was removed. It was unnecessary after the contraction variants made the check go red. The seed sweep had no failed or retried runs.
|
||||||
|
|
||||||
|
## Note for the owner
|
||||||
|
|
||||||
|
Contraction off reproduces L1 at W1/W12, while Clang on/fast and GCC default diverge first at density, so the Unreal Linux build's effective FP flags are decisive. The 48-seed sample matched across compilers and worker counts on 24 m-sided cubes in both recipes; the Windows replay commands are ready, with their MSVC build still unverified.
|
||||||
|
|
||||||
|
## Orchestrator review (Claude)
|
||||||
|
|
||||||
|
- **Surface sweep coverage is 14 effective seeds, not 48.** In `seed_hashes.csv`, 34 of the 48 SurfaceWorld
|
||||||
|
seeds give seed 0's exact density hash `0xe93491225d0202f9`, i.e. the fixed 24 m cube carries no
|
||||||
|
seed-dependent surface for them. Only 14 seeds exercise distinct terrain, so the 6.18% bound applies to
|
||||||
|
FloatingIslands (48 distinct hashes) but not to SurfaceWorld. Future sweeps should place the cube on each
|
||||||
|
seed's surface and report a per-seed non-empty-mesh count, so an empty cube can't count as a pass.
|
||||||
|
- Re-run by me: `VoxelForgeCoreHeadless-clang19-l2-off`, W12, plain 8 MiB `ulimit -s`, L1 view:
|
||||||
|
whole view 3.361 s, hashes `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724`.
|
||||||
|
- **Consequence of the contraction table:** Core's world now provably depends on the toolchain's FP-contract
|
||||||
|
setting, which every build outside `Build.ps1`/`BuildLinux.sh` (UBT on Windows and Linux) sets for itself.
|
||||||
|
Next: make Core immune to, or loudly detect, contraction instead of relying on flags.
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Run the deterministic Linux2 seed/compiler/worker matrix under the owner limits."""
|
||||||
|
import csv
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path.cwd()
|
||||||
|
ROUND = ROOT / "Standalone/Research/WorldAssemblerM3/Linux2"
|
||||||
|
LOG_DIR = ROOT / "Saved/Linux"
|
||||||
|
MEASURE = ROUND / "MeasureProcess.py"
|
||||||
|
DATA = ROOT / "Standalone/data/owner_world.json"
|
||||||
|
BINARIES = {
|
||||||
|
"clang19": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-clang19-l2-off",
|
||||||
|
"gcc14": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-gcc14-l2-off",
|
||||||
|
}
|
||||||
|
CAMERAS = {
|
||||||
|
"surface-world": "0,-35,-487.94,0,-22",
|
||||||
|
"floating-islands": "0,0,-32,0,-22",
|
||||||
|
}
|
||||||
|
HASH_RE = re.compile(
|
||||||
|
r"\[PipelineWholeViewHash\] tiles=(\d+) density=0x([0-9a-f]+) "
|
||||||
|
r"mesh=0x([0-9a-f]+) payload=0x([0-9a-f]+) topology=0x([0-9a-f]+)"
|
||||||
|
)
|
||||||
|
VOLUME_RE = re.compile(
|
||||||
|
r"\[PipelineVolume\] tiles=(\d+) lod=(\d+)\.\.(\d+) "
|
||||||
|
r"min_voxel=\((-?\d+),(-?\d+),(-?\d+)\) "
|
||||||
|
r"max_voxel=\((-?\d+),(-?\d+),(-?\d+)\)"
|
||||||
|
)
|
||||||
|
READY_RE = re.compile(r"\[StreamPipeline\].*whole_view_ready=([0-9.]+)s")
|
||||||
|
RESOURCE_RE = re.compile(r"\[ProcessResources\] exit_code=(-?\d+) wall_s=([0-9.]+) peak_rss_kib=(\d+)")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if not (1 <= len(sys.argv) <= 2):
|
||||||
|
raise SystemExit("usage: RunSeedSweep.py [budget-seconds; default 1800]")
|
||||||
|
budget_seconds = int(sys.argv[1]) if len(sys.argv) == 2 else 1800
|
||||||
|
seeds = [int(line.strip()) for line in (ROUND / "seeds.txt").read_text().splitlines() if line.strip()]
|
||||||
|
if len(seeds) != 48 or len(set(seeds)) != len(seeds):
|
||||||
|
raise SystemExit("seeds.txt must contain 48 unique signed int32 seeds")
|
||||||
|
missing = [str(path) for path in [MEASURE, DATA, *BINARIES.values()] if not path.is_file()]
|
||||||
|
if missing:
|
||||||
|
raise SystemExit("missing sweep input/build: " + ", ".join(missing))
|
||||||
|
|
||||||
|
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
output_path = ROUND / "seed_hashes.csv"
|
||||||
|
fields = [
|
||||||
|
"seed", "recipe", "compiler", "workers", "tiles", "lod_min", "lod_max",
|
||||||
|
"min_x", "min_y", "min_z", "max_x", "max_y", "max_z",
|
||||||
|
"density_hash", "mesh_hash", "payload_hash", "topology_hash",
|
||||||
|
"whole_view_ready_s", "wall_s", "peak_rss_kib", "exit_code", "status",
|
||||||
|
]
|
||||||
|
started = time.monotonic()
|
||||||
|
total = len(seeds) * len(CAMERAS) * len(BINARIES) * 2
|
||||||
|
print(f"Sweep: {len(seeds)} seeds × 2 recipes × 2 compilers × W1/W12 = {total} runs; budget={budget_seconds}s", flush=True)
|
||||||
|
|
||||||
|
with output_path.open("w", newline="") as csv_file:
|
||||||
|
writer = csv.DictWriter(csv_file, fieldnames=fields)
|
||||||
|
writer.writeheader()
|
||||||
|
for seed in seeds:
|
||||||
|
for recipe, camera in CAMERAS.items():
|
||||||
|
for compiler, binary in BINARIES.items():
|
||||||
|
for workers in (1, 12):
|
||||||
|
remaining = budget_seconds - (time.monotonic() - started)
|
||||||
|
if remaining <= 0:
|
||||||
|
print("Sweep exceeded its 30 minute budget; stopping.", file=sys.stderr, flush=True)
|
||||||
|
return 124
|
||||||
|
stem = f"linux2-seed-{seed}-{recipe}-{compiler}-w{workers}"
|
||||||
|
log_path = LOG_DIR / f"{stem}.log"
|
||||||
|
args = [
|
||||||
|
str(binary), str(DATA), f"--seed={seed}", f"--recipe={recipe}",
|
||||||
|
"--render-distance-chunks=0", f"--workers={workers}",
|
||||||
|
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
|
||||||
|
"--stream-hash", "--force-generate", "--clip-radius=1",
|
||||||
|
"--max-clip-level=0", f"--camera={camera}", "--far-horizon-lod8-step=0",
|
||||||
|
]
|
||||||
|
command = [
|
||||||
|
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
||||||
|
"python3", str(MEASURE), *args,
|
||||||
|
]
|
||||||
|
with log_path.open("w") as log_file:
|
||||||
|
log_file.write("[SweepCommand] " + " ".join(command) + "\n")
|
||||||
|
log_file.flush()
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
command, cwd=ROOT, stdout=log_file, stderr=subprocess.STDOUT,
|
||||||
|
timeout=min(900, max(1, remaining)), check=False,
|
||||||
|
)
|
||||||
|
exit_code = result.returncode
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
exit_code = 124
|
||||||
|
log_file.write("\n[SweepTimeout] run reached its allotted limit\n")
|
||||||
|
|
||||||
|
output = log_path.read_text(errors="replace")
|
||||||
|
volume = VOLUME_RE.search(output)
|
||||||
|
hashes = HASH_RE.search(output)
|
||||||
|
ready = READY_RE.search(output)
|
||||||
|
resources = RESOURCE_RE.search(output)
|
||||||
|
passed = exit_code == 0 and volume and hashes and ready and resources
|
||||||
|
row = {
|
||||||
|
"seed": seed, "recipe": recipe, "compiler": compiler, "workers": workers,
|
||||||
|
"tiles": "", "lod_min": "", "lod_max": "",
|
||||||
|
"min_x": "", "min_y": "", "min_z": "", "max_x": "", "max_y": "", "max_z": "",
|
||||||
|
"density_hash": "", "mesh_hash": "", "payload_hash": "", "topology_hash": "",
|
||||||
|
"whole_view_ready_s": "", "wall_s": "", "peak_rss_kib": "",
|
||||||
|
"exit_code": exit_code, "status": "PASS" if passed else "FAIL",
|
||||||
|
}
|
||||||
|
if passed:
|
||||||
|
row.update({
|
||||||
|
"tiles": hashes.group(1),
|
||||||
|
"lod_min": volume.group(2), "lod_max": volume.group(3),
|
||||||
|
"min_x": volume.group(4), "min_y": volume.group(5), "min_z": volume.group(6),
|
||||||
|
"max_x": volume.group(7), "max_y": volume.group(8), "max_z": volume.group(9),
|
||||||
|
"density_hash": "0x" + hashes.group(2), "mesh_hash": "0x" + hashes.group(3),
|
||||||
|
"payload_hash": "0x" + hashes.group(4), "topology_hash": "0x" + hashes.group(5),
|
||||||
|
"whole_view_ready_s": ready.group(1), "wall_s": resources.group(2),
|
||||||
|
"peak_rss_kib": resources.group(3),
|
||||||
|
})
|
||||||
|
writer.writerow(row)
|
||||||
|
csv_file.flush()
|
||||||
|
completed = sum(1 for _ in output_path.open()) - 1
|
||||||
|
elapsed = time.monotonic() - started
|
||||||
|
print(f"[{completed}/{total}] seed={seed} recipe={recipe} compiler={compiler} W{workers} "
|
||||||
|
f"tiles={row['tiles']} wall={row['wall_s']}s status={row['status']} "
|
||||||
|
f"elapsed={elapsed:.1f}s", flush=True)
|
||||||
|
if not passed:
|
||||||
|
print(f"Run failed; details: {log_path}", file=sys.stderr, flush=True)
|
||||||
|
return exit_code or 1
|
||||||
|
|
||||||
|
rows = list(csv.DictReader(output_path.open(newline="")))
|
||||||
|
keys = ("density_hash", "mesh_hash", "payload_hash", "topology_hash")
|
||||||
|
checks = []
|
||||||
|
for seed in seeds:
|
||||||
|
for recipe in CAMERAS:
|
||||||
|
for workers in (1, 12):
|
||||||
|
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
|
||||||
|
and int(r["workers"]) == workers]
|
||||||
|
equal = len(pair) == 2 and all(pair[0][key] == pair[1][key] for key in keys)
|
||||||
|
checks.append((seed, recipe, workers, equal))
|
||||||
|
worker_checks = []
|
||||||
|
for seed in seeds:
|
||||||
|
for recipe in CAMERAS:
|
||||||
|
for compiler in BINARIES:
|
||||||
|
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
|
||||||
|
and r["compiler"] == compiler]
|
||||||
|
equal = len(pair) == 2 and all(pair[0][key] == pair[1][key] for key in keys)
|
||||||
|
worker_checks.append((seed, recipe, compiler, equal))
|
||||||
|
summary_path = ROUND / "seed_sweep_summary.txt"
|
||||||
|
mismatch_count = sum(not equal for _, _, _, equal in checks)
|
||||||
|
worker_mismatch_count = sum(not equal for _, _, _, equal in worker_checks)
|
||||||
|
summary_path.write_text(
|
||||||
|
f"runs={len(rows)} seeds={len(seeds)} recipes={len(CAMERAS)} compilers={len(BINARIES)} "
|
||||||
|
f"workers=1,12 cross_compiler_comparisons={len(checks)} cross_compiler_mismatches={mismatch_count} "
|
||||||
|
f"cross_worker_comparisons={len(worker_checks)} cross_worker_mismatches={worker_mismatch_count} "
|
||||||
|
f"elapsed_s={time.monotonic()-started:.3f}\n"
|
||||||
|
)
|
||||||
|
print(summary_path.read_text(), end="", flush=True)
|
||||||
|
return 0 if mismatch_count == 0 and worker_mismatch_count == 0 else 3
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$Root = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..\..\..'))
|
||||||
|
$Viewer = Join-Path $Root 'Standalone\bin\VoxelForgeCoreStandalone.exe'
|
||||||
|
$Data = Join-Path $Root 'Standalone\data\owner_world.json'
|
||||||
|
$SeedFile = Join-Path $PSScriptRoot 'seeds.txt'
|
||||||
|
$LogDir = Join-Path $Root 'Saved\Linux'
|
||||||
|
[IO.Directory]::CreateDirectory($LogDir) | Out-Null
|
||||||
|
|
||||||
|
$Recipes = @(
|
||||||
|
@{ Name = 'surface-world'; Camera = '0,-35,-487.94,0,-22' },
|
||||||
|
@{ Name = 'floating-islands'; Camera = '0,0,-32,0,-22' }
|
||||||
|
)
|
||||||
|
$Seeds = @(Get-Content -LiteralPath $SeedFile | ForEach-Object { [int]$_.Trim() })
|
||||||
|
if ($Seeds.Count -ne 48) { throw "Expected 48 seeds in $SeedFile" }
|
||||||
|
if (-not (Test-Path -LiteralPath $Viewer -PathType Leaf)) { throw "Viewer not found: $Viewer" }
|
||||||
|
|
||||||
|
foreach ($Recipe in $Recipes) {
|
||||||
|
foreach ($Seed in $Seeds) {
|
||||||
|
foreach ($Workers in @(1, 12)) {
|
||||||
|
$Arguments = @(
|
||||||
|
$Data,
|
||||||
|
"--seed=$Seed",
|
||||||
|
"--recipe=$($Recipe.Name)",
|
||||||
|
'--render-distance-chunks=0',
|
||||||
|
"--workers=$Workers",
|
||||||
|
'--world-assembler-prototype',
|
||||||
|
'--stream-benchmark',
|
||||||
|
'--stream-pipeline',
|
||||||
|
'--stream-hash',
|
||||||
|
'--force-generate',
|
||||||
|
'--clip-radius=1',
|
||||||
|
'--max-clip-level=0',
|
||||||
|
"--camera=$($Recipe.Camera)",
|
||||||
|
'--far-horizon-lod8-step=0',
|
||||||
|
'--process-affinity=4095',
|
||||||
|
'--process-priority=Normal',
|
||||||
|
'--frame-limit=60'
|
||||||
|
)
|
||||||
|
$Stem = "windows2-seed-$Seed-$($Recipe.Name)-w$Workers"
|
||||||
|
$Log = Join-Path $LogDir "$Stem.log"
|
||||||
|
Write-Host "& `"$Viewer`" $($Arguments -join ' ')"
|
||||||
|
& $Viewer @Arguments *> $Log
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "Viewer failed ($LASTEXITCODE); see $Log" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,385 @@
|
|||||||
|
seed,recipe,compiler,workers,tiles,lod_min,lod_max,min_x,min_y,min_z,max_x,max_y,max_z,density_hash,mesh_hash,payload_hash,topology_hash,whole_view_ready_s,wall_s,peak_rss_kib,exit_code,status
|
||||||
|
-1990830953,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.124,0.139871,82432,0,PASS
|
||||||
|
-1990830953,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.447,0.472868,277576,0,PASS
|
||||||
|
-1990830953,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.104,0.120573,83292,0,PASS
|
||||||
|
-1990830953,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.418,0.444282,277964,0,PASS
|
||||||
|
-1990830953,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,0.913,0.929393,83896,0,PASS
|
||||||
|
-1990830953,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,0.611,0.639175,286112,0,PASS
|
||||||
|
-1990830953,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,1.007,1.024022,84836,0,PASS
|
||||||
|
-1990830953,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xbd4dd4a500b8d62e,0xe1d28012b857510b,0x3ecc1269ee435844,0x10c100e1503e62f6,0.604,0.631134,287396,0,PASS
|
||||||
|
-1900684165,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.122,0.138823,87580,0,PASS
|
||||||
|
-1900684165,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.443,0.470531,282936,0,PASS
|
||||||
|
-1900684165,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.115,0.131311,88568,0,PASS
|
||||||
|
-1900684165,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.430,0.455647,283260,0,PASS
|
||||||
|
-1900684165,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,1.468,1.485107,88252,0,PASS
|
||||||
|
-1900684165,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,0.724,0.749926,291776,0,PASS
|
||||||
|
-1900684165,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,1.654,1.671498,88740,0,PASS
|
||||||
|
-1900684165,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x6579d1933b1981fa,0xfd19fc2d3a0c84b3,0xb8c9aa5ec03bea15,0x854620bb0b15a2da,0.722,0.748795,292444,0,PASS
|
||||||
|
-1766412538,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.123,0.139772,82472,0,PASS
|
||||||
|
-1766412538,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.421,0.446302,277376,0,PASS
|
||||||
|
-1766412538,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.118,0.135907,82932,0,PASS
|
||||||
|
-1766412538,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.413,0.439059,278060,0,PASS
|
||||||
|
-1766412538,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,1.182,1.198659,83916,0,PASS
|
||||||
|
-1766412538,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,0.635,0.661517,288544,0,PASS
|
||||||
|
-1766412538,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,1.217,1.234070,84676,0,PASS
|
||||||
|
-1766412538,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x2a92f5e32e60e02f,0x8f64e72825b53b77,0xc8ef053d65d9a8f2,0xf908b7c927a221be,0.641,0.668605,289160,0,PASS
|
||||||
|
-1721984596,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.135727,82528,0,PASS
|
||||||
|
-1721984596,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.412,0.437074,277672,0,PASS
|
||||||
|
-1721984596,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.111,0.126643,83176,0,PASS
|
||||||
|
-1721984596,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.443825,278120,0,PASS
|
||||||
|
-1721984596,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,1.217,1.234173,84404,0,PASS
|
||||||
|
-1721984596,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,0.637,0.663034,287872,0,PASS
|
||||||
|
-1721984596,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,1.317,1.333028,84808,0,PASS
|
||||||
|
-1721984596,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x232835b6d49194bf,0x1caaf34cc5d6cd64,0x03053c530184f232,0xb660395e0dc7fd90,0.655,0.681308,287700,0,PASS
|
||||||
|
-1239598758,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.298,0.314757,83276,0,PASS
|
||||||
|
-1239598758,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.445,0.471042,288560,0,PASS
|
||||||
|
-1239598758,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.285,0.301659,84036,0,PASS
|
||||||
|
-1239598758,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x0bf609e90c8c98cd,0x73cd83a10b4aada9,0x4eba3fd151b267a4,0x559a118b768faf58,0.443,0.468361,288380,0,PASS
|
||||||
|
-1239598758,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,1.387,1.403191,84688,0,PASS
|
||||||
|
-1239598758,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,0.673,0.699757,289244,0,PASS
|
||||||
|
-1239598758,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,1.443,1.458164,85260,0,PASS
|
||||||
|
-1239598758,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x13ec8dd8009a6ca3,0xa834791c4bf4a3a6,0xf75429e19a3d3f57,0xec51f6ca14f0103f,0.687,0.712986,289888,0,PASS
|
||||||
|
-1085993262,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.146,0.161610,83596,0,PASS
|
||||||
|
-1085993262,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.434,0.459626,280092,0,PASS
|
||||||
|
-1085993262,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.137,0.155311,84108,0,PASS
|
||||||
|
-1085993262,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x58d4e8746928d967,0x40dd37203989d7ba,0x912a7f27bda7e867,0x3aaea1143bebf060,0.429,0.457999,280480,0,PASS
|
||||||
|
-1085993262,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,1.270,1.286525,86016,0,PASS
|
||||||
|
-1085993262,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,0.627,0.653909,289560,0,PASS
|
||||||
|
-1085993262,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,1.410,1.427078,86780,0,PASS
|
||||||
|
-1085993262,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x2f2773f2a0da46ab,0x3bc615085f3da506,0xf696b9a9fcf6e3e6,0x7726f0e025442908,0.648,0.673667,290288,0,PASS
|
||||||
|
-1033703345,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.153,0.171501,82920,0,PASS
|
||||||
|
-1033703345,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.433,0.459168,278696,0,PASS
|
||||||
|
-1033703345,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.146,0.161211,83612,0,PASS
|
||||||
|
-1033703345,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5e33a829837b74bd,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.436,0.462555,279276,0,PASS
|
||||||
|
-1033703345,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,2.179,2.196290,84960,0,PASS
|
||||||
|
-1033703345,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,0.837,0.862488,286132,0,PASS
|
||||||
|
-1033703345,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,2.229,2.245540,85384,0,PASS
|
||||||
|
-1033703345,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x65b606ed9df8b9dd,0x874360dc2d5480ad,0xe1a7c4c63c916b8a,0xf8bfac0093f57137,0.854,0.878634,286968,0,PASS
|
||||||
|
-854671705,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.168,0.184503,81968,0,PASS
|
||||||
|
-854671705,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.458,0.482105,276888,0,PASS
|
||||||
|
-854671705,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.156,0.172642,82296,0,PASS
|
||||||
|
-854671705,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.440,0.463845,277156,0,PASS
|
||||||
|
-854671705,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,1.997,2.014139,83980,0,PASS
|
||||||
|
-854671705,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,0.777,0.803614,286988,0,PASS
|
||||||
|
-854671705,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,1.975,1.991424,84460,0,PASS
|
||||||
|
-854671705,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xb324a85fd9f31fa1,0x92f35776d53f0bbe,0x5b4e0dc015e5a4b1,0x3dcce3ff950e5940,0.827,0.853700,287876,0,PASS
|
||||||
|
-713963806,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.116,0.133079,83972,0,PASS
|
||||||
|
-713963806,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.403,0.432000,278940,0,PASS
|
||||||
|
-713963806,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.103,0.119423,84248,0,PASS
|
||||||
|
-713963806,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.395,0.419569,279096,0,PASS
|
||||||
|
-713963806,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,1.614,1.634105,84584,0,PASS
|
||||||
|
-713963806,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,0.696,0.722153,287504,0,PASS
|
||||||
|
-713963806,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,1.642,1.658169,84804,0,PASS
|
||||||
|
-713963806,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x38a60c8389c671eb,0xcbca321fa24f4d74,0x6aa8ea9d8c735dbb,0x8b9d8e479ea5329e,0.702,0.728362,287544,0,PASS
|
||||||
|
-621039221,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.108,0.123847,84240,0,PASS
|
||||||
|
-621039221,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.404,0.429052,279360,0,PASS
|
||||||
|
-621039221,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.097,0.114239,84872,0,PASS
|
||||||
|
-621039221,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.418,0.445942,279796,0,PASS
|
||||||
|
-621039221,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,1.740,1.756998,85916,0,PASS
|
||||||
|
-621039221,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,0.736,0.762822,290788,0,PASS
|
||||||
|
-621039221,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,1.779,1.795250,86420,0,PASS
|
||||||
|
-621039221,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xa70bd050fb2e002e,0x93c9bfa37a0cd298,0x5fd74cd54a52292b,0x194b571023058cf7,0.767,0.793669,291496,0,PASS
|
||||||
|
-474448608,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.126682,82408,0,PASS
|
||||||
|
-474448608,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.420,0.445710,277208,0,PASS
|
||||||
|
-474448608,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.131780,83016,0,PASS
|
||||||
|
-474448608,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.408,0.434334,277788,0,PASS
|
||||||
|
-474448608,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,1.639,1.655937,85268,0,PASS
|
||||||
|
-474448608,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,0.748,0.775722,289208,0,PASS
|
||||||
|
-474448608,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,1.756,1.771783,86096,0,PASS
|
||||||
|
-474448608,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x80da251d7da20717,0x54a773cac2ae0da4,0xb42e970d98e5e448,0x08d56fddf5a487d6,0.758,0.784193,289568,0,PASS
|
||||||
|
-432690581,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.249,0.264467,83624,0,PASS
|
||||||
|
-432690581,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.457,0.482472,286124,0,PASS
|
||||||
|
-432690581,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.251,0.267531,83844,0,PASS
|
||||||
|
-432690581,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1e3b98fa361c46b9,0x510dd77a7ca94d0e,0x4e6917a7b06f3f41,0x09791c912e85d14a,0.456,0.481234,286612,0,PASS
|
||||||
|
-432690581,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,1.465,1.481966,84272,0,PASS
|
||||||
|
-432690581,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,0.651,0.678094,286596,0,PASS
|
||||||
|
-432690581,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,1.518,1.534396,84508,0,PASS
|
||||||
|
-432690581,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x85185a56cb2ff97a,0x656076e11a4da13b,0x708d7e58be02ab16,0xfa20cfd819664d48,0.675,0.700961,287236,0,PASS
|
||||||
|
-380556572,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.122,0.138061,83744,0,PASS
|
||||||
|
-380556572,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.443950,278968,0,PASS
|
||||||
|
-380556572,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.119,0.136000,84296,0,PASS
|
||||||
|
-380556572,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.409,0.435025,279452,0,PASS
|
||||||
|
-380556572,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.903,0.918921,85380,0,PASS
|
||||||
|
-380556572,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.587,0.614393,289360,0,PASS
|
||||||
|
-380556572,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.983,0.998686,85572,0,PASS
|
||||||
|
-380556572,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x18cb13a590f41d1f,0xdb9b7450859f053a,0x5dc9ac331ba35450,0x8cda9fbcede81e46,0.567,0.592607,290168,0,PASS
|
||||||
|
-238925630,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121729,82080,0,PASS
|
||||||
|
-238925630,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.426,0.453650,277360,0,PASS
|
||||||
|
-238925630,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.120742,82848,0,PASS
|
||||||
|
-238925630,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.391,0.417157,277784,0,PASS
|
||||||
|
-238925630,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,2.159,2.174883,84956,0,PASS
|
||||||
|
-238925630,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,0.798,0.823378,286820,0,PASS
|
||||||
|
-238925630,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,2.135,2.151003,86032,0,PASS
|
||||||
|
-238925630,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x3b99d22e2baa2ad7,0xf8a56dd82f8dbe0f,0x91fbb129908c4373,0x0d0d12d4bc8eca05,0.848,0.872951,287200,0,PASS
|
||||||
|
-216679974,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.113,0.128975,84840,0,PASS
|
||||||
|
-216679974,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.424,0.448196,279868,0,PASS
|
||||||
|
-216679974,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.110,0.125699,85388,0,PASS
|
||||||
|
-216679974,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.443897,280212,0,PASS
|
||||||
|
-216679974,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,1.154,1.170155,87404,0,PASS
|
||||||
|
-216679974,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,0.599,0.627832,291380,0,PASS
|
||||||
|
-216679974,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,1.244,1.260024,88080,0,PASS
|
||||||
|
-216679974,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x329264ded82099ac,0x4fe355cb337a1fd9,0x0f1cf173f8b6da09,0x29c9025339a1891c,0.652,0.682174,292220,0,PASS
|
||||||
|
-133096164,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.137668,83564,0,PASS
|
||||||
|
-133096164,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.416,0.440317,278792,0,PASS
|
||||||
|
-133096164,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.129823,84168,0,PASS
|
||||||
|
-133096164,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.430509,278888,0,PASS
|
||||||
|
-133096164,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,0.922,0.937785,84360,0,PASS
|
||||||
|
-133096164,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,0.589,0.618394,288344,0,PASS
|
||||||
|
-133096164,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,1.012,1.027635,84716,0,PASS
|
||||||
|
-133096164,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xd365848036423e24,0x8357d602689e662a,0x71d6cc040cfb374d,0xe50280db1b51428d,0.635,0.660045,288680,0,PASS
|
||||||
|
-112366806,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.243,0.260958,84464,0,PASS
|
||||||
|
-112366806,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.493,0.519148,283500,0,PASS
|
||||||
|
-112366806,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.227,0.243726,84772,0,PASS
|
||||||
|
-112366806,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x117219c29ee67785,0x997b517646187e1a,0x85cb430517cbbf42,0x685ea038d9f06065,0.465,0.489473,284084,0,PASS
|
||||||
|
-112366806,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,1.309,1.326524,85228,0,PASS
|
||||||
|
-112366806,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,0.701,0.726986,287836,0,PASS
|
||||||
|
-112366806,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,1.395,1.411147,85016,0,PASS
|
||||||
|
-112366806,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x9014ca6f9bc869cb,0x8b4f78faf1311e89,0x9556cf42e66d3d0a,0x74d6915603c033ad,0.739,0.765027,288736,0,PASS
|
||||||
|
0,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.119,0.135072,84800,0,PASS
|
||||||
|
0,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.426,0.451782,279552,0,PASS
|
||||||
|
0,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.113,0.128723,84848,0,PASS
|
||||||
|
0,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.420,0.445716,280480,0,PASS
|
||||||
|
0,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,1.559,1.574177,85036,0,PASS
|
||||||
|
0,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,0.717,0.744287,287992,0,PASS
|
||||||
|
0,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,1.736,1.751668,85428,0,PASS
|
||||||
|
0,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xea74d3354b5ce671,0x476d49ae2a4ba2a6,0x16078fcd36b68ff0,0xcfb6c412b7118172,0.739,0.765220,288024,0,PASS
|
||||||
|
5808593,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.138,0.152855,82892,0,PASS
|
||||||
|
5808593,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.442,0.467475,277756,0,PASS
|
||||||
|
5808593,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.135,0.152123,83220,0,PASS
|
||||||
|
5808593,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.455,0.480133,278336,0,PASS
|
||||||
|
5808593,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,1.035,1.051725,84148,0,PASS
|
||||||
|
5808593,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,0.590,0.616756,287312,0,PASS
|
||||||
|
5808593,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,1.066,1.081777,85048,0,PASS
|
||||||
|
5808593,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xebd71c4fe9dd2dc6,0x9ffa12a70e6f7875,0x1a4ca0cc9847ee58,0xf19d80d6dd09e180,0.607,0.633661,287888,0,PASS
|
||||||
|
28573228,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.129946,83304,0,PASS
|
||||||
|
28573228,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.413,0.438628,278012,0,PASS
|
||||||
|
28573228,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121266,83976,0,PASS
|
||||||
|
28573228,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.430367,278532,0,PASS
|
||||||
|
28573228,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,1.328,1.344479,84096,0,PASS
|
||||||
|
28573228,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,0.657,0.682189,287896,0,PASS
|
||||||
|
28573228,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,1.475,1.493744,84604,0,PASS
|
||||||
|
28573228,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x8bc79bd6b4d338f9,0xac4276d07d65ceb0,0x357351bb0d2f1cb8,0x900a254512dfc430,0.688,0.715502,288240,0,PASS
|
||||||
|
70955227,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.122,0.139162,83836,0,PASS
|
||||||
|
70955227,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.446187,279048,0,PASS
|
||||||
|
70955227,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.118,0.133338,84804,0,PASS
|
||||||
|
70955227,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.428654,279540,0,PASS
|
||||||
|
70955227,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,1.560,1.576865,86016,0,PASS
|
||||||
|
70955227,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,0.849,0.882918,288164,0,PASS
|
||||||
|
70955227,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,1.635,1.651152,86548,0,PASS
|
||||||
|
70955227,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xdaf7faa124800a90,0x0e2038b6f58233ec,0x9df861ebdd4ad5a0,0x50b94b2a529261d7,0.767,0.793113,288924,0,PASS
|
||||||
|
75274690,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.129015,83520,0,PASS
|
||||||
|
75274690,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.432266,278808,0,PASS
|
||||||
|
75274690,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.107,0.122969,84248,0,PASS
|
||||||
|
75274690,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.400,0.425046,279232,0,PASS
|
||||||
|
75274690,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,1.140,1.158530,86028,0,PASS
|
||||||
|
75274690,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,0.635,0.661364,290020,0,PASS
|
||||||
|
75274690,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,1.237,1.253451,86900,0,PASS
|
||||||
|
75274690,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xdf250106794ae38c,0x76706ba6a26f55ce,0x533b1070a58f2158,0x4f2ac497b8e00d2c,0.629,0.657284,290424,0,PASS
|
||||||
|
81375760,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.302,0.321425,84348,0,PASS
|
||||||
|
81375760,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.473,0.498702,288596,0,PASS
|
||||||
|
81375760,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.284,0.300131,84776,0,PASS
|
||||||
|
81375760,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x55d1e034d67632f5,0xf493f363535135e7,0xf1081c7533a6b533,0x24c1ef771b2e29df,0.465,0.493912,289032,0,PASS
|
||||||
|
81375760,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,1.644,1.660225,85756,0,PASS
|
||||||
|
81375760,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,0.738,0.765107,289596,0,PASS
|
||||||
|
81375760,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,1.724,1.741866,86704,0,PASS
|
||||||
|
81375760,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x5e5bc1daf1855a5d,0x6d9a375c60771dd6,0x0e23381363a677c9,0xcd4cbbab580c6da6,0.751,0.778126,289620,0,PASS
|
||||||
|
146979566,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.146,0.162199,83420,0,PASS
|
||||||
|
146979566,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.434165,281384,0,PASS
|
||||||
|
146979566,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.154,0.171817,84220,0,PASS
|
||||||
|
146979566,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x28dc20a8ab6fb2d0,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.404,0.429003,282144,0,PASS
|
||||||
|
146979566,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,1.638,1.654237,86300,0,PASS
|
||||||
|
146979566,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,0.698,0.725703,289448,0,PASS
|
||||||
|
146979566,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,1.845,1.861845,86680,0,PASS
|
||||||
|
146979566,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xac33a725e13e3886,0x86611ee4c12947c9,0x2991daf2b7f1f2e4,0x91e98f0e880b1f3d,0.759,0.786078,290128,0,PASS
|
||||||
|
244951180,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.195,0.213011,86480,0,PASS
|
||||||
|
244951180,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.452,0.479860,284556,0,PASS
|
||||||
|
244951180,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.181,0.197358,87220,0,PASS
|
||||||
|
244951180,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x1cc26cbbf38ba8e9,0xeaace7e8b8443be0,0x61a9b62f2967c453,0xd0358bf6bbc94bb9,0.434,0.459596,284852,0,PASS
|
||||||
|
244951180,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,1.121,1.137204,86652,0,PASS
|
||||||
|
244951180,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,0.603,0.628602,289720,0,PASS
|
||||||
|
244951180,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,1.192,1.207485,87296,0,PASS
|
||||||
|
244951180,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x8bd265dfa2c428c4,0x47904e96f2a9213c,0xa9683a3e3251c768,0x585c686bcfe6be65,0.638,0.665330,290548,0,PASS
|
||||||
|
245433414,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.131222,82516,0,PASS
|
||||||
|
245433414,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.408,0.432991,277848,0,PASS
|
||||||
|
245433414,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.100,0.115984,83136,0,PASS
|
||||||
|
245433414,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.444156,277616,0,PASS
|
||||||
|
245433414,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,1.203,1.220959,86352,0,PASS
|
||||||
|
245433414,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,0.630,0.655544,290084,0,PASS
|
||||||
|
245433414,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,1.279,1.296620,86904,0,PASS
|
||||||
|
245433414,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x8740ccf600a029e2,0x04589dea4d5c0710,0x15ebf34a211b4233,0x1249a8b782a9ff85,0.664,0.692096,290640,0,PASS
|
||||||
|
277442974,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.190,0.206505,84588,0,PASS
|
||||||
|
277442974,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.498,0.524538,279420,0,PASS
|
||||||
|
277442974,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.188,0.203434,85052,0,PASS
|
||||||
|
277442974,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.493,0.518404,279564,0,PASS
|
||||||
|
277442974,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,1.322,1.338231,87924,0,PASS
|
||||||
|
277442974,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,0.676,0.700980,292844,0,PASS
|
||||||
|
277442974,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,1.366,1.382495,88588,0,PASS
|
||||||
|
277442974,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x175a35be1d6f3efe,0xec304bc7b17ae96e,0x3559b943893fa981,0x491b549b23966102,0.701,0.727447,293072,0,PASS
|
||||||
|
297746112,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.245,0.260033,85384,0,PASS
|
||||||
|
297746112,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.465,0.490415,288008,0,PASS
|
||||||
|
297746112,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.243,0.258435,86024,0,PASS
|
||||||
|
297746112,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xca1d94b876e4eeab,0xa25988b781b26dd4,0x054762688f50e323,0x71019e04b6b0de40,0.471,0.498359,288480,0,PASS
|
||||||
|
297746112,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,1.652,1.667443,86192,0,PASS
|
||||||
|
297746112,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,0.747,0.773312,289872,0,PASS
|
||||||
|
297746112,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,1.731,1.748813,86708,0,PASS
|
||||||
|
297746112,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x87cc040ef39b9130,0x0a2ea7d615d2f513,0x22cdcf9ca191de12,0xe2f6e225caca52f0,0.764,0.789221,290484,0,PASS
|
||||||
|
336768467,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.128946,82460,0,PASS
|
||||||
|
336768467,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.419,0.445300,277468,0,PASS
|
||||||
|
336768467,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.110,0.125258,83208,0,PASS
|
||||||
|
336768467,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.397,0.423317,278004,0,PASS
|
||||||
|
336768467,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,1.629,1.646272,85052,0,PASS
|
||||||
|
336768467,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,0.728,0.754451,288124,0,PASS
|
||||||
|
336768467,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,1.705,1.720538,85388,0,PASS
|
||||||
|
336768467,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x51c11d2bb0b34ea1,0x7b5968648098e169,0x6671281233fba737,0xf6d98fa4825abf1c,0.738,0.766954,288356,0,PASS
|
||||||
|
512532080,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.153,0.168716,82560,0,PASS
|
||||||
|
512532080,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.440,0.467645,277488,0,PASS
|
||||||
|
512532080,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.143,0.159069,82904,0,PASS
|
||||||
|
512532080,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.445,0.469304,277704,0,PASS
|
||||||
|
512532080,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,1.226,1.242263,84388,0,PASS
|
||||||
|
512532080,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,0.629,0.654951,288556,0,PASS
|
||||||
|
512532080,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,1.360,1.375755,85232,0,PASS
|
||||||
|
512532080,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x072b184717239693,0x9fac948bbd70a853,0xc00c647e52d9427e,0x4cc2ff6aed2ad23d,0.672,0.697654,289308,0,PASS
|
||||||
|
821120640,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.153,0.168054,82828,0,PASS
|
||||||
|
821120640,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.462,0.487309,277536,0,PASS
|
||||||
|
821120640,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.149,0.163984,82908,0,PASS
|
||||||
|
821120640,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.445,0.471081,277668,0,PASS
|
||||||
|
821120640,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,1.491,1.507224,85000,0,PASS
|
||||||
|
821120640,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,0.700,0.726549,289052,0,PASS
|
||||||
|
821120640,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,1.661,1.677544,85416,0,PASS
|
||||||
|
821120640,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x799f3dddb77b2373,0x2ff216b7c9c0a0f7,0xbd06c753c834d621,0xe6452e48c09c779c,0.775,0.801706,289404,0,PASS
|
||||||
|
853538490,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.351,0.367197,83708,0,PASS
|
||||||
|
853538490,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.498,0.524390,287376,0,PASS
|
||||||
|
853538490,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.309,0.325235,84408,0,PASS
|
||||||
|
853538490,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe9c955bb88ef453e,0xf6ff06a22d87a886,0x8affd2ace9c02ca9,0xa87ab0dfc3a7abaf,0.503,0.529485,287824,0,PASS
|
||||||
|
853538490,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,1.594,1.609537,84548,0,PASS
|
||||||
|
853538490,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,0.744,0.770634,287636,0,PASS
|
||||||
|
853538490,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,1.565,1.581727,85352,0,PASS
|
||||||
|
853538490,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xf325b1581a7f5166,0x375b7d2ab1227a19,0xa5b6bfe633662d7e,0xaceab7327811c4f7,0.783,0.809731,287652,0,PASS
|
||||||
|
861026696,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.140722,84164,0,PASS
|
||||||
|
861026696,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.424,0.450365,279168,0,PASS
|
||||||
|
861026696,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.128137,84788,0,PASS
|
||||||
|
861026696,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.404,0.429204,279848,0,PASS
|
||||||
|
861026696,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,1.511,1.528290,85840,0,PASS
|
||||||
|
861026696,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,0.690,0.716270,288668,0,PASS
|
||||||
|
861026696,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,1.581,1.598332,86244,0,PASS
|
||||||
|
861026696,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xca1edaff577a4e1c,0xd032eac020ae2194,0x573cba10f70617e8,0xa8ef305116ad999c,0.737,0.763910,288720,0,PASS
|
||||||
|
1026251636,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.125,0.140307,87376,0,PASS
|
||||||
|
1026251636,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.431,0.456676,282440,0,PASS
|
||||||
|
1026251636,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.120,0.136933,87768,0,PASS
|
||||||
|
1026251636,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.410,0.435138,282592,0,PASS
|
||||||
|
1026251636,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,2.194,2.209401,90204,0,PASS
|
||||||
|
1026251636,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,0.851,0.878001,292176,0,PASS
|
||||||
|
1026251636,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,2.274,2.290952,90476,0,PASS
|
||||||
|
1026251636,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x389074d90273f26e,0xa38bcee9be5ec7eb,0x640d982fa1ac7f9c,0xe03c1c060ff49cca,0.835,0.863009,292140,0,PASS
|
||||||
|
1077415394,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.146,0.163297,86188,0,PASS
|
||||||
|
1077415394,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.414,0.439121,283756,0,PASS
|
||||||
|
1077415394,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.148,0.168584,86796,0,PASS
|
||||||
|
1077415394,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x87ee69cb17aba224,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.426,0.450855,284368,0,PASS
|
||||||
|
1077415394,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,1.601,1.617268,87912,0,PASS
|
||||||
|
1077415394,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,0.699,0.725603,292220,0,PASS
|
||||||
|
1077415394,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,1.727,1.745677,88476,0,PASS
|
||||||
|
1077415394,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x9584311b92b45072,0xee776f01c536080b,0x6648ac4dfaf4abfd,0x18119783a47a0df1,0.833,0.867727,292828,0,PASS
|
||||||
|
1130999017,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.291,0.307690,85160,0,PASS
|
||||||
|
1130999017,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.452,0.481022,289968,0,PASS
|
||||||
|
1130999017,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.266,0.282332,85784,0,PASS
|
||||||
|
1130999017,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x38c8b5c86fc861ed,0x0871f41c7adbcbec,0x983b9c5b7bfc9c68,0x920b30bf2774555b,0.444,0.470657,290324,0,PASS
|
||||||
|
1130999017,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,1.472,1.489302,84108,0,PASS
|
||||||
|
1130999017,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,0.713,0.738699,287528,0,PASS
|
||||||
|
1130999017,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,1.530,1.545977,84776,0,PASS
|
||||||
|
1130999017,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x519dd11ec1b6fd25,0x03655ab9c5d71117,0xbd12d3dae54569a6,0x80d8d87e27a7de44,0.685,0.710911,288188,0,PASS
|
||||||
|
1156488597,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.121,0.139125,83040,0,PASS
|
||||||
|
1156488597,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.403,0.428569,278288,0,PASS
|
||||||
|
1156488597,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.109,0.125855,83948,0,PASS
|
||||||
|
1156488597,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.425,0.450644,278660,0,PASS
|
||||||
|
1156488597,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,1.216,1.232170,85424,0,PASS
|
||||||
|
1156488597,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,0.645,0.670839,287908,0,PASS
|
||||||
|
1156488597,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,1.312,1.328475,86080,0,PASS
|
||||||
|
1156488597,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x640a6e138f3d100a,0x89a1c96de1216f8a,0xabb2594c0f2aa5e1,0xbdaec02426d2a060,0.704,0.729815,288444,0,PASS
|
||||||
|
1172304228,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.109,0.123809,82616,0,PASS
|
||||||
|
1172304228,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.431733,277580,0,PASS
|
||||||
|
1172304228,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.101,0.115688,82980,0,PASS
|
||||||
|
1172304228,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.407,0.432724,277708,0,PASS
|
||||||
|
1172304228,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.869,0.885113,85556,0,PASS
|
||||||
|
1172304228,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.584,0.611186,288244,0,PASS
|
||||||
|
1172304228,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.964,0.980259,85884,0,PASS
|
||||||
|
1172304228,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xfb46579ab737c12d,0x0a000a703c549cc1,0xfea6b41d2c3dda0e,0x9640bd6047c9a630,0.611,0.636011,289012,0,PASS
|
||||||
|
1370340570,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121360,82860,0,PASS
|
||||||
|
1370340570,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.413,0.439779,277640,0,PASS
|
||||||
|
1370340570,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.105,0.120822,83596,0,PASS
|
||||||
|
1370340570,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.406,0.430247,278132,0,PASS
|
||||||
|
1370340570,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,1.678,1.694262,85176,0,PASS
|
||||||
|
1370340570,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,0.691,0.717560,287996,0,PASS
|
||||||
|
1370340570,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,1.820,1.836129,85504,0,PASS
|
||||||
|
1370340570,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x34624cba09f42b66,0xd81a376b1e97ec8b,0xf965f89b36b5d843,0xf6abf6a7f4a15687,0.768,0.793448,288372,0,PASS
|
||||||
|
1383925073,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.112,0.129033,81792,0,PASS
|
||||||
|
1383925073,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.401,0.427476,277224,0,PASS
|
||||||
|
1383925073,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.105,0.120673,82892,0,PASS
|
||||||
|
1383925073,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.402,0.425822,277488,0,PASS
|
||||||
|
1383925073,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,1.772,1.788831,84816,0,PASS
|
||||||
|
1383925073,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,0.882,0.907588,287224,0,PASS
|
||||||
|
1383925073,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,1.870,1.886415,84956,0,PASS
|
||||||
|
1383925073,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x32c8a3f9cd2d249e,0xe504e184d0529243,0x58408898b37b6d53,0x3154f68bf8585d9e,0.907,0.933394,287936,0,PASS
|
||||||
|
1401164998,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.287,0.303400,84652,0,PASS
|
||||||
|
1401164998,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.478,0.503793,287484,0,PASS
|
||||||
|
1401164998,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.275,0.290885,85324,0,PASS
|
||||||
|
1401164998,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.467,0.494139,288496,0,PASS
|
||||||
|
1401164998,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,1.963,1.979104,84732,0,PASS
|
||||||
|
1401164998,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,0.747,0.775087,287448,0,PASS
|
||||||
|
1401164998,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,1.910,1.926095,85012,0,PASS
|
||||||
|
1401164998,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xec2a42ee2976845f,0xa295763ea8d9e67f,0xe9c0bff6914243ba,0x62b04de967523696,0.798,0.823400,288392,0,PASS
|
||||||
|
1558879574,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.115,0.132445,81992,0,PASS
|
||||||
|
1558879574,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.422,0.447714,276768,0,PASS
|
||||||
|
1558879574,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.103,0.119871,82376,0,PASS
|
||||||
|
1558879574,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.421,0.447570,277272,0,PASS
|
||||||
|
1558879574,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.920,0.936756,83620,0,PASS
|
||||||
|
1558879574,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.595,0.621724,287708,0,PASS
|
||||||
|
1558879574,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.939,0.954884,84488,0,PASS
|
||||||
|
1558879574,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x6a6961f63402e799,0xcdeb03b89b00d39d,0x0b036e09b5273b49,0x971cac1901dff195,0.600,0.626689,288548,0,PASS
|
||||||
|
1753015542,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.121516,83192,0,PASS
|
||||||
|
1753015542,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.420,0.448397,278160,0,PASS
|
||||||
|
1753015542,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.110,0.129636,83988,0,PASS
|
||||||
|
1753015542,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.405,0.431222,278696,0,PASS
|
||||||
|
1753015542,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,1.661,1.678331,85292,0,PASS
|
||||||
|
1753015542,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,0.725,0.750781,288032,0,PASS
|
||||||
|
1753015542,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,1.786,1.802204,86188,0,PASS
|
||||||
|
1753015542,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xb91a6e87bdb9610e,0xfdbb714aa24253d8,0xfea893be04158e3f,0x3365335c4b56e58c,0.739,0.765903,288808,0,PASS
|
||||||
|
1827697875,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.106,0.122073,84540,0,PASS
|
||||||
|
1827697875,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.412,0.435966,279476,0,PASS
|
||||||
|
1827697875,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.105,0.121830,84676,0,PASS
|
||||||
|
1827697875,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.409,0.434709,279752,0,PASS
|
||||||
|
1827697875,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,1.666,1.681850,89140,0,PASS
|
||||||
|
1827697875,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,0.739,0.764550,292172,0,PASS
|
||||||
|
1827697875,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,1.784,1.800585,89620,0,PASS
|
||||||
|
1827697875,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x699dd931ec3a2699,0x88331e1e5644593e,0xaa2288bc01794464,0xf92b0fbeb4ea279b,0.774,0.801097,293460,0,PASS
|
||||||
|
1909311298,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.126,0.140793,81792,0,PASS
|
||||||
|
1909311298,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.454,0.479793,277000,0,PASS
|
||||||
|
1909311298,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.119,0.138021,82780,0,PASS
|
||||||
|
1909311298,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.439,0.465770,277320,0,PASS
|
||||||
|
1909311298,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,1.677,1.692282,84504,0,PASS
|
||||||
|
1909311298,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,0.726,0.753056,287464,0,PASS
|
||||||
|
1909311298,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,1.895,1.911071,84364,0,PASS
|
||||||
|
1909311298,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x15c0afb4c79cdd4e,0xc5f83ce7199a4708,0x1a923e880b787190,0xb9ca42e4a6e19d87,0.754,0.781499,287952,0,PASS
|
||||||
|
2011898099,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.113,0.129139,83892,0,PASS
|
||||||
|
2011898099,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.433,0.459151,278756,0,PASS
|
||||||
|
2011898099,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.103,0.117822,84760,0,PASS
|
||||||
|
2011898099,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.428,0.456161,279268,0,PASS
|
||||||
|
2011898099,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,1.148,1.163696,87080,0,PASS
|
||||||
|
2011898099,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,0.624,0.651689,289916,0,PASS
|
||||||
|
2011898099,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,1.234,1.252059,87640,0,PASS
|
||||||
|
2011898099,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x4e5bc61fa6d60b4e,0x3c54a6c3cc817e24,0xa9a3c69c604071a5,0x53009044905f1269,0.650,0.677250,290788,0,PASS
|
||||||
|
2015768509,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.319,0.335248,82712,0,PASS
|
||||||
|
2015768509,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.497,0.523192,286708,0,PASS
|
||||||
|
2015768509,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.280,0.296244,83728,0,PASS
|
||||||
|
2015768509,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0x5d69d4a0b6a3d1c3,0x300ab4e08dc23479,0xb1638622b8b616ad,0x082af297bc0e2595,0.479,0.505113,287436,0,PASS
|
||||||
|
2015768509,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,1.490,1.506239,84120,0,PASS
|
||||||
|
2015768509,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,0.717,0.744393,288996,0,PASS
|
||||||
|
2015768509,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,1.600,1.617351,84900,0,PASS
|
||||||
|
2015768509,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0xd9c1ee0b4c2e8ce8,0x7d2329c4b87bc6f1,0x8f9d279d8d590839,0x7ac25c667e165fa7,0.742,0.769135,289484,0,PASS
|
||||||
|
2070776516,surface-world,clang19,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.126,0.141678,81840,0,PASS
|
||||||
|
2070776516,surface-world,clang19,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.430,0.456364,276976,0,PASS
|
||||||
|
2070776516,surface-world,gcc14,1,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.114,0.131120,82540,0,PASS
|
||||||
|
2070776516,surface-world,gcc14,12,27,0,0,-32,-192,-1984,64,-96,-1888,0xe93491225d0202f9,0x6b2a630951428df2,0xfc2798d6a5478b25,0x0c08d7d980a84301,0.401,0.425293,277436,0,PASS
|
||||||
|
2070776516,floating-islands,clang19,1,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,0.998,1.014096,84548,0,PASS
|
||||||
|
2070776516,floating-islands,clang19,12,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,0.575,0.600529,286932,0,PASS
|
||||||
|
2070776516,floating-islands,gcc14,1,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,1.054,1.070063,84768,0,PASS
|
||||||
|
2070776516,floating-islands,gcc14,12,27,0,0,-32,-32,-160,64,64,-64,0x2cc0f6dce797b31f,0x8760f9677ab58f62,0x03d2511d3ea2f55b,0x2f55edd35d7b78ef,0.597,0.622079,287140,0,PASS
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
runs=384 seeds=48 recipes=2 compilers=2 workers=1,12 cross_compiler_comparisons=192 cross_compiler_mismatches=0 cross_worker_comparisons=192 cross_worker_mismatches=0 elapsed_s=290.100
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
-1990830953
|
||||||
|
-1900684165
|
||||||
|
-1766412538
|
||||||
|
-1721984596
|
||||||
|
-1239598758
|
||||||
|
-1085993262
|
||||||
|
-1033703345
|
||||||
|
-854671705
|
||||||
|
-713963806
|
||||||
|
-621039221
|
||||||
|
-474448608
|
||||||
|
-432690581
|
||||||
|
-380556572
|
||||||
|
-238925630
|
||||||
|
-216679974
|
||||||
|
-133096164
|
||||||
|
-112366806
|
||||||
|
0
|
||||||
|
5808593
|
||||||
|
28573228
|
||||||
|
70955227
|
||||||
|
75274690
|
||||||
|
81375760
|
||||||
|
146979566
|
||||||
|
244951180
|
||||||
|
245433414
|
||||||
|
277442974
|
||||||
|
297746112
|
||||||
|
336768467
|
||||||
|
512532080
|
||||||
|
821120640
|
||||||
|
853538490
|
||||||
|
861026696
|
||||||
|
1026251636
|
||||||
|
1077415394
|
||||||
|
1130999017
|
||||||
|
1156488597
|
||||||
|
1172304228
|
||||||
|
1370340570
|
||||||
|
1383925073
|
||||||
|
1401164998
|
||||||
|
1558879574
|
||||||
|
1753015542
|
||||||
|
1827697875
|
||||||
|
1909311298
|
||||||
|
2011898099
|
||||||
|
2015768509
|
||||||
|
2070776516
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=surface-world --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=surface-world --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1990830953 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1900684165 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1766412538 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1721984596 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1239598758 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1085993262 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-1033703345 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-854671705 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-713963806 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-621039221 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-474448608 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-432690581 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-380556572 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-238925630 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-216679974 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-133096164 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=-112366806 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=0 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=5808593 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=28573228 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=70955227 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=75274690 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=81375760 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=146979566 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=244951180 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=245433414 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=277442974 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=297746112 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=336768467 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=512532080 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=821120640 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=853538490 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=861026696 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1026251636 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1077415394 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1130999017 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1156488597 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1172304228 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1370340570 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1383925073 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1401164998 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1558879574 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1753015542 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1827697875 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=1909311298 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2011898099 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2015768509 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=floating-islands --render-distance-chunks=0 --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
|
& ".\Standalone\bin\VoxelForgeCoreStandalone.exe" ".\Standalone\data\owner_world.json" --seed=2070776516 --recipe=floating-islands --render-distance-chunks=0 --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=1 --max-clip-level=0 --camera=0,0,-32,0,-22 --far-horizon-lod8-step=0 --process-affinity=4095 --process-priority=Normal --frame-limit=60
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
# WorldAssemblerM3 Linux3 — FP contraction
|
||||||
|
|
||||||
|
## Unreal flags: documented and inferred
|
||||||
|
|
||||||
|
UE 5.7's Target Reference documents `FPSemantics`; Epic's Module Properties page documents the matching module-level property and says it overrides FP semantics. Epic Support says module and target overrides have existed since UE 5.4. This repo's `VoxelForgeCore.Build.cs` already sets `FPSemantics = FPSemanticsMode.Precise` and `PCHUsage = PCHUsageMode.NoPCHs` (existing lines 44–45). [UE 5.7 Target Reference](https://dev.epicgames.com/documentation/en-us/unreal-engine/unreal-engine-build-tool-target-reference?application_version=5.7), [Module Properties](https://dev.epicgames.com/documentation/unreal-engine/module-properties-in-unreal-engine), [Epic Support answer](https://forums.unrealengine.com/t/debug-game-development/2668723)
|
||||||
|
|
||||||
|
Public UBT documentation does **not** publish one exact compiler argv for every plugin, platform, and configuration. Epic Support reports Windows DebugGame uses `/fp:precise` and Development uses `/fp:fast` by default. MSVC 2022 17+ defaults `/fp:precise` to contraction off; explicit `/fp:contract` can enable it under `/fp:precise`, and `/fp:fast` permits it by default. Earlier MSVC versions defaulted precise contraction on. Explicit `#pragma fp_contract(off)` overrides `/fp:fast`. Clang's `precise` model allows same-expression `-ffp-contract=on`; `-ffp-contract=fast` can fuse across statements and ignores `#pragma clang fp contract(off)`. GCC defaults to `-ffp-contract=fast`; its standard `FP_CONTRACT` pragma is not implemented, so this patch uses GCC's function-option pragma instead. [MSVC `/fp`](https://learn.microsoft.com/en-us/cpp/build/reference/fp-specify-floating-point-behavior?view=msvc-170), [MSVC pragma](https://learn.microsoft.com/en-us/cpp/preprocessor/fp-contract?view=msvc-170), [Clang FP pragmas and model](https://clang.llvm.org/docs/LanguageExtensions.html#extensions-to-specify-floating-point-flags), [GCC FP options](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html), [GCC function-specific pragmas](https://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html), [GCC FP implementation](https://gcc.gnu.org/onlinedocs/gcc/Floating-point-implementation.html)
|
||||||
|
|
||||||
|
**Inference for this repo:** The standalone BuildHost is safe-by-configuration on current VS 2022: `Build.ps1` explicitly uses `/fp:precise`, whose 17.0+ default is contraction off. The owner's UBT Windows build is likely safe for the same reason because the module sets `Precise`, but it was not captured here; an older MSVC or an explicit `/fp:contract` could put it at risk. On Linux, `Precise` alone does not mean contraction off for Clang, so the UBT build was at risk before this change. UE 5.7's supported Linux compiler is Clang 20.1.8; this host tested Clang 19.1.7. Epic's UE 5.7 PS5 notes also show Clang flags vary by platform: PS5 removed `-ffp-contract=off` because its `-ffast-math` setting conflicted with it. This does not establish that Linux UBT passes `-ffast-math`; capture that module's actual command line on the owner PC. [UE Linux requirements](https://dev.epicgames.com/documentation/unreal-engine/linux-development-requirements-for-unreal-engine?lang=en-US), [UE 5.7 PS5 notes](https://dev.epicgames.com/documentation/en-us/unreal-engine/playstation-5-release-notes-for-unreal-engine-5-7)
|
||||||
|
|
||||||
|
## Mechanism and Core lines touched
|
||||||
|
|
||||||
|
Each Core translation unit loads `CoreNamespacePreamble.h` before its implementation. The preamble applies Clang `contract(off)`, MSVC `fp_contract(off)`, or GCC `optimize("fp-contract=off")`; unknown compilers fail at compile time. Its noinline probe evaluates `(1 + 2^-27) * (1 - 2^-27) - 1` using volatile inputs. Separate multiply/add rounds to `0`; a fused operation returns `-2^-54`.
|
||||||
|
|
||||||
|
`World::compile` runs that probe before building the shape and returns an error before density generation if it fuses. The check and density implementation receive the same preamble/FP pragma in Core. Clang `fast` is deliberately refused because Clang documents that mode as ignoring the source pragma. GCC's default and the explicit Clang `on` mode are instead compiled with the source-level off control.
|
||||||
|
|
||||||
|
Only these Core lines changed:
|
||||||
|
|
||||||
|
- `Standalone/Core/src/CoreNamespacePreamble.h:58–93` — per-compiler pragma and shared self-test.
|
||||||
|
- `Standalone/Core/src/VoxelForgeCore.cpp:972–976` — refusal before shape build.
|
||||||
|
|
||||||
|
For this sweep, the standalone headless runner also gained `--auto-surface-camera` and `--mesh-coverage` in `Standalone/Source/StreamBenchmarkHeadless.cpp` and `Standalone/Source/StreamBenchmarkPipeline.h`.
|
||||||
|
|
||||||
|
The probe guards FP contraction. It does not establish immunity to unrelated `-ffast-math` transformations such as reassociation; those flags must be captured and handled separately if present.
|
||||||
|
|
||||||
|
## Hash immunity
|
||||||
|
|
||||||
|
All successful rows cover the L1 whole view (2,553 tiles); each cell below lists density / mesh / payload / topology hashes. Runs used `Standalone/data/owner_world.json` and `--world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0`. `Clang fast` was built with `-ffp-contract=fast` and `-fno-fast-math`.
|
||||||
|
|
||||||
|
| Compiler and setting | W1 | W12 |
|
||||||
|
|---|---|---|
|
||||||
|
| Clang 19 `-ffp-contract=off` | `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724` | same |
|
||||||
|
| Clang 19 `-ffp-contract=on` | same | same |
|
||||||
|
| Clang 19 `-ffp-contract=fast` | refused before generation | refused before generation |
|
||||||
|
| GCC 14 default (effective contract=fast) | `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724` | same |
|
||||||
|
|
||||||
|
All three supported configurations (Clang off/on, GCC default) match the L1 reference. Both Clang `fast` runs returned exit code 2 in about 0.066 s with the explicit diagnostic, before generating a density hash. Logs: [W1 refusal](../../../../Saved/Linux/linux3-final-hash-clang-fast-w1.log), [W12 refusal](../../../../Saved/Linux/linux3-final-hash-clang-fast-w12.log); successful per-run logs are `linux3-final-hash-*.log` under `Saved/Linux`.
|
||||||
|
|
||||||
|
## Self-test negative control
|
||||||
|
|
||||||
|
The test is in the shared Core preamble, not a separate differently compiled test file. In the deliberate Clang `fast` build it detected the fused result and the Core API rejected world generation at W1 and W12. A compiler-only probe also returned `0` for Clang off/on and GCC with its off pragma, and `-0x1p-54` for Clang fast ([probe log](../../../../Saved/Linux/linux3-pragma-probe.log)). The production-build refusal is the negative control.
|
||||||
|
|
||||||
|
## Corrected seed sweep
|
||||||
|
|
||||||
|
The sweep used 48 unique seeds, both recipes, Clang off/on and GCC default, and W1/W12: 576 runs in 432.977 s. Each SurfaceWorld 96³-voxel cube was centered at the original XY and moved to that seed's nearest heightfield surface; each FloatingIslands cube was centered on that seed's largest planned island. Every run covered 27 LOD0 tiles and contained triangles.
|
||||||
|
|
||||||
|
| Recipe | Per-seed coverage across the sweep |
|
||||||
|
|---|---|
|
||||||
|
| SurfaceWorld | 9–18 nonempty mesh tiles; 26,182–52,468 indexed triangles |
|
||||||
|
| FloatingIslands | 7–15 nonempty mesh tiles; 15,728–46,224 indexed triangles |
|
||||||
|
|
||||||
|
All seeds had distinct density hashes within each recipe. Cross-build comparisons: 192, mismatches 0. W1/W12 comparisons: 288, mismatches 0. Empty-mesh rows: 0. Peak run RSS: 306,580 KiB. The full compiler/worker results are in [seed_mesh_coverage.csv](seed_mesh_coverage.csv); one row per seed and recipe, including the nonempty tile and triangle counts and placed camera, is in [seed_mesh_coverage_per_seed.csv](seed_mesh_coverage_per_seed.csv). Summary: [seed_mesh_coverage_summary.txt](seed_mesh_coverage_summary.txt).
|
||||||
|
|
||||||
|
## Cost
|
||||||
|
|
||||||
|
Three interleaved W12 runs per binary used the same 2,553-tile view, without mesh-coverage counting. “Before” is the S14 executable; “after” is the Clang-off L3 executable.
|
||||||
|
|
||||||
|
| Build | Whole-view ready times (s) | Median |
|
||||||
|
|---|---|---:|
|
||||||
|
| S14 before | 2.260, 2.326, 2.339 | 2.326 s |
|
||||||
|
| L3 after | 2.329, 2.384, 2.337 | 2.337 s |
|
||||||
|
|
||||||
|
The interleaved median change is +0.011 s (+0.5%). The agreed owner-provided before baseline was 2.42 s; L3's 2.337 s median is 0.083 s below it. All six runs retained the L1 hashes. Maximum run RSS was about 550 MiB. Governor remained `powersave`; EPP remained `balance_performance`.
|
||||||
|
|
||||||
|
## Windows work still needed
|
||||||
|
|
||||||
|
MSVC was not available here. On the Windows BuildHost:
|
||||||
|
|
||||||
|
1. Build the standalone Core and viewer from the updated tree: `powershell -ExecutionPolicy Bypass -File Standalone\Build.ps1 -Target All -CompileWorkers 12`. This uses `/fp:precise`; inspect `Standalone\Build\VoxelForgeCore\core-compile.rsp` to confirm.
|
||||||
|
2. Run the resulting viewer on the L1 view twice, once with `--workers=1` and once with `--workers=12`, using `--world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0`. Require the four L1 hashes both times and no self-test error.
|
||||||
|
3. To validate the MSVC pragma under an explicitly contracted setting, make a temporary copy of `Build.ps1`, change its single `/fp:precise` entry to `/fp:fast`, and build it with `-OutputName VoxelForgeCoreStandalone-msvc-fast.exe`. Run the same W1/W12 L1 checks and require unchanged hashes and a passing self-test.
|
||||||
|
4. Build the owner project's UE 5.7 Win64 Development Editor target (and its Server target if configured) with this plugin enabled. Save the actual UBT `cl.exe` commands for `VoxelForgeCore` and record `/fp:*`, `/fp:contract`, and any `/fp:fast` or `/fp:precise` options. Run the owner's existing seed-0 Core world/hash path at W1 and W12 and confirm the L1 result and passing self-test.
|
||||||
|
|
||||||
|
MSVC-specific risks: the pragma has not been compiled here; `/fp:precise` contraction defaults changed at VS 2022 17.0; target configuration may add `/fp:fast` or `/fp:contract`; and UBT's module override must reach every Core source. Microsoft documents that the explicit pragma overrides `/fp:fast`, but the Windows build must confirm that the actual toolset honors it. `VoxelForgeCore.Build.cs` already disables PCH and unity builds, and each Core wrapper includes the pragma preamble.
|
||||||
|
|
||||||
|
## Runs and limits
|
||||||
|
|
||||||
|
No build, hash, sweep, or timing run failed or needed a retry. The two Clang `fast` exits were the expected negative control. Build variants were Clang 19.1.7 and GCC 14.2; builds and runs used CPUs 0–11, at most 12 jobs, normal priority, and a 6 GiB per-process address-space limit. Build peak RSS: 895,640 KiB (GCC); L1 hash-run peak: 551,004 KiB; seed-sweep peak: 306,580 KiB. The 8 MiB process stack was unchanged; Linux workers retain their existing 32 MiB stacks. Build artifacts are under `Standalone/Build/linux-l3-*` and `Standalone/bin/linux/`; logs are under `Saved/Linux/`.
|
||||||
|
|
||||||
|
## Note for the owner
|
||||||
|
|
||||||
|
Core now disables expression contraction for Clang, GCC, and MSVC, and rejects Clang fast when that compiler ignores the off pragma; all supported Linux settings retained the L1 hashes. Please validate the source pragma on native MSVC and capture UE 5.7 UBT's actual Windows and Linux compiler arguments, since those builds were not available here.
|
||||||
|
|
||||||
|
## Orchestrator review (Claude)
|
||||||
|
|
||||||
|
- Re-run by me on Luna's binaries, W12, L1 view: Clang `off` 2.299 s and Clang `on` 2.302 s, both density
|
||||||
|
`c10697a8f48380c7`; GCC default 2.469 s, also `c10697a8f48380c7`; Clang `fast` exits 2 with the self-test
|
||||||
|
refusal. Clang `on` and GCC default gave *different* worlds in L2, so the pragma is demonstrably effective.
|
||||||
|
- Known gap (small): the pragma sits after the standard headers, `Json.h` and the public API header in the
|
||||||
|
preamble, so inline/template code defined there is not covered. All Core world math (Compat, `*Internal.h`,
|
||||||
|
legacy sources) comes after it.
|
||||||
|
- The probe guards contraction only; `-ffast-math` reassociation is a separate risk (as Luna says). The
|
||||||
|
Windows to-do list above is the gate before claiming this on MSVC/UBT.
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Run the corrected L3 seed/compiler/worker matrix with per-seed mesh coverage."""
|
||||||
|
import csv
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path.cwd()
|
||||||
|
ROUND = ROOT / "Standalone/Research/WorldAssemblerM3/Linux3"
|
||||||
|
SEEDS = ROOT / "Standalone/Research/WorldAssemblerM3/Linux2/seeds.txt"
|
||||||
|
LOG_DIR = ROOT / "Saved/Linux"
|
||||||
|
MEASURE = ROOT / "Standalone/Research/WorldAssemblerM3/Linux2/MeasureProcess.py"
|
||||||
|
DATA = ROOT / "Standalone/data/owner_world.json"
|
||||||
|
BINARIES = {
|
||||||
|
"clang19-off": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-clang19-l3-off",
|
||||||
|
"clang19-on": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-clang19-l3-on",
|
||||||
|
"gcc14-default": ROOT / "Standalone/bin/linux/VoxelForgeCoreHeadless-gcc14-l3-default",
|
||||||
|
}
|
||||||
|
CAMERAS = {
|
||||||
|
"surface-world": "0,-35,-487.94,0,-22",
|
||||||
|
"floating-islands": "0,0,-32,0,-22",
|
||||||
|
}
|
||||||
|
HASH_RE = re.compile(
|
||||||
|
r"\[PipelineWholeViewHash\] tiles=(\d+) density=0x([0-9a-f]+) "
|
||||||
|
r"mesh=0x([0-9a-f]+) payload=0x([0-9a-f]+) topology=0x([0-9a-f]+)"
|
||||||
|
)
|
||||||
|
MESH_RE = re.compile(
|
||||||
|
r"\[PipelineMeshCoverage\] tiles=(\d+) nonempty_mesh_tiles=(\d+) indexed_triangles=(\d+)"
|
||||||
|
)
|
||||||
|
PLACEMENT_RE = re.compile(
|
||||||
|
r"\[SeedSurfacePlacement\].*camera_voxel=\(([-0-9.]+),([-0-9.]+),([-0-9.]+)\) status=PASS"
|
||||||
|
)
|
||||||
|
READY_RE = re.compile(r"\[StreamPipeline\].*whole_view_ready=([0-9.]+)s")
|
||||||
|
RESOURCE_RE = re.compile(
|
||||||
|
r"\[ProcessResources\] exit_code=(-?\d+) wall_s=([0-9.]+) peak_rss_kib=(\d+)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
raise SystemExit("usage: RunSeedSweep.py [budget-seconds; default 1800]")
|
||||||
|
budget = int(sys.argv[1]) if len(sys.argv) == 2 else 1800
|
||||||
|
seeds = [int(line.strip()) for line in SEEDS.read_text().splitlines() if line.strip()]
|
||||||
|
if len(seeds) != 48 or len(set(seeds)) != 48:
|
||||||
|
raise SystemExit("expected the 48 unique signed int32 L2 seeds")
|
||||||
|
missing = [str(path) for path in [MEASURE, DATA, *BINARIES.values()] if not path.is_file()]
|
||||||
|
if missing:
|
||||||
|
raise SystemExit("missing sweep input/build: " + ", ".join(missing))
|
||||||
|
|
||||||
|
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
output_path = ROUND / "seed_mesh_coverage.csv"
|
||||||
|
fields = [
|
||||||
|
"seed", "recipe", "compiler_setting", "workers", "tiles",
|
||||||
|
"nonempty_mesh_tiles", "indexed_triangles", "camera_x_vox", "camera_y_vox", "camera_z_vox",
|
||||||
|
"density_hash", "mesh_hash", "payload_hash", "topology_hash",
|
||||||
|
"whole_view_ready_s", "wall_s", "peak_rss_kib", "exit_code", "status",
|
||||||
|
]
|
||||||
|
started = time.monotonic()
|
||||||
|
total = len(seeds) * len(CAMERAS) * len(BINARIES) * 2
|
||||||
|
print(f"L3 sweep: {len(seeds)} seeds x 2 recipes x 3 builds x W1/W12 = {total}; budget={budget}s", flush=True)
|
||||||
|
with output_path.open("w", newline="") as csv_file:
|
||||||
|
writer = csv.DictWriter(csv_file, fieldnames=fields)
|
||||||
|
writer.writeheader()
|
||||||
|
completed = 0
|
||||||
|
for seed in seeds:
|
||||||
|
for recipe, camera in CAMERAS.items():
|
||||||
|
for compiler, binary in BINARIES.items():
|
||||||
|
for workers in (1, 12):
|
||||||
|
remaining = budget - (time.monotonic() - started)
|
||||||
|
if remaining <= 0:
|
||||||
|
print("L3 sweep exceeded its 30-minute budget; stopping.", file=sys.stderr, flush=True)
|
||||||
|
return 124
|
||||||
|
stem = f"linux3-seed-{seed}-{recipe}-{compiler}-w{workers}"
|
||||||
|
log_path = LOG_DIR / f"{stem}.log"
|
||||||
|
args = [
|
||||||
|
str(binary), str(DATA), f"--seed={seed}", f"--recipe={recipe}",
|
||||||
|
"--render-distance-chunks=0", f"--workers={workers}",
|
||||||
|
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
|
||||||
|
"--stream-hash", "--mesh-coverage", "--auto-surface-camera", "--force-generate",
|
||||||
|
"--clip-radius=1", "--max-clip-level=0", f"--camera={camera}",
|
||||||
|
"--far-horizon-lod8-step=0",
|
||||||
|
]
|
||||||
|
command = [
|
||||||
|
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
||||||
|
"python3", str(MEASURE), *args,
|
||||||
|
]
|
||||||
|
with log_path.open("w") as log_file:
|
||||||
|
log_file.write("[SweepCommand] " + " ".join(command) + "\n")
|
||||||
|
log_file.flush()
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
command, cwd=ROOT, stdout=log_file, stderr=subprocess.STDOUT,
|
||||||
|
timeout=min(900, max(1, remaining)), check=False,
|
||||||
|
)
|
||||||
|
exit_code = result.returncode
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
exit_code = 124
|
||||||
|
log_file.write("\n[SweepTimeout] row reached its allotted limit\n")
|
||||||
|
|
||||||
|
output = log_path.read_text(errors="replace")
|
||||||
|
hashes = HASH_RE.search(output)
|
||||||
|
mesh = MESH_RE.search(output)
|
||||||
|
placement = PLACEMENT_RE.search(output)
|
||||||
|
ready = READY_RE.search(output)
|
||||||
|
resources = RESOURCE_RE.search(output)
|
||||||
|
passed = bool(
|
||||||
|
exit_code == 0 and hashes and mesh and placement and ready and resources
|
||||||
|
and int(hashes.group(1)) == 27 and int(mesh.group(1)) == 27
|
||||||
|
and int(mesh.group(2)) > 0 and int(mesh.group(3)) > 0
|
||||||
|
and int(resources.group(1)) == 0
|
||||||
|
)
|
||||||
|
row = {
|
||||||
|
"seed": seed, "recipe": recipe, "compiler_setting": compiler, "workers": workers,
|
||||||
|
"tiles": mesh.group(1) if mesh else "",
|
||||||
|
"nonempty_mesh_tiles": mesh.group(2) if mesh else "",
|
||||||
|
"indexed_triangles": mesh.group(3) if mesh else "",
|
||||||
|
"camera_x_vox": placement.group(1) if placement else "",
|
||||||
|
"camera_y_vox": placement.group(2) if placement else "",
|
||||||
|
"camera_z_vox": placement.group(3) if placement else "",
|
||||||
|
"density_hash": "0x" + hashes.group(2) if hashes else "",
|
||||||
|
"mesh_hash": "0x" + hashes.group(3) if hashes else "",
|
||||||
|
"payload_hash": "0x" + hashes.group(4) if hashes else "",
|
||||||
|
"topology_hash": "0x" + hashes.group(5) if hashes else "",
|
||||||
|
"whole_view_ready_s": ready.group(1) if ready else "",
|
||||||
|
"wall_s": resources.group(2) if resources else "",
|
||||||
|
"peak_rss_kib": resources.group(3) if resources else "",
|
||||||
|
"exit_code": exit_code, "status": "PASS" if passed else "FAIL",
|
||||||
|
}
|
||||||
|
writer.writerow(row)
|
||||||
|
csv_file.flush()
|
||||||
|
completed += 1
|
||||||
|
print(
|
||||||
|
f"[{completed}/{total}] seed={seed} recipe={recipe} build={compiler} W{workers} "
|
||||||
|
f"nonempty={row['nonempty_mesh_tiles']}/27 triangles={row['indexed_triangles']} "
|
||||||
|
f"wall={row['wall_s']}s status={row['status']} elapsed={time.monotonic()-started:.1f}s",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
if not passed:
|
||||||
|
print(f"Failed row log: {log_path}", file=sys.stderr, flush=True)
|
||||||
|
return exit_code or 1
|
||||||
|
|
||||||
|
rows = list(csv.DictReader(output_path.open(newline="")))
|
||||||
|
hash_columns = ("density_hash", "mesh_hash", "payload_hash", "topology_hash")
|
||||||
|
compiler_checks = []
|
||||||
|
worker_checks = []
|
||||||
|
for seed in seeds:
|
||||||
|
for recipe in CAMERAS:
|
||||||
|
for workers in (1, 12):
|
||||||
|
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
|
||||||
|
and int(r["workers"]) == workers]
|
||||||
|
compiler_checks.append(len(pair) == len(BINARIES)
|
||||||
|
and all(all(row[key] == pair[0][key] for key in hash_columns) for row in pair))
|
||||||
|
for compiler in BINARIES:
|
||||||
|
pair = [r for r in rows if int(r["seed"]) == seed and r["recipe"] == recipe
|
||||||
|
and r["compiler_setting"] == compiler]
|
||||||
|
worker_checks.append(len(pair) == 2
|
||||||
|
and all(all(row[key] == pair[0][key] for key in hash_columns) for row in pair))
|
||||||
|
elapsed = time.monotonic() - started
|
||||||
|
maximum_rss = max(int(row["peak_rss_kib"]) for row in rows)
|
||||||
|
empty_rows = sum(int(row["nonempty_mesh_tiles"]) == 0 or int(row["indexed_triangles"]) == 0 for row in rows)
|
||||||
|
summary = (
|
||||||
|
f"runs={len(rows)} seeds={len(seeds)} recipes={len(CAMERAS)} builds={len(BINARIES)} workers=1,12 "
|
||||||
|
f"cross_build_checks={len(compiler_checks)} cross_build_mismatches={sum(not x for x in compiler_checks)} "
|
||||||
|
f"worker_checks={len(worker_checks)} worker_mismatches={sum(not x for x in worker_checks)} "
|
||||||
|
f"empty_mesh_rows={empty_rows} max_peak_rss_kib={maximum_rss} elapsed_s={elapsed:.3f}\n"
|
||||||
|
)
|
||||||
|
(ROUND / "seed_mesh_coverage_summary.txt").write_text(summary)
|
||||||
|
print(summary, end="", flush=True)
|
||||||
|
return 0 if all(compiler_checks) and all(worker_checks) and empty_rows == 0 and elapsed <= budget else 3
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -0,0 +1,577 @@
|
|||||||
|
seed,recipe,compiler_setting,workers,tiles,nonempty_mesh_tiles,indexed_triangles,camera_x_vox,camera_y_vox,camera_z_vox,density_hash,mesh_hash,payload_hash,topology_hash,whole_view_ready_s,wall_s,peak_rss_kib,exit_code,status
|
||||||
|
-1990830953,surface-world,clang19-off,1,27,9,26366,0.000000,-140.000000,-2021.785156,0x125d085ff63ece8a,0x3f219420ffe76ceb,0x386c66f61f66fde5,0x9fc08404031eb99b,0.162,0.180221,84360,0,PASS
|
||||||
|
-1990830953,surface-world,clang19-off,12,27,9,26366,0.000000,-140.000000,-2021.785156,0x125d085ff63ece8a,0x3f219420ffe76ceb,0x386c66f61f66fde5,0x9fc08404031eb99b,0.397,0.424425,294988,0,PASS
|
||||||
|
-1990830953,surface-world,clang19-on,1,27,9,26366,0.000000,-140.000000,-2021.785156,0x125d085ff63ece8a,0x3f219420ffe76ceb,0x386c66f61f66fde5,0x9fc08404031eb99b,0.163,0.180433,84540,0,PASS
|
||||||
|
-1990830953,surface-world,clang19-on,12,27,9,26366,0.000000,-140.000000,-2021.785156,0x125d085ff63ece8a,0x3f219420ffe76ceb,0x386c66f61f66fde5,0x9fc08404031eb99b,0.401,0.427873,294656,0,PASS
|
||||||
|
-1990830953,surface-world,gcc14-default,1,27,9,26366,0.000000,-140.000000,-2021.785156,0x125d085ff63ece8a,0x3f219420ffe76ceb,0x386c66f61f66fde5,0x9fc08404031eb99b,0.152,0.167928,84996,0,PASS
|
||||||
|
-1990830953,surface-world,gcc14-default,12,27,9,26366,0.000000,-140.000000,-2021.785156,0x125d085ff63ece8a,0x3f219420ffe76ceb,0x386c66f61f66fde5,0x9fc08404031eb99b,0.398,0.424793,295392,0,PASS
|
||||||
|
-1990830953,floating-islands,clang19-off,1,27,12,23386,-39.199219,16.363281,-121.039062,0xc04ef8acd44d8736,0x00e92c97d841dfe5,0xb57496fb3be7da11,0x64b0c5c3655299c2,0.872,0.887909,85248,0,PASS
|
||||||
|
-1990830953,floating-islands,clang19-off,12,27,12,23386,-39.199219,16.363281,-121.039062,0xc04ef8acd44d8736,0x00e92c97d841dfe5,0xb57496fb3be7da11,0x64b0c5c3655299c2,0.549,0.575731,300132,0,PASS
|
||||||
|
-1990830953,floating-islands,clang19-on,1,27,12,23386,-39.199219,16.363281,-121.039062,0xc04ef8acd44d8736,0x00e92c97d841dfe5,0xb57496fb3be7da11,0x64b0c5c3655299c2,0.884,0.901147,85000,0,PASS
|
||||||
|
-1990830953,floating-islands,clang19-on,12,27,12,23386,-39.199219,16.363281,-121.039062,0xc04ef8acd44d8736,0x00e92c97d841dfe5,0xb57496fb3be7da11,0x64b0c5c3655299c2,0.578,0.605578,299564,0,PASS
|
||||||
|
-1990830953,floating-islands,gcc14-default,1,27,12,23386,-39.199219,16.363281,-121.039062,0xc04ef8acd44d8736,0x00e92c97d841dfe5,0xb57496fb3be7da11,0x64b0c5c3655299c2,0.943,0.959068,85752,0,PASS
|
||||||
|
-1990830953,floating-islands,gcc14-default,12,27,12,23386,-39.199219,16.363281,-121.039062,0xc04ef8acd44d8736,0x00e92c97d841dfe5,0xb57496fb3be7da11,0x64b0c5c3655299c2,0.588,0.614935,300548,0,PASS
|
||||||
|
-1900684165,surface-world,clang19-off,1,27,10,27890,0.000000,-140.000000,-2011.214844,0xcc9819b02bd2f880,0x8cbe19f740d2b408,0xbe822577766381d4,0x69b6a50c6286fdf7,0.185,0.202214,89956,0,PASS
|
||||||
|
-1900684165,surface-world,clang19-off,12,27,10,27890,0.000000,-140.000000,-2011.214844,0xcc9819b02bd2f880,0x8cbe19f740d2b408,0xbe822577766381d4,0x69b6a50c6286fdf7,0.418,0.446199,301944,0,PASS
|
||||||
|
-1900684165,surface-world,clang19-on,1,27,10,27890,0.000000,-140.000000,-2011.214844,0xcc9819b02bd2f880,0x8cbe19f740d2b408,0xbe822577766381d4,0x69b6a50c6286fdf7,0.177,0.193134,89684,0,PASS
|
||||||
|
-1900684165,surface-world,clang19-on,12,27,10,27890,0.000000,-140.000000,-2011.214844,0xcc9819b02bd2f880,0x8cbe19f740d2b408,0xbe822577766381d4,0x69b6a50c6286fdf7,0.438,0.466528,301656,0,PASS
|
||||||
|
-1900684165,surface-world,gcc14-default,1,27,10,27890,0.000000,-140.000000,-2011.214844,0xcc9819b02bd2f880,0x8cbe19f740d2b408,0xbe822577766381d4,0x69b6a50c6286fdf7,0.180,0.196807,90492,0,PASS
|
||||||
|
-1900684165,surface-world,gcc14-default,12,27,10,27890,0.000000,-140.000000,-2011.214844,0xcc9819b02bd2f880,0x8cbe19f740d2b408,0xbe822577766381d4,0x69b6a50c6286fdf7,0.442,0.468384,300628,0,PASS
|
||||||
|
-1900684165,floating-islands,clang19-off,1,27,10,23186,39.199219,17.675781,-116.339844,0xfc7386c15431e2e1,0x46ce25dfb3745f53,0x97c9ffd0022012ad,0x64303145c5cc6d24,1.558,1.574129,89380,0,PASS
|
||||||
|
-1900684165,floating-islands,clang19-off,12,27,10,23186,39.199219,17.675781,-116.339844,0xfc7386c15431e2e1,0x46ce25dfb3745f53,0x97c9ffd0022012ad,0x64303145c5cc6d24,0.699,0.726109,303932,0,PASS
|
||||||
|
-1900684165,floating-islands,clang19-on,1,27,10,23186,39.199219,17.675781,-116.339844,0xfc7386c15431e2e1,0x46ce25dfb3745f53,0x97c9ffd0022012ad,0x64303145c5cc6d24,1.599,1.615516,89308,0,PASS
|
||||||
|
-1900684165,floating-islands,clang19-on,12,27,10,23186,39.199219,17.675781,-116.339844,0xfc7386c15431e2e1,0x46ce25dfb3745f53,0x97c9ffd0022012ad,0x64303145c5cc6d24,0.727,0.755017,303964,0,PASS
|
||||||
|
-1900684165,floating-islands,gcc14-default,1,27,10,23186,39.199219,17.675781,-116.339844,0xfc7386c15431e2e1,0x46ce25dfb3745f53,0x97c9ffd0022012ad,0x64303145c5cc6d24,1.692,1.708073,89664,0,PASS
|
||||||
|
-1900684165,floating-islands,gcc14-default,12,27,10,23186,39.199219,17.675781,-116.339844,0xfc7386c15431e2e1,0x46ce25dfb3745f53,0x97c9ffd0022012ad,0x64303145c5cc6d24,0.763,0.790272,304528,0,PASS
|
||||||
|
-1766412538,surface-world,clang19-off,1,27,9,27572,0.000000,-140.000000,-2004.851562,0x4d04ec633754c4ec,0xca8833dcfe9639d3,0x0a4008899d91f10e,0x2d6116327735df9a,0.181,0.196881,84084,0,PASS
|
||||||
|
-1766412538,surface-world,clang19-off,12,27,9,27572,0.000000,-140.000000,-2004.851562,0x4d04ec633754c4ec,0xca8833dcfe9639d3,0x0a4008899d91f10e,0x2d6116327735df9a,0.414,0.439405,294580,0,PASS
|
||||||
|
-1766412538,surface-world,clang19-on,1,27,9,27572,0.000000,-140.000000,-2004.851562,0x4d04ec633754c4ec,0xca8833dcfe9639d3,0x0a4008899d91f10e,0x2d6116327735df9a,0.181,0.196772,84172,0,PASS
|
||||||
|
-1766412538,surface-world,clang19-on,12,27,9,27572,0.000000,-140.000000,-2004.851562,0x4d04ec633754c4ec,0xca8833dcfe9639d3,0x0a4008899d91f10e,0x2d6116327735df9a,0.412,0.438983,294880,0,PASS
|
||||||
|
-1766412538,surface-world,gcc14-default,1,27,9,27572,0.000000,-140.000000,-2004.851562,0x4d04ec633754c4ec,0xca8833dcfe9639d3,0x0a4008899d91f10e,0x2d6116327735df9a,0.175,0.192855,84688,0,PASS
|
||||||
|
-1766412538,surface-world,gcc14-default,12,27,9,27572,0.000000,-140.000000,-2004.851562,0x4d04ec633754c4ec,0xca8833dcfe9639d3,0x0a4008899d91f10e,0x2d6116327735df9a,0.430,0.455090,295516,0,PASS
|
||||||
|
-1766412538,floating-islands,clang19-off,1,27,12,23618,-25.199219,-73.816406,-135.394531,0xdb6557b98f29060e,0x3b3147a1d020ca02,0x010127525a940a1e,0xc9563575ca60b627,1.542,1.556645,86260,0,PASS
|
||||||
|
-1766412538,floating-islands,clang19-off,12,27,12,23618,-25.199219,-73.816406,-135.394531,0xdb6557b98f29060e,0x3b3147a1d020ca02,0x010127525a940a1e,0xc9563575ca60b627,0.673,0.699377,300448,0,PASS
|
||||||
|
-1766412538,floating-islands,clang19-on,1,27,12,23618,-25.199219,-73.816406,-135.394531,0xdb6557b98f29060e,0x3b3147a1d020ca02,0x010127525a940a1e,0xc9563575ca60b627,1.587,1.602433,86588,0,PASS
|
||||||
|
-1766412538,floating-islands,clang19-on,12,27,12,23618,-25.199219,-73.816406,-135.394531,0xdb6557b98f29060e,0x3b3147a1d020ca02,0x010127525a940a1e,0xc9563575ca60b627,0.702,0.728925,300536,0,PASS
|
||||||
|
-1766412538,floating-islands,gcc14-default,1,27,12,23618,-25.199219,-73.816406,-135.394531,0xdb6557b98f29060e,0x3b3147a1d020ca02,0x010127525a940a1e,0xc9563575ca60b627,1.744,1.760677,87052,0,PASS
|
||||||
|
-1766412538,floating-islands,gcc14-default,12,27,12,23618,-25.199219,-73.816406,-135.394531,0xdb6557b98f29060e,0x3b3147a1d020ca02,0x010127525a940a1e,0xc9563575ca60b627,0.741,0.770803,301248,0,PASS
|
||||||
|
-1721984596,surface-world,clang19-off,1,27,9,27374,0.000000,-140.000000,-2006.878906,0x65b6ae0a3a1fdd35,0x117d40e403c960bc,0x9bc7a92591e7d7e3,0x988675caf5879337,0.172,0.187451,84428,0,PASS
|
||||||
|
-1721984596,surface-world,clang19-off,12,27,9,27374,0.000000,-140.000000,-2006.878906,0x65b6ae0a3a1fdd35,0x117d40e403c960bc,0x9bc7a92591e7d7e3,0x988675caf5879337,0.424,0.450959,294996,0,PASS
|
||||||
|
-1721984596,surface-world,clang19-on,1,27,9,27374,0.000000,-140.000000,-2006.878906,0x65b6ae0a3a1fdd35,0x117d40e403c960bc,0x9bc7a92591e7d7e3,0x988675caf5879337,0.183,0.199333,84536,0,PASS
|
||||||
|
-1721984596,surface-world,clang19-on,12,27,9,27374,0.000000,-140.000000,-2006.878906,0x65b6ae0a3a1fdd35,0x117d40e403c960bc,0x9bc7a92591e7d7e3,0x988675caf5879337,0.426,0.452557,294916,0,PASS
|
||||||
|
-1721984596,surface-world,gcc14-default,1,27,9,27374,0.000000,-140.000000,-2006.878906,0x65b6ae0a3a1fdd35,0x117d40e403c960bc,0x9bc7a92591e7d7e3,0x988675caf5879337,0.178,0.193728,85196,0,PASS
|
||||||
|
-1721984596,surface-world,gcc14-default,12,27,9,27374,0.000000,-140.000000,-2006.878906,0x65b6ae0a3a1fdd35,0x117d40e403c960bc,0x9bc7a92591e7d7e3,0x988675caf5879337,0.427,0.454505,295184,0,PASS
|
||||||
|
-1721984596,floating-islands,clang19-off,1,27,10,23728,64.398438,74.085938,-128.433594,0xbb7777932cd3328a,0x5d7243f5afb8902a,0xdb6cef72728d0d64,0x625882823c87a40b,1.554,1.570584,85220,0,PASS
|
||||||
|
-1721984596,floating-islands,clang19-off,12,27,10,23728,64.398438,74.085938,-128.433594,0xbb7777932cd3328a,0x5d7243f5afb8902a,0xdb6cef72728d0d64,0x625882823c87a40b,0.718,0.745795,300772,0,PASS
|
||||||
|
-1721984596,floating-islands,clang19-on,1,27,10,23728,64.398438,74.085938,-128.433594,0xbb7777932cd3328a,0x5d7243f5afb8902a,0xdb6cef72728d0d64,0x625882823c87a40b,1.578,1.593432,85580,0,PASS
|
||||||
|
-1721984596,floating-islands,clang19-on,12,27,10,23728,64.398438,74.085938,-128.433594,0xbb7777932cd3328a,0x5d7243f5afb8902a,0xdb6cef72728d0d64,0x625882823c87a40b,0.708,0.734658,299780,0,PASS
|
||||||
|
-1721984596,floating-islands,gcc14-default,1,27,10,23728,64.398438,74.085938,-128.433594,0xbb7777932cd3328a,0x5d7243f5afb8902a,0xdb6cef72728d0d64,0x625882823c87a40b,1.714,1.730034,85816,0,PASS
|
||||||
|
-1721984596,floating-islands,gcc14-default,12,27,10,23728,64.398438,74.085938,-128.433594,0xbb7777932cd3328a,0x5d7243f5afb8902a,0xdb6cef72728d0d64,0x625882823c87a40b,0.757,0.784127,301460,0,PASS
|
||||||
|
-1239598758,surface-world,clang19-off,1,27,15,38978,0.000000,-140.000000,-2001.816406,0x8aaf7c7c610e550f,0xeaa948233176c456,0x32c71b1231361cd2,0xecd43272e8d589a7,0.269,0.284560,84356,0,PASS
|
||||||
|
-1239598758,surface-world,clang19-off,12,27,15,38978,0.000000,-140.000000,-2001.816406,0x8aaf7c7c610e550f,0xeaa948233176c456,0x32c71b1231361cd2,0xecd43272e8d589a7,0.447,0.473801,299712,0,PASS
|
||||||
|
-1239598758,surface-world,clang19-on,1,27,15,38978,0.000000,-140.000000,-2001.816406,0x8aaf7c7c610e550f,0xeaa948233176c456,0x32c71b1231361cd2,0xecd43272e8d589a7,0.277,0.293296,84584,0,PASS
|
||||||
|
-1239598758,surface-world,clang19-on,12,27,15,38978,0.000000,-140.000000,-2001.816406,0x8aaf7c7c610e550f,0xeaa948233176c456,0x32c71b1231361cd2,0xecd43272e8d589a7,0.460,0.486378,298388,0,PASS
|
||||||
|
-1239598758,surface-world,gcc14-default,1,27,15,38978,0.000000,-140.000000,-2001.816406,0x8aaf7c7c610e550f,0xeaa948233176c456,0x32c71b1231361cd2,0xecd43272e8d589a7,0.261,0.276573,84996,0,PASS
|
||||||
|
-1239598758,surface-world,gcc14-default,12,27,15,38978,0.000000,-140.000000,-2001.816406,0x8aaf7c7c610e550f,0xeaa948233176c456,0x32c71b1231361cd2,0xecd43272e8d589a7,0.464,0.492223,300696,0,PASS
|
||||||
|
-1239598758,floating-islands,clang19-off,1,27,12,28162,39.199219,19.425781,-116.691406,0x9ee03f2326224bbc,0x0ea03da61381b41a,0x4b658d0bd4e527e6,0x402b075c754192e3,1.280,1.297085,85588,0,PASS
|
||||||
|
-1239598758,floating-islands,clang19-off,12,27,12,28162,39.199219,19.425781,-116.691406,0x9ee03f2326224bbc,0x0ea03da61381b41a,0x4b658d0bd4e527e6,0x402b075c754192e3,0.642,0.669720,300940,0,PASS
|
||||||
|
-1239598758,floating-islands,clang19-on,1,27,12,28162,39.199219,19.425781,-116.691406,0x9ee03f2326224bbc,0x0ea03da61381b41a,0x4b658d0bd4e527e6,0x402b075c754192e3,1.324,1.342774,85712,0,PASS
|
||||||
|
-1239598758,floating-islands,clang19-on,12,27,12,28162,39.199219,19.425781,-116.691406,0x9ee03f2326224bbc,0x0ea03da61381b41a,0x4b658d0bd4e527e6,0x402b075c754192e3,0.637,0.664175,300712,0,PASS
|
||||||
|
-1239598758,floating-islands,gcc14-default,1,27,12,28162,39.199219,19.425781,-116.691406,0x9ee03f2326224bbc,0x0ea03da61381b41a,0x4b658d0bd4e527e6,0x402b075c754192e3,1.465,1.480710,85820,0,PASS
|
||||||
|
-1239598758,floating-islands,gcc14-default,12,27,12,28162,39.199219,19.425781,-116.691406,0x9ee03f2326224bbc,0x0ea03da61381b41a,0x4b658d0bd4e527e6,0x402b075c754192e3,0.678,0.706467,301428,0,PASS
|
||||||
|
-1085993262,surface-world,clang19-off,1,27,13,30779,0.000000,-140.000000,-2018.355469,0x6dd63983ab04ee63,0x606e6964e1b2bfa0,0x30f2ccb9c65750ff,0x72fb3b77904151b8,0.203,0.219019,84900,0,PASS
|
||||||
|
-1085993262,surface-world,clang19-off,12,27,13,30779,0.000000,-140.000000,-2018.355469,0x6dd63983ab04ee63,0x606e6964e1b2bfa0,0x30f2ccb9c65750ff,0x72fb3b77904151b8,0.442,0.468936,300076,0,PASS
|
||||||
|
-1085993262,surface-world,clang19-on,1,27,13,30779,0.000000,-140.000000,-2018.355469,0x6dd63983ab04ee63,0x606e6964e1b2bfa0,0x30f2ccb9c65750ff,0x72fb3b77904151b8,0.209,0.226037,84848,0,PASS
|
||||||
|
-1085993262,surface-world,clang19-on,12,27,13,30779,0.000000,-140.000000,-2018.355469,0x6dd63983ab04ee63,0x606e6964e1b2bfa0,0x30f2ccb9c65750ff,0x72fb3b77904151b8,0.434,0.461038,299916,0,PASS
|
||||||
|
-1085993262,surface-world,gcc14-default,1,27,13,30779,0.000000,-140.000000,-2018.355469,0x6dd63983ab04ee63,0x606e6964e1b2bfa0,0x30f2ccb9c65750ff,0x72fb3b77904151b8,0.194,0.212574,85588,0,PASS
|
||||||
|
-1085993262,surface-world,gcc14-default,12,27,13,30779,0.000000,-140.000000,-2018.355469,0x6dd63983ab04ee63,0x606e6964e1b2bfa0,0x30f2ccb9c65750ff,0x72fb3b77904151b8,0.421,0.449569,300836,0,PASS
|
||||||
|
-1085993262,floating-islands,clang19-off,1,27,11,25186,-39.199219,16.968750,-116.531250,0x8dec867557d4e27c,0x13de3a8f9465573d,0x2e2ca36cfff2558a,0x42ad0d371549e563,1.085,1.101264,86672,0,PASS
|
||||||
|
-1085993262,floating-islands,clang19-off,12,27,11,25186,-39.199219,16.968750,-116.531250,0x8dec867557d4e27c,0x13de3a8f9465573d,0x2e2ca36cfff2558a,0x42ad0d371549e563,0.573,0.602307,301496,0,PASS
|
||||||
|
-1085993262,floating-islands,clang19-on,1,27,11,25186,-39.199219,16.968750,-116.531250,0x8dec867557d4e27c,0x13de3a8f9465573d,0x2e2ca36cfff2558a,0x42ad0d371549e563,1.085,1.100702,86848,0,PASS
|
||||||
|
-1085993262,floating-islands,clang19-on,12,27,11,25186,-39.199219,16.968750,-116.531250,0x8dec867557d4e27c,0x13de3a8f9465573d,0x2e2ca36cfff2558a,0x42ad0d371549e563,0.576,0.603241,301652,0,PASS
|
||||||
|
-1085993262,floating-islands,gcc14-default,1,27,11,25186,-39.199219,16.968750,-116.531250,0x8dec867557d4e27c,0x13de3a8f9465573d,0x2e2ca36cfff2558a,0x42ad0d371549e563,1.195,1.210876,87352,0,PASS
|
||||||
|
-1085993262,floating-islands,gcc14-default,12,27,11,25186,-39.199219,16.968750,-116.531250,0x8dec867557d4e27c,0x13de3a8f9465573d,0x2e2ca36cfff2558a,0x42ad0d371549e563,0.617,0.646640,302080,0,PASS
|
||||||
|
-1033703345,surface-world,clang19-off,1,27,16,50890,0.000000,-140.000000,-1585.519531,0xe2f8c4b421a9402a,0x730fd7c4692eaff3,0xacf64857ef930634,0x86e7853e9d0b4a35,0.342,0.358880,85076,0,PASS
|
||||||
|
-1033703345,surface-world,clang19-off,12,27,16,50890,0.000000,-140.000000,-1585.519531,0xe2f8c4b421a9402a,0x730fd7c4692eaff3,0xacf64857ef930634,0x86e7853e9d0b4a35,0.451,0.477876,301748,0,PASS
|
||||||
|
-1033703345,surface-world,clang19-on,1,27,16,50890,0.000000,-140.000000,-1585.519531,0xe2f8c4b421a9402a,0x730fd7c4692eaff3,0xacf64857ef930634,0x86e7853e9d0b4a35,0.318,0.334873,84996,0,PASS
|
||||||
|
-1033703345,surface-world,clang19-on,12,27,16,50890,0.000000,-140.000000,-1585.519531,0xe2f8c4b421a9402a,0x730fd7c4692eaff3,0xacf64857ef930634,0x86e7853e9d0b4a35,0.461,0.490652,301616,0,PASS
|
||||||
|
-1033703345,surface-world,gcc14-default,1,27,16,50890,0.000000,-140.000000,-1585.519531,0xe2f8c4b421a9402a,0x730fd7c4692eaff3,0xacf64857ef930634,0x86e7853e9d0b4a35,0.305,0.322211,85560,0,PASS
|
||||||
|
-1033703345,surface-world,gcc14-default,12,27,16,50890,0.000000,-140.000000,-1585.519531,0xe2f8c4b421a9402a,0x730fd7c4692eaff3,0xacf64857ef930634,0x86e7853e9d0b4a35,0.476,0.502916,302484,0,PASS
|
||||||
|
-1033703345,floating-islands,clang19-off,1,27,10,17406,-25.199219,-75.605469,-128.097656,0x6edfcf6b89aee9cd,0xc7b92cd1b8a58590,0x570a869c76c15846,0x8139f7fb5146e402,2.065,2.083040,86192,0,PASS
|
||||||
|
-1033703345,floating-islands,clang19-off,12,27,10,17406,-25.199219,-75.605469,-128.097656,0x6edfcf6b89aee9cd,0xc7b92cd1b8a58590,0x570a869c76c15846,0x8139f7fb5146e402,0.776,0.804394,299624,0,PASS
|
||||||
|
-1033703345,floating-islands,clang19-on,1,27,10,17406,-25.199219,-75.605469,-128.097656,0x6edfcf6b89aee9cd,0xc7b92cd1b8a58590,0x570a869c76c15846,0x8139f7fb5146e402,1.996,2.016862,86136,0,PASS
|
||||||
|
-1033703345,floating-islands,clang19-on,12,27,10,17406,-25.199219,-75.605469,-128.097656,0x6edfcf6b89aee9cd,0xc7b92cd1b8a58590,0x570a869c76c15846,0x8139f7fb5146e402,0.841,0.879778,299580,0,PASS
|
||||||
|
-1033703345,floating-islands,gcc14-default,1,27,10,17406,-25.199219,-75.605469,-128.097656,0x6edfcf6b89aee9cd,0xc7b92cd1b8a58590,0x570a869c76c15846,0x8139f7fb5146e402,1.997,2.013598,86416,0,PASS
|
||||||
|
-1033703345,floating-islands,gcc14-default,12,27,10,17406,-25.199219,-75.605469,-128.097656,0x6edfcf6b89aee9cd,0xc7b92cd1b8a58590,0x570a869c76c15846,0x8139f7fb5146e402,0.820,0.848116,300464,0,PASS
|
||||||
|
-854671705,surface-world,clang19-off,1,27,10,26198,0.000000,-140.000000,-2018.242188,0x0a9e017447ffff3d,0x807299923966d5be,0xdd97f14916c8157a,0x95313b997ff55c26,0.216,0.232793,83632,0,PASS
|
||||||
|
-854671705,surface-world,clang19-off,12,27,10,26198,0.000000,-140.000000,-2018.242188,0x0a9e017447ffff3d,0x807299923966d5be,0xdd97f14916c8157a,0x95313b997ff55c26,0.462,0.492727,295640,0,PASS
|
||||||
|
-854671705,surface-world,clang19-on,1,27,10,26198,0.000000,-140.000000,-2018.242188,0x0a9e017447ffff3d,0x807299923966d5be,0xdd97f14916c8157a,0x95313b997ff55c26,0.210,0.225523,83756,0,PASS
|
||||||
|
-854671705,surface-world,clang19-on,12,27,10,26198,0.000000,-140.000000,-2018.242188,0x0a9e017447ffff3d,0x807299923966d5be,0xdd97f14916c8157a,0x95313b997ff55c26,0.460,0.486882,295460,0,PASS
|
||||||
|
-854671705,surface-world,gcc14-default,1,27,10,26198,0.000000,-140.000000,-2018.242188,0x0a9e017447ffff3d,0x807299923966d5be,0xdd97f14916c8157a,0x95313b997ff55c26,0.204,0.220779,84224,0,PASS
|
||||||
|
-854671705,surface-world,gcc14-default,12,27,10,26198,0.000000,-140.000000,-2018.242188,0x0a9e017447ffff3d,0x807299923966d5be,0xdd97f14916c8157a,0x95313b997ff55c26,0.447,0.476285,295724,0,PASS
|
||||||
|
-854671705,floating-islands,clang19-off,1,27,13,39000,0.000000,-19.800781,-116.507812,0xbb5718ca3ad4c181,0x3250d2591365d443,0xec60f80b7f67216b,0xfe710427da53178b,1.858,1.873454,84868,0,PASS
|
||||||
|
-854671705,floating-islands,clang19-off,12,27,13,39000,0.000000,-19.800781,-116.507812,0xbb5718ca3ad4c181,0x3250d2591365d443,0xec60f80b7f67216b,0xfe710427da53178b,0.769,0.797051,301256,0,PASS
|
||||||
|
-854671705,floating-islands,clang19-on,1,27,13,39000,0.000000,-19.800781,-116.507812,0xbb5718ca3ad4c181,0x3250d2591365d443,0xec60f80b7f67216b,0xfe710427da53178b,1.927,1.944057,84916,0,PASS
|
||||||
|
-854671705,floating-islands,clang19-on,12,27,13,39000,0.000000,-19.800781,-116.507812,0xbb5718ca3ad4c181,0x3250d2591365d443,0xec60f80b7f67216b,0xfe710427da53178b,0.798,0.826241,300776,0,PASS
|
||||||
|
-854671705,floating-islands,gcc14-default,1,27,13,39000,0.000000,-19.800781,-116.507812,0xbb5718ca3ad4c181,0x3250d2591365d443,0xec60f80b7f67216b,0xfe710427da53178b,1.908,1.924264,85304,0,PASS
|
||||||
|
-854671705,floating-islands,gcc14-default,12,27,13,39000,0.000000,-19.800781,-116.507812,0xbb5718ca3ad4c181,0x3250d2591365d443,0xec60f80b7f67216b,0xfe710427da53178b,0.804,0.831547,301148,0,PASS
|
||||||
|
-713963806,surface-world,clang19-off,1,27,16,30292,0.000000,-140.000000,-2018.582031,0x0bdd79cefc1c4003,0x9807c528ec8ea0e6,0x3f6ba7ffdf385024,0x7183d3025a48e8ea,0.211,0.228046,85784,0,PASS
|
||||||
|
-713963806,surface-world,clang19-off,12,27,16,30292,0.000000,-140.000000,-2018.582031,0x0bdd79cefc1c4003,0x9807c528ec8ea0e6,0x3f6ba7ffdf385024,0x7183d3025a48e8ea,0.443,0.470682,300976,0,PASS
|
||||||
|
-713963806,surface-world,clang19-on,1,27,16,30292,0.000000,-140.000000,-2018.582031,0x0bdd79cefc1c4003,0x9807c528ec8ea0e6,0x3f6ba7ffdf385024,0x7183d3025a48e8ea,0.210,0.226264,86008,0,PASS
|
||||||
|
-713963806,surface-world,clang19-on,12,27,16,30292,0.000000,-140.000000,-2018.582031,0x0bdd79cefc1c4003,0x9807c528ec8ea0e6,0x3f6ba7ffdf385024,0x7183d3025a48e8ea,0.416,0.444035,300924,0,PASS
|
||||||
|
-713963806,surface-world,gcc14-default,1,27,16,30292,0.000000,-140.000000,-2018.582031,0x0bdd79cefc1c4003,0x9807c528ec8ea0e6,0x3f6ba7ffdf385024,0x7183d3025a48e8ea,0.214,0.230669,86420,0,PASS
|
||||||
|
-713963806,surface-world,gcc14-default,12,27,16,30292,0.000000,-140.000000,-2018.582031,0x0bdd79cefc1c4003,0x9807c528ec8ea0e6,0x3f6ba7ffdf385024,0x7183d3025a48e8ea,0.417,0.445410,301040,0,PASS
|
||||||
|
-713963806,floating-islands,clang19-off,1,27,8,16002,64.398438,74.308594,-120.453125,0xd590c16395cc515f,0x3a62d63b76bdd260,0x9424147669e1808f,0x137dd286dcedcad6,1.356,1.372073,84768,0,PASS
|
||||||
|
-713963806,floating-islands,clang19-off,12,27,8,16002,64.398438,74.308594,-120.453125,0xd590c16395cc515f,0x3a62d63b76bdd260,0x9424147669e1808f,0x137dd286dcedcad6,0.676,0.703891,297840,0,PASS
|
||||||
|
-713963806,floating-islands,clang19-on,1,27,8,16002,64.398438,74.308594,-120.453125,0xd590c16395cc515f,0x3a62d63b76bdd260,0x9424147669e1808f,0x137dd286dcedcad6,1.360,1.376357,84572,0,PASS
|
||||||
|
-713963806,floating-islands,clang19-on,12,27,8,16002,64.398438,74.308594,-120.453125,0xd590c16395cc515f,0x3a62d63b76bdd260,0x9424147669e1808f,0x137dd286dcedcad6,0.655,0.682658,297928,0,PASS
|
||||||
|
-713963806,floating-islands,gcc14-default,1,27,8,16002,64.398438,74.308594,-120.453125,0xd590c16395cc515f,0x3a62d63b76bdd260,0x9424147669e1808f,0x137dd286dcedcad6,1.293,1.309713,85500,0,PASS
|
||||||
|
-713963806,floating-islands,gcc14-default,12,27,8,16002,64.398438,74.308594,-120.453125,0xd590c16395cc515f,0x3a62d63b76bdd260,0x9424147669e1808f,0x137dd286dcedcad6,0.656,0.682912,298628,0,PASS
|
||||||
|
-621039221,surface-world,clang19-off,1,27,17,30168,0.000000,-140.000000,-2015.613281,0xa27c25107de22a4d,0xde2ffe789eb7fb05,0x966dae7a483679d3,0xf608770036c256a5,0.195,0.211023,85856,0,PASS
|
||||||
|
-621039221,surface-world,clang19-off,12,27,17,30168,0.000000,-140.000000,-2015.613281,0xa27c25107de22a4d,0xde2ffe789eb7fb05,0x966dae7a483679d3,0xf608770036c256a5,0.426,0.453981,301240,0,PASS
|
||||||
|
-621039221,surface-world,clang19-on,1,27,17,30168,0.000000,-140.000000,-2015.613281,0xa27c25107de22a4d,0xde2ffe789eb7fb05,0x966dae7a483679d3,0xf608770036c256a5,0.192,0.208197,86544,0,PASS
|
||||||
|
-621039221,surface-world,clang19-on,12,27,17,30168,0.000000,-140.000000,-2015.613281,0xa27c25107de22a4d,0xde2ffe789eb7fb05,0x966dae7a483679d3,0xf608770036c256a5,0.427,0.454462,301016,0,PASS
|
||||||
|
-621039221,surface-world,gcc14-default,1,27,17,30168,0.000000,-140.000000,-2015.613281,0xa27c25107de22a4d,0xde2ffe789eb7fb05,0x966dae7a483679d3,0xf608770036c256a5,0.194,0.212277,86740,0,PASS
|
||||||
|
-621039221,surface-world,gcc14-default,12,27,17,30168,0.000000,-140.000000,-2015.613281,0xa27c25107de22a4d,0xde2ffe789eb7fb05,0x966dae7a483679d3,0xf608770036c256a5,0.407,0.437082,301508,0,PASS
|
||||||
|
-621039221,floating-islands,clang19-off,1,27,15,46224,0.000000,-18.796875,-116.769531,0x8bf4ceae8c1ddbf6,0x61557967c37529fe,0xbe41280640aaac59,0xd511ae5cd4a47551,1.622,1.638054,87236,0,PASS
|
||||||
|
-621039221,floating-islands,clang19-off,12,27,15,46224,0.000000,-18.796875,-116.769531,0x8bf4ceae8c1ddbf6,0x61557967c37529fe,0xbe41280640aaac59,0xd511ae5cd4a47551,0.688,0.715350,304400,0,PASS
|
||||||
|
-621039221,floating-islands,clang19-on,1,27,15,46224,0.000000,-18.796875,-116.769531,0x8bf4ceae8c1ddbf6,0x61557967c37529fe,0xbe41280640aaac59,0xd511ae5cd4a47551,1.623,1.638541,87444,0,PASS
|
||||||
|
-621039221,floating-islands,clang19-on,12,27,15,46224,0.000000,-18.796875,-116.769531,0x8bf4ceae8c1ddbf6,0x61557967c37529fe,0xbe41280640aaac59,0xd511ae5cd4a47551,0.717,0.744065,303692,0,PASS
|
||||||
|
-621039221,floating-islands,gcc14-default,1,27,15,46224,0.000000,-18.796875,-116.769531,0x8bf4ceae8c1ddbf6,0x61557967c37529fe,0xbe41280640aaac59,0xd511ae5cd4a47551,1.757,1.775436,87644,0,PASS
|
||||||
|
-621039221,floating-islands,gcc14-default,12,27,15,46224,0.000000,-18.796875,-116.769531,0x8bf4ceae8c1ddbf6,0x61557967c37529fe,0xbe41280640aaac59,0xd511ae5cd4a47551,0.731,0.760059,304508,0,PASS
|
||||||
|
-474448608,surface-world,clang19-off,1,27,11,28424,0.000000,-140.000000,-2020.160156,0x0d40ad842a0123ea,0x273fb800c1246cac,0x7a8c602b445dc956,0xd0584f94b9e78e65,0.169,0.185724,84116,0,PASS
|
||||||
|
-474448608,surface-world,clang19-off,12,27,11,28424,0.000000,-140.000000,-2020.160156,0x0d40ad842a0123ea,0x273fb800c1246cac,0x7a8c602b445dc956,0xd0584f94b9e78e65,0.407,0.433876,297484,0,PASS
|
||||||
|
-474448608,surface-world,clang19-on,1,27,11,28424,0.000000,-140.000000,-2020.160156,0x0d40ad842a0123ea,0x273fb800c1246cac,0x7a8c602b445dc956,0xd0584f94b9e78e65,0.171,0.188006,84236,0,PASS
|
||||||
|
-474448608,surface-world,clang19-on,12,27,11,28424,0.000000,-140.000000,-2020.160156,0x0d40ad842a0123ea,0x273fb800c1246cac,0x7a8c602b445dc956,0xd0584f94b9e78e65,0.435,0.461874,296040,0,PASS
|
||||||
|
-474448608,surface-world,gcc14-default,1,27,11,28424,0.000000,-140.000000,-2020.160156,0x0d40ad842a0123ea,0x273fb800c1246cac,0x7a8c602b445dc956,0xd0584f94b9e78e65,0.165,0.180445,84884,0,PASS
|
||||||
|
-474448608,surface-world,gcc14-default,12,27,11,28424,0.000000,-140.000000,-2020.160156,0x0d40ad842a0123ea,0x273fb800c1246cac,0x7a8c602b445dc956,0xd0584f94b9e78e65,0.426,0.453272,298176,0,PASS
|
||||||
|
-474448608,floating-islands,clang19-off,1,27,12,26122,-39.199219,20.921875,-121.671875,0x2a634b2a3d2e38ef,0x52d2036bf1406614,0x0f3ab05afb9043d4,0x47b6e01bb7fbb7ba,1.629,1.645685,86612,0,PASS
|
||||||
|
-474448608,floating-islands,clang19-off,12,27,12,26122,-39.199219,20.921875,-121.671875,0x2a634b2a3d2e38ef,0x52d2036bf1406614,0x0f3ab05afb9043d4,0x47b6e01bb7fbb7ba,0.726,0.754007,301436,0,PASS
|
||||||
|
-474448608,floating-islands,clang19-on,1,27,12,26122,-39.199219,20.921875,-121.671875,0x2a634b2a3d2e38ef,0x52d2036bf1406614,0x0f3ab05afb9043d4,0x47b6e01bb7fbb7ba,1.622,1.638207,86372,0,PASS
|
||||||
|
-474448608,floating-islands,clang19-on,12,27,12,26122,-39.199219,20.921875,-121.671875,0x2a634b2a3d2e38ef,0x52d2036bf1406614,0x0f3ab05afb9043d4,0x47b6e01bb7fbb7ba,0.718,0.747095,301408,0,PASS
|
||||||
|
-474448608,floating-islands,gcc14-default,1,27,12,26122,-39.199219,20.921875,-121.671875,0x2a634b2a3d2e38ef,0x52d2036bf1406614,0x0f3ab05afb9043d4,0x47b6e01bb7fbb7ba,1.768,1.787964,87120,0,PASS
|
||||||
|
-474448608,floating-islands,gcc14-default,12,27,12,26122,-39.199219,20.921875,-121.671875,0x2a634b2a3d2e38ef,0x52d2036bf1406614,0x0f3ab05afb9043d4,0x47b6e01bb7fbb7ba,0.743,0.770994,301472,0,PASS
|
||||||
|
-432690581,surface-world,clang19-off,1,27,16,44640,0.000000,-140.000000,-1699.710938,0x3a23c958501ee719,0x45e154a2ee8b0f36,0x9077f2c785e84257,0x14d8bfb36426cbc5,0.306,0.322544,84304,0,PASS
|
||||||
|
-432690581,surface-world,clang19-off,12,27,16,44640,0.000000,-140.000000,-1699.710938,0x3a23c958501ee719,0x45e154a2ee8b0f36,0x9077f2c785e84257,0x14d8bfb36426cbc5,0.459,0.485418,300580,0,PASS
|
||||||
|
-432690581,surface-world,clang19-on,1,27,16,44640,0.000000,-140.000000,-1699.710938,0x3a23c958501ee719,0x45e154a2ee8b0f36,0x9077f2c785e84257,0x14d8bfb36426cbc5,0.306,0.321647,84076,0,PASS
|
||||||
|
-432690581,surface-world,clang19-on,12,27,16,44640,0.000000,-140.000000,-1699.710938,0x3a23c958501ee719,0x45e154a2ee8b0f36,0x9077f2c785e84257,0x14d8bfb36426cbc5,0.474,0.502246,300440,0,PASS
|
||||||
|
-432690581,surface-world,gcc14-default,1,27,16,44640,0.000000,-140.000000,-1699.710938,0x3a23c958501ee719,0x45e154a2ee8b0f36,0x9077f2c785e84257,0x14d8bfb36426cbc5,0.305,0.321094,85004,0,PASS
|
||||||
|
-432690581,surface-world,gcc14-default,12,27,16,44640,0.000000,-140.000000,-1699.710938,0x3a23c958501ee719,0x45e154a2ee8b0f36,0x9077f2c785e84257,0x14d8bfb36426cbc5,0.479,0.507033,301668,0,PASS
|
||||||
|
-432690581,floating-islands,clang19-off,1,27,7,20532,-39.199219,16.421875,-114.292969,0xd8b65942bf1c005c,0xe6557b8cadfb3356,0x446eeeb1e1fec3de,0x829b06ef76e4306d,1.352,1.368398,86148,0,PASS
|
||||||
|
-432690581,floating-islands,clang19-off,12,27,7,20532,-39.199219,16.421875,-114.292969,0xd8b65942bf1c005c,0xe6557b8cadfb3356,0x446eeeb1e1fec3de,0x829b06ef76e4306d,0.661,0.690096,300352,0,PASS
|
||||||
|
-432690581,floating-islands,clang19-on,1,27,7,20532,-39.199219,16.421875,-114.292969,0xd8b65942bf1c005c,0xe6557b8cadfb3356,0x446eeeb1e1fec3de,0x829b06ef76e4306d,1.354,1.371146,86172,0,PASS
|
||||||
|
-432690581,floating-islands,clang19-on,12,27,7,20532,-39.199219,16.421875,-114.292969,0xd8b65942bf1c005c,0xe6557b8cadfb3356,0x446eeeb1e1fec3de,0x829b06ef76e4306d,0.657,0.685687,300432,0,PASS
|
||||||
|
-432690581,floating-islands,gcc14-default,1,27,7,20532,-39.199219,16.421875,-114.292969,0xd8b65942bf1c005c,0xe6557b8cadfb3356,0x446eeeb1e1fec3de,0x829b06ef76e4306d,1.460,1.475496,86412,0,PASS
|
||||||
|
-432690581,floating-islands,gcc14-default,12,27,7,20532,-39.199219,16.421875,-114.292969,0xd8b65942bf1c005c,0xe6557b8cadfb3356,0x446eeeb1e1fec3de,0x829b06ef76e4306d,0.665,0.692459,301076,0,PASS
|
||||||
|
-380556572,surface-world,clang19-off,1,27,15,27832,0.000000,-140.000000,-2015.980469,0x54c47dd125294a9d,0x6e95e2a4fb185b89,0xdf1ac7f070338e53,0xe8b65412d19b0872,0.207,0.221590,85812,0,PASS
|
||||||
|
-380556572,surface-world,clang19-off,12,27,15,27832,0.000000,-140.000000,-2015.980469,0x54c47dd125294a9d,0x6e95e2a4fb185b89,0xdf1ac7f070338e53,0xe8b65412d19b0872,0.437,0.466566,300296,0,PASS
|
||||||
|
-380556572,surface-world,clang19-on,1,27,15,27832,0.000000,-140.000000,-2015.980469,0x54c47dd125294a9d,0x6e95e2a4fb185b89,0xdf1ac7f070338e53,0xe8b65412d19b0872,0.202,0.218609,85576,0,PASS
|
||||||
|
-380556572,surface-world,clang19-on,12,27,15,27832,0.000000,-140.000000,-2015.980469,0x54c47dd125294a9d,0x6e95e2a4fb185b89,0xdf1ac7f070338e53,0xe8b65412d19b0872,0.440,0.468031,300284,0,PASS
|
||||||
|
-380556572,surface-world,gcc14-default,1,27,15,27832,0.000000,-140.000000,-2015.980469,0x54c47dd125294a9d,0x6e95e2a4fb185b89,0xdf1ac7f070338e53,0xe8b65412d19b0872,0.190,0.205873,86136,0,PASS
|
||||||
|
-380556572,surface-world,gcc14-default,12,27,15,27832,0.000000,-140.000000,-2015.980469,0x54c47dd125294a9d,0x6e95e2a4fb185b89,0xdf1ac7f070338e53,0xe8b65412d19b0872,0.432,0.460376,300688,0,PASS
|
||||||
|
-380556572,floating-islands,clang19-off,1,27,10,25334,39.199219,17.386719,-117.285156,0x118f50002e1af1b1,0x57d82fed86d7545c,0xe6196a35a7e64fb8,0x094fe80cdf7fda78,0.839,0.855823,86260,0,PASS
|
||||||
|
-380556572,floating-islands,clang19-off,12,27,10,25334,39.199219,17.386719,-117.285156,0x118f50002e1af1b1,0x57d82fed86d7545c,0xe6196a35a7e64fb8,0x094fe80cdf7fda78,0.572,0.600560,301428,0,PASS
|
||||||
|
-380556572,floating-islands,clang19-on,1,27,10,25334,39.199219,17.386719,-117.285156,0x118f50002e1af1b1,0x57d82fed86d7545c,0xe6196a35a7e64fb8,0x094fe80cdf7fda78,0.875,0.890833,86184,0,PASS
|
||||||
|
-380556572,floating-islands,clang19-on,12,27,10,25334,39.199219,17.386719,-117.285156,0x118f50002e1af1b1,0x57d82fed86d7545c,0xe6196a35a7e64fb8,0x094fe80cdf7fda78,0.551,0.578834,300960,0,PASS
|
||||||
|
-380556572,floating-islands,gcc14-default,1,27,10,25334,39.199219,17.386719,-117.285156,0x118f50002e1af1b1,0x57d82fed86d7545c,0xe6196a35a7e64fb8,0x094fe80cdf7fda78,0.916,0.932667,86836,0,PASS
|
||||||
|
-380556572,floating-islands,gcc14-default,12,27,10,25334,39.199219,17.386719,-117.285156,0x118f50002e1af1b1,0x57d82fed86d7545c,0xe6196a35a7e64fb8,0x094fe80cdf7fda78,0.606,0.635544,301708,0,PASS
|
||||||
|
-238925630,surface-world,clang19-off,1,27,9,26908,0.000000,-140.000000,-2021.289062,0x01debb25b2642a4d,0xd316a4d6bbbdceee,0xba64591c42277c82,0x80e23990f3cb20b9,0.163,0.178003,84112,0,PASS
|
||||||
|
-238925630,surface-world,clang19-off,12,27,9,26908,0.000000,-140.000000,-2021.289062,0x01debb25b2642a4d,0xd316a4d6bbbdceee,0xba64591c42277c82,0x80e23990f3cb20b9,0.405,0.433901,294484,0,PASS
|
||||||
|
-238925630,surface-world,clang19-on,1,27,9,26908,0.000000,-140.000000,-2021.289062,0x01debb25b2642a4d,0xd316a4d6bbbdceee,0xba64591c42277c82,0x80e23990f3cb20b9,0.155,0.170979,84116,0,PASS
|
||||||
|
-238925630,surface-world,clang19-on,12,27,9,26908,0.000000,-140.000000,-2021.289062,0x01debb25b2642a4d,0xd316a4d6bbbdceee,0xba64591c42277c82,0x80e23990f3cb20b9,0.424,0.450283,294552,0,PASS
|
||||||
|
-238925630,surface-world,gcc14-default,1,27,9,26908,0.000000,-140.000000,-2021.289062,0x01debb25b2642a4d,0xd316a4d6bbbdceee,0xba64591c42277c82,0x80e23990f3cb20b9,0.157,0.173793,84632,0,PASS
|
||||||
|
-238925630,surface-world,gcc14-default,12,27,9,26908,0.000000,-140.000000,-2021.289062,0x01debb25b2642a4d,0xd316a4d6bbbdceee,0xba64591c42277c82,0x80e23990f3cb20b9,0.418,0.444259,295140,0,PASS
|
||||||
|
-238925630,floating-islands,clang19-off,1,27,10,20680,-39.199219,16.394531,-123.812500,0x36a07bf8d4383533,0x12f59de7f06e5270,0x327832e51af1db70,0xff0a971f18b6b590,2.096,2.113022,86240,0,PASS
|
||||||
|
-238925630,floating-islands,clang19-off,12,27,10,20680,-39.199219,16.394531,-123.812500,0x36a07bf8d4383533,0x12f59de7f06e5270,0x327832e51af1db70,0xff0a971f18b6b590,0.812,0.839647,299904,0,PASS
|
||||||
|
-238925630,floating-islands,clang19-on,1,27,10,20680,-39.199219,16.394531,-123.812500,0x36a07bf8d4383533,0x12f59de7f06e5270,0x327832e51af1db70,0xff0a971f18b6b590,2.107,2.123614,86584,0,PASS
|
||||||
|
-238925630,floating-islands,clang19-on,12,27,10,20680,-39.199219,16.394531,-123.812500,0x36a07bf8d4383533,0x12f59de7f06e5270,0x327832e51af1db70,0xff0a971f18b6b590,0.795,0.823151,299740,0,PASS
|
||||||
|
-238925630,floating-islands,gcc14-default,1,27,10,20680,-39.199219,16.394531,-123.812500,0x36a07bf8d4383533,0x12f59de7f06e5270,0x327832e51af1db70,0xff0a971f18b6b590,2.122,2.139698,87080,0,PASS
|
||||||
|
-238925630,floating-islands,gcc14-default,12,27,10,20680,-39.199219,16.394531,-123.812500,0x36a07bf8d4383533,0x12f59de7f06e5270,0x327832e51af1db70,0xff0a971f18b6b590,0.807,0.834762,300372,0,PASS
|
||||||
|
-216679974,surface-world,clang19-off,1,27,9,26538,0.000000,-140.000000,-2025.835938,0x04339f7c537f8920,0xb6d8dab4a5cd82ca,0x5bdc85d7f66eed92,0xac3b586f9be3e44e,0.168,0.185930,86460,0,PASS
|
||||||
|
-216679974,surface-world,clang19-off,12,27,9,26538,0.000000,-140.000000,-2025.835938,0x04339f7c537f8920,0xb6d8dab4a5cd82ca,0x5bdc85d7f66eed92,0xac3b586f9be3e44e,0.408,0.433793,296948,0,PASS
|
||||||
|
-216679974,surface-world,clang19-on,1,27,9,26538,0.000000,-140.000000,-2025.835938,0x04339f7c537f8920,0xb6d8dab4a5cd82ca,0x5bdc85d7f66eed92,0xac3b586f9be3e44e,0.160,0.176766,86712,0,PASS
|
||||||
|
-216679974,surface-world,clang19-on,12,27,9,26538,0.000000,-140.000000,-2025.835938,0x04339f7c537f8920,0xb6d8dab4a5cd82ca,0x5bdc85d7f66eed92,0xac3b586f9be3e44e,0.426,0.453535,296576,0,PASS
|
||||||
|
-216679974,surface-world,gcc14-default,1,27,9,26538,0.000000,-140.000000,-2025.835938,0x04339f7c537f8920,0xb6d8dab4a5cd82ca,0x5bdc85d7f66eed92,0xac3b586f9be3e44e,0.156,0.172641,87192,0,PASS
|
||||||
|
-216679974,surface-world,gcc14-default,12,27,9,26538,0.000000,-140.000000,-2025.835938,0x04339f7c537f8920,0xb6d8dab4a5cd82ca,0x5bdc85d7f66eed92,0xac3b586f9be3e44e,0.431,0.459265,297424,0,PASS
|
||||||
|
-216679974,floating-islands,clang19-off,1,27,9,25284,39.199219,20.230469,-108.953125,0x79bb86763243b67e,0x7fd748d3021d506d,0x83442fd7561cbb4e,0x5a36191d75130d85,1.202,1.219265,88692,0,PASS
|
||||||
|
-216679974,floating-islands,clang19-off,12,27,9,25284,39.199219,20.230469,-108.953125,0x79bb86763243b67e,0x7fd748d3021d506d,0x83442fd7561cbb4e,0x5a36191d75130d85,0.652,0.679940,303236,0,PASS
|
||||||
|
-216679974,floating-islands,clang19-on,1,27,9,25284,39.199219,20.230469,-108.953125,0x79bb86763243b67e,0x7fd748d3021d506d,0x83442fd7561cbb4e,0x5a36191d75130d85,1.221,1.237304,88612,0,PASS
|
||||||
|
-216679974,floating-islands,clang19-on,12,27,9,25284,39.199219,20.230469,-108.953125,0x79bb86763243b67e,0x7fd748d3021d506d,0x83442fd7561cbb4e,0x5a36191d75130d85,0.613,0.640836,303412,0,PASS
|
||||||
|
-216679974,floating-islands,gcc14-default,1,27,9,25284,39.199219,20.230469,-108.953125,0x79bb86763243b67e,0x7fd748d3021d506d,0x83442fd7561cbb4e,0x5a36191d75130d85,1.322,1.339480,89104,0,PASS
|
||||||
|
-216679974,floating-islands,gcc14-default,12,27,9,25284,39.199219,20.230469,-108.953125,0x79bb86763243b67e,0x7fd748d3021d506d,0x83442fd7561cbb4e,0x5a36191d75130d85,0.655,0.683872,303612,0,PASS
|
||||||
|
-133096164,surface-world,clang19-off,1,27,9,26182,0.000000,-140.000000,-2023.140625,0x1dadb5c6440181c0,0x4681d673371781ba,0x7b8f2bafde1628a9,0xf8f07e5a6d4f38f9,0.169,0.184384,85324,0,PASS
|
||||||
|
-133096164,surface-world,clang19-off,12,27,9,26182,0.000000,-140.000000,-2023.140625,0x1dadb5c6440181c0,0x4681d673371781ba,0x7b8f2bafde1628a9,0xf8f07e5a6d4f38f9,0.417,0.443885,295568,0,PASS
|
||||||
|
-133096164,surface-world,clang19-on,1,27,9,26182,0.000000,-140.000000,-2023.140625,0x1dadb5c6440181c0,0x4681d673371781ba,0x7b8f2bafde1628a9,0xf8f07e5a6d4f38f9,0.170,0.186315,85648,0,PASS
|
||||||
|
-133096164,surface-world,clang19-on,12,27,9,26182,0.000000,-140.000000,-2023.140625,0x1dadb5c6440181c0,0x4681d673371781ba,0x7b8f2bafde1628a9,0xf8f07e5a6d4f38f9,0.429,0.457985,295652,0,PASS
|
||||||
|
-133096164,surface-world,gcc14-default,1,27,9,26182,0.000000,-140.000000,-2023.140625,0x1dadb5c6440181c0,0x4681d673371781ba,0x7b8f2bafde1628a9,0xf8f07e5a6d4f38f9,0.162,0.178058,86036,0,PASS
|
||||||
|
-133096164,surface-world,gcc14-default,12,27,9,26182,0.000000,-140.000000,-2023.140625,0x1dadb5c6440181c0,0x4681d673371781ba,0x7b8f2bafde1628a9,0xf8f07e5a6d4f38f9,0.424,0.454505,296144,0,PASS
|
||||||
|
-133096164,floating-islands,clang19-off,1,27,11,26248,-39.199219,16.050781,-118.000000,0xad7be7cd6b0dbffc,0x06d2caf87f019f22,0xbede324e7af07e61,0xf2eff51f24bf458a,0.872,0.891001,85524,0,PASS
|
||||||
|
-133096164,floating-islands,clang19-off,12,27,11,26248,-39.199219,16.050781,-118.000000,0xad7be7cd6b0dbffc,0x06d2caf87f019f22,0xbede324e7af07e61,0xf2eff51f24bf458a,0.563,0.589920,300908,0,PASS
|
||||||
|
-133096164,floating-islands,clang19-on,1,27,11,26248,-39.199219,16.050781,-118.000000,0xad7be7cd6b0dbffc,0x06d2caf87f019f22,0xbede324e7af07e61,0xf2eff51f24bf458a,0.877,0.892147,85604,0,PASS
|
||||||
|
-133096164,floating-islands,clang19-on,12,27,11,26248,-39.199219,16.050781,-118.000000,0xad7be7cd6b0dbffc,0x06d2caf87f019f22,0xbede324e7af07e61,0xf2eff51f24bf458a,0.561,0.587310,300416,0,PASS
|
||||||
|
-133096164,floating-islands,gcc14-default,1,27,11,26248,-39.199219,16.050781,-118.000000,0xad7be7cd6b0dbffc,0x06d2caf87f019f22,0xbede324e7af07e61,0xf2eff51f24bf458a,0.936,0.951685,86128,0,PASS
|
||||||
|
-133096164,floating-islands,gcc14-default,12,27,11,26248,-39.199219,16.050781,-118.000000,0xad7be7cd6b0dbffc,0x06d2caf87f019f22,0xbede324e7af07e61,0xf2eff51f24bf458a,0.581,0.608952,301120,0,PASS
|
||||||
|
-112366806,surface-world,clang19-off,1,27,16,46567,0.000000,-140.000000,-1699.476562,0x7aafaa55fce58f77,0x84c7d73393ccdb09,0x46a53de4a9e7617c,0xc79fcc56dd0181c2,0.324,0.340848,85804,0,PASS
|
||||||
|
-112366806,surface-world,clang19-off,12,27,16,46567,0.000000,-140.000000,-1699.476562,0x7aafaa55fce58f77,0x84c7d73393ccdb09,0x46a53de4a9e7617c,0xc79fcc56dd0181c2,0.487,0.514033,302296,0,PASS
|
||||||
|
-112366806,surface-world,clang19-on,1,27,16,46567,0.000000,-140.000000,-1699.476562,0x7aafaa55fce58f77,0x84c7d73393ccdb09,0x46a53de4a9e7617c,0xc79fcc56dd0181c2,0.326,0.343022,85380,0,PASS
|
||||||
|
-112366806,surface-world,clang19-on,12,27,16,46567,0.000000,-140.000000,-1699.476562,0x7aafaa55fce58f77,0x84c7d73393ccdb09,0x46a53de4a9e7617c,0xc79fcc56dd0181c2,0.482,0.509381,302920,0,PASS
|
||||||
|
-112366806,surface-world,gcc14-default,1,27,16,46567,0.000000,-140.000000,-1699.476562,0x7aafaa55fce58f77,0x84c7d73393ccdb09,0x46a53de4a9e7617c,0xc79fcc56dd0181c2,0.308,0.323509,86516,0,PASS
|
||||||
|
-112366806,surface-world,gcc14-default,12,27,16,46567,0.000000,-140.000000,-1699.476562,0x7aafaa55fce58f77,0x84c7d73393ccdb09,0x46a53de4a9e7617c,0xc79fcc56dd0181c2,0.480,0.507907,301052,0,PASS
|
||||||
|
-112366806,floating-islands,clang19-off,1,27,9,21148,39.199219,16.867188,-114.605469,0xda065c33dc944d23,0x3c27d1ee8688fec9,0xa497259af00952cf,0x8697ac7f0567f069,1.266,1.282382,85796,0,PASS
|
||||||
|
-112366806,floating-islands,clang19-off,12,27,9,21148,39.199219,16.867188,-114.605469,0xda065c33dc944d23,0x3c27d1ee8688fec9,0xa497259af00952cf,0x8697ac7f0567f069,0.681,0.717905,299852,0,PASS
|
||||||
|
-112366806,floating-islands,clang19-on,1,27,9,21148,39.199219,16.867188,-114.605469,0xda065c33dc944d23,0x3c27d1ee8688fec9,0xa497259af00952cf,0x8697ac7f0567f069,1.340,1.364175,85696,0,PASS
|
||||||
|
-112366806,floating-islands,clang19-on,12,27,9,21148,39.199219,16.867188,-114.605469,0xda065c33dc944d23,0x3c27d1ee8688fec9,0xa497259af00952cf,0x8697ac7f0567f069,0.705,0.732861,299840,0,PASS
|
||||||
|
-112366806,floating-islands,gcc14-default,1,27,9,21148,39.199219,16.867188,-114.605469,0xda065c33dc944d23,0x3c27d1ee8688fec9,0xa497259af00952cf,0x8697ac7f0567f069,1.379,1.395616,86172,0,PASS
|
||||||
|
-112366806,floating-islands,gcc14-default,12,27,9,21148,39.199219,16.867188,-114.605469,0xda065c33dc944d23,0x3c27d1ee8688fec9,0xa497259af00952cf,0x8697ac7f0567f069,0.744,0.770938,300416,0,PASS
|
||||||
|
0,surface-world,clang19-off,1,27,9,27910,0.000000,-140.000000,-2003.089844,0x2339a02328c5ffa6,0x83d31e15bf9161b0,0xc056f0c0987d79b6,0x435c44ce6ca8e4ea,0.180,0.198233,86824,0,PASS
|
||||||
|
0,surface-world,clang19-off,12,27,9,27910,0.000000,-140.000000,-2003.089844,0x2339a02328c5ffa6,0x83d31e15bf9161b0,0xc056f0c0987d79b6,0x435c44ce6ca8e4ea,0.422,0.449664,297060,0,PASS
|
||||||
|
0,surface-world,clang19-on,1,27,9,27910,0.000000,-140.000000,-2003.089844,0x2339a02328c5ffa6,0x83d31e15bf9161b0,0xc056f0c0987d79b6,0x435c44ce6ca8e4ea,0.173,0.188744,86728,0,PASS
|
||||||
|
0,surface-world,clang19-on,12,27,9,27910,0.000000,-140.000000,-2003.089844,0x2339a02328c5ffa6,0x83d31e15bf9161b0,0xc056f0c0987d79b6,0x435c44ce6ca8e4ea,0.450,0.477889,296820,0,PASS
|
||||||
|
0,surface-world,gcc14-default,1,27,9,27910,0.000000,-140.000000,-2003.089844,0x2339a02328c5ffa6,0x83d31e15bf9161b0,0xc056f0c0987d79b6,0x435c44ce6ca8e4ea,0.165,0.181852,87064,0,PASS
|
||||||
|
0,surface-world,gcc14-default,12,27,9,27910,0.000000,-140.000000,-2003.089844,0x2339a02328c5ffa6,0x83d31e15bf9161b0,0xc056f0c0987d79b6,0x435c44ce6ca8e4ea,0.435,0.462262,297640,0,PASS
|
||||||
|
0,floating-islands,clang19-off,1,27,9,20740,-25.199219,-76.226562,-105.089844,0x7fd1e3389642e6f6,0x577e52a5ba8d96be,0x7c6ffe9f5bbbb450,0xb4d308de116f4657,1.761,1.778352,86204,0,PASS
|
||||||
|
0,floating-islands,clang19-off,12,27,9,20740,-25.199219,-76.226562,-105.089844,0x7fd1e3389642e6f6,0x577e52a5ba8d96be,0x7c6ffe9f5bbbb450,0xb4d308de116f4657,0.768,0.794881,299068,0,PASS
|
||||||
|
0,floating-islands,clang19-on,1,27,9,20740,-25.199219,-76.226562,-105.089844,0x7fd1e3389642e6f6,0x577e52a5ba8d96be,0x7c6ffe9f5bbbb450,0xb4d308de116f4657,1.765,1.781702,86056,0,PASS
|
||||||
|
0,floating-islands,clang19-on,12,27,9,20740,-25.199219,-76.226562,-105.089844,0x7fd1e3389642e6f6,0x577e52a5ba8d96be,0x7c6ffe9f5bbbb450,0xb4d308de116f4657,0.765,0.792583,298772,0,PASS
|
||||||
|
0,floating-islands,gcc14-default,1,27,9,20740,-25.199219,-76.226562,-105.089844,0x7fd1e3389642e6f6,0x577e52a5ba8d96be,0x7c6ffe9f5bbbb450,0xb4d308de116f4657,1.894,1.910737,86536,0,PASS
|
||||||
|
0,floating-islands,gcc14-default,12,27,9,20740,-25.199219,-76.226562,-105.089844,0x7fd1e3389642e6f6,0x577e52a5ba8d96be,0x7c6ffe9f5bbbb450,0xb4d308de116f4657,0.802,0.828791,299460,0,PASS
|
||||||
|
5808593,surface-world,clang19-off,1,27,14,29050,0.000000,-140.000000,-2014.406250,0x355972d90ab29593,0x563daf944391ab7c,0x8804eebac2acd898,0xc2b049b4f6426af0,0.209,0.225170,84472,0,PASS
|
||||||
|
5808593,surface-world,clang19-off,12,27,14,29050,0.000000,-140.000000,-2014.406250,0x355972d90ab29593,0x563daf944391ab7c,0x8804eebac2acd898,0xc2b049b4f6426af0,0.440,0.467263,299048,0,PASS
|
||||||
|
5808593,surface-world,clang19-on,1,27,14,29050,0.000000,-140.000000,-2014.406250,0x355972d90ab29593,0x563daf944391ab7c,0x8804eebac2acd898,0xc2b049b4f6426af0,0.214,0.230107,84720,0,PASS
|
||||||
|
5808593,surface-world,clang19-on,12,27,14,29050,0.000000,-140.000000,-2014.406250,0x355972d90ab29593,0x563daf944391ab7c,0x8804eebac2acd898,0xc2b049b4f6426af0,0.450,0.477642,299356,0,PASS
|
||||||
|
5808593,surface-world,gcc14-default,1,27,14,29050,0.000000,-140.000000,-2014.406250,0x355972d90ab29593,0x563daf944391ab7c,0x8804eebac2acd898,0xc2b049b4f6426af0,0.206,0.223073,85136,0,PASS
|
||||||
|
5808593,surface-world,gcc14-default,12,27,14,29050,0.000000,-140.000000,-2014.406250,0x355972d90ab29593,0x563daf944391ab7c,0x8804eebac2acd898,0xc2b049b4f6426af0,0.441,0.468922,299624,0,PASS
|
||||||
|
5808593,floating-islands,clang19-off,1,27,10,21000,39.199219,16.003906,-114.574219,0xb96bffb27bc457e0,0x1f867a2add682123,0xfd4c94fd6f9b5863,0x82dc1a7add5ea530,0.978,0.993595,85604,0,PASS
|
||||||
|
5808593,floating-islands,clang19-off,12,27,10,21000,39.199219,16.003906,-114.574219,0xb96bffb27bc457e0,0x1f867a2add682123,0xfd4c94fd6f9b5863,0x82dc1a7add5ea530,0.587,0.614676,299336,0,PASS
|
||||||
|
5808593,floating-islands,clang19-on,1,27,10,21000,39.199219,16.003906,-114.574219,0xb96bffb27bc457e0,0x1f867a2add682123,0xfd4c94fd6f9b5863,0x82dc1a7add5ea530,0.972,0.987363,85032,0,PASS
|
||||||
|
5808593,floating-islands,clang19-on,12,27,10,21000,39.199219,16.003906,-114.574219,0xb96bffb27bc457e0,0x1f867a2add682123,0xfd4c94fd6f9b5863,0x82dc1a7add5ea530,0.607,0.635950,299516,0,PASS
|
||||||
|
5808593,floating-islands,gcc14-default,1,27,10,21000,39.199219,16.003906,-114.574219,0xb96bffb27bc457e0,0x1f867a2add682123,0xfd4c94fd6f9b5863,0x82dc1a7add5ea530,1.060,1.076946,85540,0,PASS
|
||||||
|
5808593,floating-islands,gcc14-default,12,27,10,21000,39.199219,16.003906,-114.574219,0xb96bffb27bc457e0,0x1f867a2add682123,0xfd4c94fd6f9b5863,0x82dc1a7add5ea530,0.631,0.659995,299816,0,PASS
|
||||||
|
28573228,surface-world,clang19-off,1,27,13,27054,0.000000,-140.000000,-2016.695312,0x57cb2fe09976dc54,0x35ac4f38b432e8b7,0x7ed7b8d28bbb4ae8,0xe9bf4ba938198d73,0.183,0.198431,84548,0,PASS
|
||||||
|
28573228,surface-world,clang19-off,12,27,13,27054,0.000000,-140.000000,-2016.695312,0x57cb2fe09976dc54,0x35ac4f38b432e8b7,0x7ed7b8d28bbb4ae8,0xe9bf4ba938198d73,0.413,0.440062,299560,0,PASS
|
||||||
|
28573228,surface-world,clang19-on,1,27,13,27054,0.000000,-140.000000,-2016.695312,0x57cb2fe09976dc54,0x35ac4f38b432e8b7,0x7ed7b8d28bbb4ae8,0xe9bf4ba938198d73,0.188,0.203450,84968,0,PASS
|
||||||
|
28573228,surface-world,clang19-on,12,27,13,27054,0.000000,-140.000000,-2016.695312,0x57cb2fe09976dc54,0x35ac4f38b432e8b7,0x7ed7b8d28bbb4ae8,0xe9bf4ba938198d73,0.409,0.435356,299552,0,PASS
|
||||||
|
28573228,surface-world,gcc14-default,1,27,13,27054,0.000000,-140.000000,-2016.695312,0x57cb2fe09976dc54,0x35ac4f38b432e8b7,0x7ed7b8d28bbb4ae8,0xe9bf4ba938198d73,0.185,0.200823,85508,0,PASS
|
||||||
|
28573228,surface-world,gcc14-default,12,27,13,27054,0.000000,-140.000000,-2016.695312,0x57cb2fe09976dc54,0x35ac4f38b432e8b7,0x7ed7b8d28bbb4ae8,0xe9bf4ba938198d73,0.420,0.448033,299724,0,PASS
|
||||||
|
28573228,floating-islands,clang19-off,1,27,12,32456,0.000000,-18.683594,-116.187500,0x25ed5f499f9bf7ab,0x1c8e67c20374b473,0x786447fa7fb09cab,0x244fb7a45dc74437,1.396,1.413299,85492,0,PASS
|
||||||
|
28573228,floating-islands,clang19-off,12,27,12,32456,0.000000,-18.683594,-116.187500,0x25ed5f499f9bf7ab,0x1c8e67c20374b473,0x786447fa7fb09cab,0x244fb7a45dc74437,0.693,0.719023,300784,0,PASS
|
||||||
|
28573228,floating-islands,clang19-on,1,27,12,32456,0.000000,-18.683594,-116.187500,0x25ed5f499f9bf7ab,0x1c8e67c20374b473,0x786447fa7fb09cab,0x244fb7a45dc74437,1.354,1.373140,84808,0,PASS
|
||||||
|
28573228,floating-islands,clang19-on,12,27,12,32456,0.000000,-18.683594,-116.187500,0x25ed5f499f9bf7ab,0x1c8e67c20374b473,0x786447fa7fb09cab,0x244fb7a45dc74437,0.663,0.689391,300568,0,PASS
|
||||||
|
28573228,floating-islands,gcc14-default,1,27,12,32456,0.000000,-18.683594,-116.187500,0x25ed5f499f9bf7ab,0x1c8e67c20374b473,0x786447fa7fb09cab,0x244fb7a45dc74437,1.544,1.560291,85548,0,PASS
|
||||||
|
28573228,floating-islands,gcc14-default,12,27,12,32456,0.000000,-18.683594,-116.187500,0x25ed5f499f9bf7ab,0x1c8e67c20374b473,0x786447fa7fb09cab,0x244fb7a45dc74437,0.727,0.755835,300920,0,PASS
|
||||||
|
70955227,surface-world,clang19-off,1,27,13,29926,0.000000,-140.000000,-2047.484375,0xb205ad43941e41d8,0x722e775c7e0735bc,0x44a33dfc23ec62ed,0x39969012a7375b51,0.192,0.208106,85820,0,PASS
|
||||||
|
70955227,surface-world,clang19-off,12,27,13,29926,0.000000,-140.000000,-2047.484375,0xb205ad43941e41d8,0x722e775c7e0735bc,0x44a33dfc23ec62ed,0x39969012a7375b51,0.448,0.476411,300752,0,PASS
|
||||||
|
70955227,surface-world,clang19-on,1,27,13,29926,0.000000,-140.000000,-2047.484375,0xb205ad43941e41d8,0x722e775c7e0735bc,0x44a33dfc23ec62ed,0x39969012a7375b51,0.185,0.201218,85544,0,PASS
|
||||||
|
70955227,surface-world,clang19-on,12,27,13,29926,0.000000,-140.000000,-2047.484375,0xb205ad43941e41d8,0x722e775c7e0735bc,0x44a33dfc23ec62ed,0x39969012a7375b51,0.429,0.457766,300792,0,PASS
|
||||||
|
70955227,surface-world,gcc14-default,1,27,13,29926,0.000000,-140.000000,-2047.484375,0xb205ad43941e41d8,0x722e775c7e0735bc,0x44a33dfc23ec62ed,0x39969012a7375b51,0.183,0.198664,86928,0,PASS
|
||||||
|
70955227,surface-world,gcc14-default,12,27,13,29926,0.000000,-140.000000,-2047.484375,0xb205ad43941e41d8,0x722e775c7e0735bc,0x44a33dfc23ec62ed,0x39969012a7375b51,0.438,0.466791,301440,0,PASS
|
||||||
|
70955227,floating-islands,clang19-off,1,27,12,17426,-39.199219,18.582031,-121.785156,0xbe4b9c0ebadde344,0xa9a52cc49ade0f23,0x6f301aefdb37973f,0xa38a1c2ec1a3b2f1,1.586,1.602163,87224,0,PASS
|
||||||
|
70955227,floating-islands,clang19-off,12,27,12,17426,-39.199219,18.582031,-121.785156,0xbe4b9c0ebadde344,0xa9a52cc49ade0f23,0x6f301aefdb37973f,0xa38a1c2ec1a3b2f1,0.715,0.741331,300680,0,PASS
|
||||||
|
70955227,floating-islands,clang19-on,1,27,12,17426,-39.199219,18.582031,-121.785156,0xbe4b9c0ebadde344,0xa9a52cc49ade0f23,0x6f301aefdb37973f,0xa38a1c2ec1a3b2f1,1.601,1.615814,87288,0,PASS
|
||||||
|
70955227,floating-islands,clang19-on,12,27,12,17426,-39.199219,18.582031,-121.785156,0xbe4b9c0ebadde344,0xa9a52cc49ade0f23,0x6f301aefdb37973f,0xa38a1c2ec1a3b2f1,0.746,0.774349,301108,0,PASS
|
||||||
|
70955227,floating-islands,gcc14-default,1,27,12,17426,-39.199219,18.582031,-121.785156,0xbe4b9c0ebadde344,0xa9a52cc49ade0f23,0x6f301aefdb37973f,0xa38a1c2ec1a3b2f1,1.718,1.733886,87436,0,PASS
|
||||||
|
70955227,floating-islands,gcc14-default,12,27,12,17426,-39.199219,18.582031,-121.785156,0xbe4b9c0ebadde344,0xa9a52cc49ade0f23,0x6f301aefdb37973f,0xa38a1c2ec1a3b2f1,0.780,0.806995,301540,0,PASS
|
||||||
|
75274690,surface-world,clang19-off,1,27,15,28342,0.000000,-140.000000,-2019.648438,0x84af4380d33164a6,0xa18d6de0f9267e9f,0xe4bcbdc97074b806,0x5d71387401f96959,0.189,0.204204,85448,0,PASS
|
||||||
|
75274690,surface-world,clang19-off,12,27,15,28342,0.000000,-140.000000,-2019.648438,0x84af4380d33164a6,0xa18d6de0f9267e9f,0xe4bcbdc97074b806,0x5d71387401f96959,0.445,0.471446,300620,0,PASS
|
||||||
|
75274690,surface-world,clang19-on,1,27,15,28342,0.000000,-140.000000,-2019.648438,0x84af4380d33164a6,0xa18d6de0f9267e9f,0xe4bcbdc97074b806,0x5d71387401f96959,0.184,0.200607,85196,0,PASS
|
||||||
|
75274690,surface-world,clang19-on,12,27,15,28342,0.000000,-140.000000,-2019.648438,0x84af4380d33164a6,0xa18d6de0f9267e9f,0xe4bcbdc97074b806,0x5d71387401f96959,0.420,0.448852,300344,0,PASS
|
||||||
|
75274690,surface-world,gcc14-default,1,27,15,28342,0.000000,-140.000000,-2019.648438,0x84af4380d33164a6,0xa18d6de0f9267e9f,0xe4bcbdc97074b806,0x5d71387401f96959,0.192,0.207839,85924,0,PASS
|
||||||
|
75274690,surface-world,gcc14-default,12,27,15,28342,0.000000,-140.000000,-2019.648438,0x84af4380d33164a6,0xa18d6de0f9267e9f,0xe4bcbdc97074b806,0x5d71387401f96959,0.425,0.452205,300748,0,PASS
|
||||||
|
75274690,floating-islands,clang19-off,1,27,8,19760,64.398438,72.199219,-121.019531,0x045c98172a573800,0x86618a983d61425d,0x13523110d2e6a9b3,0x6f1ad87b335e3d3e,1.103,1.118954,86812,0,PASS
|
||||||
|
75274690,floating-islands,clang19-off,12,27,8,19760,64.398438,72.199219,-121.019531,0x045c98172a573800,0x86618a983d61425d,0x13523110d2e6a9b3,0x6f1ad87b335e3d3e,0.628,0.655461,300972,0,PASS
|
||||||
|
75274690,floating-islands,clang19-on,1,27,8,19760,64.398438,72.199219,-121.019531,0x045c98172a573800,0x86618a983d61425d,0x13523110d2e6a9b3,0x6f1ad87b335e3d3e,1.083,1.101596,86924,0,PASS
|
||||||
|
75274690,floating-islands,clang19-on,12,27,8,19760,64.398438,72.199219,-121.019531,0x045c98172a573800,0x86618a983d61425d,0x13523110d2e6a9b3,0x6f1ad87b335e3d3e,0.658,0.694786,300572,0,PASS
|
||||||
|
75274690,floating-islands,gcc14-default,1,27,8,19760,64.398438,72.199219,-121.019531,0x045c98172a573800,0x86618a983d61425d,0x13523110d2e6a9b3,0x6f1ad87b335e3d3e,1.176,1.192130,87488,0,PASS
|
||||||
|
75274690,floating-islands,gcc14-default,12,27,8,19760,64.398438,72.199219,-121.019531,0x045c98172a573800,0x86618a983d61425d,0x13523110d2e6a9b3,0x6f1ad87b335e3d3e,0.653,0.680432,301468,0,PASS
|
||||||
|
81375760,surface-world,clang19-off,1,27,18,48305,0.000000,-140.000000,-1894.296875,0x20c34733457b090d,0x9a6b57b63637db1f,0x2005693f7f6d7dcc,0xc5745d7ea096cff0,0.333,0.349470,85188,0,PASS
|
||||||
|
81375760,surface-world,clang19-off,12,27,18,48305,0.000000,-140.000000,-1894.296875,0x20c34733457b090d,0x9a6b57b63637db1f,0x2005693f7f6d7dcc,0xc5745d7ea096cff0,0.480,0.508631,302276,0,PASS
|
||||||
|
81375760,surface-world,clang19-on,1,27,18,48305,0.000000,-140.000000,-1894.296875,0x20c34733457b090d,0x9a6b57b63637db1f,0x2005693f7f6d7dcc,0xc5745d7ea096cff0,0.331,0.348279,85148,0,PASS
|
||||||
|
81375760,surface-world,clang19-on,12,27,18,48305,0.000000,-140.000000,-1894.296875,0x20c34733457b090d,0x9a6b57b63637db1f,0x2005693f7f6d7dcc,0xc5745d7ea096cff0,0.506,0.532790,302092,0,PASS
|
||||||
|
81375760,surface-world,gcc14-default,1,27,18,48305,0.000000,-140.000000,-1894.296875,0x20c34733457b090d,0x9a6b57b63637db1f,0x2005693f7f6d7dcc,0xc5745d7ea096cff0,0.340,0.357917,85568,0,PASS
|
||||||
|
81375760,surface-world,gcc14-default,12,27,18,48305,0.000000,-140.000000,-1894.296875,0x20c34733457b090d,0x9a6b57b63637db1f,0x2005693f7f6d7dcc,0xc5745d7ea096cff0,0.476,0.502072,302172,0,PASS
|
||||||
|
81375760,floating-islands,clang19-off,1,27,12,24146,-39.199219,20.589844,-119.359375,0x69b66261833e4676,0x75e6b0f427e7698a,0xcb222176f7352da7,0x20224eb0a8925b4d,1.592,1.607202,87600,0,PASS
|
||||||
|
81375760,floating-islands,clang19-off,12,27,12,24146,-39.199219,20.589844,-119.359375,0x69b66261833e4676,0x75e6b0f427e7698a,0xcb222176f7352da7,0x20224eb0a8925b4d,0.729,0.756249,301856,0,PASS
|
||||||
|
81375760,floating-islands,clang19-on,1,27,12,24146,-39.199219,20.589844,-119.359375,0x69b66261833e4676,0x75e6b0f427e7698a,0xcb222176f7352da7,0x20224eb0a8925b4d,1.678,1.694265,87328,0,PASS
|
||||||
|
81375760,floating-islands,clang19-on,12,27,12,24146,-39.199219,20.589844,-119.359375,0x69b66261833e4676,0x75e6b0f427e7698a,0xcb222176f7352da7,0x20224eb0a8925b4d,0.746,0.773941,302184,0,PASS
|
||||||
|
81375760,floating-islands,gcc14-default,1,27,12,24146,-39.199219,20.589844,-119.359375,0x69b66261833e4676,0x75e6b0f427e7698a,0xcb222176f7352da7,0x20224eb0a8925b4d,1.706,1.723259,87980,0,PASS
|
||||||
|
81375760,floating-islands,gcc14-default,12,27,12,24146,-39.199219,20.589844,-119.359375,0x69b66261833e4676,0x75e6b0f427e7698a,0xcb222176f7352da7,0x20224eb0a8925b4d,0.743,0.770492,302508,0,PASS
|
||||||
|
146979566,surface-world,clang19-off,1,27,14,31096,0.000000,-140.000000,-2014.601562,0x2d27daeb8c1c8b7c,0x2218ed732f71ca53,0x6f23c17789836934,0x5063630f2a948856,0.242,0.259669,85944,0,PASS
|
||||||
|
146979566,surface-world,clang19-off,12,27,14,31096,0.000000,-140.000000,-2014.601562,0x2d27daeb8c1c8b7c,0x2218ed732f71ca53,0x6f23c17789836934,0x5063630f2a948856,0.431,0.458617,301156,0,PASS
|
||||||
|
146979566,surface-world,clang19-on,1,27,14,31096,0.000000,-140.000000,-2014.601562,0x2d27daeb8c1c8b7c,0x2218ed732f71ca53,0x6f23c17789836934,0x5063630f2a948856,0.237,0.254081,85952,0,PASS
|
||||||
|
146979566,surface-world,clang19-on,12,27,14,31096,0.000000,-140.000000,-2014.601562,0x2d27daeb8c1c8b7c,0x2218ed732f71ca53,0x6f23c17789836934,0x5063630f2a948856,0.428,0.456566,301360,0,PASS
|
||||||
|
146979566,surface-world,gcc14-default,1,27,14,31096,0.000000,-140.000000,-2014.601562,0x2d27daeb8c1c8b7c,0x2218ed732f71ca53,0x6f23c17789836934,0x5063630f2a948856,0.245,0.261764,86436,0,PASS
|
||||||
|
146979566,surface-world,gcc14-default,12,27,14,31096,0.000000,-140.000000,-2014.601562,0x2d27daeb8c1c8b7c,0x2218ed732f71ca53,0x6f23c17789836934,0x5063630f2a948856,0.453,0.480241,301596,0,PASS
|
||||||
|
146979566,floating-islands,clang19-off,1,27,9,22370,39.199219,16.625000,-109.785156,0x93d0d67042bb05d2,0xe7f4981f907e316e,0x98081f3cf86e0b7f,0xa103fc9366460065,1.584,1.600638,87472,0,PASS
|
||||||
|
146979566,floating-islands,clang19-off,12,27,9,22370,39.199219,16.625000,-109.785156,0x93d0d67042bb05d2,0xe7f4981f907e316e,0x98081f3cf86e0b7f,0xa103fc9366460065,0.691,0.717956,301644,0,PASS
|
||||||
|
146979566,floating-islands,clang19-on,1,27,9,22370,39.199219,16.625000,-109.785156,0x93d0d67042bb05d2,0xe7f4981f907e316e,0x98081f3cf86e0b7f,0xa103fc9366460065,1.645,1.662341,87336,0,PASS
|
||||||
|
146979566,floating-islands,clang19-on,12,27,9,22370,39.199219,16.625000,-109.785156,0x93d0d67042bb05d2,0xe7f4981f907e316e,0x98081f3cf86e0b7f,0xa103fc9366460065,0.716,0.744086,301388,0,PASS
|
||||||
|
146979566,floating-islands,gcc14-default,1,27,9,22370,39.199219,16.625000,-109.785156,0x93d0d67042bb05d2,0xe7f4981f907e316e,0x98081f3cf86e0b7f,0xa103fc9366460065,1.743,1.760680,87812,0,PASS
|
||||||
|
146979566,floating-islands,gcc14-default,12,27,9,22370,39.199219,16.625000,-109.785156,0x93d0d67042bb05d2,0xe7f4981f907e316e,0x98081f3cf86e0b7f,0xa103fc9366460065,0.726,0.752868,302004,0,PASS
|
||||||
|
244951180,surface-world,clang19-off,1,27,18,52468,0.000000,-140.000000,-1798.816406,0xfb0ba5f3b28b306d,0x2d5f650a41b8b2bd,0xcc6273def955b692,0x477e01281747a9c6,0.348,0.365147,87736,0,PASS
|
||||||
|
244951180,surface-world,clang19-off,12,27,18,52468,0.000000,-140.000000,-1798.816406,0xfb0ba5f3b28b306d,0x2d5f650a41b8b2bd,0xcc6273def955b692,0x477e01281747a9c6,0.475,0.502857,304536,0,PASS
|
||||||
|
244951180,surface-world,clang19-on,1,27,18,52468,0.000000,-140.000000,-1798.816406,0xfb0ba5f3b28b306d,0x2d5f650a41b8b2bd,0xcc6273def955b692,0x477e01281747a9c6,0.345,0.361096,87652,0,PASS
|
||||||
|
244951180,surface-world,clang19-on,12,27,18,52468,0.000000,-140.000000,-1798.816406,0xfb0ba5f3b28b306d,0x2d5f650a41b8b2bd,0xcc6273def955b692,0x477e01281747a9c6,0.462,0.489379,305156,0,PASS
|
||||||
|
244951180,surface-world,gcc14-default,1,27,18,52468,0.000000,-140.000000,-1798.816406,0xfb0ba5f3b28b306d,0x2d5f650a41b8b2bd,0xcc6273def955b692,0x477e01281747a9c6,0.319,0.334168,87880,0,PASS
|
||||||
|
244951180,surface-world,gcc14-default,12,27,18,52468,0.000000,-140.000000,-1798.816406,0xfb0ba5f3b28b306d,0x2d5f650a41b8b2bd,0xcc6273def955b692,0x477e01281747a9c6,0.468,0.496037,305128,0,PASS
|
||||||
|
244951180,floating-islands,clang19-off,1,27,13,32272,0.000000,-18.179688,-116.664062,0x0b22965681c5b482,0x582ef8c1d263bedb,0x00179a81f23dbeee,0x5ea7d2a08ba7a249,1.132,1.147425,87072,0,PASS
|
||||||
|
244951180,floating-islands,clang19-off,12,27,13,32272,0.000000,-18.179688,-116.664062,0x0b22965681c5b482,0x582ef8c1d263bedb,0x00179a81f23dbeee,0x5ea7d2a08ba7a249,0.586,0.615574,303052,0,PASS
|
||||||
|
244951180,floating-islands,clang19-on,1,27,13,32272,0.000000,-18.179688,-116.664062,0x0b22965681c5b482,0x582ef8c1d263bedb,0x00179a81f23dbeee,0x5ea7d2a08ba7a249,1.099,1.116192,87252,0,PASS
|
||||||
|
244951180,floating-islands,clang19-on,12,27,13,32272,0.000000,-18.179688,-116.664062,0x0b22965681c5b482,0x582ef8c1d263bedb,0x00179a81f23dbeee,0x5ea7d2a08ba7a249,0.588,0.615818,303076,0,PASS
|
||||||
|
244951180,floating-islands,gcc14-default,1,27,13,32272,0.000000,-18.179688,-116.664062,0x0b22965681c5b482,0x582ef8c1d263bedb,0x00179a81f23dbeee,0x5ea7d2a08ba7a249,1.201,1.217254,87804,0,PASS
|
||||||
|
244951180,floating-islands,gcc14-default,12,27,13,32272,0.000000,-18.179688,-116.664062,0x0b22965681c5b482,0x582ef8c1d263bedb,0x00179a81f23dbeee,0x5ea7d2a08ba7a249,0.615,0.643461,303388,0,PASS
|
||||||
|
245433414,surface-world,clang19-off,1,27,14,32860,0.000000,-140.000000,-2022.468750,0xcc51a567f61f812d,0xc59dc3105dd493b2,0x03b8f1a7d0eac0d7,0x22f468a7d1585605,0.183,0.199554,84260,0,PASS
|
||||||
|
245433414,surface-world,clang19-off,12,27,14,32860,0.000000,-140.000000,-2022.468750,0xcc51a567f61f812d,0xc59dc3105dd493b2,0x03b8f1a7d0eac0d7,0x22f468a7d1585605,0.528,0.554834,299804,0,PASS
|
||||||
|
245433414,surface-world,clang19-on,1,27,14,32860,0.000000,-140.000000,-2022.468750,0xcc51a567f61f812d,0xc59dc3105dd493b2,0x03b8f1a7d0eac0d7,0x22f468a7d1585605,0.190,0.205364,84668,0,PASS
|
||||||
|
245433414,surface-world,clang19-on,12,27,14,32860,0.000000,-140.000000,-2022.468750,0xcc51a567f61f812d,0xc59dc3105dd493b2,0x03b8f1a7d0eac0d7,0x22f468a7d1585605,0.424,0.450563,299552,0,PASS
|
||||||
|
245433414,surface-world,gcc14-default,1,27,14,32860,0.000000,-140.000000,-2022.468750,0xcc51a567f61f812d,0xc59dc3105dd493b2,0x03b8f1a7d0eac0d7,0x22f468a7d1585605,0.182,0.197759,85244,0,PASS
|
||||||
|
245433414,surface-world,gcc14-default,12,27,14,32860,0.000000,-140.000000,-2022.468750,0xcc51a567f61f812d,0xc59dc3105dd493b2,0x03b8f1a7d0eac0d7,0x22f468a7d1585605,0.433,0.459733,300260,0,PASS
|
||||||
|
245433414,floating-islands,clang19-off,1,27,11,32838,0.000000,-17.574219,-116.296875,0x2e75a175d1005e4e,0x8f45449d7125c041,0x493909fdf6e5cba4,0x576100f342da3f02,1.138,1.154872,87048,0,PASS
|
||||||
|
245433414,floating-islands,clang19-off,12,27,11,32838,0.000000,-17.574219,-116.296875,0x2e75a175d1005e4e,0x8f45449d7125c041,0x493909fdf6e5cba4,0x576100f342da3f02,0.629,0.656026,302520,0,PASS
|
||||||
|
245433414,floating-islands,clang19-on,1,27,11,32838,0.000000,-17.574219,-116.296875,0x2e75a175d1005e4e,0x8f45449d7125c041,0x493909fdf6e5cba4,0x576100f342da3f02,1.112,1.129107,87048,0,PASS
|
||||||
|
245433414,floating-islands,clang19-on,12,27,11,32838,0.000000,-17.574219,-116.296875,0x2e75a175d1005e4e,0x8f45449d7125c041,0x493909fdf6e5cba4,0x576100f342da3f02,0.582,0.610645,302704,0,PASS
|
||||||
|
245433414,floating-islands,gcc14-default,1,27,11,32838,0.000000,-17.574219,-116.296875,0x2e75a175d1005e4e,0x8f45449d7125c041,0x493909fdf6e5cba4,0x576100f342da3f02,1.189,1.205364,87708,0,PASS
|
||||||
|
245433414,floating-islands,gcc14-default,12,27,11,32838,0.000000,-17.574219,-116.296875,0x2e75a175d1005e4e,0x8f45449d7125c041,0x493909fdf6e5cba4,0x576100f342da3f02,0.635,0.663132,303108,0,PASS
|
||||||
|
277442974,surface-world,clang19-off,1,27,9,27060,0.000000,-140.000000,-2004.875000,0x8bfa82ca5e492c37,0x1630487dbcc54469,0xb37b440b5f2b1c98,0xe296c565d2eb2ef0,0.274,0.290495,86336,0,PASS
|
||||||
|
277442974,surface-world,clang19-off,12,27,9,27060,0.000000,-140.000000,-2004.875000,0x8bfa82ca5e492c37,0x1630487dbcc54469,0xb37b440b5f2b1c98,0xe296c565d2eb2ef0,0.471,0.497591,296556,0,PASS
|
||||||
|
277442974,surface-world,clang19-on,1,27,9,27060,0.000000,-140.000000,-2004.875000,0x8bfa82ca5e492c37,0x1630487dbcc54469,0xb37b440b5f2b1c98,0xe296c565d2eb2ef0,0.264,0.280808,86376,0,PASS
|
||||||
|
277442974,surface-world,clang19-on,12,27,9,27060,0.000000,-140.000000,-2004.875000,0x8bfa82ca5e492c37,0x1630487dbcc54469,0xb37b440b5f2b1c98,0xe296c565d2eb2ef0,0.481,0.507069,296232,0,PASS
|
||||||
|
277442974,surface-world,gcc14-default,1,27,9,27060,0.000000,-140.000000,-2004.875000,0x8bfa82ca5e492c37,0x1630487dbcc54469,0xb37b440b5f2b1c98,0xe296c565d2eb2ef0,0.247,0.263402,86856,0,PASS
|
||||||
|
277442974,surface-world,gcc14-default,12,27,9,27060,0.000000,-140.000000,-2004.875000,0x8bfa82ca5e492c37,0x1630487dbcc54469,0xb37b440b5f2b1c98,0xe296c565d2eb2ef0,0.476,0.504203,297224,0,PASS
|
||||||
|
277442974,floating-islands,clang19-off,1,27,13,28088,39.199219,19.328125,-117.750000,0x8cb55c56b1629d42,0xc6532d9d3b8a987d,0x1a07243bd2c586c1,0x5d957c64ae620a5e,1.172,1.186572,88460,0,PASS
|
||||||
|
277442974,floating-islands,clang19-off,12,27,13,28088,39.199219,19.328125,-117.750000,0x8cb55c56b1629d42,0xc6532d9d3b8a987d,0x1a07243bd2c586c1,0x5d957c64ae620a5e,0.642,0.673081,303884,0,PASS
|
||||||
|
277442974,floating-islands,clang19-on,1,27,13,28088,39.199219,19.328125,-117.750000,0x8cb55c56b1629d42,0xc6532d9d3b8a987d,0x1a07243bd2c586c1,0x5d957c64ae620a5e,1.187,1.211616,88412,0,PASS
|
||||||
|
277442974,floating-islands,clang19-on,12,27,13,28088,39.199219,19.328125,-117.750000,0x8cb55c56b1629d42,0xc6532d9d3b8a987d,0x1a07243bd2c586c1,0x5d957c64ae620a5e,0.664,0.692926,303956,0,PASS
|
||||||
|
277442974,floating-islands,gcc14-default,1,27,13,28088,39.199219,19.328125,-117.750000,0x8cb55c56b1629d42,0xc6532d9d3b8a987d,0x1a07243bd2c586c1,0x5d957c64ae620a5e,1.210,1.225245,89264,0,PASS
|
||||||
|
277442974,floating-islands,gcc14-default,12,27,13,28088,39.199219,19.328125,-117.750000,0x8cb55c56b1629d42,0xc6532d9d3b8a987d,0x1a07243bd2c586c1,0x5d957c64ae620a5e,0.662,0.689572,304204,0,PASS
|
||||||
|
297746112,surface-world,clang19-off,1,27,13,38252,0.000000,-140.000000,-2010.195312,0x00c869b6875b7ef5,0x085684513feca8f2,0x118ce3a71b3a4b6d,0x5e5c8df181277ea2,0.266,0.281980,86512,0,PASS
|
||||||
|
297746112,surface-world,clang19-off,12,27,13,38252,0.000000,-140.000000,-2010.195312,0x00c869b6875b7ef5,0x085684513feca8f2,0x118ce3a71b3a4b6d,0x5e5c8df181277ea2,0.462,0.489317,300184,0,PASS
|
||||||
|
297746112,surface-world,clang19-on,1,27,13,38252,0.000000,-140.000000,-2010.195312,0x00c869b6875b7ef5,0x085684513feca8f2,0x118ce3a71b3a4b6d,0x5e5c8df181277ea2,0.265,0.281098,86148,0,PASS
|
||||||
|
297746112,surface-world,clang19-on,12,27,13,38252,0.000000,-140.000000,-2010.195312,0x00c869b6875b7ef5,0x085684513feca8f2,0x118ce3a71b3a4b6d,0x5e5c8df181277ea2,0.447,0.474064,300408,0,PASS
|
||||||
|
297746112,surface-world,gcc14-default,1,27,13,38252,0.000000,-140.000000,-2010.195312,0x00c869b6875b7ef5,0x085684513feca8f2,0x118ce3a71b3a4b6d,0x5e5c8df181277ea2,0.253,0.269185,87028,0,PASS
|
||||||
|
297746112,surface-world,gcc14-default,12,27,13,38252,0.000000,-140.000000,-2010.195312,0x00c869b6875b7ef5,0x085684513feca8f2,0x118ce3a71b3a4b6d,0x5e5c8df181277ea2,0.461,0.489903,300916,0,PASS
|
||||||
|
297746112,floating-islands,clang19-off,1,27,15,29396,39.199219,20.609375,-119.089844,0x2425273f1a174c04,0x204be5cda8d98412,0x0565960cfc012768,0x14faf071d204cf2c,1.471,1.486649,86560,0,PASS
|
||||||
|
297746112,floating-islands,clang19-off,12,27,15,29396,39.199219,20.609375,-119.089844,0x2425273f1a174c04,0x204be5cda8d98412,0x0565960cfc012768,0x14faf071d204cf2c,0.707,0.733259,301392,0,PASS
|
||||||
|
297746112,floating-islands,clang19-on,1,27,15,29396,39.199219,20.609375,-119.089844,0x2425273f1a174c04,0x204be5cda8d98412,0x0565960cfc012768,0x14faf071d204cf2c,1.476,1.492227,86404,0,PASS
|
||||||
|
297746112,floating-islands,clang19-on,12,27,15,29396,39.199219,20.609375,-119.089844,0x2425273f1a174c04,0x204be5cda8d98412,0x0565960cfc012768,0x14faf071d204cf2c,0.697,0.724120,301764,0,PASS
|
||||||
|
297746112,floating-islands,gcc14-default,1,27,15,29396,39.199219,20.609375,-119.089844,0x2425273f1a174c04,0x204be5cda8d98412,0x0565960cfc012768,0x14faf071d204cf2c,1.606,1.623971,87112,0,PASS
|
||||||
|
297746112,floating-islands,gcc14-default,12,27,15,29396,39.199219,20.609375,-119.089844,0x2425273f1a174c04,0x204be5cda8d98412,0x0565960cfc012768,0x14faf071d204cf2c,0.744,0.770764,301868,0,PASS
|
||||||
|
336768467,surface-world,clang19-off,1,27,15,29748,0.000000,-140.000000,-2014.343750,0x2756e6dc388ddf57,0x66344082236c5630,0x8d1456f1c9c5391d,0x8c5dafb1129150a4,0.193,0.210861,84432,0,PASS
|
||||||
|
336768467,surface-world,clang19-off,12,27,15,29748,0.000000,-140.000000,-2014.343750,0x2756e6dc388ddf57,0x66344082236c5630,0x8d1456f1c9c5391d,0x8c5dafb1129150a4,0.439,0.465773,299308,0,PASS
|
||||||
|
336768467,surface-world,clang19-on,1,27,15,29748,0.000000,-140.000000,-2014.343750,0x2756e6dc388ddf57,0x66344082236c5630,0x8d1456f1c9c5391d,0x8c5dafb1129150a4,0.203,0.220275,84220,0,PASS
|
||||||
|
336768467,surface-world,clang19-on,12,27,15,29748,0.000000,-140.000000,-2014.343750,0x2756e6dc388ddf57,0x66344082236c5630,0x8d1456f1c9c5391d,0x8c5dafb1129150a4,0.442,0.472005,298776,0,PASS
|
||||||
|
336768467,surface-world,gcc14-default,1,27,15,29748,0.000000,-140.000000,-2014.343750,0x2756e6dc388ddf57,0x66344082236c5630,0x8d1456f1c9c5391d,0x8c5dafb1129150a4,0.195,0.210295,84640,0,PASS
|
||||||
|
336768467,surface-world,gcc14-default,12,27,15,29748,0.000000,-140.000000,-2014.343750,0x2756e6dc388ddf57,0x66344082236c5630,0x8d1456f1c9c5391d,0x8c5dafb1129150a4,0.441,0.468001,299924,0,PASS
|
||||||
|
336768467,floating-islands,clang19-off,1,27,12,33652,0.000000,-20.933594,-116.355469,0xfa8249483c186760,0xc42acd7c93e1525c,0xdef1819f3ea0dfba,0xe7f844319ae479a5,1.560,1.576635,86384,0,PASS
|
||||||
|
336768467,floating-islands,clang19-off,12,27,12,33652,0.000000,-20.933594,-116.355469,0xfa8249483c186760,0xc42acd7c93e1525c,0xdef1819f3ea0dfba,0xe7f844319ae479a5,0.687,0.715116,302356,0,PASS
|
||||||
|
336768467,floating-islands,clang19-on,1,27,12,33652,0.000000,-20.933594,-116.355469,0xfa8249483c186760,0xc42acd7c93e1525c,0xdef1819f3ea0dfba,0xe7f844319ae479a5,1.607,1.622026,86512,0,PASS
|
||||||
|
336768467,floating-islands,clang19-on,12,27,12,33652,0.000000,-20.933594,-116.355469,0xfa8249483c186760,0xc42acd7c93e1525c,0xdef1819f3ea0dfba,0xe7f844319ae479a5,0.756,0.786103,301928,0,PASS
|
||||||
|
336768467,floating-islands,gcc14-default,1,27,12,33652,0.000000,-20.933594,-116.355469,0xfa8249483c186760,0xc42acd7c93e1525c,0xdef1819f3ea0dfba,0xe7f844319ae479a5,1.659,1.676423,87116,0,PASS
|
||||||
|
336768467,floating-islands,gcc14-default,12,27,12,33652,0.000000,-20.933594,-116.355469,0xfa8249483c186760,0xc42acd7c93e1525c,0xdef1819f3ea0dfba,0xe7f844319ae479a5,0.745,0.770547,302312,0,PASS
|
||||||
|
512532080,surface-world,clang19-off,1,27,14,28800,0.000000,-140.000000,-2011.875000,0xa5ad29a27d991d10,0x060bc1fca8569368,0x726e34d2232e7e04,0x2cfa7c1af8ec4ee4,0.238,0.255841,84384,0,PASS
|
||||||
|
512532080,surface-world,clang19-off,12,27,14,28800,0.000000,-140.000000,-2011.875000,0xa5ad29a27d991d10,0x060bc1fca8569368,0x726e34d2232e7e04,0x2cfa7c1af8ec4ee4,0.472,0.498432,298872,0,PASS
|
||||||
|
512532080,surface-world,clang19-on,1,27,14,28800,0.000000,-140.000000,-2011.875000,0xa5ad29a27d991d10,0x060bc1fca8569368,0x726e34d2232e7e04,0x2cfa7c1af8ec4ee4,0.224,0.240126,84544,0,PASS
|
||||||
|
512532080,surface-world,clang19-on,12,27,14,28800,0.000000,-140.000000,-2011.875000,0xa5ad29a27d991d10,0x060bc1fca8569368,0x726e34d2232e7e04,0x2cfa7c1af8ec4ee4,0.456,0.482429,299344,0,PASS
|
||||||
|
512532080,surface-world,gcc14-default,1,27,14,28800,0.000000,-140.000000,-2011.875000,0xa5ad29a27d991d10,0x060bc1fca8569368,0x726e34d2232e7e04,0x2cfa7c1af8ec4ee4,0.219,0.236902,84712,0,PASS
|
||||||
|
512532080,surface-world,gcc14-default,12,27,14,28800,0.000000,-140.000000,-2011.875000,0xa5ad29a27d991d10,0x060bc1fca8569368,0x726e34d2232e7e04,0x2cfa7c1af8ec4ee4,0.468,0.494269,299636,0,PASS
|
||||||
|
512532080,floating-islands,clang19-off,1,27,14,34900,0.000000,-20.355469,-116.640625,0xb098abe6a38cfe3a,0x436a6541192ed00e,0x75e2b7c9004349c2,0x534923147812f216,1.231,1.246649,86052,0,PASS
|
||||||
|
512532080,floating-islands,clang19-off,12,27,14,34900,0.000000,-20.355469,-116.640625,0xb098abe6a38cfe3a,0x436a6541192ed00e,0x75e2b7c9004349c2,0x534923147812f216,0.615,0.641439,301628,0,PASS
|
||||||
|
512532080,floating-islands,clang19-on,1,27,14,34900,0.000000,-20.355469,-116.640625,0xb098abe6a38cfe3a,0x436a6541192ed00e,0x75e2b7c9004349c2,0x534923147812f216,1.228,1.242805,85768,0,PASS
|
||||||
|
512532080,floating-islands,clang19-on,12,27,14,34900,0.000000,-20.355469,-116.640625,0xb098abe6a38cfe3a,0x436a6541192ed00e,0x75e2b7c9004349c2,0x534923147812f216,0.627,0.655211,301628,0,PASS
|
||||||
|
512532080,floating-islands,gcc14-default,1,27,14,34900,0.000000,-20.355469,-116.640625,0xb098abe6a38cfe3a,0x436a6541192ed00e,0x75e2b7c9004349c2,0x534923147812f216,1.359,1.374927,86224,0,PASS
|
||||||
|
512532080,floating-islands,gcc14-default,12,27,14,34900,0.000000,-20.355469,-116.640625,0xb098abe6a38cfe3a,0x436a6541192ed00e,0x75e2b7c9004349c2,0x534923147812f216,0.653,0.684763,302532,0,PASS
|
||||||
|
821120640,surface-world,clang19-off,1,27,17,29100,0.000000,-140.000000,-2017.054688,0xb6424f19c272b61c,0xe4f7308d87cb3bc2,0x3f43e313583419b6,0xe7bf900c0a18e037,0.235,0.252205,84088,0,PASS
|
||||||
|
821120640,surface-world,clang19-off,12,27,17,29100,0.000000,-140.000000,-2017.054688,0xb6424f19c272b61c,0xe4f7308d87cb3bc2,0x3f43e313583419b6,0xe7bf900c0a18e037,0.471,0.497535,298356,0,PASS
|
||||||
|
821120640,surface-world,clang19-on,1,27,17,29100,0.000000,-140.000000,-2017.054688,0xb6424f19c272b61c,0xe4f7308d87cb3bc2,0x3f43e313583419b6,0xe7bf900c0a18e037,0.232,0.246887,84276,0,PASS
|
||||||
|
821120640,surface-world,clang19-on,12,27,17,29100,0.000000,-140.000000,-2017.054688,0xb6424f19c272b61c,0xe4f7308d87cb3bc2,0x3f43e313583419b6,0xe7bf900c0a18e037,0.444,0.469734,298640,0,PASS
|
||||||
|
821120640,surface-world,gcc14-default,1,27,17,29100,0.000000,-140.000000,-2017.054688,0xb6424f19c272b61c,0xe4f7308d87cb3bc2,0x3f43e313583419b6,0xe7bf900c0a18e037,0.227,0.242379,84848,0,PASS
|
||||||
|
821120640,surface-world,gcc14-default,12,27,17,29100,0.000000,-140.000000,-2017.054688,0xb6424f19c272b61c,0xe4f7308d87cb3bc2,0x3f43e313583419b6,0xe7bf900c0a18e037,0.446,0.472509,299120,0,PASS
|
||||||
|
821120640,floating-islands,clang19-off,1,27,11,27034,39.199219,18.121094,-108.417969,0x3db9226404527944,0xb3328f1c88e96c70,0x1e9434cf277c52f2,0x7623a6394f56d6bc,1.593,1.609040,86048,0,PASS
|
||||||
|
821120640,floating-islands,clang19-off,12,27,11,27034,39.199219,18.121094,-108.417969,0x3db9226404527944,0xb3328f1c88e96c70,0x1e9434cf277c52f2,0x7623a6394f56d6bc,0.771,0.798393,300532,0,PASS
|
||||||
|
821120640,floating-islands,clang19-on,1,27,11,27034,39.199219,18.121094,-108.417969,0x3db9226404527944,0xb3328f1c88e96c70,0x1e9434cf277c52f2,0x7623a6394f56d6bc,1.647,1.661841,85752,0,PASS
|
||||||
|
821120640,floating-islands,clang19-on,12,27,11,27034,39.199219,18.121094,-108.417969,0x3db9226404527944,0xb3328f1c88e96c70,0x1e9434cf277c52f2,0x7623a6394f56d6bc,0.731,0.757095,300348,0,PASS
|
||||||
|
821120640,floating-islands,gcc14-default,1,27,11,27034,39.199219,18.121094,-108.417969,0x3db9226404527944,0xb3328f1c88e96c70,0x1e9434cf277c52f2,0x7623a6394f56d6bc,1.791,1.807593,86356,0,PASS
|
||||||
|
821120640,floating-islands,gcc14-default,12,27,11,27034,39.199219,18.121094,-108.417969,0x3db9226404527944,0xb3328f1c88e96c70,0x1e9434cf277c52f2,0x7623a6394f56d6bc,0.778,0.806980,301348,0,PASS
|
||||||
|
853538490,surface-world,clang19-off,1,27,13,41529,0.000000,-140.000000,-2000.957031,0xbe1224f297dc7ad0,0x7e10918947195940,0xac9466d520e8d24d,0xd4a8b472e9b12049,0.325,0.340334,84252,0,PASS
|
||||||
|
853538490,surface-world,clang19-off,12,27,13,41529,0.000000,-140.000000,-2000.957031,0xbe1224f297dc7ad0,0x7e10918947195940,0xac9466d520e8d24d,0xd4a8b472e9b12049,0.490,0.517745,297932,0,PASS
|
||||||
|
853538490,surface-world,clang19-on,1,27,13,41529,0.000000,-140.000000,-2000.957031,0xbe1224f297dc7ad0,0x7e10918947195940,0xac9466d520e8d24d,0xd4a8b472e9b12049,0.307,0.324074,84504,0,PASS
|
||||||
|
853538490,surface-world,clang19-on,12,27,13,41529,0.000000,-140.000000,-2000.957031,0xbe1224f297dc7ad0,0x7e10918947195940,0xac9466d520e8d24d,0xd4a8b472e9b12049,0.484,0.510395,297860,0,PASS
|
||||||
|
853538490,surface-world,gcc14-default,1,27,13,41529,0.000000,-140.000000,-2000.957031,0xbe1224f297dc7ad0,0x7e10918947195940,0xac9466d520e8d24d,0xd4a8b472e9b12049,0.292,0.309051,85156,0,PASS
|
||||||
|
853538490,surface-world,gcc14-default,12,27,13,41529,0.000000,-140.000000,-2000.957031,0xbe1224f297dc7ad0,0x7e10918947195940,0xac9466d520e8d24d,0xd4a8b472e9b12049,0.487,0.516413,300220,0,PASS
|
||||||
|
853538490,floating-islands,clang19-off,1,27,12,21100,64.398438,75.593750,-125.132812,0x7e568fc03c907914,0x6a9fc36512216056,0x42911f340bd75887,0x9a884d5fe3bc3a9f,1.502,1.518453,85300,0,PASS
|
||||||
|
853538490,floating-islands,clang19-off,12,27,12,21100,64.398438,75.593750,-125.132812,0x7e568fc03c907914,0x6a9fc36512216056,0x42911f340bd75887,0x9a884d5fe3bc3a9f,0.752,0.778760,299572,0,PASS
|
||||||
|
853538490,floating-islands,clang19-on,1,27,12,21100,64.398438,75.593750,-125.132812,0x7e568fc03c907914,0x6a9fc36512216056,0x42911f340bd75887,0x9a884d5fe3bc3a9f,1.511,1.527571,85176,0,PASS
|
||||||
|
853538490,floating-islands,clang19-on,12,27,12,21100,64.398438,75.593750,-125.132812,0x7e568fc03c907914,0x6a9fc36512216056,0x42911f340bd75887,0x9a884d5fe3bc3a9f,0.743,0.771772,299476,0,PASS
|
||||||
|
853538490,floating-islands,gcc14-default,1,27,12,21100,64.398438,75.593750,-125.132812,0x7e568fc03c907914,0x6a9fc36512216056,0x42911f340bd75887,0x9a884d5fe3bc3a9f,1.490,1.506165,86100,0,PASS
|
||||||
|
853538490,floating-islands,gcc14-default,12,27,12,21100,64.398438,75.593750,-125.132812,0x7e568fc03c907914,0x6a9fc36512216056,0x42911f340bd75887,0x9a884d5fe3bc3a9f,0.733,0.759420,300016,0,PASS
|
||||||
|
861026696,surface-world,clang19-off,1,27,14,29214,0.000000,-140.000000,-2015.378906,0xb04a05c6e8c488dc,0x28706d092bd82c9a,0xcdcd6eb7219ba860,0x713552a70402ee90,0.206,0.222328,85820,0,PASS
|
||||||
|
861026696,surface-world,clang19-off,12,27,14,29214,0.000000,-140.000000,-2015.378906,0xb04a05c6e8c488dc,0x28706d092bd82c9a,0xcdcd6eb7219ba860,0x713552a70402ee90,0.442,0.469511,301112,0,PASS
|
||||||
|
861026696,surface-world,clang19-on,1,27,14,29214,0.000000,-140.000000,-2015.378906,0xb04a05c6e8c488dc,0x28706d092bd82c9a,0xcdcd6eb7219ba860,0x713552a70402ee90,0.198,0.218476,86120,0,PASS
|
||||||
|
861026696,surface-world,clang19-on,12,27,14,29214,0.000000,-140.000000,-2015.378906,0xb04a05c6e8c488dc,0x28706d092bd82c9a,0xcdcd6eb7219ba860,0x713552a70402ee90,0.420,0.449855,300708,0,PASS
|
||||||
|
861026696,surface-world,gcc14-default,1,27,14,29214,0.000000,-140.000000,-2015.378906,0xb04a05c6e8c488dc,0x28706d092bd82c9a,0xcdcd6eb7219ba860,0x713552a70402ee90,0.198,0.213825,86600,0,PASS
|
||||||
|
861026696,surface-world,gcc14-default,12,27,14,29214,0.000000,-140.000000,-2015.378906,0xb04a05c6e8c488dc,0x28706d092bd82c9a,0xcdcd6eb7219ba860,0x713552a70402ee90,0.425,0.451908,301600,0,PASS
|
||||||
|
861026696,floating-islands,clang19-off,1,27,12,20194,-39.199219,16.035156,-124.882812,0xcb6792ec32335dc5,0x195efb6c80156e4a,0x99d2394c065c7d84,0xa650d8cc28f6ca8c,1.205,1.221248,86916,0,PASS
|
||||||
|
861026696,floating-islands,clang19-off,12,27,12,20194,-39.199219,16.035156,-124.882812,0xcb6792ec32335dc5,0x195efb6c80156e4a,0x99d2394c065c7d84,0xa650d8cc28f6ca8c,0.626,0.656240,301180,0,PASS
|
||||||
|
861026696,floating-islands,clang19-on,1,27,12,20194,-39.199219,16.035156,-124.882812,0xcb6792ec32335dc5,0x195efb6c80156e4a,0x99d2394c065c7d84,0xa650d8cc28f6ca8c,1.204,1.220794,86292,0,PASS
|
||||||
|
861026696,floating-islands,clang19-on,12,27,12,20194,-39.199219,16.035156,-124.882812,0xcb6792ec32335dc5,0x195efb6c80156e4a,0x99d2394c065c7d84,0xa650d8cc28f6ca8c,0.629,0.656007,300976,0,PASS
|
||||||
|
861026696,floating-islands,gcc14-default,1,27,12,20194,-39.199219,16.035156,-124.882812,0xcb6792ec32335dc5,0x195efb6c80156e4a,0x99d2394c065c7d84,0xa650d8cc28f6ca8c,1.304,1.320997,87184,0,PASS
|
||||||
|
861026696,floating-islands,gcc14-default,12,27,12,20194,-39.199219,16.035156,-124.882812,0xcb6792ec32335dc5,0x195efb6c80156e4a,0x99d2394c065c7d84,0xa650d8cc28f6ca8c,0.661,0.688252,301512,0,PASS
|
||||||
|
1026251636,surface-world,clang19-off,1,27,9,28584,0.000000,-140.000000,-2001.500000,0xf6bb5ab0a9e2307d,0x4767f425e56543f4,0x7d07264eb771e914,0x4c10ed20b1feb752,0.181,0.196873,89468,0,PASS
|
||||||
|
1026251636,surface-world,clang19-off,12,27,9,28584,0.000000,-140.000000,-2001.500000,0xf6bb5ab0a9e2307d,0x4767f425e56543f4,0x7d07264eb771e914,0x4c10ed20b1feb752,0.429,0.455273,299856,0,PASS
|
||||||
|
1026251636,surface-world,clang19-on,1,27,9,28584,0.000000,-140.000000,-2001.500000,0xf6bb5ab0a9e2307d,0x4767f425e56543f4,0x7d07264eb771e914,0x4c10ed20b1feb752,0.175,0.191878,88936,0,PASS
|
||||||
|
1026251636,surface-world,clang19-on,12,27,9,28584,0.000000,-140.000000,-2001.500000,0xf6bb5ab0a9e2307d,0x4767f425e56543f4,0x7d07264eb771e914,0x4c10ed20b1feb752,0.421,0.446342,300064,0,PASS
|
||||||
|
1026251636,surface-world,gcc14-default,1,27,9,28584,0.000000,-140.000000,-2001.500000,0xf6bb5ab0a9e2307d,0x4767f425e56543f4,0x7d07264eb771e914,0x4c10ed20b1feb752,0.186,0.201393,89824,0,PASS
|
||||||
|
1026251636,surface-world,gcc14-default,12,27,9,28584,0.000000,-140.000000,-2001.500000,0xf6bb5ab0a9e2307d,0x4767f425e56543f4,0x7d07264eb771e914,0x4c10ed20b1feb752,0.440,0.465684,300752,0,PASS
|
||||||
|
1026251636,floating-islands,clang19-off,1,27,8,19958,-25.199219,-74.664062,-109.117188,0xe62d0a684fcd1398,0xca0e1740a58cafbd,0xb28adbbe9f346438,0xaeddcc5189ee4f9c,2.014,2.030369,89720,0,PASS
|
||||||
|
1026251636,floating-islands,clang19-off,12,27,8,19958,-25.199219,-74.664062,-109.117188,0xe62d0a684fcd1398,0xca0e1740a58cafbd,0xb28adbbe9f346438,0xaeddcc5189ee4f9c,0.784,0.811497,304088,0,PASS
|
||||||
|
1026251636,floating-islands,clang19-on,1,27,8,19958,-25.199219,-74.664062,-109.117188,0xe62d0a684fcd1398,0xca0e1740a58cafbd,0xb28adbbe9f346438,0xaeddcc5189ee4f9c,2.037,2.053588,90148,0,PASS
|
||||||
|
1026251636,floating-islands,clang19-on,12,27,8,19958,-25.199219,-74.664062,-109.117188,0xe62d0a684fcd1398,0xca0e1740a58cafbd,0xb28adbbe9f346438,0xaeddcc5189ee4f9c,0.805,0.831833,303992,0,PASS
|
||||||
|
1026251636,floating-islands,gcc14-default,1,27,8,19958,-25.199219,-74.664062,-109.117188,0xe62d0a684fcd1398,0xca0e1740a58cafbd,0xb28adbbe9f346438,0xaeddcc5189ee4f9c,2.030,2.046181,90280,0,PASS
|
||||||
|
1026251636,floating-islands,gcc14-default,12,27,8,19958,-25.199219,-74.664062,-109.117188,0xe62d0a684fcd1398,0xca0e1740a58cafbd,0xb28adbbe9f346438,0xaeddcc5189ee4f9c,0.829,0.855747,304588,0,PASS
|
||||||
|
1077415394,surface-world,clang19-off,1,27,12,27666,0.000000,-140.000000,-2018.636719,0xb65f4acca21a93d8,0x0a3cddad02604438,0xe1cc5b39a1d20a9c,0xba1d3df14ef1dbc1,0.193,0.208931,87732,0,PASS
|
||||||
|
1077415394,surface-world,clang19-off,12,27,12,27666,0.000000,-140.000000,-2018.636719,0xb65f4acca21a93d8,0x0a3cddad02604438,0xe1cc5b39a1d20a9c,0xba1d3df14ef1dbc1,0.436,0.463397,302684,0,PASS
|
||||||
|
1077415394,surface-world,clang19-on,1,27,12,27666,0.000000,-140.000000,-2018.636719,0xb65f4acca21a93d8,0x0a3cddad02604438,0xe1cc5b39a1d20a9c,0xba1d3df14ef1dbc1,0.193,0.210262,87604,0,PASS
|
||||||
|
1077415394,surface-world,clang19-on,12,27,12,27666,0.000000,-140.000000,-2018.636719,0xb65f4acca21a93d8,0x0a3cddad02604438,0xe1cc5b39a1d20a9c,0xba1d3df14ef1dbc1,0.420,0.447388,300700,0,PASS
|
||||||
|
1077415394,surface-world,gcc14-default,1,27,12,27666,0.000000,-140.000000,-2018.636719,0xb65f4acca21a93d8,0x0a3cddad02604438,0xe1cc5b39a1d20a9c,0xba1d3df14ef1dbc1,0.190,0.205810,88040,0,PASS
|
||||||
|
1077415394,surface-world,gcc14-default,12,27,12,27666,0.000000,-140.000000,-2018.636719,0xb65f4acca21a93d8,0x0a3cddad02604438,0xe1cc5b39a1d20a9c,0xba1d3df14ef1dbc1,0.423,0.451176,302760,0,PASS
|
||||||
|
1077415394,floating-islands,clang19-off,1,27,9,25992,39.199219,20.472656,-109.757812,0x76ffc67a9d410089,0x712f9bef468c36e1,0xd15add3c403cf9d2,0x1f98a205464ab093,1.607,1.623777,88912,0,PASS
|
||||||
|
1077415394,floating-islands,clang19-off,12,27,9,25992,39.199219,20.472656,-109.757812,0x76ffc67a9d410089,0x712f9bef468c36e1,0xd15add3c403cf9d2,0x1f98a205464ab093,0.714,0.740654,303924,0,PASS
|
||||||
|
1077415394,floating-islands,clang19-on,1,27,9,25992,39.199219,20.472656,-109.757812,0x76ffc67a9d410089,0x712f9bef468c36e1,0xd15add3c403cf9d2,0x1f98a205464ab093,1.587,1.603589,89156,0,PASS
|
||||||
|
1077415394,floating-islands,clang19-on,12,27,9,25992,39.199219,20.472656,-109.757812,0x76ffc67a9d410089,0x712f9bef468c36e1,0xd15add3c403cf9d2,0x1f98a205464ab093,0.678,0.704362,303820,0,PASS
|
||||||
|
1077415394,floating-islands,gcc14-default,1,27,9,25992,39.199219,20.472656,-109.757812,0x76ffc67a9d410089,0x712f9bef468c36e1,0xd15add3c403cf9d2,0x1f98a205464ab093,1.751,1.766817,89248,0,PASS
|
||||||
|
1077415394,floating-islands,gcc14-default,12,27,9,25992,39.199219,20.472656,-109.757812,0x76ffc67a9d410089,0x712f9bef468c36e1,0xd15add3c403cf9d2,0x1f98a205464ab093,0.726,0.753263,304336,0,PASS
|
||||||
|
1130999017,surface-world,clang19-off,1,27,15,38852,0.000000,-140.000000,-1885.390625,0xd4fee006d89064ec,0xc2e722815c510b8d,0xaee1e5e204213289,0x6107884769e6196b,0.258,0.275630,85440,0,PASS
|
||||||
|
1130999017,surface-world,clang19-off,12,27,15,38852,0.000000,-140.000000,-1885.390625,0xd4fee006d89064ec,0xc2e722815c510b8d,0xaee1e5e204213289,0x6107884769e6196b,0.452,0.478967,301608,0,PASS
|
||||||
|
1130999017,surface-world,clang19-on,1,27,15,38852,0.000000,-140.000000,-1885.390625,0xd4fee006d89064ec,0xc2e722815c510b8d,0xaee1e5e204213289,0x6107884769e6196b,0.251,0.266976,85864,0,PASS
|
||||||
|
1130999017,surface-world,clang19-on,12,27,15,38852,0.000000,-140.000000,-1885.390625,0xd4fee006d89064ec,0xc2e722815c510b8d,0xaee1e5e204213289,0x6107884769e6196b,0.443,0.472895,299580,0,PASS
|
||||||
|
1130999017,surface-world,gcc14-default,1,27,15,38852,0.000000,-140.000000,-1885.390625,0xd4fee006d89064ec,0xc2e722815c510b8d,0xaee1e5e204213289,0x6107884769e6196b,0.243,0.258360,86216,0,PASS
|
||||||
|
1130999017,surface-world,gcc14-default,12,27,15,38852,0.000000,-140.000000,-1885.390625,0xd4fee006d89064ec,0xc2e722815c510b8d,0xaee1e5e204213289,0x6107884769e6196b,0.430,0.459582,300604,0,PASS
|
||||||
|
1130999017,floating-islands,clang19-off,1,27,14,25686,-39.199219,19.199219,-119.304688,0x9fc0c1b33da03fc0,0xc0dafe8b2a4570f1,0x24ac0b621165dc1c,0x3e15c5e91f7d7e46,1.116,1.133283,84856,0,PASS
|
||||||
|
1130999017,floating-islands,clang19-off,12,27,14,25686,-39.199219,19.199219,-119.304688,0x9fc0c1b33da03fc0,0xc0dafe8b2a4570f1,0x24ac0b621165dc1c,0x3e15c5e91f7d7e46,0.608,0.635013,299952,0,PASS
|
||||||
|
1130999017,floating-islands,clang19-on,1,27,14,25686,-39.199219,19.199219,-119.304688,0x9fc0c1b33da03fc0,0xc0dafe8b2a4570f1,0x24ac0b621165dc1c,0x3e15c5e91f7d7e46,1.131,1.147307,84968,0,PASS
|
||||||
|
1130999017,floating-islands,clang19-on,12,27,14,25686,-39.199219,19.199219,-119.304688,0x9fc0c1b33da03fc0,0xc0dafe8b2a4570f1,0x24ac0b621165dc1c,0x3e15c5e91f7d7e46,0.600,0.627582,299320,0,PASS
|
||||||
|
1130999017,floating-islands,gcc14-default,1,27,14,25686,-39.199219,19.199219,-119.304688,0x9fc0c1b33da03fc0,0xc0dafe8b2a4570f1,0x24ac0b621165dc1c,0x3e15c5e91f7d7e46,1.180,1.196907,85352,0,PASS
|
||||||
|
1130999017,floating-islands,gcc14-default,12,27,14,25686,-39.199219,19.199219,-119.304688,0x9fc0c1b33da03fc0,0xc0dafe8b2a4570f1,0x24ac0b621165dc1c,0x3e15c5e91f7d7e46,0.653,0.679477,300280,0,PASS
|
||||||
|
1156488597,surface-world,clang19-off,1,27,10,26660,0.000000,-140.000000,-2012.031250,0xf918cd1d254bf5ad,0x93e291c7e8ab3281,0x115d528201ee55de,0x8282368945b9aa39,0.169,0.185411,84912,0,PASS
|
||||||
|
1156488597,surface-world,clang19-off,12,27,10,26660,0.000000,-140.000000,-2012.031250,0xf918cd1d254bf5ad,0x93e291c7e8ab3281,0x115d528201ee55de,0x8282368945b9aa39,0.415,0.440950,296868,0,PASS
|
||||||
|
1156488597,surface-world,clang19-on,1,27,10,26660,0.000000,-140.000000,-2012.031250,0xf918cd1d254bf5ad,0x93e291c7e8ab3281,0x115d528201ee55de,0x8282368945b9aa39,0.170,0.185517,85336,0,PASS
|
||||||
|
1156488597,surface-world,clang19-on,12,27,10,26660,0.000000,-140.000000,-2012.031250,0xf918cd1d254bf5ad,0x93e291c7e8ab3281,0x115d528201ee55de,0x8282368945b9aa39,0.458,0.494970,296900,0,PASS
|
||||||
|
1156488597,surface-world,gcc14-default,1,27,10,26660,0.000000,-140.000000,-2012.031250,0xf918cd1d254bf5ad,0x93e291c7e8ab3281,0x115d528201ee55de,0x8282368945b9aa39,0.178,0.205454,85672,0,PASS
|
||||||
|
1156488597,surface-world,gcc14-default,12,27,10,26660,0.000000,-140.000000,-2012.031250,0xf918cd1d254bf5ad,0x93e291c7e8ab3281,0x115d528201ee55de,0x8282368945b9aa39,0.454,0.483690,297532,0,PASS
|
||||||
|
1156488597,floating-islands,clang19-off,1,27,14,22928,-39.199219,16.464844,-121.550781,0x080c04f591e988da,0x7d2e52b446efd9d1,0x6dccf350fe593410,0x97ae318aaff326ae,1.464,1.480495,87092,0,PASS
|
||||||
|
1156488597,floating-islands,clang19-off,12,27,14,22928,-39.199219,16.464844,-121.550781,0x080c04f591e988da,0x7d2e52b446efd9d1,0x6dccf350fe593410,0x97ae318aaff326ae,0.684,0.710558,301280,0,PASS
|
||||||
|
1156488597,floating-islands,clang19-on,1,27,14,22928,-39.199219,16.464844,-121.550781,0x080c04f591e988da,0x7d2e52b446efd9d1,0x6dccf350fe593410,0x97ae318aaff326ae,1.481,1.498290,87056,0,PASS
|
||||||
|
1156488597,floating-islands,clang19-on,12,27,14,22928,-39.199219,16.464844,-121.550781,0x080c04f591e988da,0x7d2e52b446efd9d1,0x6dccf350fe593410,0x97ae318aaff326ae,0.707,0.737492,301040,0,PASS
|
||||||
|
1156488597,floating-islands,gcc14-default,1,27,14,22928,-39.199219,16.464844,-121.550781,0x080c04f591e988da,0x7d2e52b446efd9d1,0x6dccf350fe593410,0x97ae318aaff326ae,1.635,1.652170,87388,0,PASS
|
||||||
|
1156488597,floating-islands,gcc14-default,12,27,14,22928,-39.199219,16.464844,-121.550781,0x080c04f591e988da,0x7d2e52b446efd9d1,0x6dccf350fe593410,0x97ae318aaff326ae,0.730,0.758962,301644,0,PASS
|
||||||
|
1172304228,surface-world,clang19-off,1,27,9,28078,0.000000,-140.000000,-2030.214844,0x466d74beb6a3c43f,0x935c08e020dbe116,0x495814a08ffe3b6e,0xa3a7e103fe545c77,0.159,0.176089,84448,0,PASS
|
||||||
|
1172304228,surface-world,clang19-off,12,27,9,28078,0.000000,-140.000000,-2030.214844,0x466d74beb6a3c43f,0x935c08e020dbe116,0x495814a08ffe3b6e,0xa3a7e103fe545c77,0.416,0.444129,294644,0,PASS
|
||||||
|
1172304228,surface-world,clang19-on,1,27,9,28078,0.000000,-140.000000,-2030.214844,0x466d74beb6a3c43f,0x935c08e020dbe116,0x495814a08ffe3b6e,0xa3a7e103fe545c77,0.159,0.174634,84268,0,PASS
|
||||||
|
1172304228,surface-world,clang19-on,12,27,9,28078,0.000000,-140.000000,-2030.214844,0x466d74beb6a3c43f,0x935c08e020dbe116,0x495814a08ffe3b6e,0xa3a7e103fe545c77,0.409,0.435936,294684,0,PASS
|
||||||
|
1172304228,surface-world,gcc14-default,1,27,9,28078,0.000000,-140.000000,-2030.214844,0x466d74beb6a3c43f,0x935c08e020dbe116,0x495814a08ffe3b6e,0xa3a7e103fe545c77,0.161,0.177733,84864,0,PASS
|
||||||
|
1172304228,surface-world,gcc14-default,12,27,9,28078,0.000000,-140.000000,-2030.214844,0x466d74beb6a3c43f,0x935c08e020dbe116,0x495814a08ffe3b6e,0xa3a7e103fe545c77,0.407,0.433961,295552,0,PASS
|
||||||
|
1172304228,floating-islands,clang19-off,1,27,12,25280,-39.199219,16.859375,-120.363281,0xa4ceaef6289c2778,0xac854a5846adc6cb,0xc79cc3dcf8aa7882,0x2a36a844bc640838,0.855,0.871675,86436,0,PASS
|
||||||
|
1172304228,floating-islands,clang19-off,12,27,12,25280,-39.199219,16.859375,-120.363281,0xa4ceaef6289c2778,0xac854a5846adc6cb,0xc79cc3dcf8aa7882,0x2a36a844bc640838,0.566,0.594146,300964,0,PASS
|
||||||
|
1172304228,floating-islands,clang19-on,1,27,12,25280,-39.199219,16.859375,-120.363281,0xa4ceaef6289c2778,0xac854a5846adc6cb,0xc79cc3dcf8aa7882,0x2a36a844bc640838,0.866,0.882396,86372,0,PASS
|
||||||
|
1172304228,floating-islands,clang19-on,12,27,12,25280,-39.199219,16.859375,-120.363281,0xa4ceaef6289c2778,0xac854a5846adc6cb,0xc79cc3dcf8aa7882,0x2a36a844bc640838,0.576,0.603920,301252,0,PASS
|
||||||
|
1172304228,floating-islands,gcc14-default,1,27,12,25280,-39.199219,16.859375,-120.363281,0xa4ceaef6289c2778,0xac854a5846adc6cb,0xc79cc3dcf8aa7882,0x2a36a844bc640838,0.938,0.954134,86620,0,PASS
|
||||||
|
1172304228,floating-islands,gcc14-default,12,27,12,25280,-39.199219,16.859375,-120.363281,0xa4ceaef6289c2778,0xac854a5846adc6cb,0xc79cc3dcf8aa7882,0x2a36a844bc640838,0.586,0.615590,301852,0,PASS
|
||||||
|
1370340570,surface-world,clang19-off,1,27,9,26888,0.000000,-140.000000,-2026.738281,0xb71aa861999e9064,0x5e6eb187fe7aa3d1,0xdbd2bf3e112249bb,0xbb50eff77e4ba5a7,0.159,0.175263,84752,0,PASS
|
||||||
|
1370340570,surface-world,clang19-off,12,27,9,26888,0.000000,-140.000000,-2026.738281,0xb71aa861999e9064,0x5e6eb187fe7aa3d1,0xdbd2bf3e112249bb,0xbb50eff77e4ba5a7,0.416,0.441389,295492,0,PASS
|
||||||
|
1370340570,surface-world,clang19-on,1,27,9,26888,0.000000,-140.000000,-2026.738281,0xb71aa861999e9064,0x5e6eb187fe7aa3d1,0xdbd2bf3e112249bb,0xbb50eff77e4ba5a7,0.153,0.168519,84744,0,PASS
|
||||||
|
1370340570,surface-world,clang19-on,12,27,9,26888,0.000000,-140.000000,-2026.738281,0xb71aa861999e9064,0x5e6eb187fe7aa3d1,0xdbd2bf3e112249bb,0xbb50eff77e4ba5a7,0.409,0.438368,295092,0,PASS
|
||||||
|
1370340570,surface-world,gcc14-default,1,27,9,26888,0.000000,-140.000000,-2026.738281,0xb71aa861999e9064,0x5e6eb187fe7aa3d1,0xdbd2bf3e112249bb,0xbb50eff77e4ba5a7,0.155,0.170254,85124,0,PASS
|
||||||
|
1370340570,surface-world,gcc14-default,12,27,9,26888,0.000000,-140.000000,-2026.738281,0xb71aa861999e9064,0x5e6eb187fe7aa3d1,0xdbd2bf3e112249bb,0xbb50eff77e4ba5a7,0.409,0.437481,296036,0,PASS
|
||||||
|
1370340570,floating-islands,clang19-off,1,27,8,20458,-39.199219,17.164062,-114.296875,0xfe631978312f065a,0xc41cdcb438a98b86,0xc2df8d535d4c97d9,0xe26e0e5cc9e21c14,1.581,1.599496,86948,0,PASS
|
||||||
|
1370340570,floating-islands,clang19-off,12,27,8,20458,-39.199219,17.164062,-114.296875,0xfe631978312f065a,0xc41cdcb438a98b86,0xc2df8d535d4c97d9,0xe26e0e5cc9e21c14,0.702,0.729410,301536,0,PASS
|
||||||
|
1370340570,floating-islands,clang19-on,1,27,8,20458,-39.199219,17.164062,-114.296875,0xfe631978312f065a,0xc41cdcb438a98b86,0xc2df8d535d4c97d9,0xe26e0e5cc9e21c14,1.595,1.611272,87072,0,PASS
|
||||||
|
1370340570,floating-islands,clang19-on,12,27,8,20458,-39.199219,17.164062,-114.296875,0xfe631978312f065a,0xc41cdcb438a98b86,0xc2df8d535d4c97d9,0xe26e0e5cc9e21c14,0.691,0.717960,301388,0,PASS
|
||||||
|
1370340570,floating-islands,gcc14-default,1,27,8,20458,-39.199219,17.164062,-114.296875,0xfe631978312f065a,0xc41cdcb438a98b86,0xc2df8d535d4c97d9,0xe26e0e5cc9e21c14,1.728,1.744814,87540,0,PASS
|
||||||
|
1370340570,floating-islands,gcc14-default,12,27,8,20458,-39.199219,17.164062,-114.296875,0xfe631978312f065a,0xc41cdcb438a98b86,0xc2df8d535d4c97d9,0xe26e0e5cc9e21c14,0.754,0.781424,302088,0,PASS
|
||||||
|
1383925073,surface-world,clang19-off,1,27,13,27826,0.000000,-140.000000,-2018.113281,0x564bb6a29953fc31,0x891c57b01dc509f8,0xf94dfef226e94ece,0xf277b25c2571f165,0.181,0.196556,83960,0,PASS
|
||||||
|
1383925073,surface-world,clang19-off,12,27,13,27826,0.000000,-140.000000,-2018.113281,0x564bb6a29953fc31,0x891c57b01dc509f8,0xf94dfef226e94ece,0xf277b25c2571f165,0.426,0.453780,298648,0,PASS
|
||||||
|
1383925073,surface-world,clang19-on,1,27,13,27826,0.000000,-140.000000,-2018.113281,0x564bb6a29953fc31,0x891c57b01dc509f8,0xf94dfef226e94ece,0xf277b25c2571f165,0.184,0.201221,84120,0,PASS
|
||||||
|
1383925073,surface-world,clang19-on,12,27,13,27826,0.000000,-140.000000,-2018.113281,0x564bb6a29953fc31,0x891c57b01dc509f8,0xf94dfef226e94ece,0xf277b25c2571f165,0.407,0.434497,298520,0,PASS
|
||||||
|
1383925073,surface-world,gcc14-default,1,27,13,27826,0.000000,-140.000000,-2018.113281,0x564bb6a29953fc31,0x891c57b01dc509f8,0xf94dfef226e94ece,0xf277b25c2571f165,0.175,0.191617,84528,0,PASS
|
||||||
|
1383925073,surface-world,gcc14-default,12,27,13,27826,0.000000,-140.000000,-2018.113281,0x564bb6a29953fc31,0x891c57b01dc509f8,0xf94dfef226e94ece,0xf277b25c2571f165,0.406,0.432371,299400,0,PASS
|
||||||
|
1383925073,floating-islands,clang19-off,1,27,8,17340,64.398438,76.132812,-101.687500,0x20a6d43f24557065,0xace78f99c63a90bc,0xba9503af152a1017,0xb09b522bed1b8c47,1.524,1.540376,85480,0,PASS
|
||||||
|
1383925073,floating-islands,clang19-off,12,27,8,17340,64.398438,76.132812,-101.687500,0x20a6d43f24557065,0xace78f99c63a90bc,0xba9503af152a1017,0xb09b522bed1b8c47,0.688,0.716589,299068,0,PASS
|
||||||
|
1383925073,floating-islands,clang19-on,1,27,8,17340,64.398438,76.132812,-101.687500,0x20a6d43f24557065,0xace78f99c63a90bc,0xba9503af152a1017,0xb09b522bed1b8c47,1.524,1.540170,85484,0,PASS
|
||||||
|
1383925073,floating-islands,clang19-on,12,27,8,17340,64.398438,76.132812,-101.687500,0x20a6d43f24557065,0xace78f99c63a90bc,0xba9503af152a1017,0xb09b522bed1b8c47,0.693,0.719692,299196,0,PASS
|
||||||
|
1383925073,floating-islands,gcc14-default,1,27,8,17340,64.398438,76.132812,-101.687500,0x20a6d43f24557065,0xace78f99c63a90bc,0xba9503af152a1017,0xb09b522bed1b8c47,1.661,1.676492,85764,0,PASS
|
||||||
|
1383925073,floating-islands,gcc14-default,12,27,8,17340,64.398438,76.132812,-101.687500,0x20a6d43f24557065,0xace78f99c63a90bc,0xba9503af152a1017,0xb09b522bed1b8c47,0.728,0.755271,299796,0,PASS
|
||||||
|
1401164998,surface-world,clang19-off,1,27,14,33671,0.000000,-140.000000,-1923.625000,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.286,0.301458,85156,0,PASS
|
||||||
|
1401164998,surface-world,clang19-off,12,27,14,33671,0.000000,-140.000000,-1923.625000,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.451,0.477156,300516,0,PASS
|
||||||
|
1401164998,surface-world,clang19-on,1,27,14,33671,0.000000,-140.000000,-1923.625000,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.282,0.297994,85456,0,PASS
|
||||||
|
1401164998,surface-world,clang19-on,12,27,14,33671,0.000000,-140.000000,-1923.625000,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.448,0.476334,300584,0,PASS
|
||||||
|
1401164998,surface-world,gcc14-default,1,27,14,33671,0.000000,-140.000000,-1923.625000,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.278,0.294323,85820,0,PASS
|
||||||
|
1401164998,surface-world,gcc14-default,12,27,14,33671,0.000000,-140.000000,-1923.625000,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e,0xd87700809feafff4,0xc2e832153a03b5d7,0.463,0.489660,301300,0,PASS
|
||||||
|
1401164998,floating-islands,clang19-off,1,27,12,25478,-25.199219,-76.433594,-133.500000,0xa22b8a0f16d1cb98,0x85e184e7768795d1,0x29a6f8ac91d35e09,0xb778d52817341912,1.889,1.905353,86852,0,PASS
|
||||||
|
1401164998,floating-islands,clang19-off,12,27,12,25478,-25.199219,-76.433594,-133.500000,0xa22b8a0f16d1cb98,0x85e184e7768795d1,0x29a6f8ac91d35e09,0xb778d52817341912,0.755,0.783092,299600,0,PASS
|
||||||
|
1401164998,floating-islands,clang19-on,1,27,12,25478,-25.199219,-76.433594,-133.500000,0xa22b8a0f16d1cb98,0x85e184e7768795d1,0x29a6f8ac91d35e09,0xb778d52817341912,1.918,1.935211,87012,0,PASS
|
||||||
|
1401164998,floating-islands,clang19-on,12,27,12,25478,-25.199219,-76.433594,-133.500000,0xa22b8a0f16d1cb98,0x85e184e7768795d1,0x29a6f8ac91d35e09,0xb778d52817341912,0.747,0.774451,299876,0,PASS
|
||||||
|
1401164998,floating-islands,gcc14-default,1,27,12,25478,-25.199219,-76.433594,-133.500000,0xa22b8a0f16d1cb98,0x85e184e7768795d1,0x29a6f8ac91d35e09,0xb778d52817341912,1.962,1.978881,87376,0,PASS
|
||||||
|
1401164998,floating-islands,gcc14-default,12,27,12,25478,-25.199219,-76.433594,-133.500000,0xa22b8a0f16d1cb98,0x85e184e7768795d1,0x29a6f8ac91d35e09,0xb778d52817341912,0.773,0.800827,300436,0,PASS
|
||||||
|
1558879574,surface-world,clang19-off,1,27,12,30022,0.000000,-140.000000,-2026.257812,0x566bd8e41e9ce9de,0xd7344edfeac99334,0xffbfbdcc9b7796a9,0x0ab334df0eb60fd6,0.178,0.192933,83876,0,PASS
|
||||||
|
1558879574,surface-world,clang19-off,12,27,12,30022,0.000000,-140.000000,-2026.257812,0x566bd8e41e9ce9de,0xd7344edfeac99334,0xffbfbdcc9b7796a9,0x0ab334df0eb60fd6,0.430,0.457703,298956,0,PASS
|
||||||
|
1558879574,surface-world,clang19-on,1,27,12,30022,0.000000,-140.000000,-2026.257812,0x566bd8e41e9ce9de,0xd7344edfeac99334,0xffbfbdcc9b7796a9,0x0ab334df0eb60fd6,0.176,0.192307,83696,0,PASS
|
||||||
|
1558879574,surface-world,clang19-on,12,27,12,30022,0.000000,-140.000000,-2026.257812,0x566bd8e41e9ce9de,0xd7344edfeac99334,0xffbfbdcc9b7796a9,0x0ab334df0eb60fd6,0.413,0.440116,297112,0,PASS
|
||||||
|
1558879574,surface-world,gcc14-default,1,27,12,30022,0.000000,-140.000000,-2026.257812,0x566bd8e41e9ce9de,0xd7344edfeac99334,0xffbfbdcc9b7796a9,0x0ab334df0eb60fd6,0.182,0.197351,84408,0,PASS
|
||||||
|
1558879574,surface-world,gcc14-default,12,27,12,30022,0.000000,-140.000000,-2026.257812,0x566bd8e41e9ce9de,0xd7344edfeac99334,0xffbfbdcc9b7796a9,0x0ab334df0eb60fd6,0.425,0.451513,299728,0,PASS
|
||||||
|
1558879574,floating-islands,clang19-off,1,27,15,37078,0.000000,-15.878906,-116.753906,0x675134538e8ca09b,0x2e32a5444b8be6d7,0xa3945849da18e24a,0xda29fda6f39d36f9,0.864,0.880169,84868,0,PASS
|
||||||
|
1558879574,floating-islands,clang19-off,12,27,15,37078,0.000000,-15.878906,-116.753906,0x675134538e8ca09b,0x2e32a5444b8be6d7,0xa3945849da18e24a,0xda29fda6f39d36f9,0.595,0.623192,301320,0,PASS
|
||||||
|
1558879574,floating-islands,clang19-on,1,27,15,37078,0.000000,-15.878906,-116.753906,0x675134538e8ca09b,0x2e32a5444b8be6d7,0xa3945849da18e24a,0xda29fda6f39d36f9,0.898,0.914741,84904,0,PASS
|
||||||
|
1558879574,floating-islands,clang19-on,12,27,15,37078,0.000000,-15.878906,-116.753906,0x675134538e8ca09b,0x2e32a5444b8be6d7,0xa3945849da18e24a,0xda29fda6f39d36f9,0.576,0.602221,300580,0,PASS
|
||||||
|
1558879574,floating-islands,gcc14-default,1,27,15,37078,0.000000,-15.878906,-116.753906,0x675134538e8ca09b,0x2e32a5444b8be6d7,0xa3945849da18e24a,0xda29fda6f39d36f9,0.948,0.964253,85196,0,PASS
|
||||||
|
1558879574,floating-islands,gcc14-default,12,27,15,37078,0.000000,-15.878906,-116.753906,0x675134538e8ca09b,0x2e32a5444b8be6d7,0xa3945849da18e24a,0xda29fda6f39d36f9,0.596,0.625674,301684,0,PASS
|
||||||
|
1753015542,surface-world,clang19-off,1,27,9,27536,0.000000,-140.000000,-2004.562500,0x3557e0f7c1298c35,0x833da36dd2c02e13,0x656f82e69ccdecc2,0xac9935bb75fdb59c,0.157,0.174474,85136,0,PASS
|
||||||
|
1753015542,surface-world,clang19-off,12,27,9,27536,0.000000,-140.000000,-2004.562500,0x3557e0f7c1298c35,0x833da36dd2c02e13,0x656f82e69ccdecc2,0xac9935bb75fdb59c,0.400,0.426649,295468,0,PASS
|
||||||
|
1753015542,surface-world,clang19-on,1,27,9,27536,0.000000,-140.000000,-2004.562500,0x3557e0f7c1298c35,0x833da36dd2c02e13,0x656f82e69ccdecc2,0xac9935bb75fdb59c,0.157,0.173307,85120,0,PASS
|
||||||
|
1753015542,surface-world,clang19-on,12,27,9,27536,0.000000,-140.000000,-2004.562500,0x3557e0f7c1298c35,0x833da36dd2c02e13,0x656f82e69ccdecc2,0xac9935bb75fdb59c,0.426,0.452773,295640,0,PASS
|
||||||
|
1753015542,surface-world,gcc14-default,1,27,9,27536,0.000000,-140.000000,-2004.562500,0x3557e0f7c1298c35,0x833da36dd2c02e13,0x656f82e69ccdecc2,0xac9935bb75fdb59c,0.161,0.180130,85696,0,PASS
|
||||||
|
1753015542,surface-world,gcc14-default,12,27,9,27536,0.000000,-140.000000,-2004.562500,0x3557e0f7c1298c35,0x833da36dd2c02e13,0x656f82e69ccdecc2,0xac9935bb75fdb59c,0.404,0.430695,296144,0,PASS
|
||||||
|
1753015542,floating-islands,clang19-off,1,27,13,23050,-25.199219,-75.425781,-125.304688,0xd628ec790fd17bd2,0x5602b3e7ed3f852a,0x844b0f983d0a8dcb,0xdef4bef7bdf60b15,1.084,1.099925,85304,0,PASS
|
||||||
|
1753015542,floating-islands,clang19-off,12,27,13,23050,-25.199219,-75.425781,-125.304688,0xd628ec790fd17bd2,0x5602b3e7ed3f852a,0x844b0f983d0a8dcb,0xdef4bef7bdf60b15,0.611,0.636921,299408,0,PASS
|
||||||
|
1753015542,floating-islands,clang19-on,1,27,13,23050,-25.199219,-75.425781,-125.304688,0xd628ec790fd17bd2,0x5602b3e7ed3f852a,0x844b0f983d0a8dcb,0xdef4bef7bdf60b15,1.100,1.116086,85256,0,PASS
|
||||||
|
1753015542,floating-islands,clang19-on,12,27,13,23050,-25.199219,-75.425781,-125.304688,0xd628ec790fd17bd2,0x5602b3e7ed3f852a,0x844b0f983d0a8dcb,0xdef4bef7bdf60b15,0.615,0.646016,299692,0,PASS
|
||||||
|
1753015542,floating-islands,gcc14-default,1,27,13,23050,-25.199219,-75.425781,-125.304688,0xd628ec790fd17bd2,0x5602b3e7ed3f852a,0x844b0f983d0a8dcb,0xdef4bef7bdf60b15,1.222,1.237954,85648,0,PASS
|
||||||
|
1753015542,floating-islands,gcc14-default,12,27,13,23050,-25.199219,-75.425781,-125.304688,0xd628ec790fd17bd2,0x5602b3e7ed3f852a,0x844b0f983d0a8dcb,0xdef4bef7bdf60b15,0.638,0.665451,300048,0,PASS
|
||||||
|
1827697875,surface-world,clang19-off,1,27,12,29182,0.000000,-140.000000,-2018.507812,0xd945dc9d11f16156,0x59cd0f8103174807,0xbeae510e83e10bb9,0xe561cd4f1b5fc4a0,0.176,0.193003,86328,0,PASS
|
||||||
|
1827697875,surface-world,clang19-off,12,27,12,29182,0.000000,-140.000000,-2018.507812,0xd945dc9d11f16156,0x59cd0f8103174807,0xbeae510e83e10bb9,0xe561cd4f1b5fc4a0,0.404,0.432768,301456,0,PASS
|
||||||
|
1827697875,surface-world,clang19-on,1,27,12,29182,0.000000,-140.000000,-2018.507812,0xd945dc9d11f16156,0x59cd0f8103174807,0xbeae510e83e10bb9,0xe561cd4f1b5fc4a0,0.168,0.184638,86524,0,PASS
|
||||||
|
1827697875,surface-world,clang19-on,12,27,12,29182,0.000000,-140.000000,-2018.507812,0xd945dc9d11f16156,0x59cd0f8103174807,0xbeae510e83e10bb9,0xe561cd4f1b5fc4a0,0.403,0.430151,301156,0,PASS
|
||||||
|
1827697875,surface-world,gcc14-default,1,27,12,29182,0.000000,-140.000000,-2018.507812,0xd945dc9d11f16156,0x59cd0f8103174807,0xbeae510e83e10bb9,0xe561cd4f1b5fc4a0,0.171,0.187425,86968,0,PASS
|
||||||
|
1827697875,surface-world,gcc14-default,12,27,12,29182,0.000000,-140.000000,-2018.507812,0xd945dc9d11f16156,0x59cd0f8103174807,0xbeae510e83e10bb9,0xe561cd4f1b5fc4a0,0.404,0.431313,301904,0,PASS
|
||||||
|
1827697875,floating-islands,clang19-off,1,27,11,34624,0.000000,-19.441406,-116.312500,0x786671c16ae75f4f,0x2c0c94465b7da251,0x6bad3e5799515fde,0x7ff03f198fd07c37,1.637,1.653412,90444,0,PASS
|
||||||
|
1827697875,floating-islands,clang19-off,12,27,11,34624,0.000000,-19.441406,-116.312500,0x786671c16ae75f4f,0x2c0c94465b7da251,0x6bad3e5799515fde,0x7ff03f198fd07c37,0.721,0.749622,306368,0,PASS
|
||||||
|
1827697875,floating-islands,clang19-on,1,27,11,34624,0.000000,-19.441406,-116.312500,0x786671c16ae75f4f,0x2c0c94465b7da251,0x6bad3e5799515fde,0x7ff03f198fd07c37,1.650,1.665968,90588,0,PASS
|
||||||
|
1827697875,floating-islands,clang19-on,12,27,11,34624,0.000000,-19.441406,-116.312500,0x786671c16ae75f4f,0x2c0c94465b7da251,0x6bad3e5799515fde,0x7ff03f198fd07c37,0.694,0.721945,306148,0,PASS
|
||||||
|
1827697875,floating-islands,gcc14-default,1,27,11,34624,0.000000,-19.441406,-116.312500,0x786671c16ae75f4f,0x2c0c94465b7da251,0x6bad3e5799515fde,0x7ff03f198fd07c37,2.219,2.236609,90628,0,PASS
|
||||||
|
1827697875,floating-islands,gcc14-default,12,27,11,34624,0.000000,-19.441406,-116.312500,0x786671c16ae75f4f,0x2c0c94465b7da251,0x6bad3e5799515fde,0x7ff03f198fd07c37,0.725,0.753570,306580,0,PASS
|
||||||
|
1909311298,surface-world,clang19-off,1,27,13,28862,0.000000,-140.000000,-2007.000000,0x79cb6cf093ee2d27,0xa818f8c1904f73b0,0x529738f49021b6e2,0x22bd170f9b244b7c,0.181,0.196690,83948,0,PASS
|
||||||
|
1909311298,surface-world,clang19-off,12,27,13,28862,0.000000,-140.000000,-2007.000000,0x79cb6cf093ee2d27,0xa818f8c1904f73b0,0x529738f49021b6e2,0x22bd170f9b244b7c,0.414,0.439403,298828,0,PASS
|
||||||
|
1909311298,surface-world,clang19-on,1,27,13,28862,0.000000,-140.000000,-2007.000000,0x79cb6cf093ee2d27,0xa818f8c1904f73b0,0x529738f49021b6e2,0x22bd170f9b244b7c,0.183,0.197951,84020,0,PASS
|
||||||
|
1909311298,surface-world,clang19-on,12,27,13,28862,0.000000,-140.000000,-2007.000000,0x79cb6cf093ee2d27,0xa818f8c1904f73b0,0x529738f49021b6e2,0x22bd170f9b244b7c,0.418,0.445146,297192,0,PASS
|
||||||
|
1909311298,surface-world,gcc14-default,1,27,13,28862,0.000000,-140.000000,-2007.000000,0x79cb6cf093ee2d27,0xa818f8c1904f73b0,0x529738f49021b6e2,0x22bd170f9b244b7c,0.179,0.194761,84464,0,PASS
|
||||||
|
1909311298,surface-world,gcc14-default,12,27,13,28862,0.000000,-140.000000,-2007.000000,0x79cb6cf093ee2d27,0xa818f8c1904f73b0,0x529738f49021b6e2,0x22bd170f9b244b7c,0.414,0.441193,299492,0,PASS
|
||||||
|
1909311298,floating-islands,clang19-off,1,27,12,22040,-39.199219,18.164062,-122.738281,0x7bdc9a6cccc15b70,0x14e5e1428a1a5543,0x9b01cc95b7b3358d,0xd049ccb5663e4449,1.229,1.245451,85180,0,PASS
|
||||||
|
1909311298,floating-islands,clang19-off,12,27,12,22040,-39.199219,18.164062,-122.738281,0x7bdc9a6cccc15b70,0x14e5e1428a1a5543,0x9b01cc95b7b3358d,0xd049ccb5663e4449,0.658,0.685935,299900,0,PASS
|
||||||
|
1909311298,floating-islands,clang19-on,1,27,12,22040,-39.199219,18.164062,-122.738281,0x7bdc9a6cccc15b70,0x14e5e1428a1a5543,0x9b01cc95b7b3358d,0xd049ccb5663e4449,1.261,1.277763,85712,0,PASS
|
||||||
|
1909311298,floating-islands,clang19-on,12,27,12,22040,-39.199219,18.164062,-122.738281,0x7bdc9a6cccc15b70,0x14e5e1428a1a5543,0x9b01cc95b7b3358d,0xd049ccb5663e4449,0.650,0.678722,299884,0,PASS
|
||||||
|
1909311298,floating-islands,gcc14-default,1,27,12,22040,-39.199219,18.164062,-122.738281,0x7bdc9a6cccc15b70,0x14e5e1428a1a5543,0x9b01cc95b7b3358d,0xd049ccb5663e4449,1.358,1.374066,86140,0,PASS
|
||||||
|
1909311298,floating-islands,gcc14-default,12,27,12,22040,-39.199219,18.164062,-122.738281,0x7bdc9a6cccc15b70,0x14e5e1428a1a5543,0x9b01cc95b7b3358d,0xd049ccb5663e4449,0.694,0.722178,300560,0,PASS
|
||||||
|
2011898099,surface-world,clang19-off,1,27,9,28654,0.000000,-140.000000,-2005.066406,0x95f389e603d74998,0xff02d8e0b112c865,0xd5d0a255cb1b18be,0x1138243eba6d47a9,0.171,0.187716,86176,0,PASS
|
||||||
|
2011898099,surface-world,clang19-off,12,27,9,28654,0.000000,-140.000000,-2005.066406,0x95f389e603d74998,0xff02d8e0b112c865,0xd5d0a255cb1b18be,0x1138243eba6d47a9,0.430,0.457289,296284,0,PASS
|
||||||
|
2011898099,surface-world,clang19-on,1,27,9,28654,0.000000,-140.000000,-2005.066406,0x95f389e603d74998,0xff02d8e0b112c865,0xd5d0a255cb1b18be,0x1138243eba6d47a9,0.164,0.180262,85708,0,PASS
|
||||||
|
2011898099,surface-world,clang19-on,12,27,9,28654,0.000000,-140.000000,-2005.066406,0x95f389e603d74998,0xff02d8e0b112c865,0xd5d0a255cb1b18be,0x1138243eba6d47a9,0.421,0.448994,296448,0,PASS
|
||||||
|
2011898099,surface-world,gcc14-default,1,27,9,28654,0.000000,-140.000000,-2005.066406,0x95f389e603d74998,0xff02d8e0b112c865,0xd5d0a255cb1b18be,0x1138243eba6d47a9,0.162,0.178213,86360,0,PASS
|
||||||
|
2011898099,surface-world,gcc14-default,12,27,9,28654,0.000000,-140.000000,-2005.066406,0x95f389e603d74998,0xff02d8e0b112c865,0xd5d0a255cb1b18be,0x1138243eba6d47a9,0.412,0.438827,296832,0,PASS
|
||||||
|
2011898099,floating-islands,clang19-off,1,27,9,21292,39.199219,18.968750,-106.898438,0xb3ad433a09a0d127,0xdea39968a98e0861,0x53948649c6b2beee,0x908898f1ffc5bd9b,1.189,1.205816,88312,0,PASS
|
||||||
|
2011898099,floating-islands,clang19-off,12,27,9,21292,39.199219,18.968750,-106.898438,0xb3ad433a09a0d127,0xdea39968a98e0861,0x53948649c6b2beee,0x908898f1ffc5bd9b,0.603,0.630257,302380,0,PASS
|
||||||
|
2011898099,floating-islands,clang19-on,1,27,9,21292,39.199219,18.968750,-106.898438,0xb3ad433a09a0d127,0xdea39968a98e0861,0x53948649c6b2beee,0x908898f1ffc5bd9b,1.159,1.174149,88360,0,PASS
|
||||||
|
2011898099,floating-islands,clang19-on,12,27,9,21292,39.199219,18.968750,-106.898438,0xb3ad433a09a0d127,0xdea39968a98e0861,0x53948649c6b2beee,0x908898f1ffc5bd9b,0.618,0.645079,302396,0,PASS
|
||||||
|
2011898099,floating-islands,gcc14-default,1,27,9,21292,39.199219,18.968750,-106.898438,0xb3ad433a09a0d127,0xdea39968a98e0861,0x53948649c6b2beee,0x908898f1ffc5bd9b,1.289,1.305695,88604,0,PASS
|
||||||
|
2011898099,floating-islands,gcc14-default,12,27,9,21292,39.199219,18.968750,-106.898438,0xb3ad433a09a0d127,0xdea39968a98e0861,0x53948649c6b2beee,0x908898f1ffc5bd9b,0.656,0.682775,302628,0,PASS
|
||||||
|
2015768509,surface-world,clang19-off,1,27,18,51706,0.000000,-140.000000,-1918.304688,0x9506739f358ba5c5,0xaba43fe9407d51fb,0xb75c6eb38dcff774,0x76ccbd695880c541,0.325,0.339879,84052,0,PASS
|
||||||
|
2015768509,surface-world,clang19-off,12,27,18,51706,0.000000,-140.000000,-1918.304688,0x9506739f358ba5c5,0xaba43fe9407d51fb,0xb75c6eb38dcff774,0x76ccbd695880c541,0.462,0.488815,300564,0,PASS
|
||||||
|
2015768509,surface-world,clang19-on,1,27,18,51706,0.000000,-140.000000,-1918.304688,0x9506739f358ba5c5,0xaba43fe9407d51fb,0xb75c6eb38dcff774,0x76ccbd695880c541,0.327,0.342810,84232,0,PASS
|
||||||
|
2015768509,surface-world,clang19-on,12,27,18,51706,0.000000,-140.000000,-1918.304688,0x9506739f358ba5c5,0xaba43fe9407d51fb,0xb75c6eb38dcff774,0x76ccbd695880c541,0.463,0.489510,300696,0,PASS
|
||||||
|
2015768509,surface-world,gcc14-default,1,27,18,51706,0.000000,-140.000000,-1918.304688,0x9506739f358ba5c5,0xaba43fe9407d51fb,0xb75c6eb38dcff774,0x76ccbd695880c541,0.316,0.332179,84352,0,PASS
|
||||||
|
2015768509,surface-world,gcc14-default,12,27,18,51706,0.000000,-140.000000,-1918.304688,0x9506739f358ba5c5,0xaba43fe9407d51fb,0xb75c6eb38dcff774,0x76ccbd695880c541,0.461,0.488549,301088,0,PASS
|
||||||
|
2015768509,floating-islands,clang19-off,1,27,11,29426,39.199219,20.148438,-111.468750,0x92d4f0690eaa02fd,0x5cea2b8d8ae9a094,0xc520e4594055d037,0x1f0f86bd23a0ade4,1.597,1.614573,85204,0,PASS
|
||||||
|
2015768509,floating-islands,clang19-off,12,27,11,29426,39.199219,20.148438,-111.468750,0x92d4f0690eaa02fd,0x5cea2b8d8ae9a094,0xc520e4594055d037,0x1f0f86bd23a0ade4,0.755,0.784367,300176,0,PASS
|
||||||
|
2015768509,floating-islands,clang19-on,1,27,11,29426,39.199219,20.148438,-111.468750,0x92d4f0690eaa02fd,0x5cea2b8d8ae9a094,0xc520e4594055d037,0x1f0f86bd23a0ade4,1.623,1.646497,85312,0,PASS
|
||||||
|
2015768509,floating-islands,clang19-on,12,27,11,29426,39.199219,20.148438,-111.468750,0x92d4f0690eaa02fd,0x5cea2b8d8ae9a094,0xc520e4594055d037,0x1f0f86bd23a0ade4,0.734,0.761770,300316,0,PASS
|
||||||
|
2015768509,floating-islands,gcc14-default,1,27,11,29426,39.199219,20.148438,-111.468750,0x92d4f0690eaa02fd,0x5cea2b8d8ae9a094,0xc520e4594055d037,0x1f0f86bd23a0ade4,1.884,1.901163,85704,0,PASS
|
||||||
|
2015768509,floating-islands,gcc14-default,12,27,11,29426,39.199219,20.148438,-111.468750,0x92d4f0690eaa02fd,0x5cea2b8d8ae9a094,0xc520e4594055d037,0x1f0f86bd23a0ade4,0.782,0.808616,300972,0,PASS
|
||||||
|
2070776516,surface-world,clang19-off,1,27,10,26952,0.000000,-140.000000,-2010.421875,0x28df1e26bab2140f,0x4af65af7af7045c3,0x9832cc0f7fef9416,0xcc5b3fd5040e7c87,0.192,0.206509,84096,0,PASS
|
||||||
|
2070776516,surface-world,clang19-off,12,27,10,26952,0.000000,-140.000000,-2010.421875,0x28df1e26bab2140f,0x4af65af7af7045c3,0x9832cc0f7fef9416,0xcc5b3fd5040e7c87,0.437,0.465311,295796,0,PASS
|
||||||
|
2070776516,surface-world,clang19-on,1,27,10,26952,0.000000,-140.000000,-2010.421875,0x28df1e26bab2140f,0x4af65af7af7045c3,0x9832cc0f7fef9416,0xcc5b3fd5040e7c87,0.193,0.209540,83692,0,PASS
|
||||||
|
2070776516,surface-world,clang19-on,12,27,10,26952,0.000000,-140.000000,-2010.421875,0x28df1e26bab2140f,0x4af65af7af7045c3,0x9832cc0f7fef9416,0xcc5b3fd5040e7c87,0.456,0.482411,295584,0,PASS
|
||||||
|
2070776516,surface-world,gcc14-default,1,27,10,26952,0.000000,-140.000000,-2010.421875,0x28df1e26bab2140f,0x4af65af7af7045c3,0x9832cc0f7fef9416,0xcc5b3fd5040e7c87,0.190,0.206251,84608,0,PASS
|
||||||
|
2070776516,surface-world,gcc14-default,12,27,10,26952,0.000000,-140.000000,-2010.421875,0x28df1e26bab2140f,0x4af65af7af7045c3,0x9832cc0f7fef9416,0xcc5b3fd5040e7c87,0.453,0.479961,296012,0,PASS
|
||||||
|
2070776516,floating-islands,clang19-off,1,27,8,15728,39.199219,16.496094,-110.636719,0x486603470bf1e852,0xaa6022efbc268013,0xd3227a7e0b6e8b9e,0xefb848cb7eb47d5c,1.112,1.128854,86188,0,PASS
|
||||||
|
2070776516,floating-islands,clang19-off,12,27,8,15728,39.199219,16.496094,-110.636719,0x486603470bf1e852,0xaa6022efbc268013,0xd3227a7e0b6e8b9e,0xefb848cb7eb47d5c,0.567,0.594910,299448,0,PASS
|
||||||
|
2070776516,floating-islands,clang19-on,1,27,8,15728,39.199219,16.496094,-110.636719,0x486603470bf1e852,0xaa6022efbc268013,0xd3227a7e0b6e8b9e,0xefb848cb7eb47d5c,1.115,1.131163,86004,0,PASS
|
||||||
|
2070776516,floating-islands,clang19-on,12,27,8,15728,39.199219,16.496094,-110.636719,0x486603470bf1e852,0xaa6022efbc268013,0xd3227a7e0b6e8b9e,0xefb848cb7eb47d5c,0.613,0.639860,299736,0,PASS
|
||||||
|
2070776516,floating-islands,gcc14-default,1,27,8,15728,39.199219,16.496094,-110.636719,0x486603470bf1e852,0xaa6022efbc268013,0xd3227a7e0b6e8b9e,0xefb848cb7eb47d5c,1.167,1.183633,86500,0,PASS
|
||||||
|
2070776516,floating-islands,gcc14-default,12,27,8,15728,39.199219,16.496094,-110.636719,0x486603470bf1e852,0xaa6022efbc268013,0xd3227a7e0b6e8b9e,0xefb848cb7eb47d5c,0.637,0.663327,300240,0,PASS
|
||||||
|
@@ -0,0 +1,97 @@
|
|||||||
|
seed,recipe,camera_x_vox,camera_y_vox,camera_z_vox,nonempty_mesh_tiles,indexed_triangles,density_hash,mesh_hash
|
||||||
|
-1990830953,floating-islands,-39.199219,16.363281,-121.039062,12,23386,0xc04ef8acd44d8736,0x00e92c97d841dfe5
|
||||||
|
-1900684165,floating-islands,39.199219,17.675781,-116.339844,10,23186,0xfc7386c15431e2e1,0x46ce25dfb3745f53
|
||||||
|
-1766412538,floating-islands,-25.199219,-73.816406,-135.394531,12,23618,0xdb6557b98f29060e,0x3b3147a1d020ca02
|
||||||
|
-1721984596,floating-islands,64.398438,74.085938,-128.433594,10,23728,0xbb7777932cd3328a,0x5d7243f5afb8902a
|
||||||
|
-1239598758,floating-islands,39.199219,19.425781,-116.691406,12,28162,0x9ee03f2326224bbc,0x0ea03da61381b41a
|
||||||
|
-1085993262,floating-islands,-39.199219,16.968750,-116.531250,11,25186,0x8dec867557d4e27c,0x13de3a8f9465573d
|
||||||
|
-1033703345,floating-islands,-25.199219,-75.605469,-128.097656,10,17406,0x6edfcf6b89aee9cd,0xc7b92cd1b8a58590
|
||||||
|
-854671705,floating-islands,0.000000,-19.800781,-116.507812,13,39000,0xbb5718ca3ad4c181,0x3250d2591365d443
|
||||||
|
-713963806,floating-islands,64.398438,74.308594,-120.453125,8,16002,0xd590c16395cc515f,0x3a62d63b76bdd260
|
||||||
|
-621039221,floating-islands,0.000000,-18.796875,-116.769531,15,46224,0x8bf4ceae8c1ddbf6,0x61557967c37529fe
|
||||||
|
-474448608,floating-islands,-39.199219,20.921875,-121.671875,12,26122,0x2a634b2a3d2e38ef,0x52d2036bf1406614
|
||||||
|
-432690581,floating-islands,-39.199219,16.421875,-114.292969,7,20532,0xd8b65942bf1c005c,0xe6557b8cadfb3356
|
||||||
|
-380556572,floating-islands,39.199219,17.386719,-117.285156,10,25334,0x118f50002e1af1b1,0x57d82fed86d7545c
|
||||||
|
-238925630,floating-islands,-39.199219,16.394531,-123.812500,10,20680,0x36a07bf8d4383533,0x12f59de7f06e5270
|
||||||
|
-216679974,floating-islands,39.199219,20.230469,-108.953125,9,25284,0x79bb86763243b67e,0x7fd748d3021d506d
|
||||||
|
-133096164,floating-islands,-39.199219,16.050781,-118.000000,11,26248,0xad7be7cd6b0dbffc,0x06d2caf87f019f22
|
||||||
|
-112366806,floating-islands,39.199219,16.867188,-114.605469,9,21148,0xda065c33dc944d23,0x3c27d1ee8688fec9
|
||||||
|
0,floating-islands,-25.199219,-76.226562,-105.089844,9,20740,0x7fd1e3389642e6f6,0x577e52a5ba8d96be
|
||||||
|
5808593,floating-islands,39.199219,16.003906,-114.574219,10,21000,0xb96bffb27bc457e0,0x1f867a2add682123
|
||||||
|
28573228,floating-islands,0.000000,-18.683594,-116.187500,12,32456,0x25ed5f499f9bf7ab,0x1c8e67c20374b473
|
||||||
|
70955227,floating-islands,-39.199219,18.582031,-121.785156,12,17426,0xbe4b9c0ebadde344,0xa9a52cc49ade0f23
|
||||||
|
75274690,floating-islands,64.398438,72.199219,-121.019531,8,19760,0x045c98172a573800,0x86618a983d61425d
|
||||||
|
81375760,floating-islands,-39.199219,20.589844,-119.359375,12,24146,0x69b66261833e4676,0x75e6b0f427e7698a
|
||||||
|
146979566,floating-islands,39.199219,16.625000,-109.785156,9,22370,0x93d0d67042bb05d2,0xe7f4981f907e316e
|
||||||
|
244951180,floating-islands,0.000000,-18.179688,-116.664062,13,32272,0x0b22965681c5b482,0x582ef8c1d263bedb
|
||||||
|
245433414,floating-islands,0.000000,-17.574219,-116.296875,11,32838,0x2e75a175d1005e4e,0x8f45449d7125c041
|
||||||
|
277442974,floating-islands,39.199219,19.328125,-117.750000,13,28088,0x8cb55c56b1629d42,0xc6532d9d3b8a987d
|
||||||
|
297746112,floating-islands,39.199219,20.609375,-119.089844,15,29396,0x2425273f1a174c04,0x204be5cda8d98412
|
||||||
|
336768467,floating-islands,0.000000,-20.933594,-116.355469,12,33652,0xfa8249483c186760,0xc42acd7c93e1525c
|
||||||
|
512532080,floating-islands,0.000000,-20.355469,-116.640625,14,34900,0xb098abe6a38cfe3a,0x436a6541192ed00e
|
||||||
|
821120640,floating-islands,39.199219,18.121094,-108.417969,11,27034,0x3db9226404527944,0xb3328f1c88e96c70
|
||||||
|
853538490,floating-islands,64.398438,75.593750,-125.132812,12,21100,0x7e568fc03c907914,0x6a9fc36512216056
|
||||||
|
861026696,floating-islands,-39.199219,16.035156,-124.882812,12,20194,0xcb6792ec32335dc5,0x195efb6c80156e4a
|
||||||
|
1026251636,floating-islands,-25.199219,-74.664062,-109.117188,8,19958,0xe62d0a684fcd1398,0xca0e1740a58cafbd
|
||||||
|
1077415394,floating-islands,39.199219,20.472656,-109.757812,9,25992,0x76ffc67a9d410089,0x712f9bef468c36e1
|
||||||
|
1130999017,floating-islands,-39.199219,19.199219,-119.304688,14,25686,0x9fc0c1b33da03fc0,0xc0dafe8b2a4570f1
|
||||||
|
1156488597,floating-islands,-39.199219,16.464844,-121.550781,14,22928,0x080c04f591e988da,0x7d2e52b446efd9d1
|
||||||
|
1172304228,floating-islands,-39.199219,16.859375,-120.363281,12,25280,0xa4ceaef6289c2778,0xac854a5846adc6cb
|
||||||
|
1370340570,floating-islands,-39.199219,17.164062,-114.296875,8,20458,0xfe631978312f065a,0xc41cdcb438a98b86
|
||||||
|
1383925073,floating-islands,64.398438,76.132812,-101.687500,8,17340,0x20a6d43f24557065,0xace78f99c63a90bc
|
||||||
|
1401164998,floating-islands,-25.199219,-76.433594,-133.500000,12,25478,0xa22b8a0f16d1cb98,0x85e184e7768795d1
|
||||||
|
1558879574,floating-islands,0.000000,-15.878906,-116.753906,15,37078,0x675134538e8ca09b,0x2e32a5444b8be6d7
|
||||||
|
1753015542,floating-islands,-25.199219,-75.425781,-125.304688,13,23050,0xd628ec790fd17bd2,0x5602b3e7ed3f852a
|
||||||
|
1827697875,floating-islands,0.000000,-19.441406,-116.312500,11,34624,0x786671c16ae75f4f,0x2c0c94465b7da251
|
||||||
|
1909311298,floating-islands,-39.199219,18.164062,-122.738281,12,22040,0x7bdc9a6cccc15b70,0x14e5e1428a1a5543
|
||||||
|
2011898099,floating-islands,39.199219,18.968750,-106.898438,9,21292,0xb3ad433a09a0d127,0xdea39968a98e0861
|
||||||
|
2015768509,floating-islands,39.199219,20.148438,-111.468750,11,29426,0x92d4f0690eaa02fd,0x5cea2b8d8ae9a094
|
||||||
|
2070776516,floating-islands,39.199219,16.496094,-110.636719,8,15728,0x486603470bf1e852,0xaa6022efbc268013
|
||||||
|
-1990830953,surface-world,0.000000,-140.000000,-2021.785156,9,26366,0x125d085ff63ece8a,0x3f219420ffe76ceb
|
||||||
|
-1900684165,surface-world,0.000000,-140.000000,-2011.214844,10,27890,0xcc9819b02bd2f880,0x8cbe19f740d2b408
|
||||||
|
-1766412538,surface-world,0.000000,-140.000000,-2004.851562,9,27572,0x4d04ec633754c4ec,0xca8833dcfe9639d3
|
||||||
|
-1721984596,surface-world,0.000000,-140.000000,-2006.878906,9,27374,0x65b6ae0a3a1fdd35,0x117d40e403c960bc
|
||||||
|
-1239598758,surface-world,0.000000,-140.000000,-2001.816406,15,38978,0x8aaf7c7c610e550f,0xeaa948233176c456
|
||||||
|
-1085993262,surface-world,0.000000,-140.000000,-2018.355469,13,30779,0x6dd63983ab04ee63,0x606e6964e1b2bfa0
|
||||||
|
-1033703345,surface-world,0.000000,-140.000000,-1585.519531,16,50890,0xe2f8c4b421a9402a,0x730fd7c4692eaff3
|
||||||
|
-854671705,surface-world,0.000000,-140.000000,-2018.242188,10,26198,0x0a9e017447ffff3d,0x807299923966d5be
|
||||||
|
-713963806,surface-world,0.000000,-140.000000,-2018.582031,16,30292,0x0bdd79cefc1c4003,0x9807c528ec8ea0e6
|
||||||
|
-621039221,surface-world,0.000000,-140.000000,-2015.613281,17,30168,0xa27c25107de22a4d,0xde2ffe789eb7fb05
|
||||||
|
-474448608,surface-world,0.000000,-140.000000,-2020.160156,11,28424,0x0d40ad842a0123ea,0x273fb800c1246cac
|
||||||
|
-432690581,surface-world,0.000000,-140.000000,-1699.710938,16,44640,0x3a23c958501ee719,0x45e154a2ee8b0f36
|
||||||
|
-380556572,surface-world,0.000000,-140.000000,-2015.980469,15,27832,0x54c47dd125294a9d,0x6e95e2a4fb185b89
|
||||||
|
-238925630,surface-world,0.000000,-140.000000,-2021.289062,9,26908,0x01debb25b2642a4d,0xd316a4d6bbbdceee
|
||||||
|
-216679974,surface-world,0.000000,-140.000000,-2025.835938,9,26538,0x04339f7c537f8920,0xb6d8dab4a5cd82ca
|
||||||
|
-133096164,surface-world,0.000000,-140.000000,-2023.140625,9,26182,0x1dadb5c6440181c0,0x4681d673371781ba
|
||||||
|
-112366806,surface-world,0.000000,-140.000000,-1699.476562,16,46567,0x7aafaa55fce58f77,0x84c7d73393ccdb09
|
||||||
|
0,surface-world,0.000000,-140.000000,-2003.089844,9,27910,0x2339a02328c5ffa6,0x83d31e15bf9161b0
|
||||||
|
5808593,surface-world,0.000000,-140.000000,-2014.406250,14,29050,0x355972d90ab29593,0x563daf944391ab7c
|
||||||
|
28573228,surface-world,0.000000,-140.000000,-2016.695312,13,27054,0x57cb2fe09976dc54,0x35ac4f38b432e8b7
|
||||||
|
70955227,surface-world,0.000000,-140.000000,-2047.484375,13,29926,0xb205ad43941e41d8,0x722e775c7e0735bc
|
||||||
|
75274690,surface-world,0.000000,-140.000000,-2019.648438,15,28342,0x84af4380d33164a6,0xa18d6de0f9267e9f
|
||||||
|
81375760,surface-world,0.000000,-140.000000,-1894.296875,18,48305,0x20c34733457b090d,0x9a6b57b63637db1f
|
||||||
|
146979566,surface-world,0.000000,-140.000000,-2014.601562,14,31096,0x2d27daeb8c1c8b7c,0x2218ed732f71ca53
|
||||||
|
244951180,surface-world,0.000000,-140.000000,-1798.816406,18,52468,0xfb0ba5f3b28b306d,0x2d5f650a41b8b2bd
|
||||||
|
245433414,surface-world,0.000000,-140.000000,-2022.468750,14,32860,0xcc51a567f61f812d,0xc59dc3105dd493b2
|
||||||
|
277442974,surface-world,0.000000,-140.000000,-2004.875000,9,27060,0x8bfa82ca5e492c37,0x1630487dbcc54469
|
||||||
|
297746112,surface-world,0.000000,-140.000000,-2010.195312,13,38252,0x00c869b6875b7ef5,0x085684513feca8f2
|
||||||
|
336768467,surface-world,0.000000,-140.000000,-2014.343750,15,29748,0x2756e6dc388ddf57,0x66344082236c5630
|
||||||
|
512532080,surface-world,0.000000,-140.000000,-2011.875000,14,28800,0xa5ad29a27d991d10,0x060bc1fca8569368
|
||||||
|
821120640,surface-world,0.000000,-140.000000,-2017.054688,17,29100,0xb6424f19c272b61c,0xe4f7308d87cb3bc2
|
||||||
|
853538490,surface-world,0.000000,-140.000000,-2000.957031,13,41529,0xbe1224f297dc7ad0,0x7e10918947195940
|
||||||
|
861026696,surface-world,0.000000,-140.000000,-2015.378906,14,29214,0xb04a05c6e8c488dc,0x28706d092bd82c9a
|
||||||
|
1026251636,surface-world,0.000000,-140.000000,-2001.500000,9,28584,0xf6bb5ab0a9e2307d,0x4767f425e56543f4
|
||||||
|
1077415394,surface-world,0.000000,-140.000000,-2018.636719,12,27666,0xb65f4acca21a93d8,0x0a3cddad02604438
|
||||||
|
1130999017,surface-world,0.000000,-140.000000,-1885.390625,15,38852,0xd4fee006d89064ec,0xc2e722815c510b8d
|
||||||
|
1156488597,surface-world,0.000000,-140.000000,-2012.031250,10,26660,0xf918cd1d254bf5ad,0x93e291c7e8ab3281
|
||||||
|
1172304228,surface-world,0.000000,-140.000000,-2030.214844,9,28078,0x466d74beb6a3c43f,0x935c08e020dbe116
|
||||||
|
1370340570,surface-world,0.000000,-140.000000,-2026.738281,9,26888,0xb71aa861999e9064,0x5e6eb187fe7aa3d1
|
||||||
|
1383925073,surface-world,0.000000,-140.000000,-2018.113281,13,27826,0x564bb6a29953fc31,0x891c57b01dc509f8
|
||||||
|
1401164998,surface-world,0.000000,-140.000000,-1923.625000,14,33671,0x539b7c44ed2d40c4,0x2daa8cf5e08fb16e
|
||||||
|
1558879574,surface-world,0.000000,-140.000000,-2026.257812,12,30022,0x566bd8e41e9ce9de,0xd7344edfeac99334
|
||||||
|
1753015542,surface-world,0.000000,-140.000000,-2004.562500,9,27536,0x3557e0f7c1298c35,0x833da36dd2c02e13
|
||||||
|
1827697875,surface-world,0.000000,-140.000000,-2018.507812,12,29182,0xd945dc9d11f16156,0x59cd0f8103174807
|
||||||
|
1909311298,surface-world,0.000000,-140.000000,-2007.000000,13,28862,0x79cb6cf093ee2d27,0xa818f8c1904f73b0
|
||||||
|
2011898099,surface-world,0.000000,-140.000000,-2005.066406,9,28654,0x95f389e603d74998,0xff02d8e0b112c865
|
||||||
|
2015768509,surface-world,0.000000,-140.000000,-1918.304688,18,51706,0x9506739f358ba5c5,0xaba43fe9407d51fb
|
||||||
|
2070776516,surface-world,0.000000,-140.000000,-2010.421875,10,26952,0x28df1e26bab2140f,0x4af65af7af7045c3
|
||||||
|
@@ -0,0 +1 @@
|
|||||||
|
runs=576 seeds=48 recipes=2 builds=3 workers=1,12 cross_build_checks=192 cross_build_mismatches=0 worker_checks=288 worker_mismatches=0 empty_mesh_rows=0 max_peak_rss_kib=306580 elapsed_s=432.977
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
# WorldAssemblerM3 Linux4 — lazy worker caches
|
||||||
|
|
||||||
|
## Change
|
||||||
|
|
||||||
|
Added `VoxelForgeCoreThreadLocal::FLazy<T>`: each cache now has a thread-local pointer, allocates its private table on first use, and deletes it when that thread exits. The same helper is used by the namespaced Core and legacy source copies. No cache locks or cross-thread cache sharing were added. The L3 FP-contract preamble and self-test are unchanged.
|
||||||
|
|
||||||
|
The change covers the heightfield and island caches in Core, plus the large surface, relief, room-graph, tunnel-density, and diff caches in the shared generator sources. Tunnel-density lookup is now restricted to its `TunnelNetwork` and `Underwater` routes, which are the only routes that populate that table. The standalone TLS probe reports spawn time, RSS and per-thread minor faults, and can touch synthetic SurfaceWorld or FloatingIslands samples. Worker stacks are now 8 MiB.
|
||||||
|
|
||||||
|
## Where the baseline TLS came from
|
||||||
|
|
||||||
|
Sizes are from the S14 / `046f2af` Clang binary's TLS symbols. The two raw and namespaced source copies are both linked into the standalone executable; both occupy TLS even though a Core call uses the namespaced copy and the legacy/reference route uses the raw copy. The raw legacy cache is not used by the Core API route. `Standalone/Core/core_sources.txt` describes this dual build.
|
||||||
|
|
||||||
|
| Cache | Section | Bytes per copy | Copies | Total bytes | Route / use |
|
||||||
|
|---|---:|---:|---:|---:|---|
|
||||||
|
| `HeightfieldColumnCache` | `.tbss` | 6,815,744 | 1 | 6,815,744 | Core SurfaceWorld height samples; S14 hot path, any LOD that queries the heightfield |
|
||||||
|
| `GFloorReliefCache` | `.tdata` | 1,310,720 | 2 | 2,621,440 | Cave room/tunnel/landing floor-relief queries |
|
||||||
|
| `GRoomGraphCache` | `.tdata` | 970,752 | 2 | 1,941,504 | Room-graph SDF windows; fine/coarse region banks |
|
||||||
|
| `GSurfColCache` | `.tbss` | 827,000 | 2 | 1,654,000 | `ClassifyTile` surface-column pass; classifier is opt-in in runtime streaming |
|
||||||
|
| `FSurfaceColumnSource` column table | `.tbss` | 826,856 | 2 | 1,653,712 | Surface operator-stack integer XY columns |
|
||||||
|
| `PassageReliefCache` | `.tdata` | 655,360 | 2 | 1,310,720 | Passage-relief samples when that feature is queried |
|
||||||
|
| `IslandColumnCache` | `.tbss` | 1,114,112 | 1 | 1,114,112 | Core FloatingIslands column density, all LOD sample paths |
|
||||||
|
| `CP_TunnelDensityCache` | `.tbss` | 401,408 | 2 | 802,816 | Native TunnelNetwork/Underwater density chunks |
|
||||||
|
| `RootLobeCache` | `.tdata` | 155,648 | 1 | 155,648 | Core FloatingIslands root density |
|
||||||
|
| `HeightfieldColumnCacheNextWay` | `.tbss` | 16,384 | 1 | 16,384 | Heightfield cache replacement metadata |
|
||||||
|
| `DiffSlots` | `.tdata` | 10,752 | 2 | 21,504 | Only when a sampled chunk has player modifications |
|
||||||
|
| `RoomGraphCacheSlots` | `.tdata` | 10,240 | 2 | 20,480 | Room-graph generator route |
|
||||||
|
|
||||||
|
The listed `.tdata` cache symbols total 6,071,296 bytes of the 6,093,024-byte image; the remaining 21,728 bytes are small TLS state. Their nonzero defaults explain the initialized image: for example, room-graph keys start at `INT32_MIN` / `0xFFFFFFFF`, passage and floor-relief keys use `INDEX_NONE`, diff slots use `INT32_MAX` chunk coordinates, and root-lobe radii default to `1.0`. Zero-default large arrays such as the heightfield and island column tables account for the listed `.tbss` bytes. The listed `.tbss` symbols total 12,056,768 bytes; 21,997 bytes remain for small TLS state and alignment.
|
||||||
|
|
||||||
|
The caches have no universal per-LOD allocation: a thread allocates a table only if it reaches that route. Heightfield and island tables are keyed by recipe/plan or island identity and sampled coordinates; surface columns can be reused by repeated XY queries. Room-graph and classifier paths carry region/tile data in their keys, so coarse and fine requests can occupy distinct entries. Relief, tunnel and diff caches are likewise conditional on those features or modified chunks. All preserve the existing thread-local ownership and eviction behavior.
|
||||||
|
|
||||||
|
## TLS and per-thread cost
|
||||||
|
|
||||||
|
`PT_TLS` was read with `readelf -lW`. The baseline is the committed `046f2af` build; the after builds use this tree.
|
||||||
|
|
||||||
|
| Build | `PT_TLS` FileSiz (initialized) | `PT_TLS` MemSiz (per-thread block) |
|
||||||
|
|---|---:|---:|
|
||||||
|
| Clang 19 before | 6,093,024 B (5.81 MiB) | 18,171,789 B (17.33 MiB) |
|
||||||
|
| Clang 19 after | 21,728 B (21.2 KiB) | 43,977 B (42.95 KiB) |
|
||||||
|
| GCC 14 before | 6,060,396 B (5.78 MiB) | 18,172,504 B (17.33 MiB) |
|
||||||
|
| GCC 14 after | 9,580 B (9.36 KiB) | 44,696 B (43.65 KiB) |
|
||||||
|
|
||||||
|
Serial 12-worker no-touch, SurfaceWorld, and FloatingIslands probes compared baseline and L4. Spawn timing and resident delta use 32 MiB stacks on both sides to isolate TLS cost; the separately tested L4 tool uses 8 MiB stacks. Spawn medians/ranges use the per-worker samples; first-touch fault medians/ranges use each worker's `getrusage(RUSAGE_THREAD)` delta.
|
||||||
|
|
||||||
|
| Measurement | Before | After |
|
||||||
|
|---|---:|---:|
|
||||||
|
| Median time to start one worker | 5.175 ms | 0.119 ms |
|
||||||
|
| Median RSS added per new worker, no cache query | 17,756 KiB | 52 KiB |
|
||||||
|
| 12-worker no-touch probe peak RSS | 268,168 KiB | 32,328 KiB |
|
||||||
|
| First SurfaceWorld use: RSS increase per worker | 20 KiB | 6,691 KiB |
|
||||||
|
| First SurfaceWorld use: minor faults per worker | median 1 (range 1–4) | median 331 (range 8–649) |
|
||||||
|
| First FloatingIslands use: RSS increase per worker | 27–30 KiB | 1,283 KiB |
|
||||||
|
| First FloatingIslands use: minor faults per worker | median 0 (range 0–7) | median 314 (range 313–319) |
|
||||||
|
|
||||||
|
The baseline's first-use deltas are small because its large static TLS cost was already incurred at worker creation. After L4, a SurfaceWorld first use adds about 6.54 MiB per worker, while a FloatingIslands first use adds about 1.25 MiB. The no-touch worker increase is about 99.7% lower. These first-use probes call Core directly with four synthetic samples per worker; the full-view benchmark below measures the hot generation path.
|
||||||
|
|
||||||
|
The baseline binary's first `pthread_create` with an 8 MiB worker stack fails with `pthread_create: Invalid argument`; the 17.33 MiB static TLS block cannot fit that stack configuration. Baseline probes succeeded with 32 MiB stacks. L4 passed the 8 MiB worker-stack probe and the L1 checks, so the 32 MiB wrapper is no longer needed. Keep the normal 8 MiB worker stack; these runs provide no reason to retain 32 MiB as a safety margin.
|
||||||
|
|
||||||
|
## Generation speed and output
|
||||||
|
|
||||||
|
Three interleaved W12 whole-view runs per binary used the 2,553-tile L1 view. `Before` is the exact `046f2af` Clang-off executable.
|
||||||
|
|
||||||
|
| Build | Whole-view times | Median (range) |
|
||||||
|
|---|---|---:|
|
||||||
|
| `046f2af` baseline | 2.347, 2.399, 2.432 s | 2.399 s (2.347–2.432) |
|
||||||
|
| L4 Clang 19 off | 2.139, 2.197, 2.207 s | 2.197 s (2.139–2.207) |
|
||||||
|
|
||||||
|
L4 is 0.202 s (8.4%) faster at the median; no generation-speed regression was measured. The speed runs also changed the worker stack from 32 to 8 MiB, so the timing difference is not attributed solely to the cache indirection. Peak process RSS was 550,856 KiB before and 410,052 KiB after.
|
||||||
|
|
||||||
|
The L1 hashes match at W1 and W12 for both requested compiler settings:
|
||||||
|
|
||||||
|
| Build | Density / mesh / payload / topology |
|
||||||
|
|---|---|
|
||||||
|
| Clang 19 off, W1 and W12 | `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724` |
|
||||||
|
| GCC 14 default, W1 and W12 | same |
|
||||||
|
|
||||||
|
FloatingIslands seed 0 also matches at W1 and W12: `7fd1e3389642e6f6 / 577e52a5ba8d96be / 7c6ffe9f5bbbb450 / b4d308de116f4657` (density / mesh / payload / topology). It covers 27 tiles, with 9 nonempty mesh tiles and 20,740 indexed triangles; the existing L3 seed-0 hashes match.
|
||||||
|
|
||||||
|
## Unreal Linux TLS: documented and inferred
|
||||||
|
|
||||||
|
**Documented by glibc:** Its dynamic-linker guidance describes the `dlopen`/TLS compatibility issue and recommends global-dynamic TLS for general shared-object use. In glibc's current `dl-tls.c`, DTV slots for dynamically loaded TLS modules are marked for deferred allocation; `tls_get_addr_tail` performs the allocation when that thread first resolves the TLS address. The new-thread path calls `_dl_allocate_tls_init`, which also records deferred allocation for dynamically loaded modules. Thus, for the dynamic path, the large module block is allocated on first access, per thread that touches the module; a thread that never accesses it does not get that module's payload block. [glibc dynamic-linker guidance](https://www.sourceware.org/glibc/manual/latest/html_node/Dynamic-Linker-Hardening.html), [glibc TLS implementation](https://codebrowser.dev/glibc/glibc/elf/dl-tls.c.html#L599), [glibc thread creation path](https://codebrowser.dev/glibc/glibc/nptl/allocatestack.c.html#L141).
|
||||||
|
|
||||||
|
**Inference for Unreal:** This machine did not build or inspect the owner's UE `.so`, so the Core module's TLS model and load timing are unverified. GCC documents global-dynamic as the default model with `-fPIC`, but compiler/linker relaxation and UBT's exact flags can change the emitted access sequence. If Unreal loads Core after engine threads exist and the module uses general-dynamic TLS, any engine thread that first accesses a Core TLS symbol can incur the module's whole static TLS block once; it is not limited to generation workers. The L4 pointer handles reduce that block to about 43 KiB, with each large cache allocated only when its own route runs. Verify the actual `.so` `PT_TLS`, TLS relocations, and UBT compile commands on the owner's Linux build; `LD_DEBUG=tls` can show loader TLS activity. [GCC TLS model options](https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options).
|
||||||
|
|
||||||
|
## Windows/MSVC to-do
|
||||||
|
|
||||||
|
1. Build the updated standalone: `powershell -ExecutionPolicy Bypass -File Standalone\Build.ps1 -Target All -CompileWorkers 12`. Confirm the Core response file still carries `/fp:precise` and the shared header is included.
|
||||||
|
2. Run the L1 view at W1 and W12 with `--world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0`. Require the four L1 hashes above and no self-test error.
|
||||||
|
3. Run the seed-0 FloatingIslands check at W1 and W12 with mesh coverage enabled; require matching density/mesh/payload/topology hashes and nonempty mesh coverage.
|
||||||
|
4. Build the owner's UE 5.7 Windows target with the plugin, inspect the actual `cl.exe` options, and exercise worker creation/use/shutdown. MSVC-specific risks are `/fp:precise` versus any `/fp:fast` or `/fp:contract` override, `thread_local` destructor handling on engine task threads, and allocator/container construction and destruction when a thread first touches or exits a cache. Linux ELF sizes do not predict Windows TLS costs.
|
||||||
|
|
||||||
|
## Machine and run record
|
||||||
|
|
||||||
|
Builds and benchmarks used CPUs 0–11, at most 12 build jobs, a 6 GiB address-space limit, and normal priority. Governor remained `powersave`; EPP remained `balance_performance`. Clang build: 29.06 s, peak RSS 431,732 KiB. GCC build: 46.14 s, peak RSS 896,076 KiB. Largest benchmark RSS was 550,856 KiB. Logs are in `Saved/Linux/linux4-*.log`; artifacts are under `Standalone/Build/linux-*` and `Standalone/bin/linux/`.
|
||||||
|
|
||||||
|
Failed or retried runs:
|
||||||
|
|
||||||
|
- The first baseline probes with an 8 MiB worker stack failed for `none`, `surface-world`, and `floating-islands` (`pthread_create: Invalid argument`, exit `-6`, three attempts each). They were rerun serially at 32 MiB and passed. L4 passed all three probes at 8 MiB.
|
||||||
|
- An early before/after probe batch ran the six probe types concurrently, so its timings and RSS were discarded. Each type was rerun serially; the final before/after comparison uses those serial logs. The discarded logs are retained with `linux4-discarded-parallel-` names.
|
||||||
|
- No build or world/hash run failed. Both Clang and GCC final builds succeeded.
|
||||||
|
|
||||||
|
## Note for the owner
|
||||||
|
|
||||||
|
The shared cache change reduces standalone static TLS from 17.33 MiB to about 43 KiB and preserves the L1 and FloatingIslands hashes; the W12 median moved from 2.399 s to 2.197 s. Please run the listed standalone and Unreal checks on Windows/MSVC before merging, especially worker-thread TLS destruction and the actual UBT FP/TLS options.
|
||||||
|
|
||||||
|
## Orchestrator review (Claude)
|
||||||
|
|
||||||
|
- Re-run by me: interleaved W12, L1 view: `046f2af` (L3) 2.212/2.256/2.307 s vs L4 2.063/2.091/2.125 s
|
||||||
|
(medians 2.256 → 2.091 s, -7%). Density `c10697a8f48380c7` throughout. L4 `PT_TLS` MemSiz 0xabc9 = 43,977 B.
|
||||||
|
- Checked the tunnel-cache route gate in `VoxelGenerator.cpp`: entries are only *stored* when `CP_GenType`
|
||||||
|
is TunnelNetwork/Underwater, so for any other route the old lookup could only miss. Gating skips
|
||||||
|
guaranteed misses, so no output change is possible. The legacy cave route is not exercised by the
|
||||||
|
headless tool, so this rests on code reading, not a hash.
|
||||||
|
- Windows: `thread_local` destructors on UE task threads are the MSVC risk. Luna's to-do list covers it.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#include "StandaloneTlsProbe.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
int main(int argc,char** argv)
|
||||||
|
{
|
||||||
|
const int workers=argc>1?std::atoi(argv[1]):12;
|
||||||
|
const std::string_view touch=argc>2?argv[2]:"none";
|
||||||
|
return StandaloneTlsProbe::Run(workers,touch);
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
if len(sys.argv) < 4 or sys.argv[2] != "--":
|
||||||
|
raise SystemExit("usage: MeasureProcess.py LOG -- COMMAND [ARGS...]")
|
||||||
|
|
||||||
|
log_path = sys.argv[1]
|
||||||
|
command = sys.argv[3:]
|
||||||
|
os.makedirs(os.path.dirname(log_path) or ".", exist_ok=True)
|
||||||
|
start = time.monotonic()
|
||||||
|
with open(log_path, "wb") as log_file:
|
||||||
|
process = subprocess.Popen(command, stdout=log_file, stderr=subprocess.STDOUT,
|
||||||
|
start_new_session=True)
|
||||||
|
max_hwm_kib = 0
|
||||||
|
max_rss_kib = 0
|
||||||
|
max_pid = process.pid
|
||||||
|
max_name = ""
|
||||||
|
deadline = start + 1800.0
|
||||||
|
while process.poll() is None:
|
||||||
|
if time.monotonic() >= deadline:
|
||||||
|
os.killpg(process.pid, signal.SIGTERM)
|
||||||
|
try:
|
||||||
|
process.wait(timeout=10)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
os.killpg(process.pid, signal.SIGKILL)
|
||||||
|
process.wait()
|
||||||
|
print("MONITOR_TIMEOUT_SECONDS=1800", file=log_file, flush=True)
|
||||||
|
break
|
||||||
|
stat_by_pid = {}
|
||||||
|
for entry in os.scandir("/proc"):
|
||||||
|
if not entry.name.isdigit():
|
||||||
|
continue
|
||||||
|
pid = int(entry.name)
|
||||||
|
try:
|
||||||
|
with open(f"/proc/{pid}/stat", "r", encoding="ascii") as stat_file:
|
||||||
|
fields = stat_file.read().rsplit(")", 1)[1].split()
|
||||||
|
ppid = int(fields[1])
|
||||||
|
stat_by_pid[pid] = ppid
|
||||||
|
except (OSError, ValueError, IndexError):
|
||||||
|
continue
|
||||||
|
descendants = {process.pid}
|
||||||
|
changed = True
|
||||||
|
while changed:
|
||||||
|
changed = False
|
||||||
|
for pid, ppid in stat_by_pid.items():
|
||||||
|
if ppid in descendants and pid not in descendants:
|
||||||
|
descendants.add(pid)
|
||||||
|
changed = True
|
||||||
|
for pid in descendants:
|
||||||
|
try:
|
||||||
|
with open(f"/proc/{pid}/status", "r", encoding="ascii") as status_file:
|
||||||
|
status = status_file.read().splitlines()
|
||||||
|
values = {line.split(":", 1)[0]: line.split(":", 1)[1].strip()
|
||||||
|
for line in status if ":" in line}
|
||||||
|
hwm = int(values.get("VmHWM", "0 kB").split()[0])
|
||||||
|
rss = int(values.get("VmRSS", "0 kB").split()[0])
|
||||||
|
name = values.get("Name", "")
|
||||||
|
except (OSError, ValueError, IndexError):
|
||||||
|
continue
|
||||||
|
if hwm > max_hwm_kib:
|
||||||
|
max_hwm_kib, max_pid, max_name = hwm, pid, name
|
||||||
|
max_rss_kib = max(max_rss_kib, rss)
|
||||||
|
time.sleep(0.05)
|
||||||
|
result = process.wait()
|
||||||
|
elapsed = time.monotonic() - start
|
||||||
|
for line in (
|
||||||
|
f"MONITOR_EXIT_CODE={result}",
|
||||||
|
f"MONITOR_WALL_SECONDS={elapsed:.3f}",
|
||||||
|
f"MONITOR_PEAK_PROCESS_HWM_KIB={max_hwm_kib}",
|
||||||
|
f"MONITOR_PEAK_PROCESS_PID={max_pid}",
|
||||||
|
f"MONITOR_PEAK_PROCESS_NAME={max_name}",
|
||||||
|
f"MONITOR_MAX_SAMPLED_PROCESS_RSS_KIB={max_rss_kib}",
|
||||||
|
):
|
||||||
|
log_file.write((line + "\n").encode("utf-8"))
|
||||||
|
raise SystemExit(result)
|
||||||
|
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
# World Assembler M3 — Linux L5
|
||||||
|
|
||||||
|
**Result:** no octave tail is safely removable under the declared bounds. The exact far meshes already exceed the 1 px field-error and LOD-swap budgets, and the cutoff flag is 2.2% slower in the W12 view. The candidate therefore generated the exact same meshes; recipe version stays 1.
|
||||||
|
|
||||||
|
## Build and machine
|
||||||
|
|
||||||
|
Built `VoxelForgeCoreHeadless-linux5-l5-final7` and its capture target on `assembler/world` at `7770074` with Clang 19 `-ffp-contract=off`, then GCC 14 default contraction, both with 12 jobs. W1/W12 hashes match across both compilers; the L3 FP-contract preamble and runtime self-test remain active. Runs used CPUs 0–11, normal priority, and the 6 GiB process limit. Maximum process HWM was 898,692 KiB (GCC compile); the largest runtime process was 454,828 KiB. CPU governor stayed `powersave`. `/dev/dri/renderD128` was absent, so EGL used Mesa llvmpipe with `LP_NUM_THREADS=12`. No packages or system settings were changed.
|
||||||
|
|
||||||
|
## Capture and gate
|
||||||
|
|
||||||
|
`LinuxOffscreenCapture.cpp` reads the `.vfmesh` export from the headless streaming pipeline, creates a surfaceless EGL/GLES3 pbuffer, and writes 2560×1440 PNGs with libpng. `ffmpeg` made 1280×720 review JPEGs; the largest is 73,923 bytes. The shader combines surface normals and 80 m height bands. Only the small JPEGs were opened for review.
|
||||||
|
|
||||||
|
The gate samples a 65×65 XY grid on the closest native-surface tile at each LOD, excluding skirts. It reports two comparisons: displayed mesh against exact `Heightfield2D` ground/cap roots, and against a regenerated exact same-LOD mesh. The second is the zero-delta regression control; the first measures the actual field error. Swap error compares the coarse tile with its fine children at those same field roots. Full missing-surface, 2 m floating-surface, and missing fine-ring injections were rejected at every LOD3–8; so were both S13 controls.
|
||||||
|
|
||||||
|
This is a sampled heightfield gate, not a full camera-ray rasterizer. It can miss cracks narrower than one grid cell (1 m at LOD3, growing to 32 m at LOD8), and its direct-field row does not model tunnel walls or other non-heightfield faces. The same-LOD mesh comparison covers extra and missing mesh intersections at sampled points; a denser or full-screen geometry pass would be needed to certify sub-cell cracks and non-heightfield surfaces.
|
||||||
|
|
||||||
|
## Closest display distances and budgets
|
||||||
|
|
||||||
|
The code sweeps clipmap desired sets across X-boundary phases and measures tile AABB distance. The result matches the clipmap ring formula `3 × 32 chunks × 2^(LOD−1) × 0.25 m`; LOD0 is the player tile. The pixel angle is `90° / 2560 = 0.000613592 rad`.
|
||||||
|
|
||||||
|
| LOD | Closest display distance | 1 px at that distance | Active rule |
|
||||||
|
|---:|---:|---:|---:|
|
||||||
|
| 0 | 0 m | 0 cm | exact, 2 cm |
|
||||||
|
| 1 | 24.001 m | 1.473 cm | exact, 2 cm |
|
||||||
|
| 2 | 48.001 m | 2.945 cm | exact, 2 cm |
|
||||||
|
| 3 | 96.001 m | 5.891 cm | 1 px |
|
||||||
|
| 4 | 192.001 m | 11.781 cm | 1 px |
|
||||||
|
| 5 | 384.001 m | 23.562 cm | 1 px |
|
||||||
|
| 6 | 768.001 m | 47.124 cm | 1 px |
|
||||||
|
| 7 | 1,536.001 m | 94.248 cm | 1 px |
|
||||||
|
| 8 | 3,072.001 m | 188.496 cm | 1 px |
|
||||||
|
|
||||||
|
## Exact-field error and swap pop
|
||||||
|
|
||||||
|
Baseline and cutoff values are identical. The exact same-LOD regression control is 0.0000 px p50/p99/max at all LOD3–8, with no missing or floating samples. Against the continuous `Heightfield2D` roots, however, the current exact meshes already exceed 1 px at every LOD. The owner’s expected near-zero control holds for exact-versus-exact mesh output, not for the true-field comparison.
|
||||||
|
|
||||||
|
| LOD | Exact field p50 / p99 / max px (baseline → cutoff) | Swap p50 / p99 / max px | Swap cracks / floating |
|
||||||
|
|---:|---:|---:|---:|
|
||||||
|
| 3 → 2 | 0.9035 / 4.5839 / 7.3277 → same | 0.6714 / 4.1861 / 7.3277 | 0 / 0 |
|
||||||
|
| 4 → 3 | 1.1170 / 5.6056 / 8.3307 → same | 0.8269 / 5.1958 / 8.2105 | 0 / 0 |
|
||||||
|
| 5 → 4 | 1.5667 / 45.3010 / 126.2667 → same | 0.0000 / 20.7227 / 63.2266 | 0 / 0 |
|
||||||
|
| 6 → 5 | 0.5870 / 21.2445 / 82.3615 → same | 0.0000 / 21.2445 / 82.3615 | 0 / 0 |
|
||||||
|
| 7 → 6 | 0.3393 / 16.4341 / 47.9760 → same | 0.0000 / 16.4341 / 47.9760 | 0 / 0 |
|
||||||
|
| 8 → 7 | 0.9616 / 24.9479 / 50.0934 → same | 0.9616 / 24.9479 / 50.0934 | 0 / 0 |
|
||||||
|
|
||||||
|
The baseline gate rejects on the field row and every swap row. The cutoff run returns the same rejection. Fault injections also rejected: missing-surface samples were 4,225–13,642; floating-surface samples 4,225–13,641; missing fine-ring cracks 4,225–8,450.
|
||||||
|
|
||||||
|
| LOD | S13 octave-drop p99 / max px | Stride-2 column interpolation p99 / max px |
|
||||||
|
|---:|---:|---:|
|
||||||
|
| 3 | 960.2333 / 998.8654 | 9.3917 / 13.9093 |
|
||||||
|
| 4 | 3.7405 / 5.1103 | 9.2115 / 15.3435 |
|
||||||
|
| 5 | 105.7114 / 129.3089 | 125.1435 / 191.6424 |
|
||||||
|
| 6 | 218.7777 / 749.9535 | 82.1098 / 148.9485 |
|
||||||
|
| 7 | 95.1867 / 129.1796 | 40.6881 / 80.6012 |
|
||||||
|
| 8 | 38.1461 / 282.3288 | 28.8473 / 278.6236 |
|
||||||
|
|
||||||
|
Both controls were rejected at every LOD3–8. The octave-drop case produced missing samples at LOD3, 5–8 and floating samples at LOD5–8; stride-2 interpolation produced missing/floating samples at LOD5, 7 and 8.
|
||||||
|
|
||||||
|
## Cutoff contract and detail cost
|
||||||
|
|
||||||
|
The version-2 shared visual-detail contract declares stable octave terms with wavelength, octave count, displacement bound, and noise bound. A suffix is eligible only when its wavelengths are undersampled and its full displacement bound fits within one sixty-fourth of the tile’s pixel budget. Skipped zero-mean terms retain the original normalization denominator. Recipes with no terms keep the exact path; `FloatingIslandFieldV1` declares none, and its baseline/cutoff LOD hashes match. This is separate from content recipe version 1, which stays unchanged because output did not change.
|
||||||
|
|
||||||
|
SurfaceWorld declares 17 terms per LOD. No term or octave tail qualifies at LOD3–8. Sample steps are 16, 32, 64, 128, 256, and 512 voxels respectively. The bounds explain the result: even the smallest declared maximum displacement is 256 voxels, against a 0.2356-voxel 1 px budget at LOD3. The cutoff skips zero octaves, so eligible octave time is 0 ms.
|
||||||
|
|
||||||
|
| Octave | Terms | Wavelength range (voxels) | Max displacement range (voxels) |
|
||||||
|
|---:|---:|---:|---:|
|
||||||
|
| 0 | 17 | 25–10,000 | 1,024–640,000 |
|
||||||
|
| 1 | 17 | 12.5–5,000 | 512–320,000 |
|
||||||
|
| 2 | 15 | 6.25–1,250 | 256–160,000 |
|
||||||
|
| 3 | 4 | 41.664–250 | 3,968–24,800 |
|
||||||
|
|
||||||
|
W12 profile from the exact baseline; octave milliseconds are summed across evaluated calls/workers. They are all measured detail work, not removable work under the bound above.
|
||||||
|
|
||||||
|
| LOD | Worker sum s | Octave 0 ms | Octave 1 ms | Octave 2 ms | Octave 3 ms | Detail total ms (% worker sum) | Eligible ms |
|
||||||
|
|---:|---:|---:|---:|---:|---:|---:|---:|
|
||||||
|
| 3 | 1.660 | 71.585 | 69.911 | 68.535 | 15.407 | 225.437 (13.58%) | 0 |
|
||||||
|
| 4 | 3.321 | 135.512 | 131.224 | 128.645 | 26.506 | 421.887 (12.70%) | 0 |
|
||||||
|
| 5 | 2.283 | 82.131 | 80.450 | 77.545 | 16.262 | 256.388 (11.23%) | 0 |
|
||||||
|
| 6 | 3.587 | 153.409 | 148.854 | 144.175 | 29.984 | 476.422 (13.28%) | 0 |
|
||||||
|
| 7 | 1.447 | 35.301 | 34.493 | 33.138 | 7.069 | 110.001 (7.60%) | 0 |
|
||||||
|
| 8 | 2.685 | 58.763 | 57.751 | 56.277 | 11.848 | 184.638 (6.88%) | 0 |
|
||||||
|
|
||||||
|
The cutoff is recipe-generic, display-mesh-only, and activated only for LOD3+. Exact density, detail, collision, edit, and walkability paths remain outside it. LOD0–2 keep the 2 cm path. ARCHITECTURE §8.10 invariants remain: lazy thread-local caches, two-pass MC, SSE noise, and clipmap streaming. The cutoff state is scoped to mesh generation under the async-safety rules.
|
||||||
|
|
||||||
|
## W12 speed, interleaved with L4
|
||||||
|
|
||||||
|
Three L4/candidate pairs, all W12, measured on the L1 camera. The candidate is the final build with `--visual-detail-cutoff`.
|
||||||
|
|
||||||
|
| Measure (median) | L4 binary | Candidate | Change |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| Whole-view ready | 2.183 s | 2.232 s | +2.2% |
|
||||||
|
| Stream wall | 1.895 s | 1.963 s | +3.6% |
|
||||||
|
| Far worker sum, LOD3–8 | 12.247 s | 12.458 s | +1.7% |
|
||||||
|
|
||||||
|
| LOD | L4 worker sum s | Candidate worker sum s |
|
||||||
|
|---:|---:|---:|
|
||||||
|
| 0 | 3.799 | 4.094 |
|
||||||
|
| 1 | 5.304 | 5.573 |
|
||||||
|
| 2 | 1.281 | 1.340 |
|
||||||
|
| 3 | 1.102 | 1.138 |
|
||||||
|
| 4 | 2.723 | 2.719 |
|
||||||
|
| 5 | 1.898 | 1.976 |
|
||||||
|
| 6 | 2.875 | 2.944 |
|
||||||
|
| 7 | 1.243 | 1.282 |
|
||||||
|
| 8 | 2.355 | 2.400 |
|
||||||
|
|
||||||
|
There is no speed benefit because nothing qualifies for skipping; the small regression is cutoff setup and bookkeeping.
|
||||||
|
|
||||||
|
## Hashes and captures
|
||||||
|
|
||||||
|
Baseline and cutoff hashes match for all LOD0–8. The old L4 binary’s aggregate hashes also match: whole view `c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724` and full detail `0ee0579bd15cbbe4 / 32e5d4964d610fee / 1932b96ee4b1d910 / 69743c6bad3447dc`. The recipe stays version 1 because output did not change.
|
||||||
|
|
||||||
|
| LOD | Density | Mesh | Payload | Topology |
|
||||||
|
|---:|---|---|---|---|
|
||||||
|
| 0 | 769f2a706d585a72 | 33eeeb39fa443816 | 645621a1d968983f | c2457ed905036c9d |
|
||||||
|
| 1 | 69cc5a5c0a2c60af | b48335f5410c57d5 | d15c5480162ab8ba | feca1bd025823604 |
|
||||||
|
| 2 | 85deed5683a77202 | 53469895987aeea2 | e55f8ae7e1532033 | d5feb12a0e85c09b |
|
||||||
|
| 3 | 6518caefb3be7e7f | ec513c90b853a614 | f62fa1137ff17f82 | ccf1dcf681965816 |
|
||||||
|
| 4 | 62d4be96021992f4 | f1e4c6efcc2615a9 | 9dc5f9c88be02f33 | fe6f55125a07c3bf |
|
||||||
|
| 5 | 5e4a8c38b8cea6fc | 08ee56998aaf21e5 | 541eea8558f26cc8 | 6539374a8b3336d8 |
|
||||||
|
| 6 | e036e95b9006945b | 624a33f941a99b02 | 81b73e14f68bdf86 | 4de4c63ce1f80a56 |
|
||||||
|
| 7 | 8ee358af56a30d8d | 46ab3c6184048b7c | 0a6164b7e68e80c5 | 0c26b85bb03bc831 |
|
||||||
|
| 8 | c3458e1cbdb9c471 | 46c03d0994d75192 | 8f89fc5bde12d230 | d16dc0cf62031898 |
|
||||||
|
|
||||||
|
Nine direct-Core query probes also match baseline/cutoff and W1/W12 Clang/GCC: density and unclamped `e4d4a8eb95b35933`, detail `efcba20c0c70c415`, collision `e604823a249029bf`.
|
||||||
|
|
||||||
|
| Before / after pair | View |
|
||||||
|
|---|---|
|
||||||
|
| `before_l1.jpg` / `after_l1.jpg` | Exact L1 camera `0,-35,-487.94,0,-22` |
|
||||||
|
| `before_horizon.jpg` / `after_horizon.jpg` | Same position, pitch −2° |
|
||||||
|
| `before_boundary_lod2_3.jpg` / `after_boundary_lod2_3.jpg` | 20 m above local heightfield, aimed at the 96 m LOD3 entry band |
|
||||||
|
|
||||||
|
The boundary camera is `0,-35,-480.77246,0,-12`; the local heightfield is at −500.77246 m, placing the ground intersection about 96 m away.
|
||||||
|
|
||||||
|
The six review JPEGs are byte-identical within each pair. PNGs are in `Saved/Linux/captures/`; JPEGs are in `Linux5/captures/`.
|
||||||
|
|
||||||
|
## Failed and retried runs
|
||||||
|
|
||||||
|
- The first headless invocation omitted required streaming flags; the next used the default binary-relative data path and could not open the owner JSON. Both were retried with all flags and the explicit `Standalone/data/owner_world.json` path.
|
||||||
|
- The first process-monitor wrapper errored after its Clang build had completed; the run was repeated with `MeasureProcess.py` to record process HWM and duration.
|
||||||
|
- The first capture named a nonexistent mesh path and exited 2; the exported `.vfmesh` path was corrected.
|
||||||
|
- The first gate build failed on a duplicate `Distances` local; the corrected build passed. A first stride-2 control changed the MC lattice instead of reproducing S13’s every-second-column interpolation; the final control uses bilinear column interpolation.
|
||||||
|
- Initial comparison against only the continuous field mixed surface interpolation with unrelated tunnel intersections. The final instrument reports exact heightfield roots separately from the exact-mesh regression and ring checks.
|
||||||
|
- Early W12 cutoff candidates took 2.70–2.91 s. The zero-eligible path and distance setup were moved off the expensive profiling/phase-sweep path; the final interleaved candidate median is 2.232 s. It still does not improve L4.
|
||||||
|
- One final GCC W12 command omitted `--stream-pipeline` and exited 2; the corrected rerun passed. The initial −50° boundary capture mostly showed near ground; the final pair uses the camera listed above.
|
||||||
|
- The final baseline and cutoff gate commands exit 6 by design: both correctly reject the exact-field error and swap pops. No process exceeded 30 minutes or stalled for 15 minutes.
|
||||||
|
|
||||||
|
Core/API changes are in `VoxelForgeCore.h`, `WorldAssemblerInternal.h`, `FloatingIslandsInternal.h`, and `VoxelForgeCore.cpp`. Standalone changes are in `StreamingWorld.h`, `StreamBenchmarkPipeline.h`, `StreamBenchmarkHeadless.cpp`, `LinuxScreenSpaceGate.h`, `LinuxOffscreenCapture.cpp`, and `BuildLinux.sh`; process measurements are in `MeasureProcess.py`.
|
||||||
|
|
||||||
|
**For the owner:** Far terrain will look exactly as it does now because no octave tail met the bound. Existing far LOD swaps exceed the 1 px target, so the mesh sampling and transition error need attention before octave skipping can be used.
|
||||||
|
|
||||||
|
## Orchestrator review (Claude)
|
||||||
|
|
||||||
|
- **Not merged into `assembler/world`:** kept on side branch `wip/l5-far-cutoff`. With the cutoff flag OFF,
|
||||||
|
the L5 build is slower than L4. My interleaved W12 runs: L4 2.054/2.097/2.179 s vs L5 `final7`
|
||||||
|
2.127/2.193/2.208 s (medians 2.097 → 2.193, +4.6%), same world. Cost and no benefit.
|
||||||
|
- **Instrument caveat:** the gate prints `metric=vertical_height_error`. On steep slopes and cliffs, a
|
||||||
|
small horizontal offset becomes a large vertical error, so vertical error overstates screen
|
||||||
|
displacement. p50 is ~1 px but p99/max reach 20–126 px, the pattern such an artifact produces. The
|
||||||
|
claims "today's far meshes exceed 1 px" and "LOD swaps pop by up to 126 px" are therefore NOT yet
|
||||||
|
established. They need a screen-space measure: error along the surface normal or along camera rays,
|
||||||
|
projected at the display distance.
|
||||||
|
- The cutoff criterion (full displacement supremum ≤ 1/64 px) cannot pass for any SurfaceWorld octave
|
||||||
|
(smallest bound 256 voxels vs 0.24), so the null result was decided by the criterion, not measured.
|
||||||
|
- The capture path (EGL/GLES pbuffer; llvmpipe, since the sandbox hides `/dev/dri`) works and is worth keeping.
|
||||||
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,102 @@
|
|||||||
|
# Linux6 report
|
||||||
|
|
||||||
|
## Result
|
||||||
|
|
||||||
|
The screen-space gate rejects today’s far meshes at every sampled LOD3–8: the largest measured same-field error is 92.0 px, and the largest sampled swap pop is 70.3 px at LOD6→5. Same-LOD regeneration is exact, the reported swaps have no cracks or floaters, and no display mesh changed in this round.
|
||||||
|
|
||||||
|
Source base: `wip/l5-far-cutoff` at `b21a19d`; L4 reference: `7770074`.
|
||||||
|
|
||||||
|
## Screen-space method
|
||||||
|
|
||||||
|
For one surface tile nearest the L1 camera at each LOD, the gate rasterizes triangles on a 65×65 XY grid, excluding skirts. It compares the mesh hit to direct `Heightfield2D` ground/cap roots; slopes use ±1-voxel finite differences. For vertical residual `Δz` and slopes `sx,sy`, it computes normal distance `|Δz|/sqrt(1+sx²+sy²)`, projects that normal onto the camera’s screen plane, then divides by the one-pixel world distance at that LOD’s closest display distance. The view uses 90° horizontal FOV, 2560 px, yaw 0°, pitch −22°; one pixel is 0.000613592 rad. Same-LOD regeneration is the mesh reference for swaps; direct field roots are the reference for true surface error.
|
||||||
|
|
||||||
|
The known failure control is a 1 m cell on an 89.427° plane, shifted sideways by 5 mm (0.005 cell): its vertical metric says 8.488 px, while its true normal distance is 5 mm and projected screen error is 0.0849 px. This confirms that vertical height can badly overstate visible displacement.
|
||||||
|
|
||||||
|
| LOD | Closest distance (m) | Field error p50 / p99 / max (px) | Max normal distance (m) |
|
||||||
|
|---:|---:|---:|---:|
|
||||||
|
| 3 | 96 | 0.81 / 4.16 / 6.00 | 0.423 |
|
||||||
|
| 4 | 192 | 1.01 / 5.12 / 7.93 | 0.952 |
|
||||||
|
| 5 | 384 | 0.79 / 16.37 / 92.02 | 25.122 |
|
||||||
|
| 6 | 768 | 0.51 / 9.75 / 70.34 | 37.644 |
|
||||||
|
| 7 | 1,536 | 0.29 / 9.04 / 42.36 | 42.714 |
|
||||||
|
| 8 | 3,072 | 0.83 / 18.03 / 47.18 | 93.175 |
|
||||||
|
|
||||||
|
| Swap | Distance (m) | Pop p50 / p99 / max (px) | Max normal distance (m) |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| 3→2 | 96 | 0.61 / 3.77 / 6.05 | 0.367 |
|
||||||
|
| 4→3 | 192 | 0.75 / 4.63 / 7.51 | 0.896 |
|
||||||
|
| 5→4 | 384 | 0.00 / 9.58 / 31.78 | 8.139 |
|
||||||
|
| 6→5 | 768 | 0.00 / 9.75 / 70.34 | 37.644 |
|
||||||
|
| 7→6 | 1,536 | 0.00 / 9.04 / 42.36 | 42.714 |
|
||||||
|
| 8→7 | 3,072 | 0.83 / 18.03 / 47.18 | 93.175 |
|
||||||
|
|
||||||
|
The tails are not confined to cliffs. The field maximum slopes at LOD5–8 are 8.34°, 14.09°, 6.76°, and 9.33°; LOD5’s p99 is 19.8 px below 30° and 21.1 px at 45–60°. The sampled LOD6→5 maximum is at `(-472, -1432, -463.151) m`; [the marked offscreen capture](captures/lod6_to_5_max_pop.jpg) shows that location at the 768 m swap distance. This is a sampled-tile result, not a whole-world supremum.
|
||||||
|
|
||||||
|
All same-LOD mesh comparisons at LOD3–8 pass with zero error. The S13 octave-drop and corrected stride-2 column-interpolation controls are rejected at every LOD3–8, as are missing displayed surface, 2 m floating surface, and missing fine-ring injections. The measured swap rows have zero cracks and floaters; they reject solely on displacement.
|
||||||
|
|
||||||
|
## Far worker time, W12
|
||||||
|
|
||||||
|
The L1 view has 2553 tiles. Clean-run phase totals for LOD3–8 are shown below. A separate temporary timer measured complete `FractalNoiseQ16` calls; “column outside” is clean column time minus that subtotal. The timer added 3–6% to worker time, so the split between those two column subphases is approximate; it has been removed from the final tree.
|
||||||
|
|
||||||
|
| LOD | Worker (s) | Column outside noise (ms) | Fractal/noise calls (ms) | MC (ms) | Ground refine (ms) | Cap refine (ms) | Skirts (ms) | Assembly (ms) |
|
||||||
|
|---:|---:|---:|---:|---:|---:|---:|---:|---:|
|
||||||
|
| 3 | 1.084 | 171 | 276 | 473 | 0 | 0 | 118 | 33 |
|
||||||
|
| 4 | 2.581 | 1,000 | 534 | 440 | 0 | 304 | 196 | 102 |
|
||||||
|
| 5 | 1.829 | 658 | 358 | 100 | 464 | 22 | 161 | 70 |
|
||||||
|
| 6 | 2.761 | 1,608 | 284 | 59 | 385 | 58 | 162 | 70 |
|
||||||
|
| 7 | 1.192 | 234 | 198 | 32 | 275 | 202 | 153 | 96 |
|
||||||
|
| 8 | 2.224 | 264 | 469 | 256 | 424 | 299 | 333 | 177 |
|
||||||
|
| **Total** | **11.671** | **3,934** | **2,119** | **1,360** | **1,548** | **885** | **1,123** | **548** |
|
||||||
|
|
||||||
|
Column work outside the fractal calls is the largest single phase (33.7% of far worker time); all column work is 51.9%. Ground and cap refinement total 2.43 worker-s, skirts 1.12 worker-s, MC 1.36 worker-s, and assembly 0.55 worker-s. The earlier 7–13% profile timed individual Perlin calls; the L6 subtotal times complete fractal calls, including their octave accumulation.
|
||||||
|
|
||||||
|
The listed subphases total 11.52 worker-s; about 0.15 worker-s remains in timer and per-tile residuals.
|
||||||
|
|
||||||
|
The overlap scan counted about 411,000 cross-worker neighboring duplicate XY evaluations at LOD3–8 (about 166,000 at LOD4 alone). Exact column reuse is the largest plausible lever because it targets the largest phase. I did not build it: no candidate has yet shown a screen-gated, greater-than-3% whole-view win. Stride-2 interpolation is not a safe substitute; its control fails at every far LOD.
|
||||||
|
|
||||||
|
## Cost with the feature off
|
||||||
|
|
||||||
|
Three interleaved W12 runs per binary, same L1 camera and forced generation. `whole_view_ready` is the comparison metric; the six whole-view hashes matched exactly.
|
||||||
|
|
||||||
|
| Binary | Runs (s) | Median |
|
||||||
|
|---|---|---:|
|
||||||
|
| L4 reference | 2.082, 2.180, 2.183 | 2.180 s |
|
||||||
|
| L6 cleaned tree | 2.127, 2.185, 2.223 | 2.185 s (+0.2%) |
|
||||||
|
|
||||||
|
Run-to-run spread was about 0.10 s, so the 5 ms median difference is within noise. The no-op visual cutoff contract, plan, and CLI flag were removed. The opt-in research gate retains its negative controls; skirt timing uses the existing optional stage-timing pointer, which is null on the default path. Governor stayed `powersave`; runs used CPUs 0–11, W12, 6 GiB address-space limits, and normal priority. Peak runtime RSS was 403 MiB; peak build process RSS was 874 MiB (GCC).
|
||||||
|
|
||||||
|
## Determinism and hashes
|
||||||
|
|
||||||
|
Clang 19 `-ffp-contract=off` W1/W12 and GCC default W1/W12 produced the same hashes. LOD0–2, exact queries, and all whole-view hashes equal L4; no recipe bump is needed.
|
||||||
|
|
||||||
|
- Recipe / plan / manifest: `83b616a3f4fe781d` / `1ca84619c8600ee5` / `e55991385bf0ca29` (recipe version 1).
|
||||||
|
- Whole view (density / mesh / payload / topology): `c10697a8f48380c7` / `e75c9119a1498cd5` / `49a9a8d1835a6c8c` / `edcb23288b5e8724`.
|
||||||
|
- Full detail (density / mesh / payload / topology): `0ee0579bd15cbbe4` / `32e5d4964d610fee` / `1932b96ee4b1d910` / `69743c6bad3447dc`.
|
||||||
|
- Exact queries (density / unclamped / detail / collision): `e4d4a8eb95b35933` / `e4d4a8eb95b35933` / `efcba20c0c70c415` / `e604823a249029bf`.
|
||||||
|
- SHA-256 L4 binary / Clang L6 binary / GCC L6 binary: `6efb8f19a41ca3cd23aca9294ceee1e9cdd1d3dc8da23b3ee61ef8ae943aa763` / `3f5a4f88b0d911e8e66af9ef72e294926a5507a73d44fcfe868df27c666bf01e` / `de872e8fdaa9f40e8a6c096700fd998bcf35f232b06f2b4e35a374b4b0e9fa07`.
|
||||||
|
- Capture JPEG SHA-256: `483b434f3ad752dd09b82cd1c78fe81ee8cd31803ecf4dcd3c2918a8ae5d66b1` (156 KiB).
|
||||||
|
|
||||||
|
## Failed or retried runs
|
||||||
|
|
||||||
|
- First Clang build failed on a missing view argument in `LinuxScreenSpaceGate.h`; fixed and rebuilt successfully.
|
||||||
|
- First gate pass paired extra mesh hits incorrectly and reported same-LOD floaters at LOD5–8. The reference pairing was corrected; the final gate reports zero same-LOD displacement and no floaters.
|
||||||
|
- A `/usr/bin/time -v` wrapper attempt exited 127 because that binary is unavailable; the runs were retried with `/proc` RSS monitoring.
|
||||||
|
- The final quality gates exit 6 by design because measured displacement exceeds the 1 px rule. Builds, captures, determinism runs, and cost runs completed successfully. EGL could not write `~/.cache` in this environment, disabled shader caching, and rendered successfully on llvmpipe.
|
||||||
|
|
||||||
|
## Note for the owner
|
||||||
|
|
||||||
|
Today’s `assembler/world` remains at L4; this sampled view measures up to 92.0 px from the field and a 70.3 px LOD6→5 pop at the tested display distances, with the largest point marked in the capture. This round changes no default mesh or recipe output, removes the no-op cutoff, and leaves W12 cost within run-to-run noise.
|
||||||
|
|
||||||
|
## Orchestrator review (Claude)
|
||||||
|
|
||||||
|
- Cost re-run by me (interleaved W12, L1 view): L4 2.098/2.138/2.171 s vs L6 2.116/2.150/2.197 s
|
||||||
|
(median +0.6%, within noise), density `c10697a8f48380c7`; the L6 binary SHA matches the report.
|
||||||
|
Merged into `assembler/world` with L5 squashed in.
|
||||||
|
- The marked LOD6→5 maximum sits on the **rim of a flat-topped hill (mesa edge)**, not on open gentle
|
||||||
|
ground: the "8–14° slope" is the field slope at the sample, on the plateau top beside the drop. The
|
||||||
|
coarse mesh rounds the rim by about a cell (16–32 m at LOD5–6), so the pop is a real **silhouette snap
|
||||||
|
at sharp rims** (tens of px at 768 m), while p50 stays at 0 px. That is ordinary LOD-switch behaviour
|
||||||
|
without geomorphing or cross-fade, so a fix belongs in rendering (Unreal), not in generation. The
|
||||||
|
owner decides whether it is visible enough to matter.
|
||||||
|
- Next speed lever, per the far breakdown: exact cross-tile column reuse (column work outside noise is
|
||||||
|
34% of far worker time; ~411k duplicate XY evaluations at LOD3–8).
|
||||||
|
After Width: | Height: | Size: 156 KiB |
@@ -0,0 +1,340 @@
|
|||||||
|
# World Assembler S14 — Round 18
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Shipped two output-preserving changes justified by the measurements:
|
||||||
|
|
||||||
|
1. Keep the 65,536-entry XY column cache worker-local. Use the old direct-map route at LOD0–2,
|
||||||
|
where conflict counts are low, and deterministic four-way sets at LOD3–8. The LOD4 miss spike
|
||||||
|
falls from 8,224 to 1,437, with conflict misses falling from 7,407 to zero.
|
||||||
|
2. Memoize exact step-1 ShapeWorld MC grid gradients per worker and tile. The MC two-pass loop,
|
||||||
|
density grid, halo, central differences, and output values stay intact. LOD0 MC-exclusive cost
|
||||||
|
falls from 241.87 to 201.48 ns/sample in the corrected-source audit; the original S13 figure was
|
||||||
|
243.40 ns/sample.
|
||||||
|
|
||||||
|
No shared XY page was built: cross-worker repeats show opportunity, but no measured page-cache A/B
|
||||||
|
shows a net cold-path win after the cache fix. The primary cold trace used 21.722 worker-seconds against
|
||||||
|
the 28.8 s target. Output hashes remain unchanged, so the recipe stays `MarchingCubesV1`; no recipe
|
||||||
|
bump or matched captures were required.
|
||||||
|
|
||||||
|
## 1. What the 243 ns/sample contains
|
||||||
|
|
||||||
|
The S13 “MC-exclusive” timer excludes MC column evaluation; it does **not** mean “triangle loop
|
||||||
|
only.” For LOD0, the corrected-source eight-tile audit measured 8.638 ms MC-exclusive plus 3.852 ms
|
||||||
|
MC column evaluation at the tuned setting. Each LOD0 tile has 35³ = 42,875 density samples. The
|
||||||
|
exclusive result is 201.48 ns/sample. The cell loop itself is only one part of it.
|
||||||
|
|
||||||
|
In the sampled stage audit, tuned LOD0 p95 was: density grid 8.971 ms (7.071 ms excluding column
|
||||||
|
evaluation), cell classification 0.143 ms, grid-gradient normals 1.036 ms, edge interpolation
|
||||||
|
0.080 ms, vertex dedup/stream 0.545 ms, and about 2.168 ms of unassigned remainder. The stage
|
||||||
|
profiler samples one in eight cells; these are independently calculated p95 values and do not add
|
||||||
|
to a measured total. Its `Other`/setup-finalization and unassigned-residual fields are computed
|
||||||
|
remainder buckets from different inclusive/exclusive timers, not separately isolated setup or
|
||||||
|
allocator timers.
|
||||||
|
|
||||||
|
The 164.93 ns/sample grid remainder is not a standalone `height - z` timer. Every lattice sample
|
||||||
|
still enters the exact `Heightfield2D::point` path: fixed-coordinate conversion, recipe/plan lookup,
|
||||||
|
the worker-local XY cache probe, the Z-dependent ground/cap composition, and any applicable exact
|
||||||
|
feature/edit checks. Column generation itself is counted separately: LOD0 records 44,100 field
|
||||||
|
calls, 2,244 cache misses (about 94.9% hits), and 89.89 ns/sample of column computation. The audit
|
||||||
|
does not split cache-hit lookup from Z composition and call overhead. Those Z/feature checks cannot
|
||||||
|
all move to one XY-column operation. The MC gradient work can be shared per lattice point and is
|
||||||
|
now memoized exactly; edge interpolation is already limited to crossed edges and the vertex map
|
||||||
|
deduplicates shared edge vertices. Material and allocation have no separate timers; the mesher's
|
||||||
|
thread-local grids and dedup map retain capacity between tiles.
|
||||||
|
|
||||||
|
The MC route still uses the protected two-pass loop: pass one rejects empty cells from the eight
|
||||||
|
cached corners; pass two computes positions, gradients, and emitted triangles only for surface
|
||||||
|
cells. Classification is per cell; exact gradients are reused per lattice point; interpolation and
|
||||||
|
deduplication are limited to crossed edges and their shared vertex keys. The stage measurements
|
||||||
|
place classification in the first pass and interpolation plus dedup/stream in the second.
|
||||||
|
Material/ground-cap grouping and vertex attributes are folded into
|
||||||
|
vertex creation and streaming; material work has no separate timer. The 35 edge-midpoint density
|
||||||
|
probes are negligible beside the gradient fallback calls.
|
||||||
|
|
||||||
|
| LOD | Density grid incl. | Grid excl. columns | Cell classification | Gradient normals | Edge interpolation | Dedup/stream | Unassigned residual |
|
||||||
|
|---:|---:|---:|---:|---:|---:|---:|---:|
|
||||||
|
| 0 | 210.11→209.22 | 168.04→164.93 | 3.28→3.32 | 65.10→24.16 | 1.91→1.86 | 12.96→12.72 | 50.40→50.56 |
|
||||||
|
| 1 | 163.74→164.91 | 163.74→164.91 | 3.82→3.55 | 4.20→4.01 | 2.14→2.10 | 13.47→13.56 | 54.77→55.06 |
|
||||||
|
| 2 | 390.55→395.47 | 0.00→0.00 | 2.84→2.89 | 11.62→11.51 | 6.14→5.47 | 68.70→69.15 | 277.12→306.20 |
|
||||||
|
| 3 | 777.21→437.15 | 120.00→131.99 | 3.15→2.97 | 15.37→15.37 | 6.77→6.25 | 604.40→407.99 | 46.97→110.89 |
|
||||||
|
| 4 | 4,603.98→425.25 | 210.50→178.79 | 2.92→3.32 | 10.15→10.96 | 5.60→5.48 | 565.21→309.90 | 95.44→109.50 |
|
||||||
|
| 5 | 385.90→434.09 | 135.75→155.07 | 3.02→3.48 | 5.13→7.00 | 1.78→3.50 | 155.02→38.26 | 96.38→137.65 |
|
||||||
|
| 6 | 366.38→371.92 | 88.76→101.46 | 2.97→3.09 | 18.66→18.11 | 9.72→8.39 | 431.20→185.07 | 124.84→171.70 |
|
||||||
|
| 7 | 361.29→447.14 | 115.03→102.64 | 3.13→2.99 | 20.47→17.75 | 9.69→8.84 | 443.10→239.22 | 99.92→254.21 |
|
||||||
|
| 8 | 367.98→377.58 | 95.55→96.05 | 4.05→3.05 | 14.90→19.08 | 7.48→7.92 | 513.15→213.89 | 159.02→234.19 |
|
||||||
|
|
||||||
|
All stage values are p95 **ns/sample**, before→after. “Before” is this build with the direct-map
|
||||||
|
cache and gradient memo off (`1/0`); “after” is this build's tuned default (`0/1`). Each side measured eight
|
||||||
|
tiles per LOD, with `hashes_identical=1`. LOD0/1 use 42,875 samples; LOD2–8 use 6,859. Large
|
||||||
|
variation in dedup/stream and residual is content/triangle-count and sampling noise, not a new
|
||||||
|
approximation. The last column is the commandlet's unassigned-residual bucket; the separately
|
||||||
|
reported setup-finalization field is also computed as a remainder and is not an allocator timer.
|
||||||
|
These warmed-route stage probes explain the hot path; the cold production timings are the
|
||||||
|
fresh-process trace in section 4.
|
||||||
|
|
||||||
|
| LOD | Candidate tile p95 ms | MC column p95 ms | MC-exclusive p95 ms / ns per sample | Column misses / conflicts |
|
||||||
|
|---:|---:|---:|---:|---:|
|
||||||
|
| 0 | 14.079→12.492 | 3.777→3.852 | 10.370→8.638 / 241.87→201.48 | 2,244/33→2,244/33 |
|
||||||
|
| 1 | 9.824→9.842 | 4.187→4.197 | 7.183→7.307 / 167.53→170.43 | 2,289/28→2,289/28 |
|
||||||
|
| 2 | 4.715→4.709 | 3.080→3.066 | 1.606→1.616 / 281.61→282.71 | 681/4→681/4 |
|
||||||
|
| 3 | 6.945→5.393 | 4.016→2.477 | 2.917→2.903 / 425.28→423.27 | 1,634/1,119→574/0 |
|
||||||
|
| 4 | 36.854→9.227 | 30.216→2.257 | 2.970→2.946 / 432.93→429.54 | 8,224/7,407→1,437/0 |
|
||||||
|
| 5 | 11.055→9.129 | 3.029→2.278 | 1.279→1.269 / 186.43→184.98 | 1,916/1,476→1,351/0 |
|
||||||
|
| 6 | 30.703→26.872 | 5.148→3.841 | 2.142→2.000 / 312.23→291.57 | 6,403/2,094→5,570/1 |
|
||||||
|
| 7 | 20.831→15.390 | 4.725→3.460 | 2.411→2.689 / 351.52→391.97 | 3,472/2,926→1,822/0 |
|
||||||
|
| 8 | 14.948→9.829 | 5.715→3.358 | 2.534→2.770 / 369.38→403.82 | 2,708/2,215→1,162/0 |
|
||||||
|
|
||||||
|
For LOD0 specifically, the S13 audit row was 14.160 ms candidate, 3.708 ms column evaluation,
|
||||||
|
10.436 ms MC-exclusive, and 243.40 ns/sample. The tuned corrected-source 35³ route is 12.492 ms
|
||||||
|
candidate and 8.638 ms MC-exclusive. Subtracting the measured density-grid p95 from candidate p95
|
||||||
|
leaves about 3.52 ms for the remaining work (about 82 ns/sample); the independently sampled stage
|
||||||
|
subtotal is about 3.97 ms (about 93 ns/sample). This is the measured in-world estimate for the
|
||||||
|
MC/classification/normal/interpolation/streaming work after density-grid evaluation, not a direct
|
||||||
|
pre-filled-grid benchmark. Treat the p95 subtraction as an estimate, not an additive percentile.
|
||||||
|
|
||||||
|
Gradient memoization reduces LOD0 fallback density probes from 11,474 to 3,018 per sampled p95
|
||||||
|
(−73.7%) and normal cost from 65.10 to 24.16 ns/sample. It records 5,610 memo hits. The memo stores
|
||||||
|
the exact central-difference vector at each grid lattice point, is worker-local, and resets its
|
||||||
|
validity bytes per tile. The existing grid and per-worker capacities are reused. No material
|
||||||
|
approximation or altered gradient arithmetic is involved.
|
||||||
|
|
||||||
|
## 2. Why LOD4 had the cache spike
|
||||||
|
|
||||||
|
The old cache already holds 65,536 `HeightfieldPointSample`s per worker, but its direct-map index
|
||||||
|
uses pointer identity and coordinate bits. Coarse LOD coordinates share sparse low-bit patterns;
|
||||||
|
the LOD4 16-voxel cap grid interleaves different XY probes with the MC grid and its halo/normal
|
||||||
|
lookups. The measured direct-map conflict count (7,407 of 8,224 misses) shows this is mostly
|
||||||
|
eviction, rather than 8,224 necessary unique columns. The audit did not tag every miss by probe
|
||||||
|
source, so the individual halo-versus-cap contribution is not claimed.
|
||||||
|
|
||||||
|
The new default keeps the same total entries and exact key verification. Its avalanched coordinate
|
||||||
|
hash selects one of 16,384 four-way sets; deterministic round-robin replacement only changes
|
||||||
|
residency, never values. Exact recipe/plan identities, content hashes, and XY coordinates are
|
||||||
|
checked on every hit, so fill order cannot affect output. LOD0–2 keep the fast original path because
|
||||||
|
they have only 33, 28, and 4 direct-map conflict misses in the audit. LOD6 remains at 5,570 misses
|
||||||
|
but only one conflict, showing that its remaining cost comes largely from its larger real XY
|
||||||
|
footprint and connector-shell work, not direct-map collision.
|
||||||
|
|
||||||
|
`voxel.CoreColumnCacheDirectMapped=1` is the direct-map negative control and was read back as `1`
|
||||||
|
in the trace. With gradient memo still on, the initial set took 6.624 s and 43.493 worker-seconds;
|
||||||
|
LOD4 used 11.071 worker-seconds. The tuned default took 4.238 s and 21.722 worker-seconds, with
|
||||||
|
LOD4 at 1.862 worker-seconds. The isolated audit also reports the per-LOD miss deltas above.
|
||||||
|
|
||||||
|
The separate memo negative control was `voxel.CoreMCGradientMemoization=0` with the four-way
|
||||||
|
column cache still enabled; both values were read back as `0/0`. It took 4.908 s and 27.609
|
||||||
|
worker-seconds, versus 4.238 s and 21.722 s at the `0/1` default. Its 3×3 support ring was 0.602 s
|
||||||
|
versus 0.447 s, and LOD0 last apply was 1.453 s versus 1.171 s. This cold-path A/B supports keeping
|
||||||
|
the exact gradient memo. The direct-map control is `1/1` and isolates the cache behavior; the memo
|
||||||
|
control is `0/0` and isolates the gradient behavior.
|
||||||
|
|
||||||
|
## 3. Shared XY pages
|
||||||
|
|
||||||
|
The corrected-source Standalone W8 overlap capture counted 281,910 cross-worker neighboring
|
||||||
|
duplicate columns at LOD0 and 123,803 at LOD4. Against Round17 (276,658 and 202,684), LOD0 is up
|
||||||
|
about 2%, while LOD4 is down about 39% after fixing intra-worker cache conflicts. The counters are
|
||||||
|
schedule-dependent work counts, not world output. Multiplying those counts by the current stage
|
||||||
|
audit's p95 column-time-per-miss ratios gives a rough estimate of 0.68 worker-seconds across the
|
||||||
|
LOD0/LOD4 repeats if each repeat avoided a recomputation and the shared lookup had zero cost. That
|
||||||
|
is about 3.1% of the measured 21.722 worker-seconds, before synchronization and memory costs. This
|
||||||
|
is an estimate, not a cold-path A/B win measurement.
|
||||||
|
|
||||||
|
After the four-way change, the remaining upper bound is too small to justify adding an unmeasured
|
||||||
|
synchronized page in this round. It would also add ownership/lifetime and bounded-memory work under
|
||||||
|
the S8 rules. The page was therefore not built. Existing immutable region pages and their S8
|
||||||
|
lifetime are unchanged; no new page lifetime needs proving.
|
||||||
|
|
||||||
|
## 4. Cold 40 m/s trace
|
||||||
|
|
||||||
|
Fresh BuildHost process, 25 cm SurfaceWorld, 40 m/s along +Y, background worker cap 1, ready queue
|
||||||
|
8, dynamic reserve, collision lookahead 1, `CoreColumnCacheDirectMapped=0`, and
|
||||||
|
`CoreMCGradientMemoization=1`. The `worker_backend_config` JSONL row reads back all these controls.
|
||||||
|
Round17 and Round18 use the same trace command and post-`BeginPlay` `elapsed_s` origin. In this run
|
||||||
|
`elapsed_s=4.238189`; raw trace `t_s` is 4.320372. Trace `t_s` begins 0.082022 s before the
|
||||||
|
end-of-BeginPlay origin. The 3×3 walkable support ring is measured at its first ready gate using
|
||||||
|
that same origin. S12's actor report uses a different clock origin; its comparisons are stated as
|
||||||
|
references, not clock-normalized samples.
|
||||||
|
|
||||||
|
| Metric | Round17 S13 | S14 primary | S14 fresh repeat |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| Initial set | 2,578 tiles / 4.825 s | 2,578 / 4.238 s | 2,578 / 5.151 s |
|
||||||
|
| Initial-set worker seconds | 28.760 | 21.722 | 29.969 |
|
||||||
|
| 3×3 walkable support ring | 0.510 s | 0.447 s | 0.971 s |
|
||||||
|
| LOD0 last worker end | 1.131 s | 1.156 s | 1.524 s |
|
||||||
|
| LOD0 last apply | 1.146 s | 1.171 s | 1.532 s |
|
||||||
|
| 40 m/s moving readiness | 75/75 ready | 75/75 ready | 57/57 logged samples ready |
|
||||||
|
| Spawn `UWorld::Tick` p95/max | 3.133 / 5.426 ms | 4.200 / 5.571 ms | 4.601 / 6.682 ms |
|
||||||
|
| Walk `UWorld::Tick` p95/max | 30.314 / 43.142 ms | 32.218 / 45.720 ms | 33.986 / 41.654 ms |
|
||||||
|
|
||||||
|
| Initial-set LOD | Tiles | S14 primary worker s | S14 repeat worker s |
|
||||||
|
|---:|---:|---:|---:|
|
||||||
|
| 0 | 512 | 4.520 | 6.319 |
|
||||||
|
| 1 | 448 | 4.696 | 6.304 |
|
||||||
|
| 2 | 320 | 0.870 | 1.241 |
|
||||||
|
| 3 | 272 | 0.829 | 1.193 |
|
||||||
|
| 4 | 272 | 1.862 | 2.634 |
|
||||||
|
| 5 | 208 | 1.478 | 2.121 |
|
||||||
|
| 6 | 144 | 2.179 | 3.168 |
|
||||||
|
| 7 | 96 | 1.723 | 2.206 |
|
||||||
|
| 8 | 306 | 3.565 | 4.782 |
|
||||||
|
| **Total** | **2,578** | **21.722** | **29.969** |
|
||||||
|
|
||||||
|
The same-build LOD0 candidate-tile p95 fell 11.3% (14.079 to 12.492 ms). In the cold trace, LOD0
|
||||||
|
worker time fell 3.3% (4.672 to 4.520 s across 512 tiles, or 9.13 to 8.83 ms per tile).
|
||||||
|
|
||||||
|
The primary cold trace meets the 4.8 s full-set, 28.8 worker-second, and 0.51 s support-ring
|
||||||
|
targets, with all 75 moving samples ready. LOD0 is materially cheaper per tile. LOD0 last apply is
|
||||||
|
81 ms over the ~1.09 s target. I made one more fresh default trace to check the tick regression;
|
||||||
|
the same binary and `0/1` CVar readback passed the commandlet but took 5.151 s and 29.969
|
||||||
|
worker-seconds for all 2,578 tiles, 0.971 s for the support ring, and 1.532 s for the last LOD0
|
||||||
|
apply. Peak private memory was 3.29 GiB. Its spawn tick was 4.601/6.682 ms and walking tick was
|
||||||
|
33.986/41.654 ms p95/max; all 57 logged 40 m/s streaming samples stayed walkable-ready. Thus the
|
||||||
|
full-set, worker-second, support-ring, and LOD0 apply targets pass in the primary run but fail on
|
||||||
|
this repeat. Spawn tick p95/max is worse than S13 and matched S12 in both runs; walking p95 is
|
||||||
|
worse than both in both runs. The first-run walking max is worse than both references; the repeat
|
||||||
|
is worse than S12 but below S13. The strict no-worse tick goal therefore fails. I kept the S13
|
||||||
|
worker cap at 1; the measurements do not justify raising it.
|
||||||
|
|
||||||
|
## 5. Quality and determinism
|
||||||
|
|
||||||
|
- BuildHost W1/W8/W16 stable: density/mesh/payload/topology
|
||||||
|
`0cd2a1a4152ee4aa / a06243aee16b65d5 / c700162935c262d7 / 0af901aa42b452bc`.
|
||||||
|
- Standalone W1/W8/W12, fresh `--force-generate`: whole-view 2,553-tile hashes all match:
|
||||||
|
`c10697a8f48380c7 / e75c9119a1498cd5 / 49a9a8d1835a6c8c / edcb23288b5e8724`.
|
||||||
|
Full-detail 960-tile hashes also match:
|
||||||
|
`0ee0579bd15cbbe4 / 32e5d4964d610fee / 1932b96ee4b1d910 / 69743c6bad3447dc`.
|
||||||
|
- Core-off at 12.5 cm: `VOXELFORGE_CORE_OFF_LEGACY_PASS`.
|
||||||
|
- M2 Hybrid V1 and V2 at 25 cm: five analytic fixtures and borders passed.
|
||||||
|
- SurfaceWorld at 25 cm: BuildHost W1/W8/W16, geometry scale and height agreement, carve/fill,
|
||||||
|
native/bridge, and collision checks passed.
|
||||||
|
- S3 far-horizon agreement: max 0.0427 cm against 2 cm.
|
||||||
|
- S4 far-cap agreement: 128 shared points, max 0.0504 cm against 2 cm; negative control detected.
|
||||||
|
Cap rays: 1,584/1,584 (100%), no misses.
|
||||||
|
- FloatingIslands at 25 cm: W1/W8/W16 stable:
|
||||||
|
`4dcfb37585d7d986 / f14f76fbf065c6ed / 53035c45fd1a082e / 23550100654a4ec3`;
|
||||||
|
island and span contacts, anchors, carve/fill passed; water remained fixed.
|
||||||
|
|
||||||
|
No density, mesh, topology, payload, or collision output changed. No recipe bump or paired near/far
|
||||||
|
captures are needed.
|
||||||
|
|
||||||
|
## 6. Build, commands, and evidence
|
||||||
|
|
||||||
|
Builds (Normal priority, maximum 12 parallel workers):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Tools\BuildVoxelForgeCoreHost.ps1 -MaxParallelActions 12 -TimeoutSeconds 900
|
||||||
|
.\Standalone\Build.ps1 -Target All -CompileWorkers 12 -BuildPriority Normal
|
||||||
|
```
|
||||||
|
|
||||||
|
BuildHost feature-stage controls:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -SharedFeatureAuditOnly -CoreMCStageAudit -CoreColumnCacheDirectMapped 1 -CoreMCGradientMemoization 0 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -SharedFeatureAuditOnly -CoreMCStageAudit -CoreColumnCacheDirectMapped 0 -CoreMCGradientMemoization 1 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
|
||||||
|
```
|
||||||
|
|
||||||
|
Cold stream command:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 4000 -StreamingReadyQueueDepth 8 -StreamingBackgroundWorkerCap 1 -CoreColumnCacheDirectMapped 0 -CoreMCGradientMemoization 1 -TimeoutSeconds 900
|
||||||
|
```
|
||||||
|
|
||||||
|
The cold-path negative controls held every other argument fixed; the trace JSONL recorded the CVar
|
||||||
|
readbacks (`0/0` for memo-off, `1/1` for direct-map):
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 4000 -StreamingReadyQueueDepth 8 -StreamingBackgroundWorkerCap 1 -CoreColumnCacheDirectMapped 0 -CoreMCGradientMemoization 0 -TimeoutSeconds 900
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -StreamingTraceOnly -StreamingOrder Legacy -NearReserveMode Dynamic -CoreVoxelSizeCm 25 -StreamingCollisionLookahead 1 -TestMoveDirection '0,1,0' -CoreRegionConcurrentAdmission 1 -StreamingResultBacklogCap 256 -TestMoveSpeedCmPerSecond 4000 -StreamingReadyQueueDepth 8 -StreamingBackgroundWorkerCap 1 -CoreColumnCacheDirectMapped 1 -CoreMCGradientMemoization 1 -TimeoutSeconds 900
|
||||||
|
```
|
||||||
|
|
||||||
|
Standalone processes were sequential, Normal priority, 12-CPU affinity, and used `--force-generate`:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Standalone\bin\VoxelForgeCoreStandalone.exe --workers=1 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-priority=Normal --process-affinity=4095 --frame-limit=60
|
||||||
|
.\Standalone\bin\VoxelForgeCoreStandalone.exe --workers=8 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --profile-column-overlap --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-priority=Normal --process-affinity=4095 --frame-limit=60
|
||||||
|
.\Standalone\bin\VoxelForgeCoreStandalone.exe --workers=12 --world-assembler-prototype --stream-benchmark --stream-pipeline --stream-hash --force-generate --clip-radius=3 --max-clip-level=8 --camera=0,-35,-487.94,0,-22 --far-horizon-lod8-step=0 --process-priority=Normal --process-affinity=4095 --frame-limit=60
|
||||||
|
```
|
||||||
|
|
||||||
|
Other BuildHost gate commands:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -CoreOffTest -CoreVoxelSizeCm 12.5 -TimeoutSeconds 900
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -HybridFixturesOnly -CoreMesherRecipe WorldAssemblerHybridV1 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -HybridFixturesOnly -CoreMesherRecipe WorldAssemblerHybridV2 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -CoreVoxelSizeCm 25 -TimeoutSeconds 900
|
||||||
|
.\Tools\TestVoxelForgeCoreWorldHost.ps1 -FloatingIslandsOnly -CoreVoxelSizeCm 25 -TimeoutSeconds 900
|
||||||
|
```
|
||||||
|
|
||||||
|
Measured binaries and SHA-256:
|
||||||
|
|
||||||
|
| Binary | SHA-256 |
|
||||||
|
|---|---|
|
||||||
|
| UE `UnrealEditor-Cmd.exe` | `ECCE9996191F7F7E69B3D104EECDD0E678AE69176FDCCD79828C3E75A0654D6D` |
|
||||||
|
| BuildHost `UnrealEditor-VoxelForge.dll` | `4E55A38547B96221562AEC84D61B0FFC7E455E21420C51E14D2BEACA88217A07` |
|
||||||
|
| BuildHost `UnrealEditor-VoxelForgeCore.dll` | `1F34F96208FC0E0A72CE2CE80014EBFB110C29C8333053A90735DF9C7BEE7949` |
|
||||||
|
| BuildHost `UnrealEditor-VoxelForgeEditor.dll` | `9B35350BBA3E7CE4F8D8DA617C216B21CB4CF9869FE5903FD84AAC6906B8187B` |
|
||||||
|
| Standalone `VoxelForgeCoreStandalone.exe` | `91D29D8BA421304F085BFAB4CCE5EC9DDD32C40BE13F15E118E0DC9606D21B84` |
|
||||||
|
|
||||||
|
Full logs, traces, and Standalone stdout/stderr are under `Saved/BuildHost/`; the current 40 m/s
|
||||||
|
trace files are in `Saved/BuildHost/HostProject/Plugins/VoxelForge/Saved/CoreWorldValidation/Logs/`.
|
||||||
|
The fresh repeat uses the same CVar-derived JSONL path as the primary trace, so its JSONL is the
|
||||||
|
current trace; the faster primary run's engine log summary is retained in that Logs directory as
|
||||||
|
`CoreWorldValidation-owner_surface_stream_trace_only_applyboost_default_bgcap_1_readyq_8_legacy_order_colcache_4way_gradientmemo_on_nearreserve_dynamic_trace_move_4000_lookahead_1_dir_0_1_0_region_1_backlog_256-backup-2026.10.19-15.44.14.log`.
|
||||||
|
Per-run Standalone command records and logs are in `Saved/BuildHost/WorldAssemblerM3/Round18/Standalone/`.
|
||||||
|
|
||||||
|
## 7. Failed probes, retries, and safety review
|
||||||
|
|
||||||
|
- `-coremcstageaudit=1` was ignored by Unreal’s boolean argument parser; the audit was repeated
|
||||||
|
with the bare `-coremcstageaudit` flag.
|
||||||
|
- An early direct-map control did not read back `1`, and an early audit binary did not log either
|
||||||
|
new CVar. Those measurements were rejected. I added the S11-style explicit BeginPlay parse and
|
||||||
|
trace readback, rebuilt BuildHost, then reran the direct/off baseline and tuned audit; the JSONL
|
||||||
|
readbacks are `1/0` and `0/1` respectively.
|
||||||
|
- The first corrected shared-audit command was rejected by a harness guard before launch because
|
||||||
|
it treated audit CVars as trace-only controls. The guard now allows them in shared-feature
|
||||||
|
audits; the rerun passed.
|
||||||
|
- The first W8 Standalone wrapper could not resolve its process-local memory helper type. That
|
||||||
|
run exited 0 and its process peak was 0.70 GiB, but its free-memory preflight was invalid. I
|
||||||
|
repeated W8 with the helper defined in that process: free-before 17.12 GiB, peak 0.71 GiB,
|
||||||
|
exit 0, and the whole-view hashes matched W1/W12.
|
||||||
|
- `Get-CimInstance` was denied and `Get-Counter` lacked the requested counter. I used
|
||||||
|
`GlobalMemoryStatusEx` instead; the initial available-memory reading was 15.85 GiB. BuildHost
|
||||||
|
scripts also enforce the 4 GiB preflight, Normal priority, 12-CPU affinity, 8 GiB process cap,
|
||||||
|
and 900 s timeout.
|
||||||
|
- Standalone build printed that `vswhere.exe` was not recognized and emitted existing
|
||||||
|
`VoxelStrateManager.cpp` C4838 narrowing warnings, but built both targets and exited successfully.
|
||||||
|
- BuildHost UBT passed on its first attempt; the 18 Core link shims passed link-safety inspection.
|
||||||
|
No `0xC0000142` occurred. No new `UECC-*` folder appeared (the only matching folder predates
|
||||||
|
this round, from 2026-09-17).
|
||||||
|
- Final diff review made the gradient memo's per-tile validity reset explicit by clearing every
|
||||||
|
validity byte after resizing the scratch array. Both targets were rebuilt and the corrected-source
|
||||||
|
stage, determinism, quality, and cold-trace gates were rerun; hashes stayed identical.
|
||||||
|
|
||||||
|
Diff review: no edits to `Epoch`, either MPSC queue, `EndPlay` draining, worker shutdown checks,
|
||||||
|
`ModsLock`, immutable region-page lifetime, or game-thread UObject/RMC mutation. The new cache and
|
||||||
|
gradient scratch remain thread-local. The readable RealtimeMeshComponent source was not modified.
|
||||||
|
No owner project, editor, asset, generated header, `Binaries/`, or `Intermediate/` source was edited.
|
||||||
|
No commit, push, or stash.
|
||||||
|
|
||||||
|
## 8. Files and compile spots
|
||||||
|
|
||||||
|
No new source file was added.
|
||||||
|
|
||||||
|
| Changed file | Likely compile/build spot |
|
||||||
|
|---|---|
|
||||||
|
| `Standalone/Core/include/VoxelForgeCore/VoxelForgeCore.h`, `Standalone/Core/src/VoxelForgeCore.cpp`, `Standalone/Core/src/WorldAssemblerInternal.h` | Standalone Core and BuildHost `VoxelForgeCore` |
|
||||||
|
| `Standalone/Source/VoxelForge/Public/VoxelMarchingCubesMesher.h`, `Standalone/Source/VoxelForge/Private/VoxelMarchingCubesMesher.cpp` | Standalone executable and BuildHost `VoxelForge` runtime |
|
||||||
|
| `Source/VoxelForge/Private/VoxelWorld.cpp` | BuildHost `VoxelForge` runtime |
|
||||||
|
| `Source/VoxelForgeEditor/Private/VoxelForgeExploreCommandlet.cpp` | BuildHost `VoxelForgeEditor` |
|
||||||
|
| `Tools/TestVoxelForgeCoreWorldHost.ps1` | BuildHost validation harness; no compile |
|
||||||
|
| `ARCHITECTURE.md`, `CODEMAP.md` | Documentation; no compile |
|
||||||
|
|
||||||
|
### Dialogue
|
||||||
|
|
||||||
|
**Owner:** What is inside the LOD0 MC-exclusive cost, why does LOD4 miss, and is a shared page worth it?
|
||||||
|
|
||||||
|
**Codex:** LOD0’s dominant measured MC-exclusive stage is density-grid evaluation excluding XY
|
||||||
|
column work (about 165 ns/sample), followed by grid-gradient normals (24 ns/sample after exact
|
||||||
|
memoization). The cache counters show LOD4’s direct-map spike was chiefly conflicts; four-way sets
|
||||||
|
remove those while keeping exact samples. Cross-worker repeats remain, but no shared-page A/B
|
||||||
|
measured a net cold-path win, so I left the S8 page lifetime unchanged.
|
||||||
@@ -0,0 +1,397 @@
|
|||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <EGL/eglext.h>
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct FVertex
|
||||||
|
{
|
||||||
|
float Position[3];
|
||||||
|
float Normal[3];
|
||||||
|
float Height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FScene
|
||||||
|
{
|
||||||
|
std::uint32_t VoxelSizeMicrons=0;
|
||||||
|
std::array<double,3> CameraMeters{};
|
||||||
|
double YawDegrees=0.0,PitchDegrees=0.0;
|
||||||
|
std::vector<FVertex> Vertices;
|
||||||
|
std::vector<std::uint32_t> Indices;
|
||||||
|
std::uint64_t Triangles=0,SkirtTriangles=0;
|
||||||
|
std::uint32_t TileCount=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> bool Read(std::ifstream& File,T& Value)
|
||||||
|
{
|
||||||
|
File.read(reinterpret_cast<char*>(&Value),sizeof(Value));
|
||||||
|
return static_cast<bool>(File);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadScene(const std::filesystem::path& Path,FScene& Scene,std::string& Error)
|
||||||
|
{
|
||||||
|
std::ifstream File(Path,std::ios::binary);
|
||||||
|
if(!File){Error="cannot open mesh scene";return false;}
|
||||||
|
char Magic[8]{};
|
||||||
|
File.read(Magic,sizeof(Magic));
|
||||||
|
if(!File||std::memcmp(Magic,"VFMSH001",8)!=0)
|
||||||
|
{Error="mesh scene magic is invalid";return false;}
|
||||||
|
std::uint32_t Version=0,ExpectedTiles=0;
|
||||||
|
if(!Read(File,Version)||!Read(File,Scene.VoxelSizeMicrons)||!Read(File,ExpectedTiles)
|
||||||
|
||Version!=1||Scene.VoxelSizeMicrons==0||ExpectedTiles>1000000)
|
||||||
|
{Error="mesh scene header is malformed";return false;}
|
||||||
|
for(double& Value:Scene.CameraMeters)if(!Read(File,Value))
|
||||||
|
{Error="mesh scene camera is truncated";return false;}
|
||||||
|
if(!Read(File,Scene.YawDegrees)||!Read(File,Scene.PitchDegrees))
|
||||||
|
{Error="mesh scene camera orientation is truncated";return false;}
|
||||||
|
Scene.TileCount=ExpectedTiles;
|
||||||
|
std::uint64_t TotalVertices=0,TotalIndices=0;
|
||||||
|
for(std::uint32_t Tile=0;Tile<ExpectedTiles;++Tile)
|
||||||
|
{
|
||||||
|
std::int32_t Key[4]{};
|
||||||
|
std::uint32_t SurfaceVertices=0,SkirtCount=0,VertexCount=0,IndexCount=0,MaskCount=0;
|
||||||
|
for(auto& Value:Key)if(!Read(File,Value)){Error="tile key is truncated";return false;}
|
||||||
|
if(!Read(File,SurfaceVertices)||!Read(File,SkirtCount)||!Read(File,VertexCount)
|
||||||
|
||!Read(File,IndexCount)||!Read(File,MaskCount)
|
||||||
|
||VertexCount>10000000||IndexCount>60000000||MaskCount>20000000
|
||||||
|
||IndexCount%3!=0||(MaskCount!=0&&MaskCount!=IndexCount/3))
|
||||||
|
{Error="tile mesh header is malformed";return false;}
|
||||||
|
if(TotalVertices+VertexCount>std::numeric_limits<std::uint32_t>::max()
|
||||||
|
||TotalIndices+IndexCount>std::numeric_limits<std::size_t>::max())
|
||||||
|
{Error="mesh scene exceeds supported index space";return false;}
|
||||||
|
const std::size_t Base=Scene.Vertices.size();
|
||||||
|
Scene.Vertices.resize(Base+VertexCount);
|
||||||
|
Scene.Indices.reserve(Scene.Indices.size()+IndexCount);
|
||||||
|
for(std::size_t I=Base;I<Base+VertexCount;++I)
|
||||||
|
for(float& Value:Scene.Vertices[I].Position)if(!Read(File,Value))
|
||||||
|
{Error="tile positions are truncated";return false;}
|
||||||
|
for(std::size_t I=Base;I<Base+VertexCount;++I)
|
||||||
|
{
|
||||||
|
for(float& Value:Scene.Vertices[I].Normal)if(!Read(File,Value))
|
||||||
|
{Error="tile normals are truncated";return false;}
|
||||||
|
Scene.Vertices[I].Height=Scene.Vertices[I].Position[2];
|
||||||
|
}
|
||||||
|
const std::size_t IndexOffset=Scene.Indices.size();
|
||||||
|
Scene.Indices.resize(IndexOffset+IndexCount);
|
||||||
|
if(IndexCount)File.read(reinterpret_cast<char*>(Scene.Indices.data()+IndexOffset),
|
||||||
|
static_cast<std::streamsize>(sizeof(std::uint32_t)*IndexCount));
|
||||||
|
std::vector<std::uint8_t> Masks(MaskCount);
|
||||||
|
if(MaskCount)File.read(reinterpret_cast<char*>(Masks.data()),MaskCount);
|
||||||
|
if(!File){Error="tile index or skirt data is truncated";return false;}
|
||||||
|
for(std::size_t Index=IndexOffset;Index<Scene.Indices.size();++Index)
|
||||||
|
{
|
||||||
|
if(Scene.Indices[Index]>=VertexCount)
|
||||||
|
{Error="tile index points outside its vertex array";return false;}
|
||||||
|
Scene.Indices[Index]+=static_cast<std::uint32_t>(Base);
|
||||||
|
}
|
||||||
|
Scene.Triangles+=IndexCount/3;
|
||||||
|
Scene.SkirtTriangles+=SkirtCount;
|
||||||
|
TotalVertices+=VertexCount;TotalIndices+=IndexCount;
|
||||||
|
}
|
||||||
|
if(File.peek()!=std::char_traits<char>::eof())
|
||||||
|
{Error="mesh scene has trailing bytes";return false;}
|
||||||
|
if(Scene.Indices.empty()){Error="mesh scene contains no triangles";return false;}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLDisplay MakeDisplay()
|
||||||
|
{
|
||||||
|
using TGetPlatformDisplay=EGLDisplay(*)(EGLenum,void*,const EGLint*);
|
||||||
|
auto GetPlatformDisplay=reinterpret_cast<TGetPlatformDisplay>(
|
||||||
|
eglGetProcAddress("eglGetPlatformDisplayEXT"));
|
||||||
|
#ifdef EGL_PLATFORM_SURFACELESS_MESA
|
||||||
|
if(GetPlatformDisplay)
|
||||||
|
{
|
||||||
|
const EGLDisplay Display=GetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA,
|
||||||
|
EGL_DEFAULT_DISPLAY,nullptr);
|
||||||
|
if(Display!=EGL_NO_DISPLAY)return Display;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint CompileShader(GLenum Type,const char* Source)
|
||||||
|
{
|
||||||
|
const GLuint Shader=glCreateShader(Type);
|
||||||
|
glShaderSource(Shader,1,&Source,nullptr);
|
||||||
|
glCompileShader(Shader);
|
||||||
|
GLint Success=GL_FALSE;
|
||||||
|
glGetShaderiv(Shader,GL_COMPILE_STATUS,&Success);
|
||||||
|
if(Success==GL_FALSE)
|
||||||
|
{
|
||||||
|
GLint Length=0;glGetShaderiv(Shader,GL_INFO_LOG_LENGTH,&Length);
|
||||||
|
std::string Log(static_cast<std::size_t>(std::max(Length,1)),0);
|
||||||
|
glGetShaderInfoLog(Shader,Length,nullptr,Log.data());
|
||||||
|
std::fprintf(stderr,"[OffscreenGL] shader compile failed: %s\n",Log.c_str());
|
||||||
|
glDeleteShader(Shader);return 0;
|
||||||
|
}
|
||||||
|
return Shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint MakeProgram()
|
||||||
|
{
|
||||||
|
static constexpr char VertexSource[]=R"GLSL(#version 300 es
|
||||||
|
precision highp float;
|
||||||
|
layout(location=0) in vec3 inCameraPosition;
|
||||||
|
layout(location=1) in vec3 inNormal;
|
||||||
|
layout(location=2) in float inHeight;
|
||||||
|
out vec3 vNormal;
|
||||||
|
out float vHeight;
|
||||||
|
uniform float uTanHalfHorizontal;
|
||||||
|
uniform float uTanHalfVertical;
|
||||||
|
uniform float uNear;
|
||||||
|
uniform float uFar;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float z=max(inCameraPosition.z,0.0001);
|
||||||
|
float clipZ=((uFar+uNear)/(uFar-uNear))*z-(2.0*uFar*uNear)/(uFar-uNear);
|
||||||
|
gl_Position=vec4(inCameraPosition.x/uTanHalfHorizontal,
|
||||||
|
inCameraPosition.y/uTanHalfVertical,clipZ,z);
|
||||||
|
vNormal=normalize(inNormal);
|
||||||
|
vHeight=inHeight;
|
||||||
|
})GLSL";
|
||||||
|
static constexpr char FragmentSource[]=R"GLSL(#version 300 es
|
||||||
|
precision highp float;
|
||||||
|
in vec3 vNormal;
|
||||||
|
in float vHeight;
|
||||||
|
out vec4 outColor;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 n=normalize(vNormal);
|
||||||
|
vec3 normalColor=abs(n)*0.78+vec3(0.12);
|
||||||
|
float band=mod(floor((vHeight+10000.0)/80.0),2.0);
|
||||||
|
vec3 bandColor=mix(vec3(0.24,0.31,0.37),vec3(0.39,0.42,0.35),band);
|
||||||
|
outColor=vec4(mix(bandColor,normalColor,0.68),1.0);
|
||||||
|
})GLSL";
|
||||||
|
const GLuint VS=CompileShader(GL_VERTEX_SHADER,VertexSource);
|
||||||
|
const GLuint FS=CompileShader(GL_FRAGMENT_SHADER,FragmentSource);
|
||||||
|
if(!VS||!FS)return 0;
|
||||||
|
const GLuint Program=glCreateProgram();
|
||||||
|
glAttachShader(Program,VS);glAttachShader(Program,FS);glLinkProgram(Program);
|
||||||
|
glDeleteShader(VS);glDeleteShader(FS);
|
||||||
|
GLint Success=GL_FALSE;glGetProgramiv(Program,GL_LINK_STATUS,&Success);
|
||||||
|
if(Success==GL_FALSE)
|
||||||
|
{
|
||||||
|
GLint Length=0;glGetProgramiv(Program,GL_INFO_LOG_LENGTH,&Length);
|
||||||
|
std::string Log(static_cast<std::size_t>(std::max(Length,1)),0);
|
||||||
|
glGetProgramInfoLog(Program,Length,nullptr,Log.data());
|
||||||
|
std::fprintf(stderr,"[OffscreenGL] program link failed: %s\n",Log.c_str());
|
||||||
|
glDeleteProgram(Program);return 0;
|
||||||
|
}
|
||||||
|
return Program;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WritePng(const std::filesystem::path& Path,int Width,int Height,
|
||||||
|
const std::vector<std::uint8_t>& Pixels)
|
||||||
|
{
|
||||||
|
std::error_code Error;
|
||||||
|
if(!Path.parent_path().empty())std::filesystem::create_directories(Path.parent_path(),Error);
|
||||||
|
if(Error)return false;
|
||||||
|
FILE* File=std::fopen(Path.c_str(),"wb");
|
||||||
|
if(!File)return false;
|
||||||
|
png_structp Png=png_create_write_struct(PNG_LIBPNG_VER_STRING,nullptr,nullptr,nullptr);
|
||||||
|
png_infop Info=Png?png_create_info_struct(Png):nullptr;
|
||||||
|
if(!Png||!Info){if(Png)png_destroy_write_struct(&Png,nullptr);std::fclose(File);return false;}
|
||||||
|
if(setjmp(png_jmpbuf(Png)))
|
||||||
|
{png_destroy_write_struct(&Png,&Info);std::fclose(File);return false;}
|
||||||
|
png_init_io(Png,File);
|
||||||
|
png_set_IHDR(Png,Info,static_cast<png_uint_32>(Width),static_cast<png_uint_32>(Height),
|
||||||
|
8,PNG_COLOR_TYPE_RGBA,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
png_write_info(Png,Info);
|
||||||
|
const std::size_t Stride=static_cast<std::size_t>(Width)*4;
|
||||||
|
for(int Y=Height-1;Y>=0;--Y)
|
||||||
|
png_write_row(Png,const_cast<png_bytep>(Pixels.data()+static_cast<std::size_t>(Y)*Stride));
|
||||||
|
png_write_end(Png,nullptr);
|
||||||
|
png_destroy_write_struct(&Png,&Info);
|
||||||
|
const bool Good=std::fclose(File)==0;
|
||||||
|
return Good;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Render(FScene& Scene,const std::filesystem::path& Output,int Width,int Height,
|
||||||
|
double HorizontalFovDegrees)
|
||||||
|
{
|
||||||
|
EGLDisplay Display=MakeDisplay();
|
||||||
|
EGLint Major=0,Minor=0;
|
||||||
|
if(Display==EGL_NO_DISPLAY||eglInitialize(Display,&Major,&Minor)!=EGL_TRUE)
|
||||||
|
{std::fprintf(stderr,"[OffscreenEGL] eglInitialize failed (0x%x)\n",eglGetError());return false;}
|
||||||
|
if(eglBindAPI(EGL_OPENGL_ES_API)!=EGL_TRUE)
|
||||||
|
{std::fprintf(stderr,"[OffscreenEGL] eglBindAPI failed (0x%x)\n",eglGetError());eglTerminate(Display);return false;}
|
||||||
|
const EGLint ConfigAttributes[]={EGL_SURFACE_TYPE,EGL_PBUFFER_BIT,
|
||||||
|
EGL_RENDERABLE_TYPE,EGL_OPENGL_ES3_BIT,EGL_RED_SIZE,8,EGL_GREEN_SIZE,8,
|
||||||
|
EGL_BLUE_SIZE,8,EGL_ALPHA_SIZE,8,EGL_DEPTH_SIZE,24,EGL_NONE};
|
||||||
|
EGLConfig Config{};EGLint ConfigCount=0;
|
||||||
|
if(eglChooseConfig(Display,ConfigAttributes,&Config,1,&ConfigCount)!=EGL_TRUE||ConfigCount==0)
|
||||||
|
{std::fprintf(stderr,"[OffscreenEGL] no GLES3 pbuffer config (0x%x)\n",eglGetError());eglTerminate(Display);return false;}
|
||||||
|
const EGLint SurfaceAttributes[]={EGL_WIDTH,Width,EGL_HEIGHT,Height,EGL_NONE};
|
||||||
|
EGLSurface Surface=eglCreatePbufferSurface(Display,Config,SurfaceAttributes);
|
||||||
|
const EGLint ContextAttributes[]={EGL_CONTEXT_CLIENT_VERSION,3,EGL_NONE};
|
||||||
|
EGLContext Context=eglCreateContext(Display,Config,EGL_NO_CONTEXT,ContextAttributes);
|
||||||
|
if(Surface==EGL_NO_SURFACE||Context==EGL_NO_CONTEXT
|
||||||
|
||eglMakeCurrent(Display,Surface,Surface,Context)!=EGL_TRUE)
|
||||||
|
{std::fprintf(stderr,"[OffscreenEGL] context/surface creation failed (0x%x)\n",eglGetError());
|
||||||
|
if(Context!=EGL_NO_CONTEXT)eglDestroyContext(Display,Context);
|
||||||
|
if(Surface!=EGL_NO_SURFACE)eglDestroySurface(Display,Surface);
|
||||||
|
eglTerminate(Display);return false;}
|
||||||
|
|
||||||
|
const GLubyte* Renderer=glGetString(GL_RENDERER);
|
||||||
|
const GLubyte* GlVersion=glGetString(GL_VERSION);
|
||||||
|
std::printf("[OffscreenEGL] renderer=%s version=%s pbuffer=%dx%d\n",
|
||||||
|
Renderer?reinterpret_cast<const char*>(Renderer):"unknown",
|
||||||
|
GlVersion?reinterpret_cast<const char*>(GlVersion):"unknown",Width,Height);
|
||||||
|
GLuint ColorTexture=0,DepthBuffer=0,Framebuffer=0;
|
||||||
|
glGenTextures(1,&ColorTexture);glBindTexture(GL_TEXTURE_2D,ColorTexture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,Width,Height,0,GL_RGBA,GL_UNSIGNED_BYTE,nullptr);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||||
|
glGenRenderbuffers(1,&DepthBuffer);glBindRenderbuffer(GL_RENDERBUFFER,DepthBuffer);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24,Width,Height);
|
||||||
|
glGenFramebuffers(1,&Framebuffer);glBindFramebuffer(GL_FRAMEBUFFER,Framebuffer);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,ColorTexture,0);
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,DepthBuffer);
|
||||||
|
if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{std::fprintf(stderr,"[OffscreenGL] framebuffer is incomplete\n");return false;}
|
||||||
|
|
||||||
|
constexpr double Pi=3.14159265358979323846;
|
||||||
|
const double Yaw=Scene.YawDegrees*Pi/180.0,Pitch=Scene.PitchDegrees*Pi/180.0;
|
||||||
|
const std::array<double,3> Forward={std::sin(Yaw)*std::cos(Pitch),
|
||||||
|
std::cos(Yaw)*std::cos(Pitch),std::sin(Pitch)};
|
||||||
|
const std::array<double,3> Right={std::cos(Yaw),-std::sin(Yaw),0.0};
|
||||||
|
const std::array<double,3> Up={Right[1]*Forward[2]-Right[2]*Forward[1],
|
||||||
|
Right[2]*Forward[0]-Right[0]*Forward[2],Right[0]*Forward[1]-Right[1]*Forward[0]};
|
||||||
|
const double TanHalfHorizontal=std::tan(HorizontalFovDegrees*Pi/360.0);
|
||||||
|
const double Aspect=static_cast<double>(Width)/Height;
|
||||||
|
const double TanHalfVertical=TanHalfHorizontal/Aspect;
|
||||||
|
const double Near=0.1,Far=20000.0;
|
||||||
|
for(FVertex& Vertex:Scene.Vertices)
|
||||||
|
{
|
||||||
|
const double DX=Vertex.Position[0]-Scene.CameraMeters[0];
|
||||||
|
const double DY=Vertex.Position[1]-Scene.CameraMeters[1];
|
||||||
|
const double DZ=Vertex.Position[2]-Scene.CameraMeters[2];
|
||||||
|
const float CameraX=static_cast<float>(DX*Right[0]+DY*Right[1]+DZ*Right[2]);
|
||||||
|
const float CameraY=static_cast<float>(DX*Up[0]+DY*Up[1]+DZ*Up[2]);
|
||||||
|
const float CameraZ=static_cast<float>(DX*Forward[0]+DY*Forward[1]+DZ*Forward[2]);
|
||||||
|
Vertex.Position[0]=CameraX;Vertex.Position[1]=CameraY;Vertex.Position[2]=CameraZ;
|
||||||
|
}
|
||||||
|
const GLuint Program=MakeProgram();
|
||||||
|
if(!Program)return false;
|
||||||
|
GLuint Vao=0,Vbo=0,Ebo=0;
|
||||||
|
glGenVertexArrays(1,&Vao);glBindVertexArray(Vao);
|
||||||
|
glGenBuffers(1,&Vbo);glBindBuffer(GL_ARRAY_BUFFER,Vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER,static_cast<GLsizeiptr>(Scene.Vertices.size()*sizeof(FVertex)),
|
||||||
|
Scene.Vertices.data(),GL_STATIC_DRAW);
|
||||||
|
glGenBuffers(1,&Ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,Ebo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER,static_cast<GLsizeiptr>(Scene.Indices.size()*sizeof(std::uint32_t)),
|
||||||
|
Scene.Indices.data(),GL_STATIC_DRAW);
|
||||||
|
glEnableVertexAttribArray(0);glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(FVertex),
|
||||||
|
reinterpret_cast<void*>(offsetof(FVertex,Position)));
|
||||||
|
glEnableVertexAttribArray(1);glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(FVertex),
|
||||||
|
reinterpret_cast<void*>(offsetof(FVertex,Normal)));
|
||||||
|
glEnableVertexAttribArray(2);glVertexAttribPointer(2,1,GL_FLOAT,GL_FALSE,sizeof(FVertex),
|
||||||
|
reinterpret_cast<void*>(offsetof(FVertex,Height)));
|
||||||
|
glViewport(0,0,Width,Height);glDisable(GL_CULL_FACE);glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(GL_LEQUAL);glClearColor(0.035f,0.055f,0.075f,1.0f);
|
||||||
|
glClearDepthf(1.0f);glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||||
|
glUseProgram(Program);
|
||||||
|
glUniform1f(glGetUniformLocation(Program,"uTanHalfHorizontal"),static_cast<float>(TanHalfHorizontal));
|
||||||
|
glUniform1f(glGetUniformLocation(Program,"uTanHalfVertical"),static_cast<float>(TanHalfVertical));
|
||||||
|
glUniform1f(glGetUniformLocation(Program,"uNear"),static_cast<float>(Near));
|
||||||
|
glUniform1f(glGetUniformLocation(Program,"uFar"),static_cast<float>(Far));
|
||||||
|
glDrawElements(GL_TRIANGLES,static_cast<GLsizei>(Scene.Indices.size()),GL_UNSIGNED_INT,nullptr);
|
||||||
|
glFinish();
|
||||||
|
std::vector<std::uint8_t> Pixels(static_cast<std::size_t>(Width)*Height*4);
|
||||||
|
glReadPixels(0,0,Width,Height,GL_RGBA,GL_UNSIGNED_BYTE,Pixels.data());
|
||||||
|
const GLenum GlError=glGetError();
|
||||||
|
const bool PngGood=GlError==GL_NO_ERROR&&WritePng(Output,Width,Height,Pixels);
|
||||||
|
if(!PngGood)std::fprintf(stderr,"[OffscreenGL] render or PNG write failed (GL=0x%x)\n",GlError);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::error_code SizeError;
|
||||||
|
const auto Bytes=std::filesystem::file_size(Output,SizeError);
|
||||||
|
std::printf("[OffscreenCapture] triangles=%llu tiles=%u skirts=%llu png_bytes=%llu status=PASS path=%s\n",
|
||||||
|
static_cast<unsigned long long>(Scene.Triangles),Scene.TileCount,
|
||||||
|
static_cast<unsigned long long>(Scene.SkirtTriangles),
|
||||||
|
static_cast<unsigned long long>(SizeError?0:Bytes),Output.string().c_str());
|
||||||
|
}
|
||||||
|
glDeleteProgram(Program);glDeleteBuffers(1,&Ebo);glDeleteBuffers(1,&Vbo);
|
||||||
|
glDeleteVertexArrays(1,&Vao);glDeleteFramebuffers(1,&Framebuffer);
|
||||||
|
glDeleteRenderbuffers(1,&DepthBuffer);glDeleteTextures(1,&ColorTexture);
|
||||||
|
eglMakeCurrent(Display,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT);
|
||||||
|
eglDestroyContext(Display,Context);eglDestroySurface(Display,Surface);eglTerminate(Display);
|
||||||
|
return PngGood;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc,char** argv)
|
||||||
|
{
|
||||||
|
if(argc<3)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr,"Usage: %s scene.vfmesh output.png [--size=WIDTHxHEIGHT] [--fov-deg=90] [--camera-m=X,Y,Z] [--yaw-deg=N] [--pitch-deg=N]\n",argv[0]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
int Width=2560,Height=1440;double Fov=90.0;
|
||||||
|
bool HasYaw=false,HasPitch=false;double Yaw=0.0,Pitch=0.0;
|
||||||
|
bool HasCamera=false;std::array<double,3> Camera{};
|
||||||
|
for(int I=3;I<argc;++I)
|
||||||
|
{
|
||||||
|
const std::string_view Arg(argv[I]);
|
||||||
|
if(Arg.starts_with("--size="))
|
||||||
|
{
|
||||||
|
const std::string Value(Arg.substr(7));
|
||||||
|
if(std::sscanf(Value.c_str(),"%dx%d",&Width,&Height)!=2||Width<=0||Height<=0)
|
||||||
|
{std::fprintf(stderr,"Invalid image size\n");return 2;}
|
||||||
|
}
|
||||||
|
else if(Arg.starts_with("--fov-deg="))
|
||||||
|
{
|
||||||
|
char* End=nullptr;const std::string Value(Arg.substr(10));Fov=std::strtod(Value.c_str(),&End);
|
||||||
|
if(End==Value.c_str()||*End!='\0'||Fov<=1.0||Fov>=179.0)
|
||||||
|
{std::fprintf(stderr,"Invalid horizontal FOV\n");return 2;}
|
||||||
|
}
|
||||||
|
else if(Arg.starts_with("--camera-m="))
|
||||||
|
{
|
||||||
|
const std::string Value(Arg.substr(11));
|
||||||
|
if(std::sscanf(Value.c_str(),"%lf,%lf,%lf",&Camera[0],&Camera[1],&Camera[2])!=3
|
||||||
|
||!std::isfinite(Camera[0])||!std::isfinite(Camera[1])||!std::isfinite(Camera[2]))
|
||||||
|
{std::fprintf(stderr,"Invalid camera position\n");return 2;}
|
||||||
|
HasCamera=true;
|
||||||
|
}
|
||||||
|
else if(Arg.starts_with("--yaw-deg=")||Arg.starts_with("--pitch-deg="))
|
||||||
|
{
|
||||||
|
const bool IsYaw=Arg.starts_with("--yaw-deg=");
|
||||||
|
const std::size_t Prefix=IsYaw?10:12;
|
||||||
|
const std::string Value(Arg.substr(Prefix));char* End=nullptr;
|
||||||
|
const double Parsed=std::strtod(Value.c_str(),&End);
|
||||||
|
if(End==Value.c_str()||*End!='\0'||!std::isfinite(Parsed))
|
||||||
|
{std::fprintf(stderr,"Invalid camera angle\n");return 2;}
|
||||||
|
if(IsYaw){Yaw=Parsed;HasYaw=true;}else{Pitch=Parsed;HasPitch=true;}
|
||||||
|
}
|
||||||
|
else {std::fprintf(stderr,"Unknown option: %.*s\n",static_cast<int>(Arg.size()),Arg.data());return 2;}
|
||||||
|
}
|
||||||
|
FScene Scene;std::string Error;
|
||||||
|
if(!LoadScene(argv[1],Scene,Error))
|
||||||
|
{std::fprintf(stderr,"[OffscreenCapture] FAIL: %s\n",Error.c_str());return 2;}
|
||||||
|
if(HasCamera)Scene.CameraMeters=Camera;
|
||||||
|
if(HasYaw)Scene.YawDegrees=Yaw;
|
||||||
|
if(HasPitch)Scene.PitchDegrees=Pitch;
|
||||||
|
std::printf("[OffscreenScene] voxels_per_meter=%.6f camera_m=(%.3f,%.3f,%.3f) yaw=%.2f pitch=%.2f vertices=%zu triangles=%llu\n",
|
||||||
|
1000000.0/Scene.VoxelSizeMicrons,Scene.CameraMeters[0],Scene.CameraMeters[1],Scene.CameraMeters[2],
|
||||||
|
Scene.YawDegrees,Scene.PitchDegrees,Scene.Vertices.size(),
|
||||||
|
static_cast<unsigned long long>(Scene.Triangles));
|
||||||
|
return Render(Scene,argv[2],Width,Height,Fov)?0:3;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,721 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "StreamingWorld.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <limits>
|
||||||
|
#include <optional>
|
||||||
|
#include <span>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace StandaloneScreenSpaceGate
|
||||||
|
{
|
||||||
|
inline constexpr double OnePixelRadians=1.57079632679489661923/2560.0;
|
||||||
|
|
||||||
|
struct FErrorRow
|
||||||
|
{
|
||||||
|
int Lod=0;
|
||||||
|
std::uint64_t Samples=0,Missing=0,Floating=0;
|
||||||
|
double P50=0.0,P99=0.0,Maximum=0.0;
|
||||||
|
double VerticalP50=0.0,VerticalP99=0.0,VerticalMaximum=0.0;
|
||||||
|
double MaximumNormalDistanceMeters=0.0,MaximumX=0.0,MaximumY=0.0;
|
||||||
|
double MaximumReferenceZ=0.0,MaximumDisplayedZ=0.0;
|
||||||
|
double MaximumSlopeDegrees=0.0;
|
||||||
|
std::array<std::uint64_t,4> SlopeSamples{};
|
||||||
|
std::array<double,4> SlopeP99{},SlopeMaximum{};
|
||||||
|
bool Valid=false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FPopRow
|
||||||
|
{
|
||||||
|
int CoarseLod=0;
|
||||||
|
std::uint64_t Samples=0,Cracks=0,Floating=0;
|
||||||
|
double P50=0.0,P99=0.0,Maximum=0.0;
|
||||||
|
double VerticalP50=0.0,VerticalP99=0.0,VerticalMaximum=0.0;
|
||||||
|
double MaximumNormalDistanceMeters=0.0,MaximumX=0.0,MaximumY=0.0;
|
||||||
|
double MaximumReferenceZ=0.0,MaximumDisplayedZ=0.0;
|
||||||
|
double MaximumSlopeDegrees=0.0;
|
||||||
|
std::array<std::uint64_t,4> SlopeSamples{};
|
||||||
|
std::array<double,4> SlopeP99{},SlopeMaximum{};
|
||||||
|
bool Valid=false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FSurfaceRoot
|
||||||
|
{
|
||||||
|
double ZMeters=0.0;
|
||||||
|
double SlopeX=0.0;
|
||||||
|
double SlopeY=0.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FViewBasis
|
||||||
|
{
|
||||||
|
std::array<double,3> Right{};
|
||||||
|
std::array<double,3> Up{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FErrorAccumulator
|
||||||
|
{
|
||||||
|
std::vector<double> Pixels,VerticalPixels;
|
||||||
|
std::array<std::vector<double>,4> BySlope;
|
||||||
|
double Maximum=-1.0,MaximumVertical=0.0,MaximumNormalDistanceMeters=0.0;
|
||||||
|
double MaximumX=0.0,MaximumY=0.0,MaximumSlopeDegrees=0.0;
|
||||||
|
double MaximumReferenceZ=0.0,MaximumDisplayedZ=0.0;
|
||||||
|
std::array<std::uint64_t,4> SlopeSamples{};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline double Percentile(std::vector<double>& Values,double P);
|
||||||
|
|
||||||
|
inline FViewBasis MakeViewBasis(double YawDegrees,double PitchDegrees)
|
||||||
|
{
|
||||||
|
constexpr double Pi=3.14159265358979323846;
|
||||||
|
const double Yaw=YawDegrees*Pi/180.0,Pitch=PitchDegrees*Pi/180.0;
|
||||||
|
const std::array<double,3> Forward={std::sin(Yaw)*std::cos(Pitch),
|
||||||
|
std::cos(Yaw)*std::cos(Pitch),std::sin(Pitch)};
|
||||||
|
FViewBasis Basis;
|
||||||
|
Basis.Right={std::cos(Yaw),-std::sin(Yaw),0.0};
|
||||||
|
Basis.Up={Basis.Right[1]*Forward[2]-Basis.Right[2]*Forward[1],
|
||||||
|
Basis.Right[2]*Forward[0]-Basis.Right[0]*Forward[2],
|
||||||
|
Basis.Right[0]*Forward[1]-Basis.Right[1]*Forward[0]};
|
||||||
|
return Basis;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::size_t SlopeBin(double Degrees)
|
||||||
|
{
|
||||||
|
if(Degrees<30.0)return 0;
|
||||||
|
if(Degrees<45.0)return 1;
|
||||||
|
if(Degrees<60.0)return 2;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AddError(FErrorAccumulator& Accumulator,double DeltaZMeters,
|
||||||
|
const FSurfaceRoot& Root,double PixelBudgetMeters,const FViewBasis& View,
|
||||||
|
double X,double Y)
|
||||||
|
{
|
||||||
|
constexpr double Pi=3.14159265358979323846;
|
||||||
|
const double GradientSquared=Root.SlopeX*Root.SlopeX+Root.SlopeY*Root.SlopeY;
|
||||||
|
const double NormalLength=std::sqrt(1.0+GradientSquared);
|
||||||
|
const double NormalX=-Root.SlopeX/NormalLength;
|
||||||
|
const double NormalY=-Root.SlopeY/NormalLength;
|
||||||
|
const double NormalZ=1.0/NormalLength;
|
||||||
|
const double NormalDistance=std::abs(DeltaZMeters)/NormalLength;
|
||||||
|
const double ProjectedNormal=std::hypot(
|
||||||
|
NormalX*View.Right[0]+NormalY*View.Right[1]+NormalZ*View.Right[2],
|
||||||
|
NormalX*View.Up[0]+NormalY*View.Up[1]+NormalZ*View.Up[2]);
|
||||||
|
const double ProjectedVertical=std::hypot(View.Right[2],View.Up[2]);
|
||||||
|
const double NormalPixels=NormalDistance*ProjectedNormal/PixelBudgetMeters;
|
||||||
|
const double VerticalPixels=std::abs(DeltaZMeters)*ProjectedVertical/PixelBudgetMeters;
|
||||||
|
const double SlopeDegrees=std::atan(std::sqrt(GradientSquared))*180.0/Pi;
|
||||||
|
Accumulator.Pixels.push_back(NormalPixels);
|
||||||
|
Accumulator.VerticalPixels.push_back(VerticalPixels);
|
||||||
|
const std::size_t Bin=SlopeBin(SlopeDegrees);
|
||||||
|
Accumulator.BySlope[Bin].push_back(NormalPixels);
|
||||||
|
++Accumulator.SlopeSamples[Bin];
|
||||||
|
if(NormalPixels>Accumulator.Maximum)
|
||||||
|
{
|
||||||
|
Accumulator.Maximum=NormalPixels;
|
||||||
|
Accumulator.MaximumVertical=VerticalPixels;
|
||||||
|
Accumulator.MaximumNormalDistanceMeters=NormalDistance;
|
||||||
|
Accumulator.MaximumX=X;Accumulator.MaximumY=Y;
|
||||||
|
Accumulator.MaximumSlopeDegrees=SlopeDegrees;
|
||||||
|
Accumulator.MaximumReferenceZ=Root.ZMeters;
|
||||||
|
Accumulator.MaximumDisplayedZ=Root.ZMeters+DeltaZMeters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AddMissing(FErrorAccumulator& Accumulator)
|
||||||
|
{
|
||||||
|
Accumulator.Pixels.push_back(2.0);
|
||||||
|
Accumulator.VerticalPixels.push_back(2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void FinalizeError(FErrorRow& Row,FErrorAccumulator& Accumulator)
|
||||||
|
{
|
||||||
|
Row.Samples=Accumulator.Pixels.size();
|
||||||
|
Row.P50=Percentile(Accumulator.Pixels,0.50);
|
||||||
|
Row.P99=Percentile(Accumulator.Pixels,0.99);
|
||||||
|
Row.Maximum=Accumulator.Pixels.empty()?0.0
|
||||||
|
:*std::max_element(Accumulator.Pixels.begin(),Accumulator.Pixels.end());
|
||||||
|
Row.VerticalP50=Percentile(Accumulator.VerticalPixels,0.50);
|
||||||
|
Row.VerticalP99=Percentile(Accumulator.VerticalPixels,0.99);
|
||||||
|
Row.VerticalMaximum=Accumulator.VerticalPixels.empty()?0.0
|
||||||
|
:*std::max_element(Accumulator.VerticalPixels.begin(),Accumulator.VerticalPixels.end());
|
||||||
|
Row.MaximumNormalDistanceMeters=Accumulator.MaximumNormalDistanceMeters;
|
||||||
|
Row.MaximumX=Accumulator.MaximumX;Row.MaximumY=Accumulator.MaximumY;
|
||||||
|
Row.MaximumReferenceZ=Accumulator.MaximumReferenceZ;
|
||||||
|
Row.MaximumDisplayedZ=Accumulator.MaximumDisplayedZ;
|
||||||
|
Row.MaximumSlopeDegrees=Accumulator.MaximumSlopeDegrees;
|
||||||
|
Row.SlopeSamples=Accumulator.SlopeSamples;
|
||||||
|
for(std::size_t Bin=0;Bin<Accumulator.BySlope.size();++Bin)
|
||||||
|
{
|
||||||
|
Row.SlopeP99[Bin]=Percentile(Accumulator.BySlope[Bin],0.99);
|
||||||
|
Row.SlopeMaximum[Bin]=Accumulator.BySlope[Bin].empty()?0.0
|
||||||
|
:*std::max_element(Accumulator.BySlope[Bin].begin(),Accumulator.BySlope[Bin].end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FHeightGrid
|
||||||
|
{
|
||||||
|
int Side=65;
|
||||||
|
double MinimumX=0.0,MaximumX=0.0,MinimumY=0.0,MaximumY=0.0;
|
||||||
|
std::vector<std::vector<double>> Hits;
|
||||||
|
|
||||||
|
FHeightGrid()=default;
|
||||||
|
FHeightGrid(int InSide,double MinX,double MaxX,double MinY,double MaxY)
|
||||||
|
:Side(InSide),MinimumX(MinX),MaximumX(MaxX),MinimumY(MinY),MaximumY(MaxY),
|
||||||
|
Hits(static_cast<std::size_t>(InSide)*InSide)
|
||||||
|
{}
|
||||||
|
|
||||||
|
double X(int Ix) const
|
||||||
|
{return MinimumX+(MaximumX-MinimumX)*Ix/(Side-1);}
|
||||||
|
double Y(int Iy) const
|
||||||
|
{return MinimumY+(MaximumY-MinimumY)*Iy/(Side-1);}
|
||||||
|
|
||||||
|
void Add(int Ix,int Iy,double Z)
|
||||||
|
{
|
||||||
|
auto& Values=Hits[static_cast<std::size_t>(Iy)*Side+Ix];
|
||||||
|
Values.push_back(Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<double>& At(int Ix,int Iy) const
|
||||||
|
{return Hits[static_cast<std::size_t>(Iy)*Side+Ix];}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline double Percentile(std::vector<double>& Values,double P)
|
||||||
|
{
|
||||||
|
if(Values.empty())return 0.0;
|
||||||
|
std::sort(Values.begin(),Values.end());
|
||||||
|
const std::size_t Index=std::min(Values.size()-1,
|
||||||
|
static_cast<std::size_t>(std::ceil(P*Values.size())-1));
|
||||||
|
return Values[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline double TileAabbDistanceMeters(const FVoxelTileKey& Key,
|
||||||
|
const FVector& CameraVoxels,double VoxelMeters)
|
||||||
|
{
|
||||||
|
const double Extent=static_cast<double>(Key.ExtentVoxels());
|
||||||
|
const double Min[3]={static_cast<double>(Key.OriginVoxels().X),
|
||||||
|
static_cast<double>(Key.OriginVoxels().Y),static_cast<double>(Key.OriginVoxels().Z)};
|
||||||
|
const double Cam[3]={CameraVoxels.X,CameraVoxels.Y,CameraVoxels.Z};
|
||||||
|
double Squared=0.0;
|
||||||
|
for(int Axis=0;Axis<3;++Axis)
|
||||||
|
{
|
||||||
|
const double Delta=Cam[Axis]<Min[Axis]?Min[Axis]-Cam[Axis]
|
||||||
|
:Cam[Axis]>Min[Axis]+Extent?Cam[Axis]-(Min[Axis]+Extent):0.0;
|
||||||
|
Squared+=Delta*Delta;
|
||||||
|
}
|
||||||
|
return std::sqrt(Squared)*VoxelMeters;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool TileHasNativeSurface(const FVoxelTileKey& Key,
|
||||||
|
const VoxelForgeCore::WorldAssemblyManifest& Assembly,
|
||||||
|
double VoxelMeters)
|
||||||
|
{
|
||||||
|
const double Extent=static_cast<double>(Key.ExtentVoxels());
|
||||||
|
const double X=(static_cast<double>(Key.OriginVoxels().X)+Extent*0.5)*256.0;
|
||||||
|
const double Y=(static_cast<double>(Key.OriginVoxels().Y)+Extent*0.5)*256.0;
|
||||||
|
const double MinZ=static_cast<double>(Key.OriginVoxels().Z);
|
||||||
|
const double MaxZ=MinZ+Extent;
|
||||||
|
for(const auto& Plan:Assembly.plan.strates)
|
||||||
|
{
|
||||||
|
VoxelForgeCore::Heightfield2D Field(Assembly.recipe,Plan);
|
||||||
|
if(!Field.isValid())continue;
|
||||||
|
const auto Column=Field.point(static_cast<std::int64_t>(std::llround(X)),
|
||||||
|
static_cast<std::int64_t>(std::llround(Y)),0);
|
||||||
|
const double Ground=static_cast<double>(Column.groundHeightSubvoxels)/256.0;
|
||||||
|
const double Cap=static_cast<double>(Column.capHeightSubvoxels)/256.0;
|
||||||
|
const double Margin=std::max(2.0,0.25/VoxelMeters);
|
||||||
|
if(Ground<Cap&&((Ground>=MinZ-Margin&&Ground<=MaxZ+Margin)
|
||||||
|
||(Cap>=MinZ-Margin&&Cap<=MaxZ+Margin)))return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FHeightGrid Rasterize(std::span<const FStandaloneCpuTile* const> Tiles,
|
||||||
|
const FVoxelTileKey& Patch,double VoxelMeters,int Side=65)
|
||||||
|
{
|
||||||
|
const double Extent=static_cast<double>(Patch.ExtentVoxels())*VoxelMeters;
|
||||||
|
const double MinX=static_cast<double>(Patch.OriginVoxels().X)*VoxelMeters;
|
||||||
|
const double MinY=static_cast<double>(Patch.OriginVoxels().Y)*VoxelMeters;
|
||||||
|
FHeightGrid Grid(Side,MinX,MinX+Extent,MinY,MinY+Extent);
|
||||||
|
for(const FStandaloneCpuTile* Tile:Tiles)
|
||||||
|
{
|
||||||
|
if(!Tile||Tile->Indices.size()<3)continue;
|
||||||
|
const std::size_t TriangleCount=Tile->Indices.size()/3;
|
||||||
|
for(std::size_t Triangle=0;Triangle<TriangleCount;++Triangle)
|
||||||
|
{
|
||||||
|
if(Triangle<Tile->TriangleSkirtFaceMasks.size()
|
||||||
|
&&Tile->TriangleSkirtFaceMasks[Triangle]!=0)continue;
|
||||||
|
const std::uint32_t I0=Tile->Indices[Triangle*3];
|
||||||
|
const std::uint32_t I1=Tile->Indices[Triangle*3+1];
|
||||||
|
const std::uint32_t I2=Tile->Indices[Triangle*3+2];
|
||||||
|
if(I0>=Tile->Vertices.size()||I1>=Tile->Vertices.size()||I2>=Tile->Vertices.size())continue;
|
||||||
|
const auto& A=Tile->Vertices[I0].Position;
|
||||||
|
const auto& B=Tile->Vertices[I1].Position;
|
||||||
|
const auto& C=Tile->Vertices[I2].Position;
|
||||||
|
const double Denominator=(B[1]-C[1])*(A[0]-C[0])+(C[0]-B[0])*(A[1]-C[1]);
|
||||||
|
if(std::abs(Denominator)<1e-10)continue;
|
||||||
|
const double MinTriX=std::min({A[0],B[0],C[0]}),MaxTriX=std::max({A[0],B[0],C[0]});
|
||||||
|
const double MinTriY=std::min({A[1],B[1],C[1]}),MaxTriY=std::max({A[1],B[1],C[1]});
|
||||||
|
const double StepX=Extent/(Side-1),StepY=Extent/(Side-1);
|
||||||
|
const int Ix0=std::clamp(static_cast<int>(std::ceil((MinTriX-MinX)/StepX)),0,Side-1);
|
||||||
|
const int Ix1=std::clamp(static_cast<int>(std::floor((MaxTriX-MinX)/StepX)),0,Side-1);
|
||||||
|
const int Iy0=std::clamp(static_cast<int>(std::ceil((MinTriY-MinY)/StepY)),0,Side-1);
|
||||||
|
const int Iy1=std::clamp(static_cast<int>(std::floor((MaxTriY-MinY)/StepY)),0,Side-1);
|
||||||
|
for(int Iy=Iy0;Iy<=Iy1;++Iy)
|
||||||
|
for(int Ix=Ix0;Ix<=Ix1;++Ix)
|
||||||
|
{
|
||||||
|
const double X=Grid.X(Ix),Y=Grid.Y(Iy);
|
||||||
|
const double W0=((B[1]-C[1])*(X-C[0])+(C[0]-B[0])*(Y-C[1]))/Denominator;
|
||||||
|
const double W1=((C[1]-A[1])*(X-C[0])+(A[0]-C[0])*(Y-C[1]))/Denominator;
|
||||||
|
const double W2=1.0-W0-W1;
|
||||||
|
if(W0<-1e-6||W1<-1e-6||W2<-1e-6)continue;
|
||||||
|
Grid.Add(Ix,Iy,W0*A[2]+W1*B[2]+W2*C[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(auto& Values:Grid.Hits)
|
||||||
|
{
|
||||||
|
std::sort(Values.begin(),Values.end());
|
||||||
|
Values.erase(std::unique(Values.begin(),Values.end(),[](double A,double B)
|
||||||
|
{return std::abs(A-B)<0.02;}),Values.end());
|
||||||
|
}
|
||||||
|
return Grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<FSurfaceRoot> ExactHeightRoots(const FHeightGrid& Grid,int Ix,int Iy,
|
||||||
|
const FVoxelTileKey& Patch,double VoxelMeters,
|
||||||
|
const VoxelForgeCore::WorldAssemblyManifest& Assembly)
|
||||||
|
{
|
||||||
|
std::vector<FSurfaceRoot> Roots;
|
||||||
|
const double XSubvoxels=Grid.X(Ix)/VoxelMeters*256.0;
|
||||||
|
const double YSubvoxels=Grid.Y(Iy)/VoxelMeters*256.0;
|
||||||
|
const auto X=static_cast<std::int64_t>(std::llround(XSubvoxels));
|
||||||
|
const auto Y=static_cast<std::int64_t>(std::llround(YSubvoxels));
|
||||||
|
const double MinZ=static_cast<double>(Patch.OriginVoxels().Z);
|
||||||
|
const double MaxZ=MinZ+Patch.ExtentVoxels();
|
||||||
|
constexpr std::int64_t NormalProbeSubvoxels=256;
|
||||||
|
for(const auto& Plan:Assembly.plan.strates)
|
||||||
|
{
|
||||||
|
VoxelForgeCore::Heightfield2D Field(Assembly.recipe,Plan);
|
||||||
|
if(!Field.isValid())continue;
|
||||||
|
const auto Column=Field.point(X,Y,0);
|
||||||
|
if(Column.groundHeightSubvoxels>=Column.capHeightSubvoxels)continue;
|
||||||
|
const auto XMinus=Field.point(X-NormalProbeSubvoxels,Y,0);
|
||||||
|
const auto XPlus=Field.point(X+NormalProbeSubvoxels,Y,0);
|
||||||
|
const auto YMinus=Field.point(X,Y-NormalProbeSubvoxels,0);
|
||||||
|
const auto YPlus=Field.point(X,Y+NormalProbeSubvoxels,0);
|
||||||
|
const auto Slope=[&](std::int64_t Minus,std::int64_t Plus)
|
||||||
|
{return static_cast<double>(Plus-Minus)/(2.0*NormalProbeSubvoxels);};
|
||||||
|
const double Ground=static_cast<double>(Column.groundHeightSubvoxels)/256.0*VoxelMeters;
|
||||||
|
const double Cap=static_cast<double>(Column.capHeightSubvoxels)/256.0*VoxelMeters;
|
||||||
|
const double PlanMinZ=static_cast<double>(Plan.bottomChunkZ)*32.0*VoxelMeters;
|
||||||
|
const double PlanMaxZ=static_cast<double>(Plan.topChunkZ+1)*32.0*VoxelMeters;
|
||||||
|
if(Ground>=MinZ*VoxelMeters-0.25*VoxelMeters
|
||||||
|
&&Ground<=MaxZ*VoxelMeters+0.25*VoxelMeters
|
||||||
|
&&Ground>=PlanMinZ-0.25*VoxelMeters&&Ground<=PlanMaxZ+0.25*VoxelMeters)
|
||||||
|
Roots.push_back({Ground,Slope(XMinus.groundHeightSubvoxels,
|
||||||
|
XPlus.groundHeightSubvoxels),Slope(YMinus.groundHeightSubvoxels,
|
||||||
|
YPlus.groundHeightSubvoxels)});
|
||||||
|
if(Cap>=MinZ*VoxelMeters-0.25*VoxelMeters
|
||||||
|
&&Cap<=MaxZ*VoxelMeters+0.25*VoxelMeters
|
||||||
|
&&Cap>=PlanMinZ-0.25*VoxelMeters&&Cap<=PlanMaxZ+0.25*VoxelMeters)
|
||||||
|
Roots.push_back({Cap,Slope(XMinus.capHeightSubvoxels,
|
||||||
|
XPlus.capHeightSubvoxels),Slope(YMinus.capHeightSubvoxels,
|
||||||
|
YPlus.capHeightSubvoxels)});
|
||||||
|
}
|
||||||
|
std::sort(Roots.begin(),Roots.end(),[](const FSurfaceRoot& A,const FSurfaceRoot& B)
|
||||||
|
{return A.ZMeters<B.ZMeters;});
|
||||||
|
Roots.erase(std::unique(Roots.begin(),Roots.end(),[](const FSurfaceRoot& A,
|
||||||
|
const FSurfaceRoot& B){return std::abs(A.ZMeters-B.ZMeters)<0.01;}),Roots.end());
|
||||||
|
return Roots;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool MatchNearest(const std::vector<double>& Hits,const std::vector<bool>& Used,
|
||||||
|
double Root,std::size_t& OutIndex,double& OutError)
|
||||||
|
{
|
||||||
|
double Best=std::numeric_limits<double>::infinity();std::size_t BestIndex=Hits.size();
|
||||||
|
for(std::size_t I=0;I<Hits.size();++I)
|
||||||
|
if(I>=Used.size()||!Used[I])
|
||||||
|
{
|
||||||
|
const double Error=std::abs(Hits[I]-Root);
|
||||||
|
if(Error<Best){Best=Error;BestIndex=I;}
|
||||||
|
}
|
||||||
|
if(BestIndex==Hits.size())return false;
|
||||||
|
OutIndex=BestIndex;OutError=Best;return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FErrorRow CompareToExact(const FHeightGrid& MeshGrid,const FVoxelTileKey& Patch,
|
||||||
|
double VoxelMeters,double PixelBudgetMeters,
|
||||||
|
const VoxelForgeCore::WorldAssemblyManifest& Assembly,const FViewBasis& View)
|
||||||
|
{
|
||||||
|
FErrorRow Row;Row.Lod=Patch.Level;Row.Valid=true;
|
||||||
|
FErrorAccumulator Accumulator;
|
||||||
|
for(int Iy=0;Iy<MeshGrid.Side;++Iy)
|
||||||
|
for(int Ix=0;Ix<MeshGrid.Side;++Ix)
|
||||||
|
{
|
||||||
|
const auto Roots=ExactHeightRoots(MeshGrid,Ix,Iy,Patch,VoxelMeters,Assembly);
|
||||||
|
if(Roots.empty()&&MeshGrid.At(Ix,Iy).empty())continue;
|
||||||
|
std::vector<bool> Used(MeshGrid.At(Ix,Iy).size(),false);
|
||||||
|
for(const FSurfaceRoot& Root:Roots)
|
||||||
|
{
|
||||||
|
std::size_t HitIndex=0;double ErrorMeters=0.0;
|
||||||
|
if(!MatchNearest(MeshGrid.At(Ix,Iy),Used,Root.ZMeters,HitIndex,ErrorMeters))
|
||||||
|
{
|
||||||
|
++Row.Missing;
|
||||||
|
AddMissing(Accumulator);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Used[HitIndex]=true;
|
||||||
|
AddError(Accumulator,MeshGrid.At(Ix,Iy)[HitIndex]-Root.ZMeters,
|
||||||
|
Root,PixelBudgetMeters,View,MeshGrid.X(Ix),MeshGrid.Y(Iy));
|
||||||
|
++Row.Samples;
|
||||||
|
}
|
||||||
|
// Heightfield2D declares ground and cap roots only. Other mesh intersections may
|
||||||
|
// be valid tunnel geometry; the exact-mesh comparison checks extra pieces.
|
||||||
|
}
|
||||||
|
FinalizeError(Row,Accumulator);
|
||||||
|
return Row;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FErrorRow CompareToReference(const FHeightGrid& MeshGrid,
|
||||||
|
const FHeightGrid& ReferenceGrid,const FVoxelTileKey& Patch,double VoxelMeters,
|
||||||
|
double PixelBudgetMeters,const VoxelForgeCore::WorldAssemblyManifest& Assembly,
|
||||||
|
const FViewBasis& View)
|
||||||
|
{
|
||||||
|
FErrorRow Row;Row.Lod=Patch.Level;Row.Valid=true;
|
||||||
|
FErrorAccumulator Accumulator;
|
||||||
|
for(int Iy=0;Iy<ReferenceGrid.Side;++Iy)
|
||||||
|
for(int Ix=0;Ix<ReferenceGrid.Side;++Ix)
|
||||||
|
{
|
||||||
|
const auto& Reference=ReferenceGrid.At(Ix,Iy);
|
||||||
|
const auto& Mesh=MeshGrid.At(Ix,Iy);
|
||||||
|
if(Reference.empty()&&Mesh.empty())continue;
|
||||||
|
const auto Roots=ExactHeightRoots(ReferenceGrid,Ix,Iy,Patch,VoxelMeters,Assembly);
|
||||||
|
std::vector<bool> UsedReference(Reference.size(),false),UsedMesh(Mesh.size(),false);
|
||||||
|
for(std::size_t ReferenceIndex=0;ReferenceIndex<Reference.size();++ReferenceIndex)
|
||||||
|
{
|
||||||
|
const double ReferenceZ=Reference[ReferenceIndex];
|
||||||
|
UsedReference[ReferenceIndex]=true;
|
||||||
|
std::size_t MeshIndex=0;double MeshError=0.0;
|
||||||
|
if(!MatchNearest(Mesh,UsedMesh,ReferenceZ,MeshIndex,MeshError))
|
||||||
|
{
|
||||||
|
++Row.Missing;AddMissing(Accumulator);continue;
|
||||||
|
}
|
||||||
|
UsedMesh[MeshIndex]=true;
|
||||||
|
FSurfaceRoot Root{ReferenceZ,0.0,0.0};
|
||||||
|
if(!Roots.empty())
|
||||||
|
{
|
||||||
|
const auto BestRoot=std::min_element(Roots.begin(),Roots.end(),
|
||||||
|
[ReferenceZ](const FSurfaceRoot& A,const FSurfaceRoot& B)
|
||||||
|
{return std::abs(A.ZMeters-ReferenceZ)<std::abs(B.ZMeters-ReferenceZ);});
|
||||||
|
if(BestRoot!=Roots.end()&&std::abs(BestRoot->ZMeters-ReferenceZ)<1.0)
|
||||||
|
Root=*BestRoot;
|
||||||
|
}
|
||||||
|
AddError(Accumulator,Mesh[MeshIndex]-Reference[ReferenceIndex],
|
||||||
|
Root,PixelBudgetMeters,View,ReferenceGrid.X(Ix),ReferenceGrid.Y(Iy));
|
||||||
|
}
|
||||||
|
for(std::size_t I=0;I<Mesh.size();++I)
|
||||||
|
if(!UsedMesh[I]){++Row.Floating;AddMissing(Accumulator);}
|
||||||
|
}
|
||||||
|
FinalizeError(Row,Accumulator);
|
||||||
|
return Row;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline FPopRow ComparePop(const FHeightGrid& Coarse,const FHeightGrid& Fine,
|
||||||
|
const FVoxelTileKey& Patch,double VoxelMeters,double PixelBudgetMeters,
|
||||||
|
const VoxelForgeCore::WorldAssemblyManifest& Assembly,const FViewBasis& View)
|
||||||
|
{
|
||||||
|
FPopRow Row;Row.CoarseLod=Patch.Level;Row.Valid=true;
|
||||||
|
FErrorAccumulator Accumulator;
|
||||||
|
for(int Iy=0;Iy<Coarse.Side;++Iy)
|
||||||
|
for(int Ix=0;Ix<Coarse.Side;++Ix)
|
||||||
|
{
|
||||||
|
const auto& CoarseHits=Coarse.At(Ix,Iy);
|
||||||
|
const auto& FineHits=Fine.At(Ix,Iy);
|
||||||
|
const auto Roots=ExactHeightRoots(Coarse,Ix,Iy,Patch,VoxelMeters,Assembly);
|
||||||
|
if(Roots.empty()&&CoarseHits.empty()&&FineHits.empty())continue;
|
||||||
|
std::vector<bool> CoarseUsed(CoarseHits.size(),false);
|
||||||
|
std::vector<bool> FineUsed(FineHits.size(),false);
|
||||||
|
for(const FSurfaceRoot& Root:Roots)
|
||||||
|
{
|
||||||
|
std::size_t CoarseIndex=0,FineIndex=0;
|
||||||
|
double CoarseError=0.0,FineError=0.0;
|
||||||
|
if(!MatchNearest(CoarseHits,CoarseUsed,Root.ZMeters,CoarseIndex,CoarseError)
|
||||||
|
||!MatchNearest(FineHits,FineUsed,Root.ZMeters,FineIndex,FineError))
|
||||||
|
{
|
||||||
|
++Row.Cracks;AddMissing(Accumulator);continue;
|
||||||
|
}
|
||||||
|
CoarseUsed[CoarseIndex]=true;
|
||||||
|
FineUsed[FineIndex]=true;
|
||||||
|
AddError(Accumulator,CoarseHits[CoarseIndex]-FineHits[FineIndex],
|
||||||
|
Root,PixelBudgetMeters,View,Coarse.X(Ix),Coarse.Y(Iy));
|
||||||
|
++Row.Samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FErrorRow Stats;Stats.Lod=Patch.Level;Stats.Valid=true;
|
||||||
|
FinalizeError(Stats,Accumulator);
|
||||||
|
Row.Samples=Stats.Samples;Row.P50=Stats.P50;Row.P99=Stats.P99;Row.Maximum=Stats.Maximum;
|
||||||
|
Row.VerticalP50=Stats.VerticalP50;Row.VerticalP99=Stats.VerticalP99;
|
||||||
|
Row.VerticalMaximum=Stats.VerticalMaximum;
|
||||||
|
Row.MaximumNormalDistanceMeters=Stats.MaximumNormalDistanceMeters;
|
||||||
|
Row.MaximumX=Stats.MaximumX;Row.MaximumY=Stats.MaximumY;
|
||||||
|
Row.MaximumReferenceZ=Stats.MaximumReferenceZ;
|
||||||
|
Row.MaximumDisplayedZ=Stats.MaximumDisplayedZ;
|
||||||
|
Row.MaximumSlopeDegrees=Stats.MaximumSlopeDegrees;
|
||||||
|
Row.SlopeSamples=Stats.SlopeSamples;Row.SlopeP99=Stats.SlopeP99;
|
||||||
|
Row.SlopeMaximum=Stats.SlopeMaximum;
|
||||||
|
return Row;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::array<double,9> ClosestDisplayedDistancesMeters(
|
||||||
|
const FStandaloneOwnerWorld& World,const FVector& CameraVoxels,
|
||||||
|
std::uint32_t VoxelSizeMicrons)
|
||||||
|
{
|
||||||
|
const double VoxelMeters=static_cast<double>(VoxelSizeMicrons)/1000000.0;
|
||||||
|
std::array<double,9> Minimums{};
|
||||||
|
Minimums.fill(std::numeric_limits<double>::infinity());
|
||||||
|
for(int Lod=0;Lod<=8;++Lod)
|
||||||
|
{
|
||||||
|
const int PhaseCount=1<<Lod;
|
||||||
|
for(int Phase=0;Phase<PhaseCount;++Phase)
|
||||||
|
{
|
||||||
|
FVector Probe=CameraVoxels;
|
||||||
|
Probe.X=static_cast<float>(Phase*32.0+32.0-1.0/256.0);
|
||||||
|
const FStandaloneDesiredTileSet Desired=StandaloneWorldMesher::BuildDesiredSet(World,Probe);
|
||||||
|
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
||||||
|
{
|
||||||
|
if(Tile.Level!=Lod)continue;
|
||||||
|
Minimums[Lod]=std::min(Minimums[Lod],
|
||||||
|
TileAabbDistanceMeters(Tile,Probe,VoxelMeters));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(double& Distance:Minimums)
|
||||||
|
if(!std::isfinite(Distance))Distance=0.0;
|
||||||
|
return Minimums;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::array<double,9> ClipmapClosestDisplayedDistancesMeters(
|
||||||
|
const FStandaloneOwnerWorld& World,std::uint32_t VoxelSizeMicrons)
|
||||||
|
{
|
||||||
|
const double VoxelMeters=static_cast<double>(VoxelSizeMicrons)/1000000.0;
|
||||||
|
std::array<double,9> Distances{};
|
||||||
|
for(int Lod=1;Lod<=8;++Lod)
|
||||||
|
Distances[Lod]=static_cast<double>(World.ClipRadius)
|
||||||
|
*static_cast<double>(CHUNK_SIZE)*(1ull<<(Lod-1))*VoxelMeters;
|
||||||
|
return Distances;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PrintSlopeTail(const char* Kind,int Lod,const std::array<std::uint64_t,4>& Counts,
|
||||||
|
const std::array<double,4>& P99,const std::array<double,4>& Maximum)
|
||||||
|
{
|
||||||
|
constexpr const char* Labels[4]={"lt30","30to45","45to60","ge60"};
|
||||||
|
for(std::size_t Bin=0;Bin<Counts.size();++Bin)
|
||||||
|
std::printf("[ScreenSpaceSlopeTail] kind=%s lod=%d slope_deg=%s samples=%llu p99_px=%.4f max_px=%.4f\n",
|
||||||
|
Kind,Lod,Labels[Bin],static_cast<unsigned long long>(Counts[Bin]),P99[Bin],Maximum[Bin]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void PrintKnownFailureControl(double CellMeters,double DisplayDistanceMeters,
|
||||||
|
const FViewBasis& View)
|
||||||
|
{
|
||||||
|
constexpr double Slope=100.0;
|
||||||
|
const double LateralMeters=CellMeters/200.0;
|
||||||
|
const double VerticalMeters=Slope*LateralMeters;
|
||||||
|
const double NormalLength=std::sqrt(1.0+Slope*Slope);
|
||||||
|
const double NormalDistance=VerticalMeters/NormalLength;
|
||||||
|
const std::array<double,3> Normal={-Slope/NormalLength,0.0,1.0/NormalLength};
|
||||||
|
const double ProjectedNormal=std::hypot(
|
||||||
|
Normal[0]*View.Right[0]+Normal[1]*View.Right[1]+Normal[2]*View.Right[2],
|
||||||
|
Normal[0]*View.Up[0]+Normal[1]*View.Up[1]+Normal[2]*View.Up[2]);
|
||||||
|
const double PixelBudgetMeters=DisplayDistanceMeters*OnePixelRadians;
|
||||||
|
const double VerticalPixels=VerticalMeters/PixelBudgetMeters;
|
||||||
|
const double NormalPixels=NormalDistance*ProjectedNormal/PixelBudgetMeters;
|
||||||
|
const bool Passed=VerticalPixels>4.0&&NormalPixels<1.0;
|
||||||
|
std::printf("[ScreenSpaceKnownFailureControl] case=steep-plane-lateral-offset slope_deg=%.4f cell_m=%.6f lateral_m=%.6f cell_fraction=%.6f vertical_error_m=%.6f vertical_height_px=%.4f closest_normal_m=%.6f projected_normal_px=%.4f status=%s\n",
|
||||||
|
std::atan(Slope)*180.0/3.14159265358979323846,CellMeters,LateralMeters,
|
||||||
|
LateralMeters/CellMeters,VerticalMeters,VerticalPixels,NormalDistance,NormalPixels,
|
||||||
|
Passed?"EXPECTED_VERTICAL_FALSE_POSITIVE":"CONTROL_FAILED");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Run(const std::array<std::optional<FStandaloneCpuTile>,9>& SampleTiles,
|
||||||
|
FStandaloneStreamingGenerator& Streamer,
|
||||||
|
const VoxelForgeCore::WorldAssemblyManifest& Assembly,
|
||||||
|
const std::array<double,9>& Distances,std::uint32_t VoxelSizeMicrons,int MaxLod,
|
||||||
|
const std::array<std::int64_t,9>& PixelBudgetsSubvoxels,
|
||||||
|
double CameraYawDegrees,double CameraPitchDegrees)
|
||||||
|
{
|
||||||
|
const double VoxelMeters=static_cast<double>(VoxelSizeMicrons)/1000000.0;
|
||||||
|
const FViewBasis View=MakeViewBasis(CameraYawDegrees,CameraPitchDegrees);
|
||||||
|
std::array<double,9> Budgets{};
|
||||||
|
std::array<FErrorRow,9> ErrorRows{};
|
||||||
|
std::array<FPopRow,9> PopRows{};
|
||||||
|
bool GatePass=true;
|
||||||
|
std::printf("[ScreenSpaceGate] angular_pixel=%.9f rad (horizontal_fov=90deg,width=2560) lod>=3_limit=1.0px sampling=65x65 skirts=excluded metric=local_surface_normal_projected field_reference=direct-Heightfield2D-roots normal_probe_vox=1 view_yaw_deg=%.3f view_pitch_deg=%.3f\n",
|
||||||
|
OnePixelRadians,CameraYawDegrees,CameraPitchDegrees);
|
||||||
|
for(int Lod=0;Lod<=MaxLod&&Lod<9;++Lod)
|
||||||
|
{
|
||||||
|
Budgets[Lod]=Distances[Lod]*OnePixelRadians;
|
||||||
|
std::printf("[ScreenSpaceDistance] lod=%d closest_m=%.3f pixel_budget_m=%.6f pixel_budget_cm=%.3f pixel_budget_subvoxels=%lld rule=%s\n",
|
||||||
|
Lod,Distances[Lod],Budgets[Lod],Budgets[Lod]*100.0,
|
||||||
|
static_cast<long long>(PixelBudgetsSubvoxels[Lod]),Lod<3?"exact-2cm":"1px");
|
||||||
|
}
|
||||||
|
const double LOD3CellMeters=static_cast<double>(CHUNK_SIZE*(1<<3))*VoxelMeters/64.0;
|
||||||
|
PrintKnownFailureControl(LOD3CellMeters,Distances[3],View);
|
||||||
|
VoxelForgeCore::Heightfield2D::resetThreadColumnCacheStats(false,true,0);
|
||||||
|
for(int Lod=3;Lod<=MaxLod&&Lod<9;++Lod)
|
||||||
|
{
|
||||||
|
if(!SampleTiles[Lod]||SampleTiles[Lod]->Vertices.empty())
|
||||||
|
{
|
||||||
|
std::printf("[ScreenSpaceGateLOD] lod=%d status=NO_SURFACE_TILE\n",Lod);
|
||||||
|
GatePass=false;continue;
|
||||||
|
}
|
||||||
|
const FStandaloneCpuTile& CoarseTile=*SampleTiles[Lod];
|
||||||
|
const FStandaloneCpuTile* CoarsePtr=&CoarseTile;
|
||||||
|
const std::span<const FStandaloneCpuTile* const> CoarseSpan(&CoarsePtr,1);
|
||||||
|
const FHeightGrid CoarseGrid=Rasterize(CoarseSpan,CoarseTile.Key,VoxelMeters);
|
||||||
|
const FStandaloneCpuTile ExactTile=Streamer.GenerateDiagnostic(
|
||||||
|
CoarseTile.Key,0,1,true);
|
||||||
|
const FStandaloneCpuTile* ExactPointer=&ExactTile;
|
||||||
|
const std::span<const FStandaloneCpuTile* const> ExactSpan(&ExactPointer,1);
|
||||||
|
const FHeightGrid ExactGrid=Rasterize(ExactSpan,ExactTile.Key,VoxelMeters);
|
||||||
|
ErrorRows[Lod]=CompareToReference(CoarseGrid,ExactGrid,CoarseTile.Key,VoxelMeters,
|
||||||
|
Budgets[Lod],Assembly,View);
|
||||||
|
const FErrorRow& Error=ErrorRows[Lod];
|
||||||
|
const bool LodPass=Error.Valid&&Error.Missing==0&&Error.Floating==0
|
||||||
|
&&Error.Samples>=16&&Error.Maximum<=1.0;
|
||||||
|
GatePass=GatePass&&LodPass;
|
||||||
|
std::printf("[ScreenSpaceGateLOD] lod=%d key=(%d,%d,%d) samples=%llu normal_px_p50=%.4f p99=%.4f max=%.4f vertical_px_p50=%.4f p99=%.4f max=%.4f max_normal_m=%.6f max_xy_m=(%.3f,%.3f) max_slope_deg=%.2f missing=%llu floating=%llu status=%s\n",
|
||||||
|
Lod,CoarseTile.Key.Coord.X,CoarseTile.Key.Coord.Y,CoarseTile.Key.Coord.Z,
|
||||||
|
static_cast<unsigned long long>(Error.Samples),Error.P50,Error.P99,Error.Maximum,
|
||||||
|
Error.VerticalP50,Error.VerticalP99,Error.VerticalMaximum,
|
||||||
|
Error.MaximumNormalDistanceMeters,Error.MaximumX,Error.MaximumY,
|
||||||
|
Error.MaximumSlopeDegrees,
|
||||||
|
static_cast<unsigned long long>(Error.Missing),static_cast<unsigned long long>(Error.Floating),
|
||||||
|
LodPass?"PASS":"REJECT");
|
||||||
|
PrintSlopeTail("same_lod",Lod,Error.SlopeSamples,Error.SlopeP99,Error.SlopeMaximum);
|
||||||
|
|
||||||
|
const FErrorRow FieldError=CompareToExact(CoarseGrid,CoarseTile.Key,VoxelMeters,
|
||||||
|
Budgets[Lod],Assembly,View);
|
||||||
|
const bool FieldPass=FieldError.Valid&&FieldError.Missing==0&&FieldError.Floating==0
|
||||||
|
&&FieldError.Samples>=16&&FieldError.Maximum<=1.0;
|
||||||
|
GatePass=GatePass&&FieldPass;
|
||||||
|
std::printf("[ScreenSpaceGateFieldLOD] lod=%d samples=%llu normal_px_p50=%.4f p99=%.4f max=%.4f vertical_px_p50=%.4f p99=%.4f max=%.4f max_normal_m=%.6f max_xyz_m=(%.3f,%.3f,%.3f) max_slope_deg=%.2f missing=%llu floating=%llu status=%s\n",
|
||||||
|
Lod,static_cast<unsigned long long>(FieldError.Samples),FieldError.P50,
|
||||||
|
FieldError.P99,FieldError.Maximum,FieldError.VerticalP50,FieldError.VerticalP99,
|
||||||
|
FieldError.VerticalMaximum,FieldError.MaximumNormalDistanceMeters,
|
||||||
|
FieldError.MaximumX,FieldError.MaximumY,FieldError.MaximumDisplayedZ,
|
||||||
|
FieldError.MaximumSlopeDegrees,
|
||||||
|
static_cast<unsigned long long>(FieldError.Missing),
|
||||||
|
static_cast<unsigned long long>(FieldError.Floating),FieldPass?"PASS":"REJECT");
|
||||||
|
PrintSlopeTail("field",Lod,FieldError.SlopeSamples,FieldError.SlopeP99,
|
||||||
|
FieldError.SlopeMaximum);
|
||||||
|
|
||||||
|
bool FaultControlsPass=true;
|
||||||
|
const FHeightGrid MissingGrid(ExactGrid.Side,ExactGrid.MinimumX,ExactGrid.MaximumX,
|
||||||
|
ExactGrid.MinimumY,ExactGrid.MaximumY);
|
||||||
|
const FErrorRow MissingError=CompareToReference(MissingGrid,ExactGrid,
|
||||||
|
CoarseTile.Key,VoxelMeters,Budgets[Lod],Assembly,View);
|
||||||
|
const bool MissingRejected=MissingError.Missing>0&&MissingError.Maximum>1.0;
|
||||||
|
FaultControlsPass=FaultControlsPass&&MissingRejected;
|
||||||
|
std::printf("[ScreenSpaceFaultInjection] lod=%d case=missing-displayed-surface missing=%llu status=%s\n",
|
||||||
|
Lod,static_cast<unsigned long long>(MissingError.Missing),
|
||||||
|
MissingRejected?"REJECTED_AS_REQUIRED":"GATE_FALSE_NEGATIVE");
|
||||||
|
|
||||||
|
FStandaloneCpuTile FloatingTile=CoarseTile;
|
||||||
|
const std::uint32_t FloatingVertexBase=static_cast<std::uint32_t>(FloatingTile.Vertices.size());
|
||||||
|
for(FStandaloneCpuVertex Vertex:CoarseTile.Vertices)
|
||||||
|
{
|
||||||
|
Vertex.Position[2]+=2.0f;
|
||||||
|
FloatingTile.Vertices.push_back(Vertex);
|
||||||
|
}
|
||||||
|
for(const std::uint32_t Index:CoarseTile.Indices)
|
||||||
|
FloatingTile.Indices.push_back(FloatingVertexBase+Index);
|
||||||
|
FloatingTile.TriangleSkirtFaceMasks.insert(FloatingTile.TriangleSkirtFaceMasks.end(),
|
||||||
|
CoarseTile.TriangleSkirtFaceMasks.begin(),CoarseTile.TriangleSkirtFaceMasks.end());
|
||||||
|
const FStandaloneCpuTile* FloatingPointer=&FloatingTile;
|
||||||
|
const std::span<const FStandaloneCpuTile* const> FloatingSpan(&FloatingPointer,1);
|
||||||
|
const FHeightGrid FloatingGrid=Rasterize(FloatingSpan,CoarseTile.Key,VoxelMeters);
|
||||||
|
const FErrorRow FloatingError=CompareToReference(FloatingGrid,ExactGrid,
|
||||||
|
CoarseTile.Key,VoxelMeters,Budgets[Lod],Assembly,View);
|
||||||
|
const bool FloatingRejected=FloatingError.Floating>0||FloatingError.Maximum>1.0;
|
||||||
|
FaultControlsPass=FaultControlsPass&&FloatingRejected;
|
||||||
|
std::printf("[ScreenSpaceFaultInjection] lod=%d case=2m-floating-surface floating=%llu max_px=%.4f status=%s\n",
|
||||||
|
Lod,static_cast<unsigned long long>(FloatingError.Floating),FloatingError.Maximum,
|
||||||
|
FloatingRejected?"REJECTED_AS_REQUIRED":"GATE_FALSE_NEGATIVE");
|
||||||
|
|
||||||
|
std::vector<FStandaloneCpuTile> FineTiles;
|
||||||
|
FineTiles.reserve(8);
|
||||||
|
for(int Dz=0;Dz<=1;++Dz)
|
||||||
|
for(int Dy=0;Dy<=1;++Dy)
|
||||||
|
for(int Dx=0;Dx<=1;++Dx)
|
||||||
|
{
|
||||||
|
const FVoxelTileKey FineKey(FIntVector(2*CoarseTile.Key.Coord.X+Dx,
|
||||||
|
2*CoarseTile.Key.Coord.Y+Dy,2*CoarseTile.Key.Coord.Z+Dz),Lod-1);
|
||||||
|
FStandaloneCpuTile FineTile=Streamer.GenerateDiagnostic(FineKey);
|
||||||
|
if(!FineTile.Vertices.empty())FineTiles.push_back(std::move(FineTile));
|
||||||
|
}
|
||||||
|
std::vector<const FStandaloneCpuTile*> FinePointers;
|
||||||
|
FinePointers.reserve(FineTiles.size());
|
||||||
|
for(const auto& Tile:FineTiles)FinePointers.push_back(&Tile);
|
||||||
|
const auto FineSpan=std::span<const FStandaloneCpuTile* const>(
|
||||||
|
FinePointers.data(),FinePointers.size());
|
||||||
|
const FHeightGrid FineGrid=Rasterize(FineSpan,CoarseTile.Key,VoxelMeters);
|
||||||
|
PopRows[Lod]=ComparePop(CoarseGrid,FineGrid,CoarseTile.Key,VoxelMeters,
|
||||||
|
Budgets[Lod],Assembly,View);
|
||||||
|
const FPopRow& Pop=PopRows[Lod];
|
||||||
|
const bool PopPass=Pop.Valid&&Pop.Cracks==0&&Pop.Floating==0&&Pop.Maximum<=1.0;
|
||||||
|
GatePass=GatePass&&PopPass;
|
||||||
|
std::printf("[ScreenSpaceSwap] lod=%d_to_%d samples=%llu normal_px_p50=%.4f p99=%.4f max=%.4f vertical_px_p50=%.4f p99=%.4f max=%.4f max_normal_m=%.6f max_xyz_m=(%.3f,%.3f,%.3f) max_slope_deg=%.2f cracks=%llu floating=%llu status=%s\n",
|
||||||
|
Lod,Lod-1,static_cast<unsigned long long>(Pop.Samples),
|
||||||
|
Pop.P50,Pop.P99,Pop.Maximum,Pop.VerticalP50,Pop.VerticalP99,Pop.VerticalMaximum,
|
||||||
|
Pop.MaximumNormalDistanceMeters,Pop.MaximumX,Pop.MaximumY,
|
||||||
|
Pop.MaximumDisplayedZ,
|
||||||
|
Pop.MaximumSlopeDegrees,static_cast<unsigned long long>(Pop.Cracks),
|
||||||
|
static_cast<unsigned long long>(Pop.Floating),
|
||||||
|
PopPass?"PASS":"REJECT");
|
||||||
|
PrintSlopeTail("swap",Lod,Pop.SlopeSamples,Pop.SlopeP99,Pop.SlopeMaximum);
|
||||||
|
|
||||||
|
const FHeightGrid MissingFineGrid(CoarseGrid.Side,CoarseGrid.MinimumX,
|
||||||
|
CoarseGrid.MaximumX,CoarseGrid.MinimumY,CoarseGrid.MaximumY);
|
||||||
|
const FPopRow MissingFineError=ComparePop(CoarseGrid,MissingFineGrid,
|
||||||
|
CoarseTile.Key,VoxelMeters,Budgets[Lod],Assembly,View);
|
||||||
|
const bool CrackRejected=MissingFineError.Cracks>0&&MissingFineError.Maximum>1.0;
|
||||||
|
FaultControlsPass=FaultControlsPass&&CrackRejected;
|
||||||
|
GatePass=GatePass&&FaultControlsPass;
|
||||||
|
std::printf("[ScreenSpaceFaultInjection] lod=%d case=missing-fine-ring-surface cracks=%llu max_px=%.4f status=%s\n",
|
||||||
|
Lod,static_cast<unsigned long long>(MissingFineError.Cracks),
|
||||||
|
MissingFineError.Maximum,CrackRejected?"REJECTED_AS_REQUIRED":"GATE_FALSE_NEGATIVE");
|
||||||
|
|
||||||
|
bool NegativeControlsPass=true;
|
||||||
|
const auto CheckNegative=[&](const char* Name,std::uint32_t Drop,std::uint32_t Stride)
|
||||||
|
{
|
||||||
|
FStandaloneCpuTile Bad=Streamer.GenerateDiagnostic(
|
||||||
|
CoarseTile.Key,Drop,Stride,true);
|
||||||
|
const FStandaloneCpuTile* BadPointer=&Bad;
|
||||||
|
const std::span<const FStandaloneCpuTile* const> BadSpan(&BadPointer,1);
|
||||||
|
const FHeightGrid BadGrid=Rasterize(BadSpan,Bad.Key,VoxelMeters);
|
||||||
|
const FErrorRow BadError=CompareToReference(BadGrid,ExactGrid,
|
||||||
|
CoarseTile.Key,VoxelMeters,Budgets[Lod],Assembly,View);
|
||||||
|
const bool Rejected=BadError.Missing>0||BadError.Floating>0
|
||||||
|
||BadError.Samples<16||BadError.Maximum>1.0;
|
||||||
|
NegativeControlsPass=NegativeControlsPass&&Rejected;
|
||||||
|
std::printf("[ScreenSpaceNegative] lod=%d case=%s p50_px=%.4f p99_px=%.4f max_px=%.4f missing=%llu floating=%llu status=%s\n",
|
||||||
|
Lod,Name,BadError.P50,BadError.P99,BadError.Maximum,
|
||||||
|
static_cast<unsigned long long>(BadError.Missing),
|
||||||
|
static_cast<unsigned long long>(BadError.Floating),
|
||||||
|
Rejected?"REJECTED_AS_REQUIRED":"GATE_FALSE_NEGATIVE");
|
||||||
|
};
|
||||||
|
CheckNegative("s13-global-octave-drop",1,1);
|
||||||
|
CheckNegative("stride-2-column-interpolation",0,2);
|
||||||
|
GatePass=GatePass&&NegativeControlsPass;
|
||||||
|
}
|
||||||
|
std::printf("[ScreenSpaceGateResult] status=%s\n",GatePass?"PASS":"REJECT");
|
||||||
|
return GatePass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "VoxelForgeCore/VoxelForgeCore.h"
|
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||||
|
#include "StandaloneWorkerThread.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
@@ -23,7 +24,7 @@ public:
|
|||||||
const std::size_t grain=std::max<std::size_t>(1,batchSize);
|
const std::size_t grain=std::max<std::size_t>(1,batchSize);
|
||||||
std::atomic<std::size_t> next{0};
|
std::atomic<std::size_t> next{0};
|
||||||
std::vector<double> active(workers,0.0);
|
std::vector<double> active(workers,0.0);
|
||||||
std::vector<std::thread> threads;
|
std::vector<FStandaloneWorkerThread> threads;
|
||||||
threads.reserve(workers);
|
threads.reserve(workers);
|
||||||
for(std::size_t worker=0;worker<workers;++worker)
|
for(std::size_t worker=0;worker<workers;++worker)
|
||||||
threads.emplace_back([&,worker]
|
threads.emplace_back([&,worker]
|
||||||
@@ -39,7 +40,7 @@ public:
|
|||||||
active[worker]=std::chrono::duration<double>(
|
active[worker]=std::chrono::duration<double>(
|
||||||
std::chrono::steady_clock::now()-started).count();
|
std::chrono::steady_clock::now()-started).count();
|
||||||
});
|
});
|
||||||
for(std::thread& thread:threads)thread.join();
|
for(FStandaloneWorkerThread& thread:threads)thread.join();
|
||||||
double total=0.0;
|
double total=0.0;
|
||||||
for(std::size_t worker=0;worker<workers;++worker)
|
for(std::size_t worker=0;worker<workers;++worker)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "StandaloneWorkerThread.h"
|
||||||
|
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <fstream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace StandaloneTlsProbe
|
||||||
|
{
|
||||||
|
#if defined(__linux__)
|
||||||
|
struct FMemorySample
|
||||||
|
{
|
||||||
|
std::uint64_t virtualKiB=0;
|
||||||
|
std::uint64_t residentKiB=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline FMemorySample ReadMemory()
|
||||||
|
{
|
||||||
|
std::ifstream statm("/proc/self/statm");
|
||||||
|
std::uint64_t virtualPages=0,residentPages=0;
|
||||||
|
statm>>virtualPages>>residentPages;
|
||||||
|
const long pageSize=sysconf(_SC_PAGESIZE);
|
||||||
|
if(!statm||pageSize<=0)return {};
|
||||||
|
return {virtualPages*static_cast<std::uint64_t>(pageSize)/1024,
|
||||||
|
residentPages*static_cast<std::uint64_t>(pageSize)/1024};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int Run(int workerCount,std::string_view touchKind="none")
|
||||||
|
{
|
||||||
|
workerCount=std::clamp(workerCount,0,12);
|
||||||
|
VoxelForgeCore::WorldAssemblyRecipeV1 surfaceRecipe;
|
||||||
|
VoxelForgeCore::WorldAssemblyStratumPlanV1 surfacePlan;
|
||||||
|
VoxelForgeCore::Heightfield2D surfaceField(surfaceRecipe,surfacePlan);
|
||||||
|
if(touchKind=="surface-world")
|
||||||
|
{
|
||||||
|
VoxelForgeCore::WorldAssemblyBiomeProfileV1 biome;
|
||||||
|
biome.stableId=1;
|
||||||
|
surfaceRecipe.biomes.push_back(biome);
|
||||||
|
surfacePlan.strateIndex=0;
|
||||||
|
surfacePlan.topChunkZ=1;
|
||||||
|
surfacePlan.bottomChunkZ=-1;
|
||||||
|
surfaceField=VoxelForgeCore::Heightfield2D(surfaceRecipe,surfacePlan);
|
||||||
|
if(!surfaceField.isValid())
|
||||||
|
{
|
||||||
|
std::fprintf(stderr,"[TlsProbe] invalid synthetic SurfaceWorld cache probe input\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VoxelForgeCore::FloatingIslandRecipeV1 islandRecipe;
|
||||||
|
VoxelForgeCore::FloatingIslandPlanV1 islandPlan;
|
||||||
|
for(std::uint32_t index=0;index<islandRecipe.primaryIslandCount;++index)
|
||||||
|
{
|
||||||
|
VoxelForgeCore::FloatingIslandAnchorV1 island;
|
||||||
|
island.stableId=index+1;
|
||||||
|
island.ordinal=index;
|
||||||
|
island.centerSubvoxels={static_cast<std::int64_t>(index)*64*256,0,0};
|
||||||
|
island.radiusSubvoxels=20*256;
|
||||||
|
island.topHalfSubvoxels=20*256;
|
||||||
|
island.topZSubvoxels=0;
|
||||||
|
island.bottomZSubvoxels=-80*256;
|
||||||
|
island.taperEndQ16=islandRecipe.taperEndMinimumQ16;
|
||||||
|
islandPlan.islands.push_back(island);
|
||||||
|
}
|
||||||
|
VoxelForgeCore::FloatingIslandFieldV1 islandField(islandRecipe,islandPlan);
|
||||||
|
if(touchKind=="floating-islands"&&!islandField.isValid())
|
||||||
|
{
|
||||||
|
std::fprintf(stderr,"[TlsProbe] invalid synthetic FloatingIslands cache probe input\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
std::mutex mutex;
|
||||||
|
std::condition_variable changed;
|
||||||
|
bool release=false;
|
||||||
|
bool touchRequested=false;
|
||||||
|
std::atomic<int> ready{0};
|
||||||
|
std::atomic<int> touchReady{0};
|
||||||
|
std::vector<FStandaloneWorkerThread> workers;
|
||||||
|
std::vector<long> startupMinorFaults(static_cast<std::size_t>(workerCount),0);
|
||||||
|
std::vector<long> firstTouchMinorFaults(static_cast<std::size_t>(workerCount),0);
|
||||||
|
std::vector<std::int64_t> checksums(static_cast<std::size_t>(workerCount),0);
|
||||||
|
workers.reserve(static_cast<std::size_t>(workerCount));
|
||||||
|
FMemorySample previous=ReadMemory();
|
||||||
|
std::printf("[TlsProbe] workers=0 create_ms=0.000 rss_kib=%llu rss_delta_kib=0 vms_kib=%llu stack_bytes=%zu\n",
|
||||||
|
static_cast<unsigned long long>(previous.residentKiB),
|
||||||
|
static_cast<unsigned long long>(previous.virtualKiB),
|
||||||
|
FStandaloneWorkerThread::StackSizeBytes);
|
||||||
|
for(int index=1;index<=workerCount;++index)
|
||||||
|
{
|
||||||
|
const auto start=std::chrono::steady_clock::now();
|
||||||
|
workers.emplace_back([&,index]
|
||||||
|
{
|
||||||
|
#if defined(__linux__)
|
||||||
|
rusage startupUsage{};
|
||||||
|
getrusage(RUSAGE_THREAD,&startupUsage);
|
||||||
|
startupMinorFaults[static_cast<std::size_t>(index-1)]=startupUsage.ru_minflt;
|
||||||
|
#endif
|
||||||
|
ready.fetch_add(1,std::memory_order_release);
|
||||||
|
changed.notify_all();
|
||||||
|
{
|
||||||
|
std::unique_lock lock(mutex);
|
||||||
|
changed.wait(lock,[&]{return touchRequested||release;});
|
||||||
|
}
|
||||||
|
if(touchRequested)
|
||||||
|
{
|
||||||
|
#if defined(__linux__)
|
||||||
|
rusage beforeTouch{};
|
||||||
|
rusage afterTouch{};
|
||||||
|
getrusage(RUSAGE_THREAD,&beforeTouch);
|
||||||
|
#endif
|
||||||
|
std::int64_t checksum=0;
|
||||||
|
if(touchKind=="surface-world")
|
||||||
|
{
|
||||||
|
for(int sample=0;sample<4;++sample)
|
||||||
|
checksum+=surfaceField.point((index*4+sample)*256,0,0).densitySubvoxels;
|
||||||
|
}
|
||||||
|
else if(touchKind=="floating-islands")
|
||||||
|
{
|
||||||
|
for(int sample=0;sample<4;++sample)
|
||||||
|
checksum+=islandField.densitySubvoxels(
|
||||||
|
(index*4+sample)*256,0,-20*256);
|
||||||
|
}
|
||||||
|
checksums[static_cast<std::size_t>(index-1)]=checksum;
|
||||||
|
#if defined(__linux__)
|
||||||
|
getrusage(RUSAGE_THREAD,&afterTouch);
|
||||||
|
firstTouchMinorFaults[static_cast<std::size_t>(index-1)]=
|
||||||
|
afterTouch.ru_minflt-beforeTouch.ru_minflt;
|
||||||
|
#endif
|
||||||
|
touchReady.fetch_add(1,std::memory_order_release);
|
||||||
|
changed.notify_all();
|
||||||
|
}
|
||||||
|
std::unique_lock lock(mutex);
|
||||||
|
changed.wait(lock,[&]{return release;});
|
||||||
|
});
|
||||||
|
{
|
||||||
|
std::unique_lock lock(mutex);
|
||||||
|
changed.wait(lock,[&]{return ready.load(std::memory_order_acquire)>=index;});
|
||||||
|
}
|
||||||
|
const double createMs=std::chrono::duration<double,std::milli>(
|
||||||
|
std::chrono::steady_clock::now()-start).count();
|
||||||
|
const FMemorySample current=ReadMemory();
|
||||||
|
const std::int64_t rssDelta=static_cast<std::int64_t>(current.residentKiB)
|
||||||
|
-static_cast<std::int64_t>(previous.residentKiB);
|
||||||
|
std::printf("[TlsProbe] workers=%d create_ms=%.3f rss_kib=%llu rss_delta_kib=%lld vms_kib=%llu\n",
|
||||||
|
index,createMs,static_cast<unsigned long long>(current.residentKiB),
|
||||||
|
static_cast<long long>(rssDelta),static_cast<unsigned long long>(current.virtualKiB));
|
||||||
|
previous=current;
|
||||||
|
}
|
||||||
|
const FMemorySample beforeTouch=ReadMemory();
|
||||||
|
std::printf("[TlsProbeTouch] kind=%.*s rss_before_kib=%llu\n",
|
||||||
|
static_cast<int>(touchKind.size()),touchKind.data(),
|
||||||
|
static_cast<unsigned long long>(beforeTouch.residentKiB));
|
||||||
|
if(touchKind!="none")
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
touchRequested=true;
|
||||||
|
}
|
||||||
|
changed.notify_all();
|
||||||
|
{
|
||||||
|
std::unique_lock lock(mutex);
|
||||||
|
changed.wait(lock,[&]{return touchReady.load(std::memory_order_acquire)==workerCount;});
|
||||||
|
}
|
||||||
|
const FMemorySample afterTouch=ReadMemory();
|
||||||
|
std::printf("[TlsProbeTouch] kind=%.*s rss_after_kib=%llu rss_delta_kib=%lld checksum_sum=%lld\n",
|
||||||
|
static_cast<int>(touchKind.size()),touchKind.data(),
|
||||||
|
static_cast<unsigned long long>(afterTouch.residentKiB),
|
||||||
|
static_cast<long long>(static_cast<std::int64_t>(afterTouch.residentKiB)
|
||||||
|
-static_cast<std::int64_t>(beforeTouch.residentKiB)),
|
||||||
|
static_cast<long long>(std::accumulate(checksums.begin(),checksums.end(),std::int64_t{0})));
|
||||||
|
for(int index=0;index<workerCount;++index)
|
||||||
|
std::printf("[TlsProbeTouch] worker=%d startup_minor_faults=%ld first_touch_minor_faults=%ld\n",
|
||||||
|
index+1,startupMinorFaults[static_cast<std::size_t>(index)],
|
||||||
|
firstTouchMinorFaults[static_cast<std::size_t>(index)]);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mutex);
|
||||||
|
release=true;
|
||||||
|
}
|
||||||
|
changed.notify_all();
|
||||||
|
for(FStandaloneWorkerThread& worker:workers)worker.join();
|
||||||
|
std::printf("[TlsProbe] status=PASS threads_joined=%d\n",workerCount);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline int Run(int,std::string_view="none")
|
||||||
|
{
|
||||||
|
std::fprintf(stderr,"TLS probe is Linux-only.\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "OwnerWorldLoader.h"
|
#include "OwnerWorldLoader.h"
|
||||||
#include "StreamingWorld.h"
|
#include "StreamingWorld.h"
|
||||||
|
#include "StreamBenchmarkPipeline.h"
|
||||||
|
#include "WorldAssemblyPrototype.h"
|
||||||
#include "StandaloneCoreScheduler.h"
|
#include "StandaloneCoreScheduler.h"
|
||||||
#include "../Core/src/StandaloneSnapshotAdapter.h"
|
#include "../Core/src/StandaloneSnapshotAdapter.h"
|
||||||
#include "../Research/OwnerShapeWorld/gpu_field_port/GpuFarViewer.h"
|
#include "../Research/OwnerShapeWorld/gpu_field_port/GpuFarViewer.h"
|
||||||
@@ -52,6 +54,9 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
using StandaloneStreamBenchmark::FHashedTile;
|
||||||
|
using StandaloneStreamBenchmark::HashTileRows;
|
||||||
|
|
||||||
struct V3 { float X=0.0f,Y=0.0f,Z=0.0f; };
|
struct V3 { float X=0.0f,Y=0.0f,Z=0.0f; };
|
||||||
V3 Add(V3 A,V3 B){return {A.X+B.X,A.Y+B.Y,A.Z+B.Z};}
|
V3 Add(V3 A,V3 B){return {A.X+B.X,A.Y+B.Y,A.Z+B.Z};}
|
||||||
V3 Sub(V3 A,V3 B){return {A.X-B.X,A.Y-B.Y,A.Z-B.Z};}
|
V3 Sub(V3 A,V3 B){return {A.X-B.X,A.Y-B.Y,A.Z-B.Z};}
|
||||||
@@ -6932,354 +6937,6 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
|||||||
return TotalSamples>0&&LegacyToDetailed.Unmatched+DetailedToLegacy.Unmatched==0?0:10;
|
return TotalSamples>0&&LegacyToDetailed.Unmatched+DetailedToLegacy.Unmatched==0?0:10;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HashWord(uint64& Hash,uint64 Word,int32 Bytes=8)
|
|
||||||
{
|
|
||||||
for(int32 I=0;I<Bytes;++I)
|
|
||||||
{
|
|
||||||
Hash^=static_cast<uint8>(Word>>(I*8));
|
|
||||||
Hash*=1099511628211ull;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct FHashedTile
|
|
||||||
{
|
|
||||||
FVoxelTileKey Key;
|
|
||||||
uint64 Hash=14695981039346656037ull;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool TileKeyLessForHash(const FVoxelTileKey& A,const FVoxelTileKey& B)
|
|
||||||
{
|
|
||||||
if(A.Level!=B.Level)return A.Level<B.Level;
|
|
||||||
if(A.Coord.Z!=B.Coord.Z)return A.Coord.Z<B.Coord.Z;
|
|
||||||
if(A.Coord.Y!=B.Coord.Y)return A.Coord.Y<B.Coord.Y;
|
|
||||||
return A.Coord.X<B.Coord.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 HashTileRows(std::vector<FHashedTile>& Rows)
|
|
||||||
{
|
|
||||||
std::sort(Rows.begin(),Rows.end(),[](const FHashedTile& A,const FHashedTile& B)
|
|
||||||
{return TileKeyLessForHash(A.Key,B.Key);});
|
|
||||||
uint64 Hash=14695981039346656037ull;
|
|
||||||
for(const FHashedTile& Row:Rows)
|
|
||||||
{
|
|
||||||
HashWord(Hash,static_cast<uint32>(Row.Key.Level),4);
|
|
||||||
HashWord(Hash,static_cast<uint32>(Row.Key.Coord.X),4);
|
|
||||||
HashWord(Hash,static_cast<uint32>(Row.Key.Coord.Y),4);
|
|
||||||
HashWord(Hash,static_cast<uint32>(Row.Key.Coord.Z),4);
|
|
||||||
HashWord(Hash,Row.Hash);
|
|
||||||
}
|
|
||||||
return Hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RunPipelinedStreamingBenchmark(std::shared_ptr<FStandaloneOwnerWorld> OwnerWorld,
|
|
||||||
const VoxelForgeCore::ResolvedWorldSnapshot& CoreSnapshot,
|
|
||||||
const FVector& CameraPositionVoxels,int32 WorkerCount,int32 MaxLevel,
|
|
||||||
VoxelForgeCore::DetailVariant DetailVariant,const VoxelForgeCore::JobScheduler& Scheduler,
|
|
||||||
bool bHashDensity,bool bSkipUvAndColors,bool bSkipMaterialGroups,bool bSkipUV,bool bSkipColors,
|
|
||||||
std::chrono::steady_clock::time_point ColdStart,bool bProfileColumnOverlap,
|
|
||||||
int32 FarHorizonLOD8InteriorStepVoxels)
|
|
||||||
{
|
|
||||||
using Clock=std::chrono::steady_clock;
|
|
||||||
FStandaloneOwnerWorld& World=*OwnerWorld;
|
|
||||||
const bool bRoundTunnels=World.Generator->bStandaloneResearchRoundTunnels;
|
|
||||||
const bool bEnhancedTunnelWalls=World.Generator->bStandaloneResearchEnhancedWalls;
|
|
||||||
VoxelForgeCore::World Shape(CoreSnapshot);
|
|
||||||
FStandaloneDesiredTileSet Desired=StandaloneWorldMesher::BuildDesiredSet(World,CameraPositionVoxels);
|
|
||||||
const auto CoreTiles=Shape.desiredTiles(
|
|
||||||
{CameraPositionVoxels.X,CameraPositionVoxels.Y,CameraPositionVoxels.Z});
|
|
||||||
Desired.Tiles.clear();Desired.Tiles.reserve(CoreTiles.size());
|
|
||||||
for(const auto& Key:CoreTiles)
|
|
||||||
Desired.Tiles.emplace_back(FIntVector(Key.coordinate.x,Key.coordinate.y,Key.coordinate.z),Key.lod);
|
|
||||||
if(MaxLevel>=0)
|
|
||||||
Desired.Tiles.erase(std::remove_if(Desired.Tiles.begin(),Desired.Tiles.end(),
|
|
||||||
[&](const FVoxelTileKey& Tile){return Tile.Level>MaxLevel;}),Desired.Tiles.end());
|
|
||||||
FIntVector FineMin(INT32_MAX,INT32_MAX,INT32_MAX),FineMax(INT32_MIN,INT32_MIN,INT32_MIN);
|
|
||||||
FIntVector ClipMin(INT32_MAX,INT32_MAX,INT32_MAX),ClipMax(INT32_MIN,INT32_MIN,INT32_MIN);
|
|
||||||
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
|
||||||
{
|
|
||||||
const FIntVector Origin=Tile.OriginVoxels();const int32 Extent=Tile.ExtentVoxels();
|
|
||||||
ClipMin.X=std::min(ClipMin.X,Origin.X);ClipMin.Y=std::min(ClipMin.Y,Origin.Y);ClipMin.Z=std::min(ClipMin.Z,Origin.Z);
|
|
||||||
ClipMax.X=std::max(ClipMax.X,Origin.X+Extent);ClipMax.Y=std::max(ClipMax.Y,Origin.Y+Extent);ClipMax.Z=std::max(ClipMax.Z,Origin.Z+Extent);
|
|
||||||
if(Tile.Level<World.FullResClipLevels)
|
|
||||||
{
|
|
||||||
FineMin.X=std::min(FineMin.X,Origin.X);FineMin.Y=std::min(FineMin.Y,Origin.Y);FineMin.Z=std::min(FineMin.Z,Origin.Z);
|
|
||||||
FineMax.X=std::max(FineMax.X,Origin.X+Extent);FineMax.Y=std::max(FineMax.Y,Origin.Y+Extent);FineMax.Z=std::max(FineMax.Z,Origin.Z+Extent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(FineMin.X==INT32_MAX||ClipMin.X==INT32_MAX)
|
|
||||||
{std::fprintf(stderr,"[StreamPipeline] no desired detail or clipmap tiles.\n");return 7;}
|
|
||||||
|
|
||||||
const FIntVector CenterChunk=Desired.CenterChunk;
|
|
||||||
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> Neighborhood;
|
|
||||||
Neighborhood.reserve(32);
|
|
||||||
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
|
||||||
if(Tile.Level==0&&std::abs(Tile.Coord.X-CenterChunk.X)<=1
|
|
||||||
&&std::abs(Tile.Coord.Y-CenterChunk.Y)<=1&&std::abs(Tile.Coord.Z-CenterChunk.Z)<=1)
|
|
||||||
Neighborhood.insert(Tile);
|
|
||||||
if(Neighborhood.size()!=27)
|
|
||||||
{std::fprintf(stderr,"[StreamPipeline] expected 27 player-neighborhood tiles, found %zu.\n",Neighborhood.size());return 7;}
|
|
||||||
|
|
||||||
// The initial desired set now owns all clipmap metadata needed by this Core-only run.
|
|
||||||
// Release the separate compatibility-world generation graph before compiling Core.
|
|
||||||
World.Generator.reset();
|
|
||||||
World.Manager.reset();
|
|
||||||
World.DefinitionStorage.clear();
|
|
||||||
World.BiomeStorage.clear();
|
|
||||||
World.OperationStorage.clear();
|
|
||||||
World.DensitySamples.clear();
|
|
||||||
|
|
||||||
std::string BuildError;
|
|
||||||
const bool bIncludeFarWorld=MaxLevel<0||MaxLevel>=World.FullResClipLevels;
|
|
||||||
const auto ShapeBuildStart=Clock::now();
|
|
||||||
VoxelForgeCore::ShapeBuildRequest ShapeRequest;
|
|
||||||
ShapeRequest.minVoxel={FineMin.X,FineMin.Y,FineMin.Z};
|
|
||||||
ShapeRequest.maxVoxel={FineMax.X,FineMax.Y,FineMax.Z};
|
|
||||||
ShapeRequest.clipMinVoxel={ClipMin.X,ClipMin.Y,ClipMin.Z};
|
|
||||||
ShapeRequest.clipMaxVoxel={ClipMax.X,ClipMax.Y,ClipMax.Z};
|
|
||||||
ShapeRequest.workerLimit=static_cast<uint32>(std::clamp(WorkerCount,1,16));
|
|
||||||
ShapeRequest.detail=DetailVariant;ShapeRequest.includeFarWorld=bIncludeFarWorld;
|
|
||||||
ShapeRequest.roundTunnels=bRoundTunnels;
|
|
||||||
ShapeRequest.enhancedTunnelWalls=bEnhancedTunnelWalls;
|
|
||||||
if(!Shape.compile(ShapeRequest,Scheduler,BuildError))
|
|
||||||
{std::fprintf(stderr,"[StreamPipeline] full shape build failed: %s\n",BuildError.c_str());return 2;}
|
|
||||||
const auto ShapeReady=Clock::now();
|
|
||||||
const double ShapeSeconds=std::chrono::duration<double>(ShapeReady-ShapeBuildStart).count();
|
|
||||||
FStandaloneStreamingGenerator Streamer(World,WorkerCount,bHashDensity,nullptr,MaxLevel,
|
|
||||||
bSkipUvAndColors,bSkipMaterialGroups,bSkipUV,bSkipColors,&Shape,bProfileColumnOverlap,
|
|
||||||
FarHorizonLOD8InteriorStepVoxels);
|
|
||||||
const auto StreamStart=Clock::now();
|
|
||||||
const FStandaloneStreamingUpdate Update=Streamer.StartWithDesired(Desired);
|
|
||||||
if(Update.DesiredTiles!=static_cast<int32>(Desired.Tiles.size()))
|
|
||||||
{
|
|
||||||
Streamer.Stop();
|
|
||||||
std::fprintf(stderr,"[StreamPipeline] expected %zu tiles but queued %d.\n",
|
|
||||||
Desired.Tiles.size(),Update.DesiredTiles);return 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<FHashedTile> DensityRows,MeshRows,PayloadRows,TopologyRows;
|
|
||||||
int32 Finished=0,NeighborhoodFinished=0,FullDetailFinished=0;
|
|
||||||
int32 FullDetailExpected=0;
|
|
||||||
struct FColumnXY
|
|
||||||
{
|
|
||||||
std::int64_t X=0,Y=0;
|
|
||||||
bool operator==(const FColumnXY&)const=default;
|
|
||||||
};
|
|
||||||
struct FColumnXYHash
|
|
||||||
{
|
|
||||||
std::size_t operator()(const FColumnXY& Value)const noexcept
|
|
||||||
{
|
|
||||||
const std::size_t X=std::hash<std::int64_t>{}(Value.X);
|
|
||||||
const std::size_t Y=std::hash<std::int64_t>{}(Value.Y);
|
|
||||||
return X^(Y+static_cast<std::size_t>(0x9E3779B9u)+(X<<6)+(X>>2));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct FFirstColumnUse
|
|
||||||
{
|
|
||||||
FVoxelTileKey Tile;
|
|
||||||
std::uint64_t WorkerHash=0;
|
|
||||||
};
|
|
||||||
std::array<std::unordered_map<FColumnXY,std::vector<FFirstColumnUse>,FColumnXYHash>,9> ColumnUsesByLOD;
|
|
||||||
std::array<std::uint64_t,9> ColumnDuplicateEventsByLOD{},NeighbourDuplicateEventsByLOD{};
|
|
||||||
std::array<std::uint64_t,9> CrossWorkerNeighbourDuplicateEventsByLOD{};
|
|
||||||
std::array<std::uint64_t,9> ColumnCaptureTilesByLOD{},ExpectedTilesByLOD{};
|
|
||||||
std::array<bool,9> ColumnCaptureCompleteByLOD{};
|
|
||||||
ColumnCaptureCompleteByLOD.fill(true);
|
|
||||||
std::array<double,9> WorkerSecondsByLOD{};
|
|
||||||
std::array<double,9> ColumnEvalMsByLOD{},MarchingExclusiveMsByLOD{};
|
|
||||||
std::array<double,9> GroundRefineExclusiveMsByLOD{},CapRefineExclusiveMsByLOD{};
|
|
||||||
std::array<double,9> MeshAssemblyMsByLOD{};
|
|
||||||
std::array<std::uint64_t,9> TileCountByLOD{};
|
|
||||||
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
|
||||||
if(Tile.Level>=0&&Tile.Level<static_cast<int32>(ExpectedTilesByLOD.size()))
|
|
||||||
++ExpectedTilesByLOD[static_cast<std::size_t>(Tile.Level)];
|
|
||||||
const auto AreSameLODNeighbours=[](const FVoxelTileKey& A,const FVoxelTileKey& B)
|
|
||||||
{
|
|
||||||
if(A.Level!=B.Level)return false;
|
|
||||||
const std::int64_t DX=std::abs(static_cast<std::int64_t>(A.Coord.X)-B.Coord.X);
|
|
||||||
const std::int64_t DY=std::abs(static_cast<std::int64_t>(A.Coord.Y)-B.Coord.Y);
|
|
||||||
const std::int64_t DZ=std::abs(static_cast<std::int64_t>(A.Coord.Z)-B.Coord.Z);
|
|
||||||
return std::max({DX,DY,DZ})<=1&&(DX+DY+DZ)>0;
|
|
||||||
};
|
|
||||||
uint64 NativeSolidBoxes=0,NativeAirBoxes=0,NativeMixedBoxes=0,NativeUnknownBoxes=0;
|
|
||||||
uint64 NativeFieldCalls=0,NativeColumnHits=0,NativeColumnMisses=0,NativeMeshingSkips=0;
|
|
||||||
double NativeClassificationMilliseconds=0.0,NativeColumnComputeMilliseconds=0.0;
|
|
||||||
double NativeMeshingMilliseconds=0.0;
|
|
||||||
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
|
||||||
if(Tile.Level<World.FullResClipLevels)++FullDetailExpected;
|
|
||||||
Clock::time_point NeighborhoodReady{},FullDetailReady{},WholeViewReady{};
|
|
||||||
bool bNeighborhoodReported=false,bFullDetailReported=false;
|
|
||||||
while(Finished<Update.DesiredTiles)
|
|
||||||
{
|
|
||||||
std::vector<FStandaloneCpuTile> Ready=Streamer.TakeReady();
|
|
||||||
if(Ready.empty()){std::this_thread::sleep_for(std::chrono::milliseconds(1));continue;}
|
|
||||||
for(const FStandaloneCpuTile& Tile:Ready)
|
|
||||||
{
|
|
||||||
++Finished;
|
|
||||||
if(Tile.Key.Level>=0&&Tile.Key.Level<static_cast<int32>(TileCountByLOD.size()))
|
|
||||||
{
|
|
||||||
const std::size_t LOD=static_cast<std::size_t>(Tile.Key.Level);
|
|
||||||
++TileCountByLOD[LOD];
|
|
||||||
WorkerSecondsByLOD[LOD]+=Tile.WorkerSeconds;
|
|
||||||
ColumnEvalMsByLOD[LOD]+=Tile.CoreDiagnostics.columnEvaluationExclusiveMilliseconds;
|
|
||||||
MarchingExclusiveMsByLOD[LOD]+=Tile.CoreDiagnostics.marchingCubesExclusiveMilliseconds;
|
|
||||||
GroundRefineExclusiveMsByLOD[LOD]+=Tile.CoreDiagnostics.groundRefinementExclusiveMilliseconds;
|
|
||||||
CapRefineExclusiveMsByLOD[LOD]+=Tile.CoreDiagnostics.capRefinementExclusiveMilliseconds;
|
|
||||||
MeshAssemblyMsByLOD[LOD]+=Tile.CoreDiagnostics.meshAssemblyMilliseconds;
|
|
||||||
}
|
|
||||||
if(bProfileColumnOverlap&&Tile.Key.Level>=0
|
|
||||||
&&Tile.Key.Level<static_cast<int32>(ColumnCaptureTilesByLOD.size()))
|
|
||||||
{
|
|
||||||
const std::size_t LOD=static_cast<std::size_t>(Tile.Key.Level);
|
|
||||||
++ColumnCaptureTilesByLOD[LOD];
|
|
||||||
ColumnCaptureCompleteByLOD[LOD]=ColumnCaptureCompleteByLOD[LOD]
|
|
||||||
&&Tile.CoreDiagnostics.columnCoordinateCaptureComplete;
|
|
||||||
std::vector<std::array<std::int64_t,2>> Coordinates=
|
|
||||||
Tile.CoreDiagnostics.evaluatedColumnCoordinates;
|
|
||||||
std::sort(Coordinates.begin(),Coordinates.end());
|
|
||||||
Coordinates.erase(std::unique(Coordinates.begin(),Coordinates.end()),Coordinates.end());
|
|
||||||
for(const auto& Coordinate:Coordinates)
|
|
||||||
{
|
|
||||||
const FColumnXY XY{Coordinate[0],Coordinate[1]};
|
|
||||||
auto [Uses,Inserted]=ColumnUsesByLOD[LOD].try_emplace(XY);
|
|
||||||
std::vector<FFirstColumnUse>& PriorUses=Uses->second;
|
|
||||||
if(Inserted)
|
|
||||||
{
|
|
||||||
PriorUses.push_back({Tile.Key,Tile.CoreDiagnostics.columnEvaluationWorkerHash});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++ColumnDuplicateEventsByLOD[LOD];
|
|
||||||
bool bHasNeighbourDuplicate=false,bHasCrossWorkerNeighbourDuplicate=false;
|
|
||||||
for(const FFirstColumnUse& Prior:PriorUses)
|
|
||||||
{
|
|
||||||
if(!AreSameLODNeighbours(Prior.Tile,Tile.Key))continue;
|
|
||||||
bHasNeighbourDuplicate=true;
|
|
||||||
bHasCrossWorkerNeighbourDuplicate=bHasCrossWorkerNeighbourDuplicate
|
|
||||||
||Prior.WorkerHash!=Tile.CoreDiagnostics.columnEvaluationWorkerHash;
|
|
||||||
}
|
|
||||||
if(bHasNeighbourDuplicate)++NeighbourDuplicateEventsByLOD[LOD];
|
|
||||||
if(bHasCrossWorkerNeighbourDuplicate)
|
|
||||||
++CrossWorkerNeighbourDuplicateEventsByLOD[LOD];
|
|
||||||
PriorUses.push_back({Tile.Key,Tile.CoreDiagnostics.columnEvaluationWorkerHash});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WholeViewReady=std::max(WholeViewReady,Tile.CompletedAt);
|
|
||||||
if(Neighborhood.contains(Tile.Key))
|
|
||||||
{
|
|
||||||
++NeighborhoodFinished;
|
|
||||||
NeighborhoodReady=std::max(NeighborhoodReady,Tile.CompletedAt);
|
|
||||||
}
|
|
||||||
if(Tile.Key.Level<World.FullResClipLevels)
|
|
||||||
{
|
|
||||||
++FullDetailFinished;
|
|
||||||
FullDetailReady=std::max(FullDetailReady,Tile.CompletedAt);
|
|
||||||
NativeSolidBoxes+=Tile.CoreDiagnostics.solidBoxes;
|
|
||||||
NativeAirBoxes+=Tile.CoreDiagnostics.airBoxes;
|
|
||||||
NativeMixedBoxes+=Tile.CoreDiagnostics.mixedBoxes;
|
|
||||||
NativeUnknownBoxes+=Tile.CoreDiagnostics.unknownBoxes;
|
|
||||||
NativeFieldCalls+=Tile.CoreDiagnostics.fieldCalls;
|
|
||||||
NativeColumnHits+=Tile.CoreDiagnostics.columnCacheHits;
|
|
||||||
NativeColumnMisses+=Tile.CoreDiagnostics.columnCacheMisses;
|
|
||||||
NativeMeshingSkips+=Tile.CoreDiagnostics.meshingSkipped?1u:0u;
|
|
||||||
NativeClassificationMilliseconds+=Tile.CoreDiagnostics.classificationMilliseconds;
|
|
||||||
NativeColumnComputeMilliseconds+=Tile.CoreDiagnostics.columnComputeMilliseconds;
|
|
||||||
NativeMeshingMilliseconds+=Tile.CoreDiagnostics.meshingMilliseconds;
|
|
||||||
}
|
|
||||||
if(bHashDensity)
|
|
||||||
{
|
|
||||||
if(Tile.bHasDensityHash)DensityRows.push_back({Tile.Key,Tile.DensityHash});
|
|
||||||
if(Tile.bHasMeshHash)MeshRows.push_back({Tile.Key,Tile.MeshHash});
|
|
||||||
if(Tile.bHasPayloadHash)PayloadRows.push_back({Tile.Key,Tile.PayloadHash});
|
|
||||||
if(Tile.bHasTopologyHash)TopologyRows.push_back({Tile.Key,Tile.TopologyHash});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!bNeighborhoodReported&&NeighborhoodFinished==static_cast<int32>(Neighborhood.size()))
|
|
||||||
{
|
|
||||||
std::printf("[PipelineMilestone] neighborhood_ready=%.3fs generated=%d/27\n",
|
|
||||||
std::chrono::duration<double>(NeighborhoodReady-ColdStart).count(),NeighborhoodFinished);
|
|
||||||
bNeighborhoodReported=true;
|
|
||||||
}
|
|
||||||
if(!bFullDetailReported&&FullDetailFinished==FullDetailExpected)
|
|
||||||
{
|
|
||||||
std::printf("[PipelineMilestone] full_detail_ready=%.3fs generated=%d/%d\n",
|
|
||||||
std::chrono::duration<double>(FullDetailReady-ColdStart).count(),
|
|
||||||
FullDetailFinished,FullDetailExpected);
|
|
||||||
bFullDetailReported=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Streamer.Stop();
|
|
||||||
bool bColumnOverlapCapturePassing=true;
|
|
||||||
if(bProfileColumnOverlap)
|
|
||||||
{
|
|
||||||
for(std::size_t LOD=0;LOD<ColumnCaptureTilesByLOD.size();++LOD)
|
|
||||||
{
|
|
||||||
const bool bLODComplete=ColumnCaptureCompleteByLOD[LOD]
|
|
||||||
&&ColumnCaptureTilesByLOD[LOD]==ExpectedTilesByLOD[LOD];
|
|
||||||
bColumnOverlapCapturePassing=bColumnOverlapCapturePassing&&bLODComplete;
|
|
||||||
std::printf("[WorldAssemblerLODColumnOverlap] lod=%zu tiles=%llu expected_tiles=%llu unique_xy_columns=%zu repeated_tile_evaluations=%llu neighbouring_duplicate_evaluations=%llu cross_worker_neighbouring_duplicates=%llu capture_complete=%d\n",
|
|
||||||
LOD,static_cast<unsigned long long>(ColumnCaptureTilesByLOD[LOD]),
|
|
||||||
static_cast<unsigned long long>(ExpectedTilesByLOD[LOD]),
|
|
||||||
ColumnUsesByLOD[LOD].size(),
|
|
||||||
static_cast<unsigned long long>(ColumnDuplicateEventsByLOD[LOD]),
|
|
||||||
static_cast<unsigned long long>(NeighbourDuplicateEventsByLOD[LOD]),
|
|
||||||
static_cast<unsigned long long>(CrossWorkerNeighbourDuplicateEventsByLOD[LOD]),
|
|
||||||
bLODComplete?1:0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(std::size_t LOD=0;LOD<TileCountByLOD.size();++LOD)
|
|
||||||
{
|
|
||||||
std::printf("[WorldAssemblerLODWorker] lod=%zu tiles=%llu worker_sum_s=%.6f column_eval_exclusive_ms=%.3f mc_exclusive_ms=%.3f ground_refine_exclusive_ms=%.3f cap_refine_exclusive_ms=%.3f mesh_assembly_ms=%.3f\n",
|
|
||||||
LOD,static_cast<unsigned long long>(TileCountByLOD[LOD]),WorkerSecondsByLOD[LOD],
|
|
||||||
ColumnEvalMsByLOD[LOD],MarchingExclusiveMsByLOD[LOD],
|
|
||||||
GroundRefineExclusiveMsByLOD[LOD],CapRefineExclusiveMsByLOD[LOD],MeshAssemblyMsByLOD[LOD]);
|
|
||||||
}
|
|
||||||
const double NeighborhoodSeconds=std::chrono::duration<double>(NeighborhoodReady-ColdStart).count();
|
|
||||||
const double NeighborhoodMeshSeconds=std::chrono::duration<double>(NeighborhoodReady-ShapeReady).count();
|
|
||||||
const double FullDetailSeconds=std::chrono::duration<double>(FullDetailReady-ColdStart).count();
|
|
||||||
const double WholeViewSeconds=std::chrono::duration<double>(WholeViewReady-ColdStart).count();
|
|
||||||
const double StreamSeconds=std::chrono::duration<double>(WholeViewReady-StreamStart).count();
|
|
||||||
std::printf("[StreamPipeline] workers=%d shape=%.3fs neighborhood_mesh=%.3fs neighborhood_ready=%.3fs full_detail_ready=%.3fs whole_view_ready=%.3fs neighborhood_tiles=%d/27 full_detail_tiles=%d/%d whole_tiles=%d/%zu stream_wall=%.3fs cache_hits=0 full_payload=1\n",
|
|
||||||
WorkerCount,ShapeSeconds,NeighborhoodMeshSeconds,NeighborhoodSeconds,
|
|
||||||
FullDetailSeconds,WholeViewSeconds,NeighborhoodFinished,
|
|
||||||
FullDetailFinished,FullDetailExpected,Finished,Desired.Tiles.size(),StreamSeconds);
|
|
||||||
std::printf("[WorldAssemblerTilePipeline] full_detail_tiles=%d solid_boxes=%llu air_boxes=%llu mixed_boxes=%llu unknown_boxes=%llu whole_tile_skips=%llu field_calls=%llu column_cache_hits=%llu column_cache_misses=%llu column_compute_worker_ms=%.3f classification_worker_ms=%.3f meshing_worker_ms=%.3f\n",
|
|
||||||
FullDetailExpected,static_cast<unsigned long long>(NativeSolidBoxes),
|
|
||||||
static_cast<unsigned long long>(NativeAirBoxes),
|
|
||||||
static_cast<unsigned long long>(NativeMixedBoxes),
|
|
||||||
static_cast<unsigned long long>(NativeUnknownBoxes),
|
|
||||||
static_cast<unsigned long long>(NativeMeshingSkips),
|
|
||||||
static_cast<unsigned long long>(NativeFieldCalls),
|
|
||||||
static_cast<unsigned long long>(NativeColumnHits),
|
|
||||||
static_cast<unsigned long long>(NativeColumnMisses),
|
|
||||||
NativeColumnComputeMilliseconds,NativeClassificationMilliseconds,
|
|
||||||
NativeMeshingMilliseconds);
|
|
||||||
|
|
||||||
bool bHashesPassing=true;
|
|
||||||
if(bHashDensity)
|
|
||||||
{
|
|
||||||
bHashesPassing=DensityRows.size()==Desired.Tiles.size()
|
|
||||||
&&MeshRows.size()==Desired.Tiles.size()
|
|
||||||
&&PayloadRows.size()==Desired.Tiles.size()
|
|
||||||
&&TopologyRows.size()==Desired.Tiles.size();
|
|
||||||
std::vector<FHashedTile> FullDensity,FullMesh,FullPayload,FullTopology;
|
|
||||||
for(const FHashedTile& Row:DensityRows)if(Row.Key.Level<World.FullResClipLevels)FullDensity.push_back(Row);
|
|
||||||
for(const FHashedTile& Row:MeshRows)if(Row.Key.Level<World.FullResClipLevels)FullMesh.push_back(Row);
|
|
||||||
for(const FHashedTile& Row:PayloadRows)if(Row.Key.Level<World.FullResClipLevels)FullPayload.push_back(Row);
|
|
||||||
for(const FHashedTile& Row:TopologyRows)if(Row.Key.Level<World.FullResClipLevels)FullTopology.push_back(Row);
|
|
||||||
std::printf("[PipelineFullDetailHash] tiles=%d density=0x%016llx mesh=0x%016llx payload=0x%016llx topology=0x%016llx\n",
|
|
||||||
FullDetailExpected,static_cast<unsigned long long>(HashTileRows(FullDensity)),
|
|
||||||
static_cast<unsigned long long>(HashTileRows(FullMesh)),
|
|
||||||
static_cast<unsigned long long>(HashTileRows(FullPayload)),
|
|
||||||
static_cast<unsigned long long>(HashTileRows(FullTopology)));
|
|
||||||
std::printf("[PipelineWholeViewHash] tiles=%zu density=0x%016llx mesh=0x%016llx payload=0x%016llx topology=0x%016llx\n",
|
|
||||||
Desired.Tiles.size(),static_cast<unsigned long long>(HashTileRows(DensityRows)),
|
|
||||||
static_cast<unsigned long long>(HashTileRows(MeshRows)),
|
|
||||||
static_cast<unsigned long long>(HashTileRows(PayloadRows)),
|
|
||||||
static_cast<unsigned long long>(HashTileRows(TopologyRows)));
|
|
||||||
}
|
|
||||||
return NeighborhoodFinished==static_cast<int32>(Neighborhood.size())
|
|
||||||
&&FullDetailFinished==FullDetailExpected&&Finished==Update.DesiredTiles&&bHashesPassing
|
|
||||||
&&(!bProfileColumnOverlap||bColumnOverlapCapturePassing)?0:6;
|
|
||||||
}
|
|
||||||
int RunStreamingBenchmark(FStandaloneOwnerWorld& World,VoxelForgeCore::World* CoreWorld,
|
int RunStreamingBenchmark(FStandaloneOwnerWorld& World,VoxelForgeCore::World* CoreWorld,
|
||||||
const FVector& CameraPositionVoxels,
|
const FVector& CameraPositionVoxels,
|
||||||
int32 WorkerCount,int32 MaxLevel,bool bRoundTunnels,
|
int32 WorkerCount,int32 MaxLevel,bool bRoundTunnels,
|
||||||
@@ -8132,414 +7789,6 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
|||||||
&&analyticReverseCovered==1&&packedAnalyticRenderSame?0:12;
|
&&analyticReverseCovered==1&&packedAnalyticRenderSame?0:12;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::int64_t WorldAssemblyFixed(double voxels)
|
|
||||||
{return static_cast<std::int64_t>(std::llround(voxels*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));}
|
|
||||||
|
|
||||||
std::int64_t WorldAssemblyQ16(double value)
|
|
||||||
{return static_cast<std::int64_t>(std::llround(value*65536.0));}
|
|
||||||
|
|
||||||
std::int64_t WorldAssemblyWavelength(double frequency,double fallbackVoxels)
|
|
||||||
{
|
|
||||||
const double wavelength=std::isfinite(frequency)&&frequency>0.0?1.0/frequency:fallbackVoxels;
|
|
||||||
return std::max<std::int64_t>(1,WorldAssemblyFixed(wavelength));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64 WorldAssemblyFeatureId(uint32 seed,int64 x,int64 y,uint32 kind)
|
|
||||||
{
|
|
||||||
uint64 hash=14695981039346656037ull;
|
|
||||||
const auto add=[&](uint64 value,int bytes)
|
|
||||||
{
|
|
||||||
for(int i=0;i<bytes;++i){hash^=static_cast<uint8>(value>>(8*i));hash*=1099511628211ull;}
|
|
||||||
};
|
|
||||||
add(seed,4);add(static_cast<uint64>(x),8);add(static_cast<uint64>(y),8);add(kind,4);
|
|
||||||
return hash?hash:1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildFiniteStrateRoute(VoxelForgeCore::WorldAssemblyRecipeV1& recipe,
|
|
||||||
VoxelForgeCore::WorldAssemblyStratumPlanV1& stratum,std::uint64_t& tested,
|
|
||||||
std::uint64_t& gradeRejected,std::uint64_t& sweepRejected,std::string& error)
|
|
||||||
{
|
|
||||||
using namespace VoxelForgeCore;
|
|
||||||
constexpr std::int64_t PlayerRadiusQ=348; // 0.34 m in Core's 0.25 m voxel scale.
|
|
||||||
constexpr std::int64_t PlayerHeightQ=1802; // 1.76 m in Core's 0.25 m voxel scale.
|
|
||||||
constexpr std::int64_t HalfHeightQ=PlayerHeightQ/2;
|
|
||||||
constexpr std::int64_t StepQ=128; // 0.5 Core voxel, finer than the density lattice.
|
|
||||||
constexpr std::int64_t ProbeRadiusQ=174;
|
|
||||||
constexpr std::int64_t SupportDepthQ=256;
|
|
||||||
constexpr std::int64_t GradeQ16=17560; // tan(15 degrees), rounded upward.
|
|
||||||
constexpr std::int64_t RouteRadiusQ=4*WorldAssemblySubvoxelsPerVoxel;
|
|
||||||
struct Direction {std::int32_t x,y;};
|
|
||||||
constexpr std::array<Direction,8> directions{{
|
|
||||||
{65536,0},{46341,46341},{0,65536},{-46341,46341},
|
|
||||||
{-65536,0},{-46341,-46341},{0,-65536},{46341,-46341}}};
|
|
||||||
struct Candidate
|
|
||||||
{
|
|
||||||
std::int64_t score=0;
|
|
||||||
std::int32_t centerX=0,centerY=0,direction=0;
|
|
||||||
std::vector<WorldAssemblyRoutePointV1> points;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto& constraints=stratum.routeConstraints;
|
|
||||||
constraints.version=1;
|
|
||||||
constraints.capsuleRadiusSubvoxels=PlayerRadiusQ;
|
|
||||||
constraints.capsuleHeightSubvoxels=PlayerHeightQ;
|
|
||||||
constraints.maximumGradeQ16=GradeQ16;
|
|
||||||
constraints.sweepSpacingSubvoxels=StepQ;
|
|
||||||
constraints.supportProbeRadiusSubvoxels=ProbeRadiusQ;
|
|
||||||
constraints.supportSearchDepthSubvoxels=SupportDepthQ;
|
|
||||||
constraints.minimumClearanceSubvoxels=8;
|
|
||||||
constraints.minimumSupportProbes=3;
|
|
||||||
|
|
||||||
const Heightfield2D finalField(recipe,stratum);
|
|
||||||
if(!finalField.isValid())
|
|
||||||
{error="route planner received an invalid final composed field";return false;}
|
|
||||||
std::vector<Candidate> candidates;
|
|
||||||
constexpr std::int32_t halfLength=128;
|
|
||||||
constexpr std::int32_t waypointSpacing=8;
|
|
||||||
for(std::int32_t centerY=-256;centerY<=256;centerY+=64)
|
|
||||||
for(std::int32_t centerX=-256;centerX<=256;centerX+=64)
|
|
||||||
for(std::int32_t directionIndex=0;directionIndex<static_cast<std::int32_t>(directions.size());++directionIndex)
|
|
||||||
{
|
|
||||||
Candidate candidate;
|
|
||||||
candidate.centerX=centerX;candidate.centerY=centerY;candidate.direction=directionIndex;
|
|
||||||
candidate.points.reserve(33);
|
|
||||||
std::int64_t previousGround=0,previousX=0,previousY=0;
|
|
||||||
bool gradePass=true;
|
|
||||||
for(std::int32_t index=0;index<=32;++index)
|
|
||||||
{
|
|
||||||
const std::int64_t along=(index-16)*waypointSpacing;
|
|
||||||
const std::int64_t x=centerX+std::llround(
|
|
||||||
static_cast<double>(along)*directions[directionIndex].x/65536.0);
|
|
||||||
const std::int64_t y=centerY+std::llround(
|
|
||||||
static_cast<double>(along)*directions[directionIndex].y/65536.0);
|
|
||||||
const auto column=finalField.point(WorldAssemblyFixed(static_cast<double>(x)),
|
|
||||||
WorldAssemblyFixed(static_cast<double>(y)),0);
|
|
||||||
const std::int64_t horizontalQ=static_cast<std::int64_t>(std::llround(
|
|
||||||
std::hypot(static_cast<double>(x-previousX),static_cast<double>(y-previousY))
|
|
||||||
*WorldAssemblySubvoxelsPerVoxel));
|
|
||||||
if(index>0)
|
|
||||||
{
|
|
||||||
const std::int64_t riseQ=std::abs(column.groundHeightSubvoxels-previousGround);
|
|
||||||
if(horizontalQ==0||riseQ*65536>horizontalQ*GradeQ16)
|
|
||||||
{gradePass=false;break;}
|
|
||||||
candidate.score+=riseQ*65536/std::max<std::int64_t>(1,horizontalQ);
|
|
||||||
}
|
|
||||||
WorldAssemblyRoutePointV1 point;
|
|
||||||
point.positionSubvoxels={WorldAssemblyFixed(static_cast<double>(x)),
|
|
||||||
WorldAssemblyFixed(static_cast<double>(y)),column.groundHeightSubvoxels+HalfHeightQ};
|
|
||||||
point.radiusSubvoxels=RouteRadiusQ;
|
|
||||||
point.stableFeatureId=WorldAssemblyFeatureId(recipe.seed,
|
|
||||||
static_cast<std::int64_t>(x),static_cast<std::int64_t>(y),
|
|
||||||
0x52540000u+static_cast<std::uint32_t>(index));
|
|
||||||
candidate.points.push_back(point);
|
|
||||||
previousGround=column.groundHeightSubvoxels;previousX=x;previousY=y;
|
|
||||||
}
|
|
||||||
++tested;
|
|
||||||
if(gradePass)candidates.push_back(std::move(candidate));
|
|
||||||
else ++gradeRejected;
|
|
||||||
}
|
|
||||||
std::stable_sort(candidates.begin(),candidates.end(),[](const Candidate& a,const Candidate& b)
|
|
||||||
{
|
|
||||||
if(a.score!=b.score)return a.score<b.score;
|
|
||||||
if(a.centerY!=b.centerY)return a.centerY<b.centerY;
|
|
||||||
if(a.centerX!=b.centerX)return a.centerX<b.centerX;
|
|
||||||
return a.direction<b.direction;
|
|
||||||
});
|
|
||||||
std::uint64_t sweepAttempt=0,repairAttempt=0;
|
|
||||||
VoxelForgeCore::WorldAssemblyRouteAuditResult lastAudit{};
|
|
||||||
for(auto& candidate:candidates)
|
|
||||||
{
|
|
||||||
stratum.route=candidate.points;
|
|
||||||
std::int64_t liftQ=0;
|
|
||||||
constexpr std::int64_t RepairStepQ=64;
|
|
||||||
constexpr std::int64_t MaximumRepairLiftQ=SupportDepthQ-RepairStepQ;
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
if(liftQ>0)
|
|
||||||
for(std::size_t pointIndex=0;pointIndex<stratum.route.size();++pointIndex)
|
|
||||||
stratum.route[pointIndex].positionSubvoxels[2]
|
|
||||||
=candidate.points[pointIndex].positionSubvoxels[2]+liftQ;
|
|
||||||
const Heightfield2D candidateField(recipe,stratum);
|
|
||||||
const auto audit=AuditHeightfieldRoute(candidateField);
|
|
||||||
lastAudit=audit;
|
|
||||||
if(audit.passed)
|
|
||||||
{
|
|
||||||
if(liftQ>0)
|
|
||||||
std::printf("[WorldAssemblerRouteRepaired] uniform_lift_q=%lld support_limit_q=%lld\n",
|
|
||||||
static_cast<long long>(liftQ),static_cast<long long>(SupportDepthQ));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if(audit.blockedCapsuleSamples==0||liftQ>=MaximumRepairLiftQ)break;
|
|
||||||
const std::int64_t needed=std::max<std::int64_t>(1,
|
|
||||||
constraints.minimumClearanceSubvoxels-audit.minimumClearanceSubvoxels);
|
|
||||||
const std::int64_t steps=(needed+RepairStepQ-1)/RepairStepQ;
|
|
||||||
const std::int64_t nextLift=std::max(liftQ+RepairStepQ,liftQ+steps*RepairStepQ);
|
|
||||||
if(nextLift>MaximumRepairLiftQ)break;
|
|
||||||
liftQ=nextLift;
|
|
||||||
++repairAttempt;
|
|
||||||
}
|
|
||||||
if(sweepAttempt<3)
|
|
||||||
std::printf("[WorldAssemblerRouteCandidateRejected] ordinal=%llu blocked=%llu unsupported=%llu grade_failures=%llu minimum_clearance_q=%lld\n",
|
|
||||||
static_cast<unsigned long long>(sweepAttempt),
|
|
||||||
static_cast<unsigned long long>(lastAudit.blockedCapsuleSamples),
|
|
||||||
static_cast<unsigned long long>(lastAudit.unsupportedCenterSamples),
|
|
||||||
static_cast<unsigned long long>(lastAudit.gradeFailures),
|
|
||||||
static_cast<long long>(lastAudit.minimumClearanceSubvoxels));
|
|
||||||
++sweepAttempt;
|
|
||||||
++sweepRejected;
|
|
||||||
}
|
|
||||||
std::printf("[WorldAssemblerRouteSearchFailed] tested=%llu grade_rejected=%llu sweepable_candidates=%llu sweep_rejected=%llu last_blocked=%llu last_unsupported=%llu last_grade_failures=%llu\n",
|
|
||||||
static_cast<unsigned long long>(tested),static_cast<unsigned long long>(gradeRejected),
|
|
||||||
static_cast<unsigned long long>(candidates.size()),static_cast<unsigned long long>(sweepRejected),
|
|
||||||
static_cast<unsigned long long>(lastAudit.blockedCapsuleSamples),
|
|
||||||
static_cast<unsigned long long>(lastAudit.unsupportedCenterSamples),
|
|
||||||
static_cast<unsigned long long>(lastAudit.gradeFailures));
|
|
||||||
std::printf("[WorldAssemblerRouteRepairSummary] repair_attempts=%llu\n",
|
|
||||||
static_cast<unsigned long long>(repairAttempt));
|
|
||||||
stratum.route.clear();
|
|
||||||
error="finite-strate route candidates failed the composed-field capsule and support sweep";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AttachRound1WorldAssemblyPrototype(FStandaloneOwnerWorld& owner,VFJson::Value& root,
|
|
||||||
std::string& error,const std::string& manifestOutputPath)
|
|
||||||
{
|
|
||||||
if(!owner.Manager||!owner.Generator)
|
|
||||||
{error="world assembler prototype needs the resolved standalone owner world";return false;}
|
|
||||||
int32 surfaceChunkZ=0,topChunkZ=0,bottomChunkZ=0;
|
|
||||||
bool foundSurface=false;
|
|
||||||
for(int32 chunkZ=1024;chunkZ>=-4096;--chunkZ)
|
|
||||||
{
|
|
||||||
if(owner.Manager->GetGeneratorTypeForChunk(FIntVector(0,0,chunkZ))
|
|
||||||
!=ECaveGeneratorType::SurfaceWorld)continue;
|
|
||||||
surfaceChunkZ=chunkZ;
|
|
||||||
foundSurface=owner.Manager->GetStrateChunkZBounds(chunkZ,topChunkZ,bottomChunkZ);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!foundSurface)
|
|
||||||
{error="world assembler prototype could not find a finite SurfaceWorld strate";return false;}
|
|
||||||
const FIntVector chunk(0,0,surfaceChunkZ);
|
|
||||||
const FSurfaceGenerationParams surface=owner.Manager->GetSurfaceParamsForChunk(chunk);
|
|
||||||
const FBiomeContext biomeContext=owner.Manager->GetBiomeContextForChunk(chunk);
|
|
||||||
const std::int64_t bottomVoxel=static_cast<std::int64_t>(bottomChunkZ)*CHUNK_SIZE;
|
|
||||||
const std::int64_t heightVoxels=static_cast<std::int64_t>(topChunkZ-bottomChunkZ+1)*CHUNK_SIZE;
|
|
||||||
const FBiomeMapParams& map=biomeContext.Map;
|
|
||||||
const UVoxelStrateDefinition* definition=owner.Manager->GetStrateForChunk(chunk);
|
|
||||||
|
|
||||||
VoxelForgeCore::WorldAssemblyManifest manifest;
|
|
||||||
auto& recipe=manifest.recipe;
|
|
||||||
recipe.seed=static_cast<uint32>(owner.Seed);
|
|
||||||
recipe.biomeCellSizeSubvoxels=WorldAssemblyFixed(map.CellSize);
|
|
||||||
recipe.biomeWarpSubvoxels=WorldAssemblyFixed(map.WarpStrength);
|
|
||||||
recipe.biomeWarpWavelengthSubvoxels=WorldAssemblyWavelength(map.WarpFrequency,556.0);
|
|
||||||
recipe.biomeBorderBlendSubvoxels=WorldAssemblyFixed(map.BorderBlend);
|
|
||||||
recipe.biomeClimateReliefWavelengthSubvoxels=WorldAssemblyWavelength(map.ReliefFrequency,3333.0);
|
|
||||||
recipe.biomeClimateMoistureWavelengthSubvoxels=WorldAssemblyWavelength(map.MoistureFrequency,2500.0);
|
|
||||||
recipe.biomeClimateReliefContrastQ16=WorldAssemblyQ16(map.ReliefContrast);
|
|
||||||
const auto makeProfile=[&](uint32 stableId,const FSurfaceGenerationParams& params,
|
|
||||||
const FBiomeResolved* climate)
|
|
||||||
{
|
|
||||||
VoxelForgeCore::WorldAssemblyBiomeProfileV1 profile;
|
|
||||||
profile.stableId=stableId;
|
|
||||||
profile.baseHeightSubvoxels=WorldAssemblyFixed(static_cast<double>(bottomVoxel)
|
|
||||||
+static_cast<double>(heightVoxels)*params.BaseGroundRelative);
|
|
||||||
profile.continentAmplitudeSubvoxels=WorldAssemblyFixed(params.ElevationRange);
|
|
||||||
profile.continentWavelengthSubvoxels=WorldAssemblyWavelength(params.ContinentFrequency,1000.0);
|
|
||||||
profile.mountainAmplitudeSubvoxels=WorldAssemblyFixed(params.ElevationRange*params.MountainStrength);
|
|
||||||
profile.mountainWavelengthSubvoxels=WorldAssemblyWavelength(params.MountainFrequency,500.0);
|
|
||||||
profile.detailAmplitudeSubvoxels=WorldAssemblyFixed(params.SurfaceRoughness);
|
|
||||||
profile.detailWavelengthSubvoxels=WorldAssemblyWavelength(params.DetailFrequency,25.0);
|
|
||||||
profile.reliefMinimumQ16=climate?WorldAssemblyQ16(climate->ReliefMin):0;
|
|
||||||
profile.reliefMaximumQ16=climate?WorldAssemblyQ16(climate->ReliefMax):65536;
|
|
||||||
profile.moistureMinimumQ16=climate?WorldAssemblyQ16(climate->MoistureMin):0;
|
|
||||||
profile.moistureMaximumQ16=climate?WorldAssemblyQ16(climate->MoistureMax):65536;
|
|
||||||
profile.reliefStrengthQ16=WorldAssemblyQ16(params.ReliefStrength);
|
|
||||||
profile.reliefContrastQ16=WorldAssemblyQ16(params.ReliefContrast);
|
|
||||||
profile.reliefWavelengthSubvoxels=WorldAssemblyWavelength(params.ReliefFrequency,667.0);
|
|
||||||
profile.heightWarpStrengthSubvoxels=WorldAssemblyFixed(params.HeightWarpStrength);
|
|
||||||
profile.heightWarpWavelengthSubvoxels=WorldAssemblyWavelength(params.HeightWarpFrequency,125.0);
|
|
||||||
profile.beachWidthSubvoxels=WorldAssemblyFixed(params.BeachWidth);
|
|
||||||
profile.cliffStrengthQ16=WorldAssemblyQ16(params.CliffStrength);
|
|
||||||
profile.cliffSlopeThresholdQ16=std::max<std::int64_t>(1,WorldAssemblyQ16(params.CliffSlopeThreshold));
|
|
||||||
profile.cliffSharpnessQ16=WorldAssemblyQ16(params.CliffSharpness);
|
|
||||||
profile.cliffSampleDistanceSubvoxels=WorldAssemblyFixed(std::max(0.5f,params.CliffSampleDist));
|
|
||||||
const double structuralAbsBound=static_cast<double>(params.ElevationRange)
|
|
||||||
+static_cast<double>(params.ElevationRange)*params.MountainStrength
|
|
||||||
+2.0*params.SurfaceRoughness;
|
|
||||||
const double cliffAbsBound=2.0*structuralAbsBound*params.CliffStrength*params.CliffSharpness;
|
|
||||||
profile.cliffMaximumDisplacementSubvoxels=WorldAssemblyFixed(params.CliffStrength>0.0f
|
|
||||||
?std::max(1.0,cliffAbsBound):0.0);
|
|
||||||
profile.hasCapProfile=true;
|
|
||||||
profile.capHeightSubvoxels=WorldAssemblyFixed(static_cast<double>(bottomVoxel)
|
|
||||||
+static_cast<double>(heightVoxels)*params.CeilingRelative);
|
|
||||||
profile.capWarpStrengthSubvoxels=WorldAssemblyFixed(params.CeilingWarpStrength);
|
|
||||||
profile.capWarpWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingWarpFrequency,100.0);
|
|
||||||
profile.capUndulationSubvoxels=WorldAssemblyFixed(params.CeilingUndulation);
|
|
||||||
profile.capWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingUndulationFrequency,500.0);
|
|
||||||
profile.capDetailAmplitudeSubvoxels=WorldAssemblyFixed(params.CeilingRoughness);
|
|
||||||
profile.capDetailWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingRoughnessFrequency,25.0);
|
|
||||||
profile.capRidgeAmplitudeSubvoxels=WorldAssemblyFixed(params.CeilingRidgeStrength);
|
|
||||||
profile.capRidgeWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingRidgeFrequency,50.0);
|
|
||||||
return profile;
|
|
||||||
};
|
|
||||||
if(biomeContext.IsValid()&&definition)
|
|
||||||
{
|
|
||||||
for(const FBiomeResolved& resolved:biomeContext.Biomes)
|
|
||||||
{
|
|
||||||
const UVoxelBiomeDefinition* biome=definition->Biomes.IsValidIndex(resolved.Index)
|
|
||||||
?definition->Biomes[resolved.Index]:nullptr;
|
|
||||||
FSurfaceGenerationParams params=surface;
|
|
||||||
if(biome&&biome->bOverrideTerrain&&biome->GeneratorType==ECaveGeneratorType::SurfaceWorld)
|
|
||||||
{
|
|
||||||
params=biome->SurfaceParams;
|
|
||||||
params.StrateTopWorldZ=surface.StrateTopWorldZ;
|
|
||||||
params.StrateBottomWorldZ=surface.StrateBottomWorldZ;
|
|
||||||
params.BoundarySealThickness=surface.BoundarySealThickness;
|
|
||||||
params.BaseDensity=surface.BaseDensity;
|
|
||||||
params.WaterLevelRelative=surface.WaterLevelRelative;
|
|
||||||
}
|
|
||||||
recipe.biomes.push_back(makeProfile(0x1001u+static_cast<uint32>(resolved.Index),params,&resolved));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(recipe.biomes.empty())recipe.biomes.push_back(makeProfile(0x1001u,surface,nullptr));
|
|
||||||
|
|
||||||
VoxelForgeCore::WorldAssemblyStratumPlanV1 stratum;
|
|
||||||
stratum.strateIndex=owner.Manager->GetStrateIndex(
|
|
||||||
static_cast<float>((static_cast<double>(surfaceChunkZ*CHUNK_SIZE+CHUNK_SIZE/2))*VOXEL_SIZE));
|
|
||||||
stratum.topChunkZ=topChunkZ;
|
|
||||||
stratum.bottomChunkZ=bottomChunkZ;
|
|
||||||
const double strateBottom=static_cast<double>(bottomVoxel);
|
|
||||||
const double strateHeight=static_cast<double>(heightVoxels);
|
|
||||||
stratum.capHeightSubvoxels=WorldAssemblyFixed(strateBottom+strateHeight*surface.CeilingRelative);
|
|
||||||
stratum.capUndulationSubvoxels=WorldAssemblyFixed(surface.CeilingUndulation);
|
|
||||||
stratum.capWavelengthSubvoxels=WorldAssemblyWavelength(surface.CeilingUndulationFrequency,250.0);
|
|
||||||
stratum.capDetailAmplitudeSubvoxels=WorldAssemblyFixed(surface.CeilingRoughness);
|
|
||||||
stratum.capDetailWavelengthSubvoxels=WorldAssemblyWavelength(surface.CeilingRoughnessFrequency,25.0);
|
|
||||||
stratum.capRidgeAmplitudeSubvoxels=WorldAssemblyFixed(surface.CeilingRidgeStrength);
|
|
||||||
stratum.capRidgeWavelengthSubvoxels=WorldAssemblyWavelength(surface.CeilingRidgeFrequency,50.0);
|
|
||||||
stratum.waterSurfaceSubvoxels=WorldAssemblyFixed(strateBottom+strateHeight*surface.WaterLevelRelative);
|
|
||||||
stratum.waterEnabled=definition&&definition->bHasWater&&surface.WaterLevelRelative>0.0f;
|
|
||||||
|
|
||||||
// Select a deterministic steep edge in the resolved owner field for a bounded shelf.
|
|
||||||
// Selection d'une pente deterministe dans le champ resolu pour une saillie bornee.
|
|
||||||
constexpr int probeSide=49,probeStep=32;
|
|
||||||
std::array<float,probeSide*probeSide> heights{};
|
|
||||||
std::array<uint8,probeSide*probeSide> valid{};
|
|
||||||
for(int y=0;y<probeSide;++y)
|
|
||||||
for(int x=0;x<probeSide;++x)
|
|
||||||
{
|
|
||||||
const float px=static_cast<float>((x-probeSide/2)*probeStep);
|
|
||||||
const float py=static_cast<float>((y-probeSide/2)*probeStep);
|
|
||||||
float ceiling=0.0f;
|
|
||||||
const std::size_t index=static_cast<std::size_t>(y)*probeSide+x;
|
|
||||||
valid[index]=owner.Generator->GetSurfaceHeightAt(px,py,topChunkZ,heights[index],ceiling)?1u:0u;
|
|
||||||
}
|
|
||||||
double steepest=0.0;int cliffX=0,cliffY=0;bool xAxis=true;int downhill=1;
|
|
||||||
for(int y=1;y<probeSide-1;++y)
|
|
||||||
for(int x=1;x<probeSide-1;++x)
|
|
||||||
{
|
|
||||||
const std::size_t center=static_cast<std::size_t>(y)*probeSide+x;
|
|
||||||
if(!valid[center]||!valid[center-1]||!valid[center+1]||!valid[center-probeSide]||!valid[center+probeSide])continue;
|
|
||||||
const double dx=static_cast<double>(heights[center+1]-heights[center-1]);
|
|
||||||
const double dy=static_cast<double>(heights[center+probeSide]-heights[center-probeSide]);
|
|
||||||
const double slope=(std::abs(dx)+std::abs(dy))/(4.0*probeStep);
|
|
||||||
if(slope>steepest){steepest=slope;cliffX=(x-probeSide/2)*probeStep;cliffY=(y-probeSide/2)*probeStep;
|
|
||||||
xAxis=std::abs(dx)>=std::abs(dy);downhill=(xAxis?dx:dy)>=0.0?-1:1;}
|
|
||||||
}
|
|
||||||
if(steepest>0.05)
|
|
||||||
{
|
|
||||||
float ground=0.0f,ceiling=0.0f;
|
|
||||||
if(owner.Generator->GetSurfaceHeightAt(static_cast<float>(cliffX),static_cast<float>(cliffY),
|
|
||||||
topChunkZ,ground,ceiling))
|
|
||||||
{
|
|
||||||
VoxelForgeCore::WorldAssemblyFeatureV1 shelf;
|
|
||||||
shelf.stableId=WorldAssemblyFeatureId(recipe.seed,cliffX,cliffY,0x4f564552u);
|
|
||||||
shelf.type=4;
|
|
||||||
constexpr int reach=72,width=36,height=64,feather=8;
|
|
||||||
const int dirX=xAxis?downhill:0,dirY=xAxis?0:downhill;
|
|
||||||
const int minX=xAxis?(dirX>0?cliffX-feather:cliffX-reach-feather)
|
|
||||||
:cliffX-width-feather;
|
|
||||||
const int maxX=xAxis?(dirX>0?cliffX+reach+feather:cliffX+feather)
|
|
||||||
:cliffX+width+feather;
|
|
||||||
const int minY=xAxis?cliffY-width-feather
|
|
||||||
:(dirY>0?cliffY-feather:cliffY-reach-feather);
|
|
||||||
const int maxY=xAxis?cliffY+width+feather
|
|
||||||
:(dirY>0?cliffY+reach+feather:cliffY+feather);
|
|
||||||
VoxelForgeCore::Heightfield2D baseField(recipe,stratum);
|
|
||||||
double lowestGround=std::numeric_limits<double>::infinity();
|
|
||||||
double highestGround=-std::numeric_limits<double>::infinity();
|
|
||||||
for(int sampleY=minY;sampleY<=maxY;sampleY+=4)
|
|
||||||
for(int sampleX=minX;sampleX<=maxX;sampleX+=4)
|
|
||||||
{
|
|
||||||
const auto sample=baseField.point(WorldAssemblyFixed(sampleX),
|
|
||||||
WorldAssemblyFixed(sampleY),0);
|
|
||||||
const double heightQ=static_cast<double>(sample.groundHeightSubvoxels)
|
|
||||||
/VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
|
||||||
lowestGround=std::min(lowestGround,heightQ);
|
|
||||||
highestGround=std::max(highestGround,heightQ);
|
|
||||||
}
|
|
||||||
if(!std::isfinite(lowestGround)||!std::isfinite(highestGround))
|
|
||||||
{error="world assembler cliff shelf could not bound its terrain columns";return false;}
|
|
||||||
shelf.minimumSubvoxels={WorldAssemblyFixed(minX),WorldAssemblyFixed(minY),
|
|
||||||
WorldAssemblyFixed(std::max<double>(bottomVoxel,lowestGround-4.0))};
|
|
||||||
shelf.maximumSubvoxels={WorldAssemblyFixed(maxX),WorldAssemblyFixed(maxY),
|
|
||||||
WorldAssemblyFixed(std::min<double>((topChunkZ+1)*CHUNK_SIZE,
|
|
||||||
highestGround+height+4.0))};
|
|
||||||
shelf.parametersSubvoxels={WorldAssemblyFixed(dirX),WorldAssemblyFixed(dirY),
|
|
||||||
WorldAssemblyFixed(height),WorldAssemblyFixed(reach)};
|
|
||||||
stratum.features.push_back(shelf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::uint64_t routeCandidates=0,routeGradeRejected=0,routeSweepRejected=0;
|
|
||||||
if(!BuildFiniteStrateRoute(recipe,stratum,routeCandidates,routeGradeRejected,
|
|
||||||
routeSweepRejected,error))return false;
|
|
||||||
std::printf("[WorldAssemblerRoutePlan] candidates=%llu grade_rejected=%llu sweep_rejected=%llu accepted_points=%zu capsule_m=0.34x1.76 corridor_radius_vox=4 support_probe_points=5 minimum_support_probes=%u status=PASS\n",
|
|
||||||
static_cast<unsigned long long>(routeCandidates),
|
|
||||||
static_cast<unsigned long long>(routeGradeRejected),
|
|
||||||
static_cast<unsigned long long>(routeSweepRejected),stratum.route.size(),
|
|
||||||
stratum.routeConstraints.minimumSupportProbes);
|
|
||||||
manifest.plan.strates.push_back(std::move(stratum));
|
|
||||||
if(!manifest.finalize(error))return false;
|
|
||||||
const std::string manifestText=manifest.ToJson();
|
|
||||||
const auto roundTrip=VoxelForgeCore::WorldAssemblyManifest::FromJson(manifestText,error);
|
|
||||||
if(!roundTrip||!roundTrip->validate(error)||roundTrip->ToJson()!=manifestText
|
|
||||||
||roundTrip->contentHash!=manifest.contentHash)
|
|
||||||
{if(error.empty())error="world assembly canonical plan serialization did not round-trip";return false;}
|
|
||||||
std::printf("[WorldAssemblerPlanSerialization] bytes=%zu canonical_round_trip=true route_points=%zu plan_hash=%016llx manifest_hash=%016llx status=PASS\n",
|
|
||||||
manifestText.size(),manifest.plan.strates.front().route.size(),
|
|
||||||
static_cast<unsigned long long>(manifest.plan.contentHash),
|
|
||||||
static_cast<unsigned long long>(manifest.contentHash));
|
|
||||||
if(!manifestOutputPath.empty())
|
|
||||||
{
|
|
||||||
const std::filesystem::path outputPath(manifestOutputPath);
|
|
||||||
std::error_code directoryError;
|
|
||||||
if(!outputPath.parent_path().empty())
|
|
||||||
std::filesystem::create_directories(outputPath.parent_path(),directoryError);
|
|
||||||
if(directoryError)
|
|
||||||
{error="could not create the world assembly manifest output directory";return false;}
|
|
||||||
std::ofstream output(outputPath,std::ios::binary);
|
|
||||||
if(!output)
|
|
||||||
{error="could not open the world assembly manifest output path";return false;}
|
|
||||||
output.write(manifestText.data(),static_cast<std::streamsize>(manifestText.size()));
|
|
||||||
if(!output)
|
|
||||||
{error="could not write the world assembly manifest payload";return false;}
|
|
||||||
}
|
|
||||||
VFJson::Value manifestJson;
|
|
||||||
if(!VFJson::Parser(manifestText).Parse(manifestJson,error))return false;
|
|
||||||
auto* rootObject=std::get_if<VFJson::Value::Object>(&root.Data);
|
|
||||||
if(!rootObject)
|
|
||||||
{error="owner snapshot root is not a JSON object";return false;}
|
|
||||||
(*rootObject)["world_assembly"]=std::move(manifestJson);
|
|
||||||
std::printf("[WorldAssemblerPrototype] recipe_version=%u evaluator_version=%u strata=%zu biomes=%zu strate_index=%d chunk_z=%d..%d serialized_bytes=%zu recipe_hash=%016llx plan_hash=%016llx manifest_hash=%016llx source=owner_surface_params_and_biome_map route_points=%zu features=%zu\n",
|
|
||||||
manifest.recipe.schemaVersion,manifest.recipe.evaluatorVersion,manifest.plan.strates.size(),
|
|
||||||
manifest.recipe.biomes.size(),manifest.plan.strates.front().strateIndex,topChunkZ,bottomChunkZ,
|
|
||||||
manifestText.size(),static_cast<unsigned long long>(manifest.recipe.contentHash),
|
|
||||||
static_cast<unsigned long long>(manifest.plan.contentHash),
|
|
||||||
static_cast<unsigned long long>(manifest.contentHash),manifest.plan.strates.front().route.size(),
|
|
||||||
manifest.plan.strates.front().features.size());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunWorldAssemblerCapAudit(FStandaloneOwnerWorld& owner,
|
bool RunWorldAssemblerCapAudit(FStandaloneOwnerWorld& owner,
|
||||||
const VoxelForgeCore::ResolvedWorldSnapshot& snapshot,VoxelForgeCore::World& world,
|
const VoxelForgeCore::ResolvedWorldSnapshot& snapshot,VoxelForgeCore::World& world,
|
||||||
VoxelForgeCore::Vec3d walkCameraVoxels)
|
VoxelForgeCore::Vec3d walkCameraVoxels)
|
||||||
@@ -9628,6 +8877,11 @@ int main(int Argc,char** Argv)
|
|||||||
bool bStreamPipeline=false;
|
bool bStreamPipeline=false;
|
||||||
bool bProfileColumnOverlap=false;
|
bool bProfileColumnOverlap=false;
|
||||||
bool bCoarseFirstStreamOrder=false;
|
bool bCoarseFirstStreamOrder=false;
|
||||||
|
bool bHasSeedOverride=false;
|
||||||
|
int32 SeedOverride=0;
|
||||||
|
bool bHasRenderDistanceOverride=false;
|
||||||
|
int32 RenderDistanceOverride=0;
|
||||||
|
bool bFloatingIslandsRecipe=false;
|
||||||
bool bProfileDetailBand=false;
|
bool bProfileDetailBand=false;
|
||||||
bool bPassageDetailAuditOnly=false;
|
bool bPassageDetailAuditOnly=false;
|
||||||
bool bGridStairAudit=false;
|
bool bGridStairAudit=false;
|
||||||
@@ -9649,6 +8903,33 @@ int main(int Argc,char** Argv)
|
|||||||
{
|
{
|
||||||
const std::string_view Arg=Argv[I];
|
const std::string_view Arg=Argv[I];
|
||||||
if(Arg.starts_with("--capture="))App.CapturePath=std::string(Arg.substr(10));
|
if(Arg.starts_with("--capture="))App.CapturePath=std::string(Arg.substr(10));
|
||||||
|
else if(Arg.starts_with("--seed="))
|
||||||
|
{
|
||||||
|
const std::string Value(Arg.substr(std::string_view("--seed=").size()));
|
||||||
|
char* End=nullptr;
|
||||||
|
const long long Parsed=std::strtoll(Value.c_str(),&End,10);
|
||||||
|
if(End==Value.c_str()||*End!='\0'||Parsed<INT32_MIN||Parsed>INT32_MAX)
|
||||||
|
{std::fprintf(stderr,"Invalid --seed value: %s\n",Value.c_str());return 2;}
|
||||||
|
SeedOverride=static_cast<int32>(Parsed);bHasSeedOverride=true;
|
||||||
|
}
|
||||||
|
else if(Arg.starts_with("--render-distance-chunks="))
|
||||||
|
{
|
||||||
|
const std::string Value(Arg.substr(std::string_view("--render-distance-chunks=").size()));
|
||||||
|
char* End=nullptr;
|
||||||
|
const long long Parsed=std::strtoll(Value.c_str(),&End,10);
|
||||||
|
if(End==Value.c_str()||*End!='\0'||Parsed<0||Parsed>INT32_MAX)
|
||||||
|
{std::fprintf(stderr,"Invalid --render-distance-chunks value: %s\n",Value.c_str());return 2;}
|
||||||
|
RenderDistanceOverride=static_cast<int32>(Parsed);bHasRenderDistanceOverride=true;
|
||||||
|
}
|
||||||
|
else if(Arg.starts_with("--recipe="))
|
||||||
|
{
|
||||||
|
const std::string_view Recipe=Arg.substr(std::string_view("--recipe=").size());
|
||||||
|
if(Recipe=="surface-world")bFloatingIslandsRecipe=false;
|
||||||
|
else if(Recipe=="floating-islands")
|
||||||
|
{bFloatingIslandsRecipe=true;App.bWorldAssemblerPrototype=true;App.bShapeWorld=true;}
|
||||||
|
else
|
||||||
|
{std::fprintf(stderr,"Invalid --recipe value: %.*s\n",static_cast<int>(Recipe.size()),Recipe.data());return 2;}
|
||||||
|
}
|
||||||
else if(Arg.starts_with("--far-horizon-lod8-step="))
|
else if(Arg.starts_with("--far-horizon-lod8-step="))
|
||||||
App.FarHorizonLOD8InteriorStepVoxels=std::max(0,std::atoi(
|
App.FarHorizonLOD8InteriorStepVoxels=std::max(0,std::atoi(
|
||||||
std::string(Arg.substr(std::string_view("--far-horizon-lod8-step=").size())).c_str()));
|
std::string(Arg.substr(std::string_view("--far-horizon-lod8-step=").size())).c_str()));
|
||||||
@@ -9885,6 +9166,16 @@ int main(int Argc,char** Argv)
|
|||||||
if(!VFJson::Parser(std::move(OwnerJsonText)).Parse(App.OwnerJsonRoot,Error))
|
if(!VFJson::Parser(std::move(OwnerJsonText)).Parse(App.OwnerJsonRoot,Error))
|
||||||
{std::fprintf(stderr,"Owner data load failed: %s\n",Error.c_str());return 2;}
|
{std::fprintf(stderr,"Owner data load failed: %s\n",Error.c_str());return 2;}
|
||||||
}
|
}
|
||||||
|
if(bHasSeedOverride
|
||||||
|
&&!StandaloneWorldAssemblyPrototype::OverrideStandaloneSeed(App.OwnerJsonRoot,SeedOverride,Error))
|
||||||
|
{std::fprintf(stderr,"Seed override failed: %s\n",Error.c_str());return 2;}
|
||||||
|
if(bHasRenderDistanceOverride
|
||||||
|
&&!StandaloneWorldAssemblyPrototype::OverrideStandaloneRenderDistance(
|
||||||
|
App.OwnerJsonRoot,RenderDistanceOverride,Error))
|
||||||
|
{std::fprintf(stderr,"Render-distance override failed: %s\n",Error.c_str());return 2;}
|
||||||
|
if(bFloatingIslandsRecipe
|
||||||
|
&&!StandaloneWorldAssemblyPrototype::SelectTopStrateAsFloatingIslands(App.OwnerJsonRoot,Error))
|
||||||
|
{std::fprintf(stderr,"Floating-island recipe selection failed: %s\n",Error.c_str());return 2;}
|
||||||
if(!StandaloneOwnerLoader::Resolve(App.OwnerJsonRoot,*App.World,Error))
|
if(!StandaloneOwnerLoader::Resolve(App.OwnerJsonRoot,*App.World,Error))
|
||||||
{std::fprintf(stderr,"Owner data load failed: %s\n",Error.c_str());return 2;}
|
{std::fprintf(stderr,"Owner data load failed: %s\n",Error.c_str());return 2;}
|
||||||
std::printf("[ColdTimeline] stage=owner_data_load end_ms=%.3f\n",
|
std::printf("[ColdTimeline] stage=owner_data_load end_ms=%.3f\n",
|
||||||
@@ -9916,8 +9207,12 @@ int main(int Argc,char** Argv)
|
|||||||
if(App.bWorldAssemblerPrototype)
|
if(App.bWorldAssemblerPrototype)
|
||||||
{
|
{
|
||||||
const auto PlanStart=std::chrono::steady_clock::now();
|
const auto PlanStart=std::chrono::steady_clock::now();
|
||||||
const bool bPlanReady=AttachRound1WorldAssemblyPrototype(*App.World,App.OwnerJsonRoot,
|
VoxelForgeCore::WorldAssemblyManifest WorldAssembly;
|
||||||
Error,WorldAssemblyManifestOutputPath);
|
const bool bPlanReady=StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype(*App.World,App.OwnerJsonRoot,
|
||||||
|
Error,WorldAssemblyManifestOutputPath,&WorldAssembly)
|
||||||
|
&&(!bFloatingIslandsRecipe
|
||||||
|
||StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly(
|
||||||
|
*App.World,App.OwnerJsonRoot,WorldAssembly,Error));
|
||||||
const double PlanMilliseconds=std::chrono::duration<double,std::milli>(
|
const double PlanMilliseconds=std::chrono::duration<double,std::milli>(
|
||||||
std::chrono::steady_clock::now()-PlanStart).count();
|
std::chrono::steady_clock::now()-PlanStart).count();
|
||||||
std::printf("[WorldAssemblerPlanTiming] total_ms=%.3f status=%s\n",
|
std::printf("[WorldAssemblerPlanTiming] total_ms=%.3f status=%s\n",
|
||||||
@@ -9978,7 +9273,7 @@ int main(int Argc,char** Argv)
|
|||||||
if(bStreamBenchmark)
|
if(bStreamBenchmark)
|
||||||
{
|
{
|
||||||
if(bStreamPipeline)
|
if(bStreamPipeline)
|
||||||
return RunPipelinedStreamingBenchmark(App.World,App.Snapshot,
|
return StandaloneStreamBenchmark::RunPipelinedStreamingBenchmark(App.World,App.Snapshot,
|
||||||
FVector(App.Position.X*4.0,App.Position.Y*4.0,App.Position.Z*4.0),
|
FVector(App.Position.X*4.0,App.Position.Y*4.0,App.Position.Z*4.0),
|
||||||
App.WorkerCount,StreamBenchmarkMaxLevel,App.ShapeDetailVariant,App.CoreScheduler,
|
App.WorkerCount,StreamBenchmarkMaxLevel,App.ShapeDetailVariant,App.CoreScheduler,
|
||||||
bStreamHash||!BakeMeshCachePath.empty(),bSkipUvAndColors,bSkipMaterialGroups,
|
bStreamHash||!BakeMeshCachePath.empty(),bSkipUvAndColors,bSkipMaterialGroups,
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <system_error>
|
||||||
|
#include <thread>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
#include <pthread.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Keep host-owned Linux workers on the ordinary 8 MiB stack size. Core's large caches now live
|
||||||
|
// behind lazy thread-local handles, so they no longer need to be hidden by oversized stacks.
|
||||||
|
#if defined(__linux__)
|
||||||
|
class FStandaloneWorkerThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr std::size_t StackSizeBytes=8u*1024u*1024u;
|
||||||
|
|
||||||
|
FStandaloneWorkerThread()=default;
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
explicit FStandaloneWorkerThread(F&& function)
|
||||||
|
{
|
||||||
|
using FTask=std::decay_t<F>;
|
||||||
|
auto task=std::make_unique<FTask>(std::forward<F>(function));
|
||||||
|
pthread_attr_t attributes;
|
||||||
|
int result=pthread_attr_init(&attributes);
|
||||||
|
if(result!=0)throw std::system_error(result,std::generic_category(),"pthread_attr_init");
|
||||||
|
result=pthread_attr_setstacksize(&attributes,StackSizeBytes);
|
||||||
|
if(result==0)
|
||||||
|
{
|
||||||
|
result=pthread_create(&thread_,&attributes,&RunTask<FTask>,task.get());
|
||||||
|
if(result==0)task.release();
|
||||||
|
}
|
||||||
|
const int destroyResult=pthread_attr_destroy(&attributes);
|
||||||
|
if(result!=0)throw std::system_error(result,std::generic_category(),"pthread_create");
|
||||||
|
if(destroyResult!=0)
|
||||||
|
{
|
||||||
|
(void)pthread_join(thread_,nullptr);
|
||||||
|
throw std::system_error(destroyResult,std::generic_category(),"pthread_attr_destroy");
|
||||||
|
}
|
||||||
|
joinable_=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FStandaloneWorkerThread(const FStandaloneWorkerThread&)=delete;
|
||||||
|
FStandaloneWorkerThread& operator=(const FStandaloneWorkerThread&)=delete;
|
||||||
|
|
||||||
|
FStandaloneWorkerThread(FStandaloneWorkerThread&& other) noexcept
|
||||||
|
:thread_(other.thread_),joinable_(std::exchange(other.joinable_,false))
|
||||||
|
{}
|
||||||
|
|
||||||
|
FStandaloneWorkerThread& operator=(FStandaloneWorkerThread&& other) noexcept
|
||||||
|
{
|
||||||
|
if(this!=&other)
|
||||||
|
{
|
||||||
|
if(joinable_)(void)pthread_join(thread_,nullptr);
|
||||||
|
thread_=other.thread_;
|
||||||
|
joinable_=std::exchange(other.joinable_,false);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~FStandaloneWorkerThread()
|
||||||
|
{
|
||||||
|
if(joinable_)(void)pthread_join(thread_,nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool joinable()const noexcept{return joinable_;}
|
||||||
|
|
||||||
|
void join()
|
||||||
|
{
|
||||||
|
if(!joinable_)throw std::system_error(std::make_error_code(std::errc::invalid_argument));
|
||||||
|
const int result=pthread_join(thread_,nullptr);
|
||||||
|
if(result!=0)throw std::system_error(result,std::generic_category(),"pthread_join");
|
||||||
|
joinable_=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<class F>
|
||||||
|
static void* RunTask(void* raw)
|
||||||
|
{
|
||||||
|
std::unique_ptr<F> task(static_cast<F*>(raw));
|
||||||
|
(*task)();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_t thread_{};
|
||||||
|
bool joinable_=false;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
using FStandaloneWorkerThread=std::thread;
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,318 @@
|
|||||||
|
#include "OwnerWorldLoader.h"
|
||||||
|
#include "StandaloneCoreScheduler.h"
|
||||||
|
#include "StreamBenchmarkPipeline.h"
|
||||||
|
#include "WorldAssemblyPrototype.h"
|
||||||
|
#include "StandaloneTlsProbe.h"
|
||||||
|
#include "../Core/src/StandaloneSnapshotAdapter.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct FOptions
|
||||||
|
{
|
||||||
|
std::filesystem::path DataPath;
|
||||||
|
int WorkerCount=8;
|
||||||
|
int ClipRadius=3;
|
||||||
|
int MaxClipLevel=8;
|
||||||
|
int MaxLevel=-1;
|
||||||
|
int FarHorizonLOD8InteriorStepVoxels=0;
|
||||||
|
bool WorldAssemblerPrototype=false;
|
||||||
|
bool StreamBenchmark=false;
|
||||||
|
bool StreamPipeline=false;
|
||||||
|
bool StreamHash=false;
|
||||||
|
bool ProfileColumnOverlap=false;
|
||||||
|
bool ForceGenerate=false;
|
||||||
|
bool MeshCoverage=false;
|
||||||
|
bool ScreenSpaceGate=false;
|
||||||
|
bool HasSeedOverride=false;
|
||||||
|
int SeedOverride=0;
|
||||||
|
bool HasRenderDistanceOverride=false;
|
||||||
|
int RenderDistanceOverride=0;
|
||||||
|
bool FloatingIslandsRecipe=false;
|
||||||
|
bool TlsProbeRequested=false;
|
||||||
|
int TlsProbeWorkers=0;
|
||||||
|
std::string TlsProbeTouch="none";
|
||||||
|
bool HasCamera=false;
|
||||||
|
bool AutoSurfaceCamera=false;
|
||||||
|
FVector CameraMeters=FVector::ZeroVector;
|
||||||
|
float CameraYawDegrees=0.0f;
|
||||||
|
float CameraPitchDegrees=0.0f;
|
||||||
|
std::filesystem::path MeshExportPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool ParseInteger(std::string_view text,int& output)
|
||||||
|
{
|
||||||
|
if(text.empty())return false;
|
||||||
|
char* end=nullptr;
|
||||||
|
const std::string value(text);
|
||||||
|
const long parsed=std::strtol(value.c_str(),&end,10);
|
||||||
|
if(end==value.c_str()||*end!='\0'||parsed<INT32_MIN||parsed>INT32_MAX)return false;
|
||||||
|
output=static_cast<int>(parsed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParseCamera(std::string_view text,FVector& meters,float& yawDegrees,float& pitchDegrees)
|
||||||
|
{
|
||||||
|
const std::string values(text);
|
||||||
|
float x=0.0f,y=0.0f,z=0.0f,yaw=0.0f,pitch=0.0f;
|
||||||
|
if(std::sscanf(values.c_str(),"%f,%f,%f,%f,%f",&x,&y,&z,&yaw,&pitch)!=5)
|
||||||
|
return false;
|
||||||
|
meters={x,y,z};
|
||||||
|
yawDegrees=yaw;
|
||||||
|
pitchDegrees=pitch;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParseOptions(int argc,char** argv,FOptions& options)
|
||||||
|
{
|
||||||
|
const std::filesystem::path executable=std::filesystem::absolute(argv[0]);
|
||||||
|
options.DataPath=executable.parent_path().parent_path()/"data/owner_world.json";
|
||||||
|
for(int index=1;index<argc;++index)
|
||||||
|
{
|
||||||
|
const std::string_view arg(argv[index]);
|
||||||
|
const auto readInt=[&](std::string_view prefix,int& value)
|
||||||
|
{return arg.starts_with(prefix)&&ParseInteger(arg.substr(prefix.size()),value);};
|
||||||
|
if(arg=="--help"||arg=="-h")
|
||||||
|
{
|
||||||
|
std::printf("Usage: %s [owner_world.json] --world-assembler-prototype --stream-benchmark --stream-pipeline [options]\n"
|
||||||
|
" --workers=N --clip-radius=N --max-clip-level=N --max-level=N\n"
|
||||||
|
" --camera=X,Y,Z,YAW,PITCH (position in metres) --stream-hash\n"
|
||||||
|
" --mesh-export=FILE (write the exact generated tile meshes for offline rendering)\n"
|
||||||
|
" --profile-column-overlap --far-horizon-lod8-step=N --force-generate\n"
|
||||||
|
" --seed=N --recipe=surface-world|floating-islands\n"
|
||||||
|
" --auto-surface-camera (place the 27-tile cube on this seed's surface)\n"
|
||||||
|
" --mesh-coverage (report non-empty tiles and indexed triangles)\n"
|
||||||
|
" --screen-space-gate (measure display error and historical negative controls)\n"
|
||||||
|
" --render-distance-chunks=N (0 disables the extra far ring)\n"
|
||||||
|
" --tls-probe=N (Linux worker TLS/stack measurement; N=0..12)\n"
|
||||||
|
" --tls-probe-touch=none|surface-world|floating-islands (first-use probe)\n"
|
||||||
|
" --process-affinity=MASK --process-priority=Normal --frame-limit=FPS (viewer compatibility only)\n",
|
||||||
|
argv[0]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(arg=="--world-assembler-prototype")options.WorldAssemblerPrototype=true;
|
||||||
|
else if(arg=="--stream-benchmark")options.StreamBenchmark=true;
|
||||||
|
else if(arg=="--stream-pipeline")options.StreamPipeline=true;
|
||||||
|
else if(arg=="--stream-hash")options.StreamHash=true;
|
||||||
|
else if(arg=="--profile-column-overlap")options.ProfileColumnOverlap=true;
|
||||||
|
else if(arg=="--force-generate")options.ForceGenerate=true;
|
||||||
|
else if(arg=="--mesh-coverage")options.MeshCoverage=true;
|
||||||
|
else if(arg=="--screen-space-gate")options.ScreenSpaceGate=true;
|
||||||
|
else if(arg=="--auto-surface-camera")options.AutoSurfaceCamera=true;
|
||||||
|
else if(arg.starts_with("--recipe="))
|
||||||
|
{
|
||||||
|
const std::string_view recipe=arg.substr(std::string_view("--recipe=").size());
|
||||||
|
if(recipe=="surface-world")options.FloatingIslandsRecipe=false;
|
||||||
|
else if(recipe=="floating-islands")options.FloatingIslandsRecipe=true;
|
||||||
|
else {std::fprintf(stderr,"Invalid --recipe value: %.*s\n",static_cast<int>(recipe.size()),recipe.data());return false;}
|
||||||
|
}
|
||||||
|
else if(arg.starts_with("--seed="))
|
||||||
|
{if(!readInt("--seed=",options.SeedOverride))return false;options.HasSeedOverride=true;}
|
||||||
|
else if(arg.starts_with("--render-distance-chunks="))
|
||||||
|
{
|
||||||
|
if(!readInt("--render-distance-chunks=",options.RenderDistanceOverride))return false;
|
||||||
|
options.RenderDistanceOverride=std::max(0,options.RenderDistanceOverride);
|
||||||
|
options.HasRenderDistanceOverride=true;
|
||||||
|
}
|
||||||
|
else if(arg.starts_with("--tls-probe="))
|
||||||
|
{
|
||||||
|
if(!readInt("--tls-probe=",options.TlsProbeWorkers))return false;
|
||||||
|
if(options.TlsProbeWorkers<0||options.TlsProbeWorkers>12)
|
||||||
|
{std::fprintf(stderr,"--tls-probe must be in 0..12\n");return false;}
|
||||||
|
options.TlsProbeRequested=true;
|
||||||
|
}
|
||||||
|
else if(arg.starts_with("--tls-probe-touch="))
|
||||||
|
{
|
||||||
|
const std::string_view touch=arg.substr(std::string_view("--tls-probe-touch=").size());
|
||||||
|
if(touch!="none"&&touch!="surface-world"&&touch!="floating-islands")
|
||||||
|
{std::fprintf(stderr,"Invalid --tls-probe-touch value: %.*s\n",static_cast<int>(touch.size()),touch.data());return false;}
|
||||||
|
options.TlsProbeTouch=touch;
|
||||||
|
}
|
||||||
|
else if(arg.starts_with("--camera="))
|
||||||
|
{
|
||||||
|
if(!ParseCamera(arg.substr(9),options.CameraMeters,
|
||||||
|
options.CameraYawDegrees,options.CameraPitchDegrees))
|
||||||
|
{std::fprintf(stderr,"Invalid --camera value: %.*s\n",static_cast<int>(arg.size()),arg.data());return false;}
|
||||||
|
options.HasCamera=true;
|
||||||
|
}
|
||||||
|
else if(arg.starts_with("--mesh-export="))
|
||||||
|
{
|
||||||
|
options.MeshExportPath=std::filesystem::path(arg.substr(14));
|
||||||
|
if(options.MeshExportPath.empty())
|
||||||
|
{std::fprintf(stderr,"--mesh-export needs a file path\n");return false;}
|
||||||
|
}
|
||||||
|
else if(arg.starts_with("--workers="))
|
||||||
|
{if(!readInt("--workers=",options.WorkerCount))return false;}
|
||||||
|
else if(arg.starts_with("--clip-radius="))
|
||||||
|
{if(!readInt("--clip-radius=",options.ClipRadius))return false;}
|
||||||
|
else if(arg.starts_with("--max-clip-level="))
|
||||||
|
{if(!readInt("--max-clip-level=",options.MaxClipLevel))return false;}
|
||||||
|
else if(arg.starts_with("--max-level="))
|
||||||
|
{if(!readInt("--max-level=",options.MaxLevel))return false;}
|
||||||
|
else if(arg.starts_with("--far-horizon-lod8-step="))
|
||||||
|
{if(!readInt("--far-horizon-lod8-step=",options.FarHorizonLOD8InteriorStepVoxels))return false;}
|
||||||
|
else if(arg.starts_with("--process-affinity=")||arg.starts_with("--process-priority=")
|
||||||
|
||arg.starts_with("--frame-limit="))
|
||||||
|
{
|
||||||
|
// These viewer switches are accepted for command-line parity. The caller pins
|
||||||
|
// this headless process with taskset, and a headless run has no frame limiter.
|
||||||
|
}
|
||||||
|
else if(!arg.empty()&&arg.front()!='-')options.DataPath=std::filesystem::path(arg);
|
||||||
|
else
|
||||||
|
{std::fprintf(stderr,"Unknown option: %.*s\n",static_cast<int>(arg.size()),arg.data());return false;}
|
||||||
|
}
|
||||||
|
options.WorkerCount=std::clamp(options.WorkerCount,1,16);
|
||||||
|
options.ClipRadius=std::clamp(options.ClipRadius,1,64);
|
||||||
|
options.MaxClipLevel=std::clamp(options.MaxClipLevel,0,8);
|
||||||
|
options.FarHorizonLOD8InteriorStepVoxels=std::max(0,options.FarHorizonLOD8InteriorStepVoxels);
|
||||||
|
if(!options.TlsProbeRequested&&options.TlsProbeTouch!="none")
|
||||||
|
{std::fprintf(stderr,"--tls-probe-touch requires --tls-probe=N\n");return false;}
|
||||||
|
if(options.TlsProbeRequested)return true;
|
||||||
|
if(!options.WorldAssemblerPrototype||!options.StreamBenchmark||!options.StreamPipeline)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr,"This headless target runs the world-assembler streaming pipeline; pass --world-assembler-prototype --stream-benchmark --stream-pipeline.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc,char** argv)
|
||||||
|
{
|
||||||
|
using Clock=std::chrono::steady_clock;
|
||||||
|
const auto coldStart=Clock::now();
|
||||||
|
FOptions options;
|
||||||
|
if(!ParseOptions(argc,argv,options))return 2;
|
||||||
|
if(options.TlsProbeRequested)
|
||||||
|
return StandaloneTlsProbe::Run(options.TlsProbeWorkers,options.TlsProbeTouch);
|
||||||
|
std::printf("[HeadlessConfig] data=%s workers=%d clip_radius=%d max_clip_level=%d max_level=%d hash=%s column_overlap=%s force_generate=%s recipe=%s seed_override=%s render_distance_override=%s\n",
|
||||||
|
options.DataPath.string().c_str(),options.WorkerCount,options.ClipRadius,options.MaxClipLevel,
|
||||||
|
options.MaxLevel,options.StreamHash?"on":"off",options.ProfileColumnOverlap?"on":"off",
|
||||||
|
options.ForceGenerate?"on":"off",options.FloatingIslandsRecipe?"floating-islands":"surface-world",
|
||||||
|
options.HasSeedOverride?"yes":"no",options.HasRenderDistanceOverride?"yes":"no");
|
||||||
|
std::printf("[ColdTimeline] stage=owner_data_load begin_ms=%.3f\n",
|
||||||
|
std::chrono::duration<double,std::milli>(Clock::now()-coldStart).count());
|
||||||
|
|
||||||
|
std::string error;
|
||||||
|
auto ownerWorld=std::make_shared<FStandaloneOwnerWorld>();
|
||||||
|
VFJson::Value ownerJsonRoot;
|
||||||
|
{
|
||||||
|
std::ifstream jsonFile(options.DataPath,std::ios::binary);
|
||||||
|
if(!jsonFile)
|
||||||
|
{std::fprintf(stderr,"Owner data load failed: cannot open %s\n",options.DataPath.string().c_str());return 2;}
|
||||||
|
std::string ownerJsonText{std::istreambuf_iterator<char>(jsonFile),std::istreambuf_iterator<char>{}};
|
||||||
|
if(!jsonFile&&!jsonFile.eof())
|
||||||
|
{std::fprintf(stderr,"Owner data load failed: read error for %s\n",options.DataPath.string().c_str());return 2;}
|
||||||
|
if(!VFJson::Parser(std::move(ownerJsonText)).Parse(ownerJsonRoot,error))
|
||||||
|
{std::fprintf(stderr,"Owner data load failed: %s\n",error.c_str());return 2;}
|
||||||
|
}
|
||||||
|
if(options.HasSeedOverride
|
||||||
|
&&!StandaloneWorldAssemblyPrototype::OverrideStandaloneSeed(ownerJsonRoot,options.SeedOverride,error))
|
||||||
|
{std::fprintf(stderr,"Seed override failed: %s\n",error.c_str());return 2;}
|
||||||
|
if(options.HasRenderDistanceOverride
|
||||||
|
&&!StandaloneWorldAssemblyPrototype::OverrideStandaloneRenderDistance(
|
||||||
|
ownerJsonRoot,options.RenderDistanceOverride,error))
|
||||||
|
{std::fprintf(stderr,"Render-distance override failed: %s\n",error.c_str());return 2;}
|
||||||
|
if(options.FloatingIslandsRecipe
|
||||||
|
&&!StandaloneWorldAssemblyPrototype::SelectTopStrateAsFloatingIslands(ownerJsonRoot,error))
|
||||||
|
{std::fprintf(stderr,"Floating-island recipe selection failed: %s\n",error.c_str());return 2;}
|
||||||
|
if(!StandaloneOwnerLoader::Resolve(ownerJsonRoot,*ownerWorld,error))
|
||||||
|
{std::fprintf(stderr,"Owner data load failed: %s\n",error.c_str());return 2;}
|
||||||
|
std::printf("[ColdTimeline] stage=owner_data_load end_ms=%.3f\n",
|
||||||
|
std::chrono::duration<double,std::milli>(Clock::now()-coldStart).count());
|
||||||
|
|
||||||
|
const int seed=ownerWorld->Seed;
|
||||||
|
const int exportedMaxClipLevel=ownerWorld->MaxClipLevel;
|
||||||
|
ownerWorld->ClipRadius=options.ClipRadius;
|
||||||
|
ownerWorld->Settings->ClipRadius=options.ClipRadius;
|
||||||
|
ownerWorld->MaxClipLevel=options.MaxClipLevel;
|
||||||
|
ownerWorld->Settings->MaxClipLevel=options.MaxClipLevel;
|
||||||
|
if(exportedMaxClipLevel!=options.MaxClipLevel)
|
||||||
|
std::printf("Standalone max clip level override: exported=%d -> max_level=%d.\n",
|
||||||
|
exportedMaxClipLevel,options.MaxClipLevel);
|
||||||
|
|
||||||
|
FVector cameraVoxels=ownerWorld->ViewerStartVoxels;
|
||||||
|
if(options.HasCamera)
|
||||||
|
cameraVoxels=FVector(options.CameraMeters.X*4.0f,options.CameraMeters.Y*4.0f,options.CameraMeters.Z*4.0f);
|
||||||
|
|
||||||
|
const auto planStart=Clock::now();
|
||||||
|
VoxelForgeCore::WorldAssemblyManifest worldAssembly;
|
||||||
|
if(!StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype(
|
||||||
|
*ownerWorld,ownerJsonRoot,error,{},&worldAssembly))
|
||||||
|
{std::fprintf(stderr,"World assembler prototype setup failed: %s\n",error.c_str());return 2;}
|
||||||
|
if(options.FloatingIslandsRecipe
|
||||||
|
&&!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly(
|
||||||
|
*ownerWorld,ownerJsonRoot,worldAssembly,error))
|
||||||
|
{std::fprintf(stderr,"Floating-island assembly setup failed: %s\n",error.c_str());return 2;}
|
||||||
|
if(options.AutoSurfaceCamera)
|
||||||
|
{
|
||||||
|
constexpr std::int64_t UnitsPerVoxel=VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||||||
|
if(options.FloatingIslandsRecipe)
|
||||||
|
{
|
||||||
|
const VoxelForgeCore::FloatingIslandAnchorV1* chosen=nullptr;
|
||||||
|
for(const auto& islandSet:worldAssembly.floatingIslands)
|
||||||
|
for(const auto& island:islandSet.manifest.plan.islands)
|
||||||
|
if(!chosen||island.radiusSubvoxels>chosen->radiusSubvoxels)chosen=&island;
|
||||||
|
if(!chosen)
|
||||||
|
{std::fprintf(stderr,"[SeedSurfacePlacement] FAIL: island plan has no anchors\n");return 2;}
|
||||||
|
cameraVoxels={
|
||||||
|
static_cast<float>(chosen->centerSubvoxels[0])/UnitsPerVoxel,
|
||||||
|
static_cast<float>(chosen->centerSubvoxels[1])/UnitsPerVoxel,
|
||||||
|
static_cast<float>(chosen->centerSubvoxels[2])/UnitsPerVoxel};
|
||||||
|
std::printf("[SeedSurfacePlacement] recipe=floating-islands seed=%d island_radius_vox=%.3f camera_voxel=(%.6f,%.6f,%.6f) status=PASS\n",
|
||||||
|
seed,static_cast<double>(chosen->radiusSubvoxels)/UnitsPerVoxel,
|
||||||
|
cameraVoxels.X,cameraVoxels.Y,cameraVoxels.Z);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto xSubvoxels=static_cast<std::int64_t>(std::llround(cameraVoxels.X*UnitsPerVoxel));
|
||||||
|
const auto ySubvoxels=static_cast<std::int64_t>(std::llround(cameraVoxels.Y*UnitsPerVoxel));
|
||||||
|
const auto currentZSubvoxels=static_cast<std::int64_t>(std::llround(cameraVoxels.Z*UnitsPerVoxel));
|
||||||
|
std::int64_t selectedGround=0,bestDistance=std::numeric_limits<std::int64_t>::max();
|
||||||
|
for(const auto& stratum:worldAssembly.plan.strates)
|
||||||
|
{
|
||||||
|
VoxelForgeCore::Heightfield2D field(worldAssembly.recipe,stratum);
|
||||||
|
if(!field.isValid())continue;
|
||||||
|
const auto column=field.point(xSubvoxels,ySubvoxels,0);
|
||||||
|
const std::int64_t distance=std::abs(column.groundHeightSubvoxels-currentZSubvoxels);
|
||||||
|
if(distance<bestDistance)
|
||||||
|
{bestDistance=distance;selectedGround=column.groundHeightSubvoxels;}
|
||||||
|
}
|
||||||
|
if(bestDistance==std::numeric_limits<std::int64_t>::max())
|
||||||
|
{std::fprintf(stderr,"[SeedSurfacePlacement] FAIL: no valid SurfaceWorld heightfield\n");return 2;}
|
||||||
|
cameraVoxels.Z=static_cast<float>(static_cast<double>(selectedGround)/UnitsPerVoxel);
|
||||||
|
std::printf("[SeedSurfacePlacement] recipe=surface-world seed=%d ground_voxel=%.6f camera_voxel=(%.6f,%.6f,%.6f) status=PASS\n",
|
||||||
|
seed,static_cast<double>(selectedGround)/UnitsPerVoxel,
|
||||||
|
cameraVoxels.X,cameraVoxels.Y,cameraVoxels.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::printf("[WorldAssemblerPlanTiming] total_ms=%.3f status=PASS\n",
|
||||||
|
std::chrono::duration<double,std::milli>(Clock::now()-planStart).count());
|
||||||
|
|
||||||
|
auto snapshot=VoxelForgeCore::MakeStandaloneSnapshotFromParsedJson(ownerJsonRoot,seed,
|
||||||
|
options.ClipRadius,options.MaxClipLevel,false,false,error);
|
||||||
|
if(!snapshot)
|
||||||
|
{std::fprintf(stderr,"Shape interval build failed: %s\n",error.c_str());return 2;}
|
||||||
|
|
||||||
|
FStandaloneCoreScheduler scheduler;
|
||||||
|
return StandaloneStreamBenchmark::RunPipelinedStreamingBenchmark(ownerWorld,snapshot,
|
||||||
|
cameraVoxels,options.WorkerCount,options.MaxLevel,VoxelForgeCore::DetailVariant::coherent,
|
||||||
|
scheduler,options.StreamHash,false,false,false,false,coldStart,
|
||||||
|
options.ProfileColumnOverlap,options.FarHorizonLOD8InteriorStepVoxels,
|
||||||
|
options.MeshCoverage,options.MeshExportPath,options.CameraYawDegrees,
|
||||||
|
options.CameraPitchDegrees,options.ScreenSpaceGate);
|
||||||
|
}
|
||||||
@@ -0,0 +1,604 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "OwnerWorldLoader.h"
|
||||||
|
#include "StreamingWorld.h"
|
||||||
|
#include "LinuxScreenSpaceGate.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
|
#include <thread>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace StandaloneStreamBenchmark
|
||||||
|
{
|
||||||
|
struct FSceneExportWriter
|
||||||
|
{
|
||||||
|
std::ofstream File;
|
||||||
|
bool bGood=true;
|
||||||
|
std::uint32_t TileCount=0;
|
||||||
|
|
||||||
|
template<typename T> void Write(const T& Value)
|
||||||
|
{
|
||||||
|
File.write(reinterpret_cast<const char*>(&Value),sizeof(Value));
|
||||||
|
bGood=bGood&&static_cast<bool>(File);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Open(const std::filesystem::path& Path,std::uint32_t VoxelSizeMicrons,
|
||||||
|
const FVector& CameraVoxels,float YawDegrees,float PitchDegrees,
|
||||||
|
std::uint32_t ExpectedTiles)
|
||||||
|
{
|
||||||
|
std::error_code Error;
|
||||||
|
if(!Path.parent_path().empty())
|
||||||
|
std::filesystem::create_directories(Path.parent_path(),Error);
|
||||||
|
if(Error)return false;
|
||||||
|
File.open(Path,std::ios::binary|std::ios::trunc);
|
||||||
|
if(!File)return false;
|
||||||
|
constexpr char Magic[8]={'V','F','M','S','H','0','0','1'};
|
||||||
|
File.write(Magic,sizeof(Magic));
|
||||||
|
const std::uint32_t Version=1;
|
||||||
|
Write(Version);Write(VoxelSizeMicrons);Write(ExpectedTiles);
|
||||||
|
const double MicronsToMeters=static_cast<double>(VoxelSizeMicrons)/1000000.0;
|
||||||
|
const double Camera[3]={CameraVoxels.X*MicronsToMeters,
|
||||||
|
CameraVoxels.Y*MicronsToMeters,CameraVoxels.Z*MicronsToMeters};
|
||||||
|
for(const double Value:Camera)Write(Value);
|
||||||
|
const double Yaw=YawDegrees,Pitch=PitchDegrees;
|
||||||
|
Write(Yaw);Write(Pitch);
|
||||||
|
return bGood;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(const FStandaloneCpuTile& Tile)
|
||||||
|
{
|
||||||
|
const std::int32_t Key[4]={Tile.Key.Coord.X,Tile.Key.Coord.Y,
|
||||||
|
Tile.Key.Coord.Z,Tile.Key.Level};
|
||||||
|
for(const auto Value:Key)Write(Value);
|
||||||
|
const std::uint32_t SurfaceVertexCount=Tile.SurfaceVertexCount;
|
||||||
|
const std::uint32_t SkirtTriangleCount=Tile.SkirtTriangleCount;
|
||||||
|
const std::uint32_t VertexCount=static_cast<std::uint32_t>(Tile.Vertices.size());
|
||||||
|
const std::uint32_t IndexCount=static_cast<std::uint32_t>(Tile.Indices.size());
|
||||||
|
const std::uint32_t MaskCount=static_cast<std::uint32_t>(Tile.TriangleSkirtFaceMasks.size());
|
||||||
|
Write(SurfaceVertexCount);Write(SkirtTriangleCount);
|
||||||
|
Write(VertexCount);Write(IndexCount);Write(MaskCount);
|
||||||
|
for(const FStandaloneCpuVertex& Vertex:Tile.Vertices)
|
||||||
|
for(const float Value:Vertex.Position)Write(Value);
|
||||||
|
for(const FStandaloneCpuVertex& Vertex:Tile.Vertices)
|
||||||
|
for(const float Value:Vertex.Normal)Write(Value);
|
||||||
|
if(IndexCount)
|
||||||
|
File.write(reinterpret_cast<const char*>(Tile.Indices.data()),
|
||||||
|
static_cast<std::streamsize>(sizeof(std::uint32_t)*Tile.Indices.size()));
|
||||||
|
if(MaskCount)
|
||||||
|
File.write(reinterpret_cast<const char*>(Tile.TriangleSkirtFaceMasks.data()),
|
||||||
|
static_cast<std::streamsize>(Tile.TriangleSkirtFaceMasks.size()));
|
||||||
|
bGood=bGood&&static_cast<bool>(File);
|
||||||
|
++TileCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Close(std::uint32_t ExpectedTiles)
|
||||||
|
{
|
||||||
|
File.flush();
|
||||||
|
const bool bComplete=bGood&&static_cast<bool>(File)&&TileCount==ExpectedTiles;
|
||||||
|
File.close();
|
||||||
|
return bComplete;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void HashWord(uint64& Hash,uint64 Word,int32 Bytes=8)
|
||||||
|
{
|
||||||
|
for(int32 I=0;I<Bytes;++I)
|
||||||
|
{
|
||||||
|
Hash^=static_cast<uint8>(Word>>(I*8));
|
||||||
|
Hash*=1099511628211ull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FHashedTile
|
||||||
|
{
|
||||||
|
FVoxelTileKey Key;
|
||||||
|
uint64 Hash=14695981039346656037ull;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool TileKeyLessForHash(const FVoxelTileKey& A,const FVoxelTileKey& B)
|
||||||
|
{
|
||||||
|
if(A.Level!=B.Level)return A.Level<B.Level;
|
||||||
|
if(A.Coord.Z!=B.Coord.Z)return A.Coord.Z<B.Coord.Z;
|
||||||
|
if(A.Coord.Y!=B.Coord.Y)return A.Coord.Y<B.Coord.Y;
|
||||||
|
return A.Coord.X<B.Coord.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64 HashTileRows(std::vector<FHashedTile>& Rows)
|
||||||
|
{
|
||||||
|
std::sort(Rows.begin(),Rows.end(),[](const FHashedTile& A,const FHashedTile& B)
|
||||||
|
{return TileKeyLessForHash(A.Key,B.Key);});
|
||||||
|
uint64 Hash=14695981039346656037ull;
|
||||||
|
for(const FHashedTile& Row:Rows)
|
||||||
|
{
|
||||||
|
HashWord(Hash,static_cast<uint32>(Row.Key.Level),4);
|
||||||
|
HashWord(Hash,static_cast<uint32>(Row.Key.Coord.X),4);
|
||||||
|
HashWord(Hash,static_cast<uint32>(Row.Key.Coord.Y),4);
|
||||||
|
HashWord(Hash,static_cast<uint32>(Row.Key.Coord.Z),4);
|
||||||
|
HashWord(Hash,Row.Hash);
|
||||||
|
}
|
||||||
|
return Hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int RunPipelinedStreamingBenchmark(std::shared_ptr<FStandaloneOwnerWorld> OwnerWorld,
|
||||||
|
const VoxelForgeCore::ResolvedWorldSnapshot& CoreSnapshot,
|
||||||
|
const FVector& CameraPositionVoxels,int32 WorkerCount,int32 MaxLevel,
|
||||||
|
VoxelForgeCore::DetailVariant DetailVariant,const VoxelForgeCore::JobScheduler& Scheduler,
|
||||||
|
bool bHashDensity,bool bSkipUvAndColors,bool bSkipMaterialGroups,bool bSkipUV,bool bSkipColors,
|
||||||
|
std::chrono::steady_clock::time_point ColdStart,bool bProfileColumnOverlap,
|
||||||
|
int32 FarHorizonLOD8InteriorStepVoxels,bool bReportMeshCoverage=false,
|
||||||
|
const std::filesystem::path& MeshExportPath={},float CameraYawDegrees=0.0f,
|
||||||
|
float CameraPitchDegrees=0.0f,bool bScreenSpaceGate=false)
|
||||||
|
{
|
||||||
|
using Clock=std::chrono::steady_clock;
|
||||||
|
FStandaloneOwnerWorld& World=*OwnerWorld;
|
||||||
|
const VoxelForgeCore::WorldAssemblyManifest* Assembly=CoreSnapshot.worldAssembly();
|
||||||
|
std::array<double,9> ClosestDisplayDistances{};
|
||||||
|
std::array<std::int64_t,9> PixelBudgetsSubvoxels{};
|
||||||
|
if(bScreenSpaceGate)
|
||||||
|
{
|
||||||
|
ClosestDisplayDistances=StandaloneScreenSpaceGate::ClosestDisplayedDistancesMeters(
|
||||||
|
World,CameraPositionVoxels,World.CoreVoxelSizeMicrons);
|
||||||
|
const double VoxelMeters=static_cast<double>(World.CoreVoxelSizeMicrons)/1000000.0;
|
||||||
|
for(int32 Lod=3;Lod<=World.MaxClipLevel&&Lod<9;++Lod)
|
||||||
|
PixelBudgetsSubvoxels[static_cast<std::size_t>(Lod)]=static_cast<std::int64_t>(std::floor(
|
||||||
|
ClosestDisplayDistances[static_cast<std::size_t>(Lod)]
|
||||||
|
*StandaloneScreenSpaceGate::OnePixelRadians/VoxelMeters
|
||||||
|
*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));
|
||||||
|
}
|
||||||
|
const bool bRoundTunnels=World.Generator->bStandaloneResearchRoundTunnels;
|
||||||
|
const bool bEnhancedTunnelWalls=World.Generator->bStandaloneResearchEnhancedWalls;
|
||||||
|
VoxelForgeCore::World Shape(CoreSnapshot);
|
||||||
|
FStandaloneDesiredTileSet Desired=StandaloneWorldMesher::BuildDesiredSet(World,CameraPositionVoxels);
|
||||||
|
const auto CoreTiles=Shape.desiredTiles(
|
||||||
|
{CameraPositionVoxels.X,CameraPositionVoxels.Y,CameraPositionVoxels.Z});
|
||||||
|
Desired.Tiles.clear();Desired.Tiles.reserve(CoreTiles.size());
|
||||||
|
for(const auto& Key:CoreTiles)
|
||||||
|
Desired.Tiles.emplace_back(FIntVector(Key.coordinate.x,Key.coordinate.y,Key.coordinate.z),Key.lod);
|
||||||
|
if(MaxLevel>=0)
|
||||||
|
Desired.Tiles.erase(std::remove_if(Desired.Tiles.begin(),Desired.Tiles.end(),
|
||||||
|
[&](const FVoxelTileKey& Tile){return Tile.Level>MaxLevel;}),Desired.Tiles.end());
|
||||||
|
if(!Desired.Tiles.empty())
|
||||||
|
{
|
||||||
|
FIntVector volumeMin(INT32_MAX,INT32_MAX,INT32_MAX);
|
||||||
|
FIntVector volumeMax(INT32_MIN,INT32_MIN,INT32_MIN);
|
||||||
|
int32 minimumLod=INT32_MAX,maximumLod=INT32_MIN;
|
||||||
|
for(const FVoxelTileKey& tile:Desired.Tiles)
|
||||||
|
{
|
||||||
|
const FIntVector origin=tile.OriginVoxels();
|
||||||
|
const int32 extent=tile.ExtentVoxels();
|
||||||
|
volumeMin.X=std::min(volumeMin.X,origin.X);
|
||||||
|
volumeMin.Y=std::min(volumeMin.Y,origin.Y);
|
||||||
|
volumeMin.Z=std::min(volumeMin.Z,origin.Z);
|
||||||
|
volumeMax.X=std::max(volumeMax.X,origin.X+extent);
|
||||||
|
volumeMax.Y=std::max(volumeMax.Y,origin.Y+extent);
|
||||||
|
volumeMax.Z=std::max(volumeMax.Z,origin.Z+extent);
|
||||||
|
minimumLod=std::min(minimumLod,tile.Level);
|
||||||
|
maximumLod=std::max(maximumLod,tile.Level);
|
||||||
|
}
|
||||||
|
std::printf("[PipelineVolume] tiles=%zu lod=%d..%d min_voxel=(%d,%d,%d) max_voxel=(%d,%d,%d)\n",
|
||||||
|
Desired.Tiles.size(),minimumLod,maximumLod,volumeMin.X,volumeMin.Y,volumeMin.Z,
|
||||||
|
volumeMax.X,volumeMax.Y,volumeMax.Z);
|
||||||
|
}
|
||||||
|
FIntVector FineMin(INT32_MAX,INT32_MAX,INT32_MAX),FineMax(INT32_MIN,INT32_MIN,INT32_MIN);
|
||||||
|
FIntVector ClipMin(INT32_MAX,INT32_MAX,INT32_MAX),ClipMax(INT32_MIN,INT32_MIN,INT32_MIN);
|
||||||
|
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
||||||
|
{
|
||||||
|
const FIntVector Origin=Tile.OriginVoxels();const int32 Extent=Tile.ExtentVoxels();
|
||||||
|
ClipMin.X=std::min(ClipMin.X,Origin.X);ClipMin.Y=std::min(ClipMin.Y,Origin.Y);ClipMin.Z=std::min(ClipMin.Z,Origin.Z);
|
||||||
|
ClipMax.X=std::max(ClipMax.X,Origin.X+Extent);ClipMax.Y=std::max(ClipMax.Y,Origin.Y+Extent);ClipMax.Z=std::max(ClipMax.Z,Origin.Z+Extent);
|
||||||
|
if(Tile.Level<World.FullResClipLevels)
|
||||||
|
{
|
||||||
|
FineMin.X=std::min(FineMin.X,Origin.X);FineMin.Y=std::min(FineMin.Y,Origin.Y);FineMin.Z=std::min(FineMin.Z,Origin.Z);
|
||||||
|
FineMax.X=std::max(FineMax.X,Origin.X+Extent);FineMax.Y=std::max(FineMax.Y,Origin.Y+Extent);FineMax.Z=std::max(FineMax.Z,Origin.Z+Extent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(FineMin.X==INT32_MAX||ClipMin.X==INT32_MAX)
|
||||||
|
{std::fprintf(stderr,"[StreamPipeline] no desired detail or clipmap tiles.\n");return 7;}
|
||||||
|
|
||||||
|
const FIntVector CenterChunk=Desired.CenterChunk;
|
||||||
|
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> Neighborhood;
|
||||||
|
Neighborhood.reserve(32);
|
||||||
|
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
||||||
|
if(Tile.Level==0&&std::abs(Tile.Coord.X-CenterChunk.X)<=1
|
||||||
|
&&std::abs(Tile.Coord.Y-CenterChunk.Y)<=1&&std::abs(Tile.Coord.Z-CenterChunk.Z)<=1)
|
||||||
|
Neighborhood.insert(Tile);
|
||||||
|
if(Neighborhood.size()!=27)
|
||||||
|
{std::fprintf(stderr,"[StreamPipeline] expected 27 player-neighborhood tiles, found %zu.\n",Neighborhood.size());return 7;}
|
||||||
|
|
||||||
|
// The initial desired set now owns all clipmap metadata needed by this Core-only run.
|
||||||
|
// Release the separate compatibility-world generation graph before compiling Core.
|
||||||
|
World.Generator.reset();
|
||||||
|
World.Manager.reset();
|
||||||
|
World.DefinitionStorage.clear();
|
||||||
|
World.BiomeStorage.clear();
|
||||||
|
World.OperationStorage.clear();
|
||||||
|
World.DensitySamples.clear();
|
||||||
|
|
||||||
|
std::string BuildError;
|
||||||
|
const bool bIncludeFarWorld=MaxLevel<0||MaxLevel>=World.FullResClipLevels;
|
||||||
|
const auto ShapeBuildStart=Clock::now();
|
||||||
|
VoxelForgeCore::ShapeBuildRequest ShapeRequest;
|
||||||
|
ShapeRequest.minVoxel={FineMin.X,FineMin.Y,FineMin.Z};
|
||||||
|
ShapeRequest.maxVoxel={FineMax.X,FineMax.Y,FineMax.Z};
|
||||||
|
ShapeRequest.clipMinVoxel={ClipMin.X,ClipMin.Y,ClipMin.Z};
|
||||||
|
ShapeRequest.clipMaxVoxel={ClipMax.X,ClipMax.Y,ClipMax.Z};
|
||||||
|
ShapeRequest.workerLimit=static_cast<uint32>(std::clamp(WorkerCount,1,16));
|
||||||
|
ShapeRequest.detail=DetailVariant;ShapeRequest.includeFarWorld=bIncludeFarWorld;
|
||||||
|
ShapeRequest.roundTunnels=bRoundTunnels;
|
||||||
|
ShapeRequest.enhancedTunnelWalls=bEnhancedTunnelWalls;
|
||||||
|
if(!Shape.compile(ShapeRequest,Scheduler,BuildError))
|
||||||
|
{std::fprintf(stderr,"[StreamPipeline] full shape build failed: %s\n",BuildError.c_str());return 2;}
|
||||||
|
const auto ShapeReady=Clock::now();
|
||||||
|
const double ShapeSeconds=std::chrono::duration<double>(ShapeReady-ShapeBuildStart).count();
|
||||||
|
FStandaloneStreamingGenerator Streamer(World,WorkerCount,bHashDensity,nullptr,MaxLevel,
|
||||||
|
bSkipUvAndColors,bSkipMaterialGroups,bSkipUV,bSkipColors,&Shape,bProfileColumnOverlap,
|
||||||
|
FarHorizonLOD8InteriorStepVoxels);
|
||||||
|
if(bScreenSpaceGate)Streamer.SetMesherStageProfilingEnabled(true);
|
||||||
|
const auto StreamStart=Clock::now();
|
||||||
|
const FStandaloneStreamingUpdate Update=Streamer.StartWithDesired(Desired);
|
||||||
|
if(Update.DesiredTiles!=static_cast<int32>(Desired.Tiles.size()))
|
||||||
|
{
|
||||||
|
Streamer.Stop();
|
||||||
|
std::fprintf(stderr,"[StreamPipeline] expected %zu tiles but queued %d.\n",
|
||||||
|
Desired.Tiles.size(),Update.DesiredTiles);return 7;
|
||||||
|
}
|
||||||
|
FSceneExportWriter SceneExport;
|
||||||
|
const bool bExportRequested=!MeshExportPath.empty();
|
||||||
|
bool bSceneExportPassing=true;
|
||||||
|
if(bExportRequested)
|
||||||
|
{
|
||||||
|
bSceneExportPassing=SceneExport.Open(MeshExportPath,World.CoreVoxelSizeMicrons,
|
||||||
|
CameraPositionVoxels,CameraYawDegrees,CameraPitchDegrees,
|
||||||
|
static_cast<std::uint32_t>(Update.DesiredTiles));
|
||||||
|
if(!bSceneExportPassing)
|
||||||
|
{
|
||||||
|
Streamer.Stop();
|
||||||
|
std::fprintf(stderr,"[MeshSceneExport] FAIL: could not open %s\n",
|
||||||
|
MeshExportPath.string().c_str());
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<FHashedTile> DensityRows,MeshRows,PayloadRows,TopologyRows;
|
||||||
|
int32 Finished=0,NeighborhoodFinished=0,FullDetailFinished=0;
|
||||||
|
int32 FullDetailExpected=0;
|
||||||
|
uint64 WholeNonEmptyMeshTiles=0,WholeTriangleCount=0;
|
||||||
|
struct FColumnXY
|
||||||
|
{
|
||||||
|
std::int64_t X=0,Y=0;
|
||||||
|
bool operator==(const FColumnXY&)const=default;
|
||||||
|
};
|
||||||
|
struct FColumnXYHash
|
||||||
|
{
|
||||||
|
std::size_t operator()(const FColumnXY& Value)const noexcept
|
||||||
|
{
|
||||||
|
const std::size_t X=std::hash<std::int64_t>{}(Value.X);
|
||||||
|
const std::size_t Y=std::hash<std::int64_t>{}(Value.Y);
|
||||||
|
return X^(Y+static_cast<std::size_t>(0x9E3779B9u)+(X<<6)+(X>>2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct FFirstColumnUse
|
||||||
|
{
|
||||||
|
FVoxelTileKey Tile;
|
||||||
|
std::uint64_t WorkerHash=0;
|
||||||
|
};
|
||||||
|
std::array<std::unordered_map<FColumnXY,std::vector<FFirstColumnUse>,FColumnXYHash>,9> ColumnUsesByLOD;
|
||||||
|
std::array<std::uint64_t,9> ColumnDuplicateEventsByLOD{},NeighbourDuplicateEventsByLOD{};
|
||||||
|
std::array<std::uint64_t,9> CrossWorkerNeighbourDuplicateEventsByLOD{};
|
||||||
|
std::array<std::uint64_t,9> ColumnCaptureTilesByLOD{},ExpectedTilesByLOD{};
|
||||||
|
std::array<bool,9> ColumnCaptureCompleteByLOD{};
|
||||||
|
ColumnCaptureCompleteByLOD.fill(true);
|
||||||
|
std::array<double,9> WorkerSecondsByLOD{};
|
||||||
|
std::array<double,9> ColumnEvalMsByLOD{},MarchingExclusiveMsByLOD{};
|
||||||
|
std::array<double,9> GroundRefineExclusiveMsByLOD{},CapRefineExclusiveMsByLOD{};
|
||||||
|
std::array<double,9> MeshAssemblyMsByLOD{};
|
||||||
|
std::array<double,9> SkirtMsByLOD{};
|
||||||
|
std::array<std::uint64_t,9> SkirtTrianglesByLOD{};
|
||||||
|
std::array<std::uint64_t,9> TileCountByLOD{};
|
||||||
|
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
||||||
|
if(Tile.Level>=0&&Tile.Level<static_cast<int32>(ExpectedTilesByLOD.size()))
|
||||||
|
++ExpectedTilesByLOD[static_cast<std::size_t>(Tile.Level)];
|
||||||
|
const auto AreSameLODNeighbours=[](const FVoxelTileKey& A,const FVoxelTileKey& B)
|
||||||
|
{
|
||||||
|
if(A.Level!=B.Level)return false;
|
||||||
|
const std::int64_t DX=std::abs(static_cast<std::int64_t>(A.Coord.X)-B.Coord.X);
|
||||||
|
const std::int64_t DY=std::abs(static_cast<std::int64_t>(A.Coord.Y)-B.Coord.Y);
|
||||||
|
const std::int64_t DZ=std::abs(static_cast<std::int64_t>(A.Coord.Z)-B.Coord.Z);
|
||||||
|
return std::max({DX,DY,DZ})<=1&&(DX+DY+DZ)>0;
|
||||||
|
};
|
||||||
|
uint64 NativeSolidBoxes=0,NativeAirBoxes=0,NativeMixedBoxes=0,NativeUnknownBoxes=0;
|
||||||
|
uint64 NativeFieldCalls=0,NativeColumnHits=0,NativeColumnMisses=0,NativeMeshingSkips=0;
|
||||||
|
double NativeClassificationMilliseconds=0.0,NativeColumnComputeMilliseconds=0.0;
|
||||||
|
double NativeMeshingMilliseconds=0.0;
|
||||||
|
for(const FVoxelTileKey& Tile:Desired.Tiles)
|
||||||
|
if(Tile.Level<World.FullResClipLevels)++FullDetailExpected;
|
||||||
|
std::array<std::optional<FStandaloneCpuTile>,9> GateSampleTiles{};
|
||||||
|
std::array<double,9> GateSampleDistances{};
|
||||||
|
GateSampleDistances.fill(std::numeric_limits<double>::infinity());
|
||||||
|
Clock::time_point NeighborhoodReady{},FullDetailReady{},WholeViewReady{};
|
||||||
|
bool bNeighborhoodReported=false,bFullDetailReported=false;
|
||||||
|
while(Finished<Update.DesiredTiles)
|
||||||
|
{
|
||||||
|
std::vector<FStandaloneCpuTile> Ready=Streamer.TakeReady();
|
||||||
|
if(Ready.empty()){std::this_thread::sleep_for(std::chrono::milliseconds(1));continue;}
|
||||||
|
for(const FStandaloneCpuTile& Tile:Ready)
|
||||||
|
{
|
||||||
|
if(bExportRequested)SceneExport.Add(Tile);
|
||||||
|
++Finished;
|
||||||
|
if(bReportMeshCoverage)
|
||||||
|
{
|
||||||
|
const uint64 TileTriangleCount=static_cast<uint64>(Tile.Indices.size()/3);
|
||||||
|
WholeTriangleCount+=TileTriangleCount;
|
||||||
|
if(TileTriangleCount>0)++WholeNonEmptyMeshTiles;
|
||||||
|
}
|
||||||
|
if(Tile.Key.Level>=0&&Tile.Key.Level<static_cast<int32>(TileCountByLOD.size()))
|
||||||
|
{
|
||||||
|
const std::size_t LOD=static_cast<std::size_t>(Tile.Key.Level);
|
||||||
|
++TileCountByLOD[LOD];
|
||||||
|
WorkerSecondsByLOD[LOD]+=Tile.WorkerSeconds;
|
||||||
|
ColumnEvalMsByLOD[LOD]+=Tile.CoreDiagnostics.columnEvaluationExclusiveMilliseconds;
|
||||||
|
MarchingExclusiveMsByLOD[LOD]+=Tile.CoreDiagnostics.marchingCubesExclusiveMilliseconds;
|
||||||
|
GroundRefineExclusiveMsByLOD[LOD]+=Tile.CoreDiagnostics.groundRefinementExclusiveMilliseconds;
|
||||||
|
CapRefineExclusiveMsByLOD[LOD]+=Tile.CoreDiagnostics.capRefinementExclusiveMilliseconds;
|
||||||
|
MeshAssemblyMsByLOD[LOD]+=Tile.CoreDiagnostics.meshAssemblyMilliseconds;
|
||||||
|
SkirtMsByLOD[LOD]+=Tile.CoreDiagnostics.marchingCubesSkirtMilliseconds;
|
||||||
|
SkirtTrianglesByLOD[LOD]+=Tile.SkirtTriangleCount;
|
||||||
|
if(bScreenSpaceGate&&Assembly&&Tile.Key.Level>=3&&Tile.Key.Level<9
|
||||||
|
&&!Tile.Vertices.empty()
|
||||||
|
&&StandaloneScreenSpaceGate::TileHasNativeSurface(Tile.Key,*Assembly,
|
||||||
|
static_cast<double>(World.CoreVoxelSizeMicrons)/1000000.0))
|
||||||
|
{
|
||||||
|
const double Distance=StandaloneScreenSpaceGate::TileAabbDistanceMeters(
|
||||||
|
Tile.Key,CameraPositionVoxels,
|
||||||
|
static_cast<double>(World.CoreVoxelSizeMicrons)/1000000.0);
|
||||||
|
const bool bCloser=Distance<GateSampleDistances[LOD]-1e-9;
|
||||||
|
const bool bTied=std::abs(Distance-GateSampleDistances[LOD])<=1e-9;
|
||||||
|
const bool bKeyLess=!GateSampleTiles[LOD]
|
||||||
|
||TileKeyLessForHash(Tile.Key,GateSampleTiles[LOD]->Key);
|
||||||
|
if(bCloser||(bTied&&bKeyLess))
|
||||||
|
{GateSampleDistances[LOD]=Distance;GateSampleTiles[LOD]=Tile;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(bProfileColumnOverlap&&Tile.Key.Level>=0
|
||||||
|
&&Tile.Key.Level<static_cast<int32>(ColumnCaptureTilesByLOD.size()))
|
||||||
|
{
|
||||||
|
const std::size_t LOD=static_cast<std::size_t>(Tile.Key.Level);
|
||||||
|
++ColumnCaptureTilesByLOD[LOD];
|
||||||
|
ColumnCaptureCompleteByLOD[LOD]=ColumnCaptureCompleteByLOD[LOD]
|
||||||
|
&&Tile.CoreDiagnostics.columnCoordinateCaptureComplete;
|
||||||
|
std::vector<std::array<std::int64_t,2>> Coordinates=
|
||||||
|
Tile.CoreDiagnostics.evaluatedColumnCoordinates;
|
||||||
|
std::sort(Coordinates.begin(),Coordinates.end());
|
||||||
|
Coordinates.erase(std::unique(Coordinates.begin(),Coordinates.end()),Coordinates.end());
|
||||||
|
for(const auto& Coordinate:Coordinates)
|
||||||
|
{
|
||||||
|
const FColumnXY XY{Coordinate[0],Coordinate[1]};
|
||||||
|
auto [Uses,Inserted]=ColumnUsesByLOD[LOD].try_emplace(XY);
|
||||||
|
std::vector<FFirstColumnUse>& PriorUses=Uses->second;
|
||||||
|
if(Inserted)
|
||||||
|
{
|
||||||
|
PriorUses.push_back({Tile.Key,Tile.CoreDiagnostics.columnEvaluationWorkerHash});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++ColumnDuplicateEventsByLOD[LOD];
|
||||||
|
bool bHasNeighbourDuplicate=false,bHasCrossWorkerNeighbourDuplicate=false;
|
||||||
|
for(const FFirstColumnUse& Prior:PriorUses)
|
||||||
|
{
|
||||||
|
if(!AreSameLODNeighbours(Prior.Tile,Tile.Key))continue;
|
||||||
|
bHasNeighbourDuplicate=true;
|
||||||
|
bHasCrossWorkerNeighbourDuplicate=bHasCrossWorkerNeighbourDuplicate
|
||||||
|
||Prior.WorkerHash!=Tile.CoreDiagnostics.columnEvaluationWorkerHash;
|
||||||
|
}
|
||||||
|
if(bHasNeighbourDuplicate)++NeighbourDuplicateEventsByLOD[LOD];
|
||||||
|
if(bHasCrossWorkerNeighbourDuplicate)
|
||||||
|
++CrossWorkerNeighbourDuplicateEventsByLOD[LOD];
|
||||||
|
PriorUses.push_back({Tile.Key,Tile.CoreDiagnostics.columnEvaluationWorkerHash});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WholeViewReady=std::max(WholeViewReady,Tile.CompletedAt);
|
||||||
|
if(Neighborhood.contains(Tile.Key))
|
||||||
|
{
|
||||||
|
++NeighborhoodFinished;
|
||||||
|
NeighborhoodReady=std::max(NeighborhoodReady,Tile.CompletedAt);
|
||||||
|
}
|
||||||
|
if(Tile.Key.Level<World.FullResClipLevels)
|
||||||
|
{
|
||||||
|
++FullDetailFinished;
|
||||||
|
FullDetailReady=std::max(FullDetailReady,Tile.CompletedAt);
|
||||||
|
NativeSolidBoxes+=Tile.CoreDiagnostics.solidBoxes;
|
||||||
|
NativeAirBoxes+=Tile.CoreDiagnostics.airBoxes;
|
||||||
|
NativeMixedBoxes+=Tile.CoreDiagnostics.mixedBoxes;
|
||||||
|
NativeUnknownBoxes+=Tile.CoreDiagnostics.unknownBoxes;
|
||||||
|
NativeFieldCalls+=Tile.CoreDiagnostics.fieldCalls;
|
||||||
|
NativeColumnHits+=Tile.CoreDiagnostics.columnCacheHits;
|
||||||
|
NativeColumnMisses+=Tile.CoreDiagnostics.columnCacheMisses;
|
||||||
|
NativeMeshingSkips+=Tile.CoreDiagnostics.meshingSkipped?1u:0u;
|
||||||
|
NativeClassificationMilliseconds+=Tile.CoreDiagnostics.classificationMilliseconds;
|
||||||
|
NativeColumnComputeMilliseconds+=Tile.CoreDiagnostics.columnComputeMilliseconds;
|
||||||
|
NativeMeshingMilliseconds+=Tile.CoreDiagnostics.meshingMilliseconds;
|
||||||
|
}
|
||||||
|
if(bHashDensity)
|
||||||
|
{
|
||||||
|
if(Tile.bHasDensityHash)DensityRows.push_back({Tile.Key,Tile.DensityHash});
|
||||||
|
if(Tile.bHasMeshHash)MeshRows.push_back({Tile.Key,Tile.MeshHash});
|
||||||
|
if(Tile.bHasPayloadHash)PayloadRows.push_back({Tile.Key,Tile.PayloadHash});
|
||||||
|
if(Tile.bHasTopologyHash)TopologyRows.push_back({Tile.Key,Tile.TopologyHash});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!bNeighborhoodReported&&NeighborhoodFinished==static_cast<int32>(Neighborhood.size()))
|
||||||
|
{
|
||||||
|
std::printf("[PipelineMilestone] neighborhood_ready=%.3fs generated=%d/27\n",
|
||||||
|
std::chrono::duration<double>(NeighborhoodReady-ColdStart).count(),NeighborhoodFinished);
|
||||||
|
bNeighborhoodReported=true;
|
||||||
|
}
|
||||||
|
if(!bFullDetailReported&&FullDetailFinished==FullDetailExpected)
|
||||||
|
{
|
||||||
|
std::printf("[PipelineMilestone] full_detail_ready=%.3fs generated=%d/%d\n",
|
||||||
|
std::chrono::duration<double>(FullDetailReady-ColdStart).count(),
|
||||||
|
FullDetailFinished,FullDetailExpected);
|
||||||
|
bFullDetailReported=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Streamer.Stop();
|
||||||
|
bool bScreenSpaceGatePassing=true;
|
||||||
|
if(bScreenSpaceGate)
|
||||||
|
{
|
||||||
|
if(Assembly)
|
||||||
|
bScreenSpaceGatePassing=StandaloneScreenSpaceGate::Run(GateSampleTiles,
|
||||||
|
Streamer,*Assembly,ClosestDisplayDistances,World.CoreVoxelSizeMicrons,
|
||||||
|
World.MaxClipLevel,PixelBudgetsSubvoxels,CameraYawDegrees,
|
||||||
|
CameraPitchDegrees);
|
||||||
|
else
|
||||||
|
{std::fprintf(stderr,"[ScreenSpaceGateResult] no-world-assembly status=REJECT\n");bScreenSpaceGatePassing=false;}
|
||||||
|
}
|
||||||
|
if(bExportRequested)
|
||||||
|
{
|
||||||
|
bSceneExportPassing=SceneExport.Close(static_cast<std::uint32_t>(Update.DesiredTiles));
|
||||||
|
std::error_code FileSizeError;
|
||||||
|
const std::uintmax_t ExportBytes=std::filesystem::file_size(MeshExportPath,FileSizeError);
|
||||||
|
std::printf("[MeshSceneExport] tiles=%u expected=%d bytes=%llu status=%s path=%s\n",
|
||||||
|
SceneExport.TileCount,Update.DesiredTiles,
|
||||||
|
static_cast<unsigned long long>(FileSizeError?0:ExportBytes),
|
||||||
|
bSceneExportPassing?"PASS":"FAIL",MeshExportPath.string().c_str());
|
||||||
|
bSceneExportPassing=bSceneExportPassing&&!FileSizeError;
|
||||||
|
}
|
||||||
|
bool bColumnOverlapCapturePassing=true;
|
||||||
|
if(bProfileColumnOverlap)
|
||||||
|
{
|
||||||
|
for(std::size_t LOD=0;LOD<ColumnCaptureTilesByLOD.size();++LOD)
|
||||||
|
{
|
||||||
|
const bool bLODComplete=ColumnCaptureCompleteByLOD[LOD]
|
||||||
|
&&ColumnCaptureTilesByLOD[LOD]==ExpectedTilesByLOD[LOD];
|
||||||
|
bColumnOverlapCapturePassing=bColumnOverlapCapturePassing&&bLODComplete;
|
||||||
|
std::printf("[WorldAssemblerLODColumnOverlap] lod=%zu tiles=%llu expected_tiles=%llu unique_xy_columns=%zu repeated_tile_evaluations=%llu neighbouring_duplicate_evaluations=%llu cross_worker_neighbouring_duplicates=%llu capture_complete=%d\n",
|
||||||
|
LOD,static_cast<unsigned long long>(ColumnCaptureTilesByLOD[LOD]),
|
||||||
|
static_cast<unsigned long long>(ExpectedTilesByLOD[LOD]),
|
||||||
|
ColumnUsesByLOD[LOD].size(),
|
||||||
|
static_cast<unsigned long long>(ColumnDuplicateEventsByLOD[LOD]),
|
||||||
|
static_cast<unsigned long long>(NeighbourDuplicateEventsByLOD[LOD]),
|
||||||
|
static_cast<unsigned long long>(CrossWorkerNeighbourDuplicateEventsByLOD[LOD]),
|
||||||
|
bLODComplete?1:0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(std::size_t LOD=0;LOD<TileCountByLOD.size();++LOD)
|
||||||
|
{
|
||||||
|
std::printf("[WorldAssemblerLODWorker] lod=%zu tiles=%llu worker_sum_s=%.6f column_eval_exclusive_ms=%.3f mc_exclusive_ms=%.3f ground_refine_exclusive_ms=%.3f cap_refine_exclusive_ms=%.3f skirt_ms=%.3f skirt_triangles=%llu mesh_assembly_ms=%.3f\n",
|
||||||
|
LOD,static_cast<unsigned long long>(TileCountByLOD[LOD]),WorkerSecondsByLOD[LOD],
|
||||||
|
ColumnEvalMsByLOD[LOD],MarchingExclusiveMsByLOD[LOD],
|
||||||
|
GroundRefineExclusiveMsByLOD[LOD],CapRefineExclusiveMsByLOD[LOD],
|
||||||
|
SkirtMsByLOD[LOD],static_cast<unsigned long long>(SkirtTrianglesByLOD[LOD]),
|
||||||
|
MeshAssemblyMsByLOD[LOD]);
|
||||||
|
}
|
||||||
|
const double NeighborhoodSeconds=std::chrono::duration<double>(NeighborhoodReady-ColdStart).count();
|
||||||
|
const double NeighborhoodMeshSeconds=std::chrono::duration<double>(NeighborhoodReady-ShapeReady).count();
|
||||||
|
const double FullDetailSeconds=std::chrono::duration<double>(FullDetailReady-ColdStart).count();
|
||||||
|
const double WholeViewSeconds=std::chrono::duration<double>(WholeViewReady-ColdStart).count();
|
||||||
|
const double StreamSeconds=std::chrono::duration<double>(WholeViewReady-StreamStart).count();
|
||||||
|
std::printf("[StreamPipeline] workers=%d shape=%.3fs neighborhood_mesh=%.3fs neighborhood_ready=%.3fs full_detail_ready=%.3fs whole_view_ready=%.3fs neighborhood_tiles=%d/27 full_detail_tiles=%d/%d whole_tiles=%d/%zu stream_wall=%.3fs cache_hits=0 full_payload=1\n",
|
||||||
|
WorkerCount,ShapeSeconds,NeighborhoodMeshSeconds,NeighborhoodSeconds,
|
||||||
|
FullDetailSeconds,WholeViewSeconds,NeighborhoodFinished,
|
||||||
|
FullDetailFinished,FullDetailExpected,Finished,Desired.Tiles.size(),StreamSeconds);
|
||||||
|
if(bReportMeshCoverage)
|
||||||
|
std::printf("[PipelineMeshCoverage] tiles=%d nonempty_mesh_tiles=%llu indexed_triangles=%llu\n",
|
||||||
|
Finished,static_cast<unsigned long long>(WholeNonEmptyMeshTiles),
|
||||||
|
static_cast<unsigned long long>(WholeTriangleCount));
|
||||||
|
std::printf("[WorldAssemblerTilePipeline] full_detail_tiles=%d solid_boxes=%llu air_boxes=%llu mixed_boxes=%llu unknown_boxes=%llu whole_tile_skips=%llu field_calls=%llu column_cache_hits=%llu column_cache_misses=%llu column_compute_worker_ms=%.3f classification_worker_ms=%.3f meshing_worker_ms=%.3f\n",
|
||||||
|
FullDetailExpected,static_cast<unsigned long long>(NativeSolidBoxes),
|
||||||
|
static_cast<unsigned long long>(NativeAirBoxes),
|
||||||
|
static_cast<unsigned long long>(NativeMixedBoxes),
|
||||||
|
static_cast<unsigned long long>(NativeUnknownBoxes),
|
||||||
|
static_cast<unsigned long long>(NativeMeshingSkips),
|
||||||
|
static_cast<unsigned long long>(NativeFieldCalls),
|
||||||
|
static_cast<unsigned long long>(NativeColumnHits),
|
||||||
|
static_cast<unsigned long long>(NativeColumnMisses),
|
||||||
|
NativeColumnComputeMilliseconds,NativeClassificationMilliseconds,
|
||||||
|
NativeMeshingMilliseconds);
|
||||||
|
|
||||||
|
bool bHashesPassing=true;
|
||||||
|
if(bHashDensity)
|
||||||
|
{
|
||||||
|
bHashesPassing=DensityRows.size()==Desired.Tiles.size()
|
||||||
|
&&MeshRows.size()==Desired.Tiles.size()
|
||||||
|
&&PayloadRows.size()==Desired.Tiles.size()
|
||||||
|
&&TopologyRows.size()==Desired.Tiles.size();
|
||||||
|
std::vector<FHashedTile> FullDensity,FullMesh,FullPayload,FullTopology;
|
||||||
|
for(const FHashedTile& Row:DensityRows)if(Row.Key.Level<World.FullResClipLevels)FullDensity.push_back(Row);
|
||||||
|
for(const FHashedTile& Row:MeshRows)if(Row.Key.Level<World.FullResClipLevels)FullMesh.push_back(Row);
|
||||||
|
for(const FHashedTile& Row:PayloadRows)if(Row.Key.Level<World.FullResClipLevels)FullPayload.push_back(Row);
|
||||||
|
for(const FHashedTile& Row:TopologyRows)if(Row.Key.Level<World.FullResClipLevels)FullTopology.push_back(Row);
|
||||||
|
std::printf("[PipelineFullDetailHash] tiles=%d density=0x%016llx mesh=0x%016llx payload=0x%016llx topology=0x%016llx\n",
|
||||||
|
FullDetailExpected,static_cast<unsigned long long>(HashTileRows(FullDensity)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(FullMesh)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(FullPayload)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(FullTopology)));
|
||||||
|
std::printf("[PipelineWholeViewHash] tiles=%zu density=0x%016llx mesh=0x%016llx payload=0x%016llx topology=0x%016llx\n",
|
||||||
|
Desired.Tiles.size(),static_cast<unsigned long long>(HashTileRows(DensityRows)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(MeshRows)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(PayloadRows)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(TopologyRows)));
|
||||||
|
for(std::size_t LOD=0;LOD<TileCountByLOD.size();++LOD)
|
||||||
|
{
|
||||||
|
const auto FilterLOD=[LOD](const std::vector<FHashedTile>& Rows)
|
||||||
|
{
|
||||||
|
std::vector<FHashedTile> Selected;
|
||||||
|
for(const FHashedTile& Row:Rows)
|
||||||
|
if(Row.Key.Level==static_cast<int32>(LOD))Selected.push_back(Row);
|
||||||
|
return Selected;
|
||||||
|
};
|
||||||
|
auto LodDensity=FilterLOD(DensityRows),LodMesh=FilterLOD(MeshRows);
|
||||||
|
auto LodPayload=FilterLOD(PayloadRows),LodTopology=FilterLOD(TopologyRows);
|
||||||
|
std::printf("[PipelineLODHash] lod=%zu tiles=%llu density=0x%016llx mesh=0x%016llx payload=0x%016llx topology=0x%016llx\n",
|
||||||
|
LOD,static_cast<unsigned long long>(TileCountByLOD[LOD]),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(LodDensity)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(LodMesh)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(LodPayload)),
|
||||||
|
static_cast<unsigned long long>(HashTileRows(LodTopology)));
|
||||||
|
}
|
||||||
|
const std::array<VoxelForgeCore::Vec3d,9> QueryPoints={{
|
||||||
|
{CameraPositionVoxels.X,CameraPositionVoxels.Y,CameraPositionVoxels.Z},
|
||||||
|
{CameraPositionVoxels.X+8.0,CameraPositionVoxels.Y,CameraPositionVoxels.Z},
|
||||||
|
{CameraPositionVoxels.X-8.0,CameraPositionVoxels.Y,CameraPositionVoxels.Z},
|
||||||
|
{CameraPositionVoxels.X,CameraPositionVoxels.Y+8.0,CameraPositionVoxels.Z},
|
||||||
|
{CameraPositionVoxels.X,CameraPositionVoxels.Y-8.0,CameraPositionVoxels.Z},
|
||||||
|
{CameraPositionVoxels.X,CameraPositionVoxels.Y,CameraPositionVoxels.Z+8.0},
|
||||||
|
{CameraPositionVoxels.X,CameraPositionVoxels.Y,CameraPositionVoxels.Z-8.0},
|
||||||
|
{CameraPositionVoxels.X+64.0,CameraPositionVoxels.Y-32.0,CameraPositionVoxels.Z+16.0},
|
||||||
|
{CameraPositionVoxels.X-128.0,CameraPositionVoxels.Y+96.0,CameraPositionVoxels.Z-64.0}}};
|
||||||
|
uint64 ExactDensityHash=14695981039346656037ull;
|
||||||
|
uint64 ExactUnclampedHash=14695981039346656037ull;
|
||||||
|
uint64 ExactDetailHash=14695981039346656037ull;
|
||||||
|
uint64 ExactCollisionHash=14695981039346656037ull;
|
||||||
|
for(const auto& Point:QueryPoints)
|
||||||
|
{
|
||||||
|
const float Density=Shape.densityAt(Point);
|
||||||
|
const float Unclamped=Shape.unclampedDensityAt(Point);
|
||||||
|
const auto Detail=Shape.detailSampleAt(Point);
|
||||||
|
HashWord(ExactDensityHash,std::bit_cast<uint32>(Density),4);
|
||||||
|
HashWord(ExactUnclampedHash,std::bit_cast<uint32>(Unclamped),4);
|
||||||
|
HashWord(ExactDetailHash,std::bit_cast<uint32>(Detail.displacement),4);
|
||||||
|
HashWord(ExactDetailHash,std::bit_cast<uint32>(Detail.caveInfluence),4);
|
||||||
|
HashWord(ExactDetailHash,std::bit_cast<uint32>(Detail.floorInfluence),4);
|
||||||
|
HashWord(ExactCollisionHash,Shape.isSolidAt(Point)?1u:0u,1);
|
||||||
|
}
|
||||||
|
std::printf("[PipelineExactQueryHash] probes=%zu density=0x%016llx unclamped=0x%016llx detail=0x%016llx collision=0x%016llx path=direct-Core-queries\n",
|
||||||
|
QueryPoints.size(),static_cast<unsigned long long>(ExactDensityHash),
|
||||||
|
static_cast<unsigned long long>(ExactUnclampedHash),
|
||||||
|
static_cast<unsigned long long>(ExactDetailHash),
|
||||||
|
static_cast<unsigned long long>(ExactCollisionHash));
|
||||||
|
}
|
||||||
|
return NeighborhoodFinished==static_cast<int32>(Neighborhood.size())
|
||||||
|
&&FullDetailFinished==FullDetailExpected&&Finished==Update.DesiredTiles&&bHashesPassing
|
||||||
|
&&(!bProfileColumnOverlap||bColumnOverlapCapturePassing)
|
||||||
|
&&(!bExportRequested||bSceneExportPassing)&&bScreenSpaceGatePassing?0:6;
|
||||||
|
}
|
||||||
|
} // namespace StandaloneStreamBenchmark
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WorldMesher.h"
|
#include "WorldMesher.h"
|
||||||
|
#include "StandaloneWorkerThread.h"
|
||||||
#include "VoxelForgeCore/VoxelForgeCore.h"
|
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@@ -11,10 +12,12 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <limits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -509,7 +512,7 @@ public:
|
|||||||
Queue.clear();PriorityTasks.clear();
|
Queue.clear();PriorityTasks.clear();
|
||||||
}
|
}
|
||||||
Wake.notify_all();
|
Wake.notify_all();
|
||||||
for(std::thread& Worker:Workers)if(Worker.joinable())Worker.join();
|
for(FStandaloneWorkerThread& Worker:Workers)if(Worker.joinable())Worker.join();
|
||||||
Workers.clear();
|
Workers.clear();
|
||||||
std::lock_guard<std::mutex> Lock(Mutex);
|
std::lock_guard<std::mutex> Lock(Mutex);
|
||||||
Ready.clear();Outstanding.clear();Desired.clear();Running.clear();
|
Ready.clear();Outstanding.clear();Desired.clear();Running.clear();
|
||||||
@@ -643,6 +646,16 @@ public:
|
|||||||
int32 GetWorkerCount()const{return WorkerCount;}
|
int32 GetWorkerCount()const{return WorkerCount;}
|
||||||
uint64 GetCacheHits()const{return CacheHitCount.load(std::memory_order_relaxed);}
|
uint64 GetCacheHits()const{return CacheHitCount.load(std::memory_order_relaxed);}
|
||||||
|
|
||||||
|
void SetMesherStageProfilingEnabled(bool Enabled)
|
||||||
|
{bProfileMesherStages=Enabled;}
|
||||||
|
FStandaloneCpuTile GenerateDiagnostic(const FVoxelTileKey& Key,
|
||||||
|
std::uint32_t GlobalOctaveDrop=0,std::uint32_t CellStride=1,
|
||||||
|
bool ForceGenerate=false)
|
||||||
|
{
|
||||||
|
FStandaloneTileJob Job;Job.Key=Key;Job.StartedAt=FClock::now();Job.QueuedAt=Job.StartedAt;
|
||||||
|
return Generate(Job,GlobalOctaveDrop,CellStride,ForceGenerate);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FStandaloneStreamingUpdate UpdateDesiredSet(FStandaloneDesiredTileSet NewDesired,
|
FStandaloneStreamingUpdate UpdateDesiredSet(FStandaloneDesiredTileSet NewDesired,
|
||||||
const std::vector<FVoxelTileKey>& ResidentKeys,uint64 CrossingIndex)
|
const std::vector<FVoxelTileKey>& ResidentKeys,uint64 CrossingIndex)
|
||||||
@@ -758,12 +771,14 @@ private:
|
|||||||
Wake.notify_all();
|
Wake.notify_all();
|
||||||
return Stats;
|
return Stats;
|
||||||
}
|
}
|
||||||
FStandaloneCpuTile Generate(const FStandaloneTileJob& Job)
|
FStandaloneCpuTile Generate(const FStandaloneTileJob& Job,
|
||||||
|
std::uint32_t DiagnosticGlobalOctaveDrop=0,std::uint32_t DiagnosticCellStride=1,
|
||||||
|
bool ForceGenerate=false)
|
||||||
{
|
{
|
||||||
const auto StartTime=Job.StartedAt;
|
const auto StartTime=Job.StartedAt;
|
||||||
FStandaloneCpuTile Out;Out.Key=Job.Key;Out.RequestedCrossing=Job.RequestedCrossing;
|
FStandaloneCpuTile Out;Out.Key=Job.Key;Out.RequestedCrossing=Job.RequestedCrossing;
|
||||||
Out.QueuedAt=Job.QueuedAt;Out.StartedAt=Job.StartedAt;
|
Out.QueuedAt=Job.QueuedAt;Out.StartedAt=Job.StartedAt;
|
||||||
if(MeshCache)
|
if(MeshCache&&!ForceGenerate)
|
||||||
{
|
{
|
||||||
if(const FStandaloneCpuTile* Cached=MeshCache->Find(Job.Key))
|
if(const FStandaloneCpuTile* Cached=MeshCache->Find(Job.Key))
|
||||||
{
|
{
|
||||||
@@ -797,10 +812,16 @@ private:
|
|||||||
{
|
{
|
||||||
VoxelForgeCore::TileGenerationOptions Options;
|
VoxelForgeCore::TileGenerationOptions Options;
|
||||||
Options.bandMinZVoxel=Job.BandZMin;Options.bandMaxZVoxel=Job.BandZMax;
|
Options.bandMinZVoxel=Job.BandZMin;Options.bandMaxZVoxel=Job.BandZMax;
|
||||||
Options.hashDensity=bHashDensity;Options.skipUvAndColors=bSkipUvAndColors;
|
Options.hashDensity=bHashDensity;
|
||||||
|
Options.skipUvAndColors=bSkipUvAndColors;
|
||||||
Options.skipMaterialGroups=bSkipMaterialGroups;Options.skipUv=bSkipUV;Options.skipColors=bSkipColors;
|
Options.skipMaterialGroups=bSkipMaterialGroups;Options.skipUv=bSkipUV;Options.skipColors=bSkipColors;
|
||||||
Options.captureColumnCoordinates=bCaptureColumnCoordinates;
|
Options.captureColumnCoordinates=bCaptureColumnCoordinates;
|
||||||
Options.lod8HorizonInteriorStepVoxels=Lod8HorizonInteriorStepVoxels;
|
Options.lod8HorizonInteriorStepVoxels=Lod8HorizonInteriorStepVoxels;
|
||||||
|
Options.profileMesherStages=bProfileMesherStages&&!ForceGenerate;
|
||||||
|
Options.diagnosticGlobalOctaveDrop=DiagnosticGlobalOctaveDrop;
|
||||||
|
Options.diagnosticCellStride=std::max<std::uint32_t>(1,DiagnosticCellStride);
|
||||||
|
Options.diagnosticColumnInterpolationStride=
|
||||||
|
std::max<std::uint32_t>(1,DiagnosticCellStride);
|
||||||
std::string Error;
|
std::string Error;
|
||||||
auto Result=CoreWorld->generateTile(
|
auto Result=CoreWorld->generateTile(
|
||||||
{{Job.Key.Coord.X,Job.Key.Coord.Y,Job.Key.Coord.Z},Job.Key.Level},Options,Error);
|
{{Job.Key.Coord.X,Job.Key.Coord.Y,Job.Key.Coord.Z},Job.Key.Level},Options,Error);
|
||||||
@@ -973,11 +994,12 @@ private:
|
|||||||
bool bSkipColors=false;
|
bool bSkipColors=false;
|
||||||
bool bCaptureColumnCoordinates=false;
|
bool bCaptureColumnCoordinates=false;
|
||||||
int32 Lod8HorizonInteriorStepVoxels=0;
|
int32 Lod8HorizonInteriorStepVoxels=0;
|
||||||
|
bool bProfileMesherStages=false;
|
||||||
std::atomic<uint64> CacheHitCount{0};
|
std::atomic<uint64> CacheHitCount{0};
|
||||||
mutable std::mutex Mutex;
|
mutable std::mutex Mutex;
|
||||||
std::condition_variable Wake;
|
std::condition_variable Wake;
|
||||||
bool bStop=true;
|
bool bStop=true;
|
||||||
std::vector<std::thread> Workers;
|
std::vector<FStandaloneWorkerThread> Workers;
|
||||||
std::deque<std::function<void()>> PriorityTasks;
|
std::deque<std::function<void()>> PriorityTasks;
|
||||||
std::vector<FStandaloneTileJob> Queue;
|
std::vector<FStandaloneTileJob> Queue;
|
||||||
std::vector<FStandaloneCpuTile> Ready;
|
std::vector<FStandaloneCpuTile> Ready;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
// - STORE region (tight): only rooms/tunnels that can actually reach a voxel in
|
// - STORE region (tight): only rooms/tunnels that can actually reach a voxel in
|
||||||
// this chunk are kept for the per-voxel loop, so hot-path cost stays low.
|
// this chunk are kept for the per-voxel loop, so hot-path cost stays low.
|
||||||
|
|
||||||
|
#include "VoxelForgeCore/ThreadLocalStorage.h"
|
||||||
#include "VoxelCaveMorphology.h"
|
#include "VoxelCaveMorphology.h"
|
||||||
#include "VoxelDensityProfile.h"
|
#include "VoxelDensityProfile.h"
|
||||||
#include "VoxelDensityPrimitives.h"
|
#include "VoxelDensityPrimitives.h"
|
||||||
@@ -265,7 +266,8 @@ namespace
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static thread_local FVFFloorReliefCache GFloorReliefCache;
|
static thread_local VoxelForgeCoreThreadLocal::FLazy<FVFFloorReliefCache>
|
||||||
|
GFloorReliefCache;
|
||||||
|
|
||||||
FORCEINLINE float VF_ComputeFloorReliefNoiseDouble(
|
FORCEINLINE float VF_ComputeFloorReliefNoiseDouble(
|
||||||
double X, double Y, uint32 FloorSeed, float Frequency)
|
double X, double Y, uint32 FloorSeed, float Frequency)
|
||||||
@@ -300,7 +302,7 @@ namespace
|
|||||||
int32 FeatureIndex,
|
int32 FeatureIndex,
|
||||||
const FVFFloorReliefColumnKey& Column)
|
const FVFFloorReliefColumnKey& Column)
|
||||||
{
|
{
|
||||||
return GFloorReliefCache.GetOrCompute(
|
return GFloorReliefCache.Get().GetOrCompute(
|
||||||
X, Y, FloorSeed, Frequency, CacheIdentity, Feature, FeatureIndex,
|
X, Y, FloorSeed, Frequency, CacheIdentity, Feature, FeatureIndex,
|
||||||
Column,
|
Column,
|
||||||
&VF_ComputeFloorReliefNoiseDouble);
|
&VF_ComputeFloorReliefNoiseDouble);
|
||||||
@@ -313,7 +315,7 @@ namespace
|
|||||||
int32 FeatureIndex,
|
int32 FeatureIndex,
|
||||||
const FVFFloorReliefColumnKey& Column)
|
const FVFFloorReliefColumnKey& Column)
|
||||||
{
|
{
|
||||||
return GFloorReliefCache.GetOrCompute(
|
return GFloorReliefCache.Get().GetOrCompute(
|
||||||
static_cast<double>(X), static_cast<double>(Y),
|
static_cast<double>(X), static_cast<double>(Y),
|
||||||
FloorSeed, Frequency, CacheIdentity, Feature, FeatureIndex,
|
FloorSeed, Frequency, CacheIdentity, Feature, FeatureIndex,
|
||||||
Column,
|
Column,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
// Convention de signe INTERNE : positif = solide ; la pile négative une fois pour le MC.
|
// Convention de signe INTERNE : positif = solide ; la pile négative une fois pour le MC.
|
||||||
// Internal sign convention: positive = solid; the stack negates once for MC.
|
// Internal sign convention: positive = solid; the stack negates once for MC.
|
||||||
|
|
||||||
|
#include "VoxelForgeCore/ThreadLocalStorage.h"
|
||||||
#include "VoxelDensityOpStack.h"
|
#include "VoxelDensityOpStack.h"
|
||||||
#include "VoxelStrateComposer.h"
|
#include "VoxelStrateComposer.h"
|
||||||
|
|
||||||
@@ -1148,7 +1149,8 @@ namespace
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local FColumnCache Cache = {};
|
thread_local VoxelForgeCoreThreadLocal::FLazy<FColumnCache> Cache;
|
||||||
|
FColumnCache& columnCache = Cache.Get();
|
||||||
thread_local FColumn DirectColumn = {};
|
thread_local FColumn DirectColumn = {};
|
||||||
|
|
||||||
// The production mesher and the exact-lattice classifier use integer XY. Fractional
|
// The production mesher and the exact-lattice classifier use integer XY. Fractional
|
||||||
@@ -1172,7 +1174,7 @@ namespace
|
|||||||
|
|
||||||
// Acquire vérifie la clé uint64 complète et les bornes exactes avant de dériver CI.
|
// Acquire vérifie la clé uint64 complète et les bornes exactes avant de dériver CI.
|
||||||
// Acquire checks the exact uint64 key and exact bounds before deriving CI.
|
// Acquire checks the exact uint64 key and exact bounds before deriving CI.
|
||||||
FColumnBox& Box = Cache.Acquire(IX, IY, ColumnKey);
|
FColumnBox& Box = columnCache.Acquire(IX, IY, ColumnKey);
|
||||||
AcquiredBox = &Box;
|
AcquiredBox = &Box;
|
||||||
|
|
||||||
CI = (IY - Box.BaseY) * FColumnBox::Dim + (IX - Box.BaseX);
|
CI = (IY - Box.BaseY) * FColumnBox::Dim + (IX - Box.BaseX);
|
||||||
@@ -3158,8 +3160,10 @@ namespace
|
|||||||
FChunkSDFCache Cache;
|
FChunkSDFCache Cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
static thread_local FRoomGraphCacheEntry GRoomGraphCache[
|
using FRoomGraphCacheStorage = std::array<
|
||||||
RoomGraphCacheBankCount][RoomGraphCacheSlotCount];
|
std::array<FRoomGraphCacheEntry, RoomGraphCacheSlotCount>, RoomGraphCacheBankCount>;
|
||||||
|
static thread_local VoxelForgeCoreThreadLocal::FLazy<FRoomGraphCacheStorage>
|
||||||
|
GRoomGraphCache;
|
||||||
static thread_local uint32 GRoomGraphCacheClock = 0;
|
static thread_local uint32 GRoomGraphCacheClock = 0;
|
||||||
|
|
||||||
FORCEINLINE int32 RoomGraphCacheBank(int32 RegionSize)
|
FORCEINLINE int32 RoomGraphCacheBank(int32 RegionSize)
|
||||||
@@ -3190,6 +3194,7 @@ namespace
|
|||||||
uint64 ManagerLifetimeId, const TArray<FStrateTerrainOpEntry>* TerrainOps,
|
uint64 ManagerLifetimeId, const TArray<FStrateTerrainOpEntry>* TerrainOps,
|
||||||
int32 RegionMinX, int32 RegionMinY, int32 RegionSize)
|
int32 RegionMinX, int32 RegionMinY, int32 RegionSize)
|
||||||
{
|
{
|
||||||
|
auto& RoomGraphCache = GRoomGraphCache.Get();
|
||||||
auto SelectForReuse = [](FRoomGraphCacheEntry* Selected, uint32 Use)
|
auto SelectForReuse = [](FRoomGraphCacheEntry* Selected, uint32 Use)
|
||||||
-> FRoomGraphCacheEntry*
|
-> FRoomGraphCacheEntry*
|
||||||
{
|
{
|
||||||
@@ -3219,7 +3224,7 @@ namespace
|
|||||||
FRoomGraphCacheEntry* LeastRecentlyUsed = nullptr;
|
FRoomGraphCacheEntry* LeastRecentlyUsed = nullptr;
|
||||||
for (int32 Probe = 0; Probe < RoomGraphCacheSlotCount; ++Probe)
|
for (int32 Probe = 0; Probe < RoomGraphCacheSlotCount; ++Probe)
|
||||||
{
|
{
|
||||||
FRoomGraphCacheEntry& Candidate = GRoomGraphCache[Bank][
|
FRoomGraphCacheEntry& Candidate = RoomGraphCache[Bank][
|
||||||
(StartSlot + Probe) & (RoomGraphCacheSlotCount - 1)];
|
(StartSlot + Probe) & (RoomGraphCacheSlotCount - 1)];
|
||||||
if (!Candidate.bValid)
|
if (!Candidate.bValid)
|
||||||
{
|
{
|
||||||
@@ -3251,7 +3256,7 @@ namespace
|
|||||||
FRoomGraphCacheEntry* Selected = ReuseEntry != nullptr
|
FRoomGraphCacheEntry* Selected = ReuseEntry != nullptr
|
||||||
? ReuseEntry : LeastRecentlyUsed;
|
? ReuseEntry : LeastRecentlyUsed;
|
||||||
return SelectForReuse(
|
return SelectForReuse(
|
||||||
Selected != nullptr ? Selected : &GRoomGraphCache[Bank][StartSlot], Use);
|
Selected != nullptr ? Selected : &RoomGraphCache[Bank][StartSlot], Use);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Classification is dispatched across many workers before most of those workers have
|
// Classification is dispatched across many workers before most of those workers have
|
||||||
@@ -8740,11 +8745,12 @@ void VoxelDensityOps::ReportWorkerRoomGraphCacheFootprint()
|
|||||||
uint64 LargestEntryBytes = 0;
|
uint64 LargestEntryBytes = 0;
|
||||||
uint64 ValidEntries = 0;
|
uint64 ValidEntries = 0;
|
||||||
VoxelDensityProfile::FCacheMemoryBreakdown Breakdown;
|
VoxelDensityProfile::FCacheMemoryBreakdown Breakdown;
|
||||||
|
auto& RoomGraphCache = GRoomGraphCache.Get();
|
||||||
for (int32 Bank = 0; Bank < RoomGraphCacheBankCount; ++Bank)
|
for (int32 Bank = 0; Bank < RoomGraphCacheBankCount; ++Bank)
|
||||||
{
|
{
|
||||||
for (int32 Index = 0; Index < RoomGraphCacheSlotCount; ++Index)
|
for (int32 Index = 0; Index < RoomGraphCacheSlotCount; ++Index)
|
||||||
{
|
{
|
||||||
const FRoomGraphCacheEntry& Entry = GRoomGraphCache[Bank][Index];
|
const FRoomGraphCacheEntry& Entry = RoomGraphCache[Bank][Index];
|
||||||
if (!Entry.bValid)
|
if (!Entry.bValid)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -8760,12 +8766,12 @@ void VoxelDensityOps::ReportWorkerRoomGraphCacheFootprint()
|
|||||||
LargestEntryBytes = FMath::Max(LargestEntryBytes, FullEntryBytes);
|
LargestEntryBytes = FMath::Max(LargestEntryBytes, FullEntryBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Breakdown.SlotStorageBytes = static_cast<uint64>(sizeof(GRoomGraphCache));
|
Breakdown.SlotStorageBytes = static_cast<uint64>(sizeof(RoomGraphCache));
|
||||||
|
|
||||||
VoxelDensityProfile::SetWorkerRoomGraphCacheFootprint(
|
VoxelDensityProfile::SetWorkerRoomGraphCacheFootprint(
|
||||||
RoomGraphCacheBankCount * RoomGraphCacheSlotCount,
|
RoomGraphCacheBankCount * RoomGraphCacheSlotCount,
|
||||||
ValidEntries,
|
ValidEntries,
|
||||||
static_cast<uint64>(sizeof(GRoomGraphCache)),
|
static_cast<uint64>(sizeof(RoomGraphCache)),
|
||||||
DynamicBytes,
|
DynamicBytes,
|
||||||
EntryBytes,
|
EntryBytes,
|
||||||
LargestEntryBytes,
|
LargestEntryBytes,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
// Convention INTERNE: positif = solide, négatif = air (plus lisible).
|
// Convention INTERNE: positif = solide, négatif = air (plus lisible).
|
||||||
// Convention de SORTIE (marching cubes): on négate → négatif = solide.
|
// Convention de SORTIE (marching cubes): on négate → négatif = solide.
|
||||||
|
|
||||||
|
#include "VoxelForgeCore/ThreadLocalStorage.h"
|
||||||
#include "VoxelGenerator.h"
|
#include "VoxelGenerator.h"
|
||||||
#include "StandaloneResearchTunnels.h"
|
#include "StandaloneResearchTunnels.h"
|
||||||
#include "VoxelSettings.h"
|
#include "VoxelSettings.h"
|
||||||
@@ -388,7 +389,7 @@ struct FSurfaceColumnCache
|
|||||||
// Cache de colonnes par thread de ClassifyTile (T1.d) : les pré-passes et passes complètes
|
// Cache de colonnes par thread de ClassifyTile (T1.d) : les pré-passes et passes complètes
|
||||||
// successives d'une même tuile, et les tuiles voisines, réutilisent leurs colonnes.
|
// successives d'une même tuile, et les tuiles voisines, réutilisent leurs colonnes.
|
||||||
// Per-thread column cache for ClassifyTile: successive passes and neighbouring tiles reuse columns.
|
// Per-thread column cache for ClassifyTile: successive passes and neighbouring tiles reuse columns.
|
||||||
static thread_local FSurfaceColumnCache GSurfColCache;
|
static thread_local VoxelForgeCoreThreadLocal::FLazy<FSurfaceColumnCache> GSurfColCache;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// WORM N1 BLOCK PROOF (worker-local, scalar GetDensityAt hand-off)
|
// WORM N1 BLOCK PROOF (worker-local, scalar GetDensityAt hand-off)
|
||||||
@@ -3023,7 +3024,9 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ,
|
|||||||
thread_local FVoxelOpStack CP_OpStack;
|
thread_local FVoxelOpStack CP_OpStack;
|
||||||
thread_local bool CP_UseOpStack = false;
|
thread_local bool CP_UseOpStack = false;
|
||||||
thread_local uint64 CP_ManagerLifetimeId = 0;
|
thread_local uint64 CP_ManagerLifetimeId = 0;
|
||||||
thread_local FTunnelNetworkDensityCacheEntry CP_TunnelDensityCache[TunnelDensityCacheSlotCount];
|
thread_local VoxelForgeCoreThreadLocal::FLazy<
|
||||||
|
std::array<FTunnelNetworkDensityCacheEntry, TunnelDensityCacheSlotCount>>
|
||||||
|
CP_TunnelDensityCache;
|
||||||
thread_local FTunnelNetworkDensityCacheEntry* CP_ActiveTunnelDensityCache = nullptr;
|
thread_local FTunnelNetworkDensityCacheEntry* CP_ActiveTunnelDensityCache = nullptr;
|
||||||
// Cooked-season recipes and editor candidate recipes share this immutable worker-local
|
// Cooked-season recipes and editor candidate recipes share this immutable worker-local
|
||||||
// hand-off. Recipe materialisation is runtime; rolling/selection remains editor-only.
|
// hand-off. Recipe materialisation is runtime; rolling/selection remains editor-only.
|
||||||
@@ -3080,12 +3083,13 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ,
|
|||||||
auto FindTunnelDensityCacheEntry = [&](const FIntVector& QueryChunk,
|
auto FindTunnelDensityCacheEntry = [&](const FIntVector& QueryChunk,
|
||||||
FTunnelNetworkDensityCacheEntry*& OutEntry) -> bool
|
FTunnelNetworkDensityCacheEntry*& OutEntry) -> bool
|
||||||
{
|
{
|
||||||
|
auto& TunnelDensityCache = CP_TunnelDensityCache.Get();
|
||||||
const int32 StartSlot = TunnelDensityCacheSlot(TunnelCacheKey);
|
const int32 StartSlot = TunnelDensityCacheSlot(TunnelCacheKey);
|
||||||
FTunnelNetworkDensityCacheEntry* ReuseEntry = nullptr;
|
FTunnelNetworkDensityCacheEntry* ReuseEntry = nullptr;
|
||||||
for (int32 Probe = 0; Probe < TunnelDensityCacheSlotCount; ++Probe)
|
for (int32 Probe = 0; Probe < TunnelDensityCacheSlotCount; ++Probe)
|
||||||
{
|
{
|
||||||
const int32 Slot = (StartSlot + Probe) & (TunnelDensityCacheSlotCount - 1);
|
const int32 Slot = (StartSlot + Probe) & (TunnelDensityCacheSlotCount - 1);
|
||||||
FTunnelNetworkDensityCacheEntry& Candidate = CP_TunnelDensityCache[Slot];
|
FTunnelNetworkDensityCacheEntry& Candidate = TunnelDensityCache[Slot];
|
||||||
if (!Candidate.bValid || Candidate.OwnerId != DensityCacheOwnerId)
|
if (!Candidate.bValid || Candidate.OwnerId != DensityCacheOwnerId)
|
||||||
{
|
{
|
||||||
if (ReuseEntry == nullptr) { ReuseEntry = &Candidate; }
|
if (ReuseEntry == nullptr) { ReuseEntry = &Candidate; }
|
||||||
@@ -3107,11 +3111,14 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ,
|
|||||||
}
|
}
|
||||||
OutEntry = ReuseEntry != nullptr
|
OutEntry = ReuseEntry != nullptr
|
||||||
? ReuseEntry
|
? ReuseEntry
|
||||||
: &CP_TunnelDensityCache[StartSlot];
|
: &TunnelDensityCache[StartSlot];
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!bIsGapChunk)
|
const bool bTunnelDensityCacheRoute =
|
||||||
|
QueryGeneratorType == ECaveGeneratorType::TunnelNetwork
|
||||||
|
|| QueryGeneratorType == ECaveGeneratorType::Underwater;
|
||||||
|
if (!bIsGapChunk && bTunnelDensityCacheRoute)
|
||||||
{
|
{
|
||||||
if (VoxelDensityProfile::AreCountersEnabled())
|
if (VoxelDensityProfile::AreCountersEnabled())
|
||||||
{
|
{
|
||||||
@@ -3387,7 +3394,7 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ,
|
|||||||
{
|
{
|
||||||
FTunnelNetworkDensityCacheEntry& CachedEntry = TunnelDensityCacheEntryForWrite
|
FTunnelNetworkDensityCacheEntry& CachedEntry = TunnelDensityCacheEntryForWrite
|
||||||
? *TunnelDensityCacheEntryForWrite
|
? *TunnelDensityCacheEntryForWrite
|
||||||
: CP_TunnelDensityCache[TunnelDensityCacheSlot(ChunkCoord)];
|
: CP_TunnelDensityCache.Get()[TunnelDensityCacheSlot(ChunkCoord)];
|
||||||
CachedEntry.bValid = false;
|
CachedEntry.bValid = false;
|
||||||
CachedEntry.OwnerId = DensityCacheOwnerId;
|
CachedEntry.OwnerId = DensityCacheOwnerId;
|
||||||
CachedEntry.ManagerLifetimeId = ManagerLifetimeId;
|
CachedEntry.ManagerLifetimeId = ManagerLifetimeId;
|
||||||
@@ -3406,7 +3413,7 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ,
|
|||||||
CP_ActiveTunnelDensityCache = &CachedEntry;
|
CP_ActiveTunnelDensityCache = &CachedEntry;
|
||||||
ActiveOpStack = &CachedEntry.OpStack;
|
ActiveOpStack = &CachedEntry.OpStack;
|
||||||
ActiveTunnelCoreCache = &CachedEntry.TunnelCore;
|
ActiveTunnelCoreCache = &CachedEntry.TunnelCore;
|
||||||
ReportTunnelDensityCacheFootprint(CP_TunnelDensityCache);
|
ReportTunnelDensityCacheFootprint(CP_TunnelDensityCache.Get().data());
|
||||||
}
|
}
|
||||||
else if (!bLoadedTunnelDensityCache)
|
else if (!bLoadedTunnelDensityCache)
|
||||||
{
|
{
|
||||||
@@ -4023,11 +4030,13 @@ float UVoxelGenerator::GetDensityAt(float WorldX, float WorldY, float WorldZ,
|
|||||||
uint32 Version = 0;
|
uint32 Version = 0;
|
||||||
TArray<FVoxelModification> Mods;
|
TArray<FVoxelModification> Mods;
|
||||||
};
|
};
|
||||||
static thread_local FDiffSlot DiffSlots[64];
|
static thread_local VoxelForgeCoreThreadLocal::FLazy<std::array<FDiffSlot, 64>>
|
||||||
|
DiffSlots;
|
||||||
|
auto& diffSlots = DiffSlots.Get();
|
||||||
|
|
||||||
const uint64 DiffLayerOwnerId = DiffLayer->GetCacheLifetimeId();
|
const uint64 DiffLayerOwnerId = DiffLayer->GetCacheLifetimeId();
|
||||||
const uint32 V = DiffLayer->GetModsVersion();
|
const uint32 V = DiffLayer->GetModsVersion();
|
||||||
FDiffSlot& Slot = DiffSlots[(ChunkCoord.X & 3) | ((ChunkCoord.Y & 3) << 2) | ((ChunkCoord.Z & 3) << 4)];
|
FDiffSlot& Slot = diffSlots[(ChunkCoord.X & 3) | ((ChunkCoord.Y & 3) << 2) | ((ChunkCoord.Z & 3) << 4)];
|
||||||
if (Slot.OwnerId != DiffLayerOwnerId || Slot.Chunk != ChunkCoord || Slot.Version != V)
|
if (Slot.OwnerId != DiffLayerOwnerId || Slot.Chunk != ChunkCoord || Slot.Version != V)
|
||||||
{
|
{
|
||||||
Slot.OwnerId = DiffLayerOwnerId;
|
Slot.OwnerId = DiffLayerOwnerId;
|
||||||
@@ -4233,7 +4242,8 @@ float UVoxelGenerator::GetDensityWithParams(float WorldX, float WorldY, float Wo
|
|||||||
uint64 LastUse = 0;
|
uint64 LastUse = 0;
|
||||||
bool bValid = false;
|
bool bValid = false;
|
||||||
};
|
};
|
||||||
static thread_local std::array<FRoomGraphCacheSlot, 4> RoomGraphCacheSlots{};
|
static thread_local VoxelForgeCoreThreadLocal::FLazy<
|
||||||
|
std::array<FRoomGraphCacheSlot, 4>> RoomGraphCacheStorage;
|
||||||
static thread_local uint64 RoomGraphCacheUseSerial = 0;
|
static thread_local uint64 RoomGraphCacheUseSerial = 0;
|
||||||
VF_ParseRoomGraphCacheSlots();
|
VF_ParseRoomGraphCacheSlots();
|
||||||
// The envelope proof is constant for a cache-policy key. Do not run the complete room/edge
|
// The envelope proof is constant for a cache-policy key. Do not run the complete room/edge
|
||||||
@@ -4417,6 +4427,7 @@ float UVoxelGenerator::GetDensityWithParams(float WorldX, float WorldY, float Wo
|
|||||||
const int32 ActiveCacheSlots = FMath::Max(
|
const int32 ActiveCacheSlots = FMath::Max(
|
||||||
FMath::Clamp(GVoxelForgeRoomGraphCacheSlots, 1, 4),
|
FMath::Clamp(GVoxelForgeRoomGraphCacheSlots, 1, 4),
|
||||||
bNeedsTwoStrataWindows ? 2 : 1);
|
bNeedsTwoStrataWindows ? 2 : 1);
|
||||||
|
auto& RoomGraphCacheSlots = RoomGraphCacheStorage.Get();
|
||||||
FRoomGraphCacheSlot* CacheSlot = nullptr;
|
FRoomGraphCacheSlot* CacheSlot = nullptr;
|
||||||
FRoomGraphCacheSlot* EvictionSlot = &RoomGraphCacheSlots[0];
|
FRoomGraphCacheSlot* EvictionSlot = &RoomGraphCacheSlots[0];
|
||||||
for (int32 SlotIndex = 0; SlotIndex < ActiveCacheSlots; ++SlotIndex)
|
for (int32 SlotIndex = 0; SlotIndex < ActiveCacheSlots; ++SlotIndex)
|
||||||
@@ -7349,7 +7360,7 @@ EVoxelTileClass UVoxelGenerator::ClassifyTileUncached(
|
|||||||
{
|
{
|
||||||
FSurfSlot& S = Slots[s];
|
FSurfSlot& S = Slots[s];
|
||||||
if (S.InteriorZ.Num() == 0) continue;
|
if (S.InteriorZ.Num() == 0) continue;
|
||||||
FSurfaceColumnBox& Box = GSurfColCache.Acquire(
|
FSurfaceColumnBox& Box = GSurfColCache.Get().Acquire(
|
||||||
Xi, Yi, S.StrateKey, Seed, TC_LayoutVersion,
|
Xi, Yi, S.StrateKey, Seed, TC_LayoutVersion,
|
||||||
TC_OwnerId, TC_ManagerLifetimeId);
|
TC_OwnerId, TC_ManagerLifetimeId);
|
||||||
const int32 CI = (Yi - Box.BaseY) * FSurfaceColumnBox::Dim + (Xi - Box.BaseX);
|
const int32 CI = (Yi - Box.BaseY) * FSurfaceColumnBox::Dim + (Xi - Box.BaseX);
|
||||||
|
|||||||
@@ -120,13 +120,16 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
int64* OutDensitySampleCount,
|
int64* OutDensitySampleCount,
|
||||||
FVoxelSharedDensityGrid* OutPreEditDensityGrid,
|
FVoxelSharedDensityGrid* OutPreEditDensityGrid,
|
||||||
const FVoxelSharedDensityGrid* InSharedDensityGrid,
|
const FVoxelSharedDensityGrid* InSharedDensityGrid,
|
||||||
std::vector<float>* OutDebugDensitySamples)
|
std::vector<float>* OutDebugDensitySamples,
|
||||||
|
FVoxelMarchingCubesStageTimings* OutStageTimings)
|
||||||
{
|
{
|
||||||
TRACE_CPUPROFILER_EVENT_SCOPE(VoxelForge_MesherGenerateMesh);
|
TRACE_CPUPROFILER_EVENT_SCOPE(VoxelForge_MesherGenerateMesh);
|
||||||
|
const uint64 StageMesherStartCycles=OutStageTimings?FPlatformTime::Cycles64():0;
|
||||||
FVoxelMeshData MeshData;
|
FVoxelMeshData MeshData;
|
||||||
if (OutCaptureGrid) { OutCaptureGrid->Reset(); }
|
if (OutCaptureGrid) { OutCaptureGrid->Reset(); }
|
||||||
if (OutPreEditDensityGrid) { OutPreEditDensityGrid->Reset(); }
|
if (OutPreEditDensityGrid) { OutPreEditDensityGrid->Reset(); }
|
||||||
if (OutDensitySampleCount) { *OutDensitySampleCount = 0; }
|
if (OutDensitySampleCount) { *OutDensitySampleCount = 0; }
|
||||||
|
if (OutStageTimings) { *OutStageTimings = FVoxelMarchingCubesStageTimings{}; }
|
||||||
if (OutDebugDensitySamples) { OutDebugDensitySamples->clear(); }
|
if (OutDebugDensitySamples) { OutDebugDensitySamples->clear(); }
|
||||||
if (!Generator) return MeshData;
|
if (!Generator) return MeshData;
|
||||||
const bool bEmitUV = !bStandaloneSkipUvAndColors && !bStandaloneSkipUV;
|
const bool bEmitUV = !bStandaloneSkipUvAndColors && !bStandaloneSkipUV;
|
||||||
@@ -851,6 +854,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
}
|
}
|
||||||
// Bande de strate : seules les rangées Z réellement lues (cellules CzLo..CzHi + marges de
|
// Bande de strate : seules les rangées Z réellement lues (cellules CzLo..CzHi + marges de
|
||||||
// gradient) sont échantillonnées — le reste du tampon reste non initialisé et non lu.
|
// gradient) sont échantillonnées — le reste du tampon reste non initialisé et non lu.
|
||||||
|
const uint64 StageDensityGridStartCycles=OutStageTimings?FPlatformTime::Cycles64():0;
|
||||||
VoxelDensityProfile::FScopedTimer MesherDensityGridTimer(
|
VoxelDensityProfile::FScopedTimer MesherDensityGridTimer(
|
||||||
VoxelDensityProfile::EBucket::MesherDensityGrid);
|
VoxelDensityProfile::EBucket::MesherDensityGrid);
|
||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
@@ -1250,6 +1254,10 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
MesherDensityGridTimer.End();
|
MesherDensityGridTimer.End();
|
||||||
|
if(OutStageTimings)
|
||||||
|
OutStageTimings->DensityGridMilliseconds=static_cast<double>(
|
||||||
|
FPlatformTime::Cycles64()-StageDensityGridStartCycles)
|
||||||
|
*FPlatformTime::GetSecondsPerCycle64()*1000.0;
|
||||||
|
|
||||||
if (bUseProofBlocks)
|
if (bUseProofBlocks)
|
||||||
{
|
{
|
||||||
@@ -1345,6 +1353,22 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
{
|
{
|
||||||
return DensityGrid[((gz + 1) * MDim + (gy + 1)) * MDim + (gx + 1)];
|
return DensityGrid[((gz + 1) * MDim + (gy + 1)) * MDim + (gx + 1)];
|
||||||
};
|
};
|
||||||
|
// Reuse exact grid-corner gradients between incident cells within this tile.
|
||||||
|
// Reutiliser les gradients exacts des coins entre cellules voisines de cette tuile.
|
||||||
|
static thread_local TArray<FVector> GradientMemo;
|
||||||
|
static thread_local TArray<uint8> GradientMemoValid;
|
||||||
|
const bool bUseGradientMemo=bStandaloneEnableGradientMemoization
|
||||||
|
&&ShapeWorldContext!=nullptr&&Step==1;
|
||||||
|
if(bUseGradientMemo)
|
||||||
|
{
|
||||||
|
GradientMemo.SetNumUninitialized(DensityGrid.Num());
|
||||||
|
GradientMemoValid.SetNumUninitialized(DensityGrid.Num());
|
||||||
|
// Clear every tile even when the reused TArray keeps the same length.
|
||||||
|
// Effacer chaque tuile meme si le TArray reutilise conserve la meme taille.
|
||||||
|
if(GradientMemoValid.Num()>0)
|
||||||
|
FMemory::Memzero(GradientMemoValid.GetData(),
|
||||||
|
static_cast<SIZE_T>(GradientMemoValid.Num())*sizeof(uint8));
|
||||||
|
}
|
||||||
auto SampleGradientG = [&](int32 gx, int32 gy, int32 gz) -> float
|
auto SampleGradientG = [&](int32 gx, int32 gy, int32 gz) -> float
|
||||||
{
|
{
|
||||||
const float Cached = SampleG(gx, gy, gz);
|
const float Cached = SampleG(gx, gy, gz);
|
||||||
@@ -1353,6 +1377,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
{
|
{
|
||||||
return Cached;
|
return Cached;
|
||||||
}
|
}
|
||||||
|
if(OutStageTimings)++OutStageTimings->GradientFallbackDensityCalls;
|
||||||
return ShapeWorldContext->DensityAtUnclamped(
|
return ShapeWorldContext->DensityAtUnclamped(
|
||||||
static_cast<float>(OriginVoxels.X + gx * Step),
|
static_cast<float>(OriginVoxels.X + gx * Step),
|
||||||
static_cast<float>(OriginVoxels.Y + gy * Step),
|
static_cast<float>(OriginVoxels.Y + gy * Step),
|
||||||
@@ -1360,11 +1385,23 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
};
|
};
|
||||||
auto GradAt = [&](int32 gx, int32 gy, int32 gz) -> FVector
|
auto GradAt = [&](int32 gx, int32 gy, int32 gz) -> FVector
|
||||||
{
|
{
|
||||||
|
const int32 CacheIndex=((gz+1)*MDim+(gy+1))*MDim+(gx+1);
|
||||||
|
if(bUseGradientMemo&&GradientMemoValid[CacheIndex]!=0)
|
||||||
|
{
|
||||||
|
if(OutStageTimings)++OutStageTimings->GradientMemoHits;
|
||||||
|
return GradientMemo[CacheIndex];
|
||||||
|
}
|
||||||
// Densité négative=solide, positive=air → le gradient pointe vers l'air (sortant).
|
// Densité négative=solide, positive=air → le gradient pointe vers l'air (sortant).
|
||||||
return FVector(
|
const FVector Gradient(
|
||||||
SampleGradientG(gx + 1, gy, gz) - SampleGradientG(gx - 1, gy, gz),
|
SampleGradientG(gx + 1, gy, gz) - SampleGradientG(gx - 1, gy, gz),
|
||||||
SampleGradientG(gx, gy + 1, gz) - SampleGradientG(gx, gy - 1, gz),
|
SampleGradientG(gx, gy + 1, gz) - SampleGradientG(gx, gy - 1, gz),
|
||||||
SampleGradientG(gx, gy, gz + 1) - SampleGradientG(gx, gy, gz - 1));
|
SampleGradientG(gx, gy, gz + 1) - SampleGradientG(gx, gy, gz - 1));
|
||||||
|
if(bUseGradientMemo)
|
||||||
|
{
|
||||||
|
GradientMemo[CacheIndex]=Gradient;
|
||||||
|
GradientMemoValid[CacheIndex]=1;
|
||||||
|
}
|
||||||
|
return Gradient;
|
||||||
};
|
};
|
||||||
|
|
||||||
// DC is limited to tagged LOD0 patches. Coarse tiles and a connected patch that reaches a
|
// DC is limited to tagged LOD0 patches. Coarse tiles and a connected patch that reaches a
|
||||||
@@ -1401,8 +1438,12 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
GroundTris.Reset();
|
GroundTris.Reset();
|
||||||
CapTris.Reset();
|
CapTris.Reset();
|
||||||
const bool bProfileMesher = VoxelDensityProfile::IsCycleTimingEnabled();
|
const bool bProfileMesher = VoxelDensityProfile::IsCycleTimingEnabled();
|
||||||
|
const bool bAuditMesherStages=OutStageTimings!=nullptr;
|
||||||
uint64 CellClassificationCalls = 0;
|
uint64 CellClassificationCalls = 0;
|
||||||
uint64 SurfaceCellCalls = 0;
|
uint64 SurfaceCellCalls = 0;
|
||||||
|
uint64 AuditCellClassificationCycles=0,AuditGradientCycles=0;
|
||||||
|
uint64 AuditInterpolationCycles=0,AuditDedupStreamCycles=0;
|
||||||
|
uint64 AuditGradientSamples=0,AuditInterpolationSamples=0,AuditDedupStreamSamples=0;
|
||||||
uint8 CaseIndexRow[CHUNK_SIZE]{};
|
uint8 CaseIndexRow[CHUNK_SIZE]{};
|
||||||
uint8 SurfaceRow[CHUNK_SIZE]{};
|
uint8 SurfaceRow[CHUNK_SIZE]{};
|
||||||
uint8 SampleClassificationRow[CHUNK_SIZE]{};
|
uint8 SampleClassificationRow[CHUNK_SIZE]{};
|
||||||
@@ -1413,7 +1454,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
{
|
{
|
||||||
if (ShouldAbortWork()) return FVoxelMeshData();
|
if (ShouldAbortWork()) return FVoxelMeshData();
|
||||||
FMemory::Memzero(SampleClassificationRow, sizeof(SampleClassificationRow));
|
FMemory::Memzero(SampleClassificationRow, sizeof(SampleClassificationRow));
|
||||||
const uint64 ClassificationRowStart = bProfileMesher
|
const uint64 ClassificationRowStart = (bProfileMesher||bAuditMesherStages)
|
||||||
? FPlatformTime::Cycles64() : 0;
|
? FPlatformTime::Cycles64() : 0;
|
||||||
int32 ClassificationRowCalls = 0;
|
int32 ClassificationRowCalls = 0;
|
||||||
for (int32 GroupX = 0; GroupX < CellsPerAxis; GroupX += 8)
|
for (int32 GroupX = 0; GroupX < CellsPerAxis; GroupX += 8)
|
||||||
@@ -1454,9 +1495,10 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
}
|
}
|
||||||
CaseIndexRow[CellX] = static_cast<uint8>(CaseIndex);
|
CaseIndexRow[CellX] = static_cast<uint8>(CaseIndex);
|
||||||
SurfaceRow[CellX] = MCEdgeTable[CaseIndex] != 0;
|
SurfaceRow[CellX] = MCEdgeTable[CaseIndex] != 0;
|
||||||
SampleClassificationRow[CellX] = bProfileMesher
|
SampleClassificationRow[CellX] =
|
||||||
&& VoxelDensityProfile::ShouldSample(
|
(bProfileMesher&&VoxelDensityProfile::ShouldSample(
|
||||||
VoxelDensityProfile::EBucket::MesherCellClassification);
|
VoxelDensityProfile::EBucket::MesherCellClassification))
|
||||||
|
||(bAuditMesherStages&&(CellClassificationCalls%8u)==0u);
|
||||||
++ClassificationRowCalls;
|
++ClassificationRowCalls;
|
||||||
++CellClassificationCalls;
|
++CellClassificationCalls;
|
||||||
}
|
}
|
||||||
@@ -1477,26 +1519,31 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
}
|
}
|
||||||
CaseIndexRow[CellX] = static_cast<uint8>(CaseIndex);
|
CaseIndexRow[CellX] = static_cast<uint8>(CaseIndex);
|
||||||
SurfaceRow[CellX] = MCEdgeTable[CaseIndex] != 0;
|
SurfaceRow[CellX] = MCEdgeTable[CaseIndex] != 0;
|
||||||
SampleClassificationRow[CellX] = bProfileMesher
|
SampleClassificationRow[CellX] =
|
||||||
&& VoxelDensityProfile::ShouldSample(
|
(bProfileMesher&&VoxelDensityProfile::ShouldSample(
|
||||||
VoxelDensityProfile::EBucket::MesherCellClassification);
|
VoxelDensityProfile::EBucket::MesherCellClassification))
|
||||||
|
||(bAuditMesherStages&&(CellClassificationCalls%8u)==0u);
|
||||||
++ClassificationRowCalls;
|
++ClassificationRowCalls;
|
||||||
++CellClassificationCalls;
|
++CellClassificationCalls;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bProfileMesher && ClassificationRowCalls > 0)
|
if ((bProfileMesher||bAuditMesherStages) && ClassificationRowCalls > 0)
|
||||||
{
|
{
|
||||||
const uint64 RowCycles = FPlatformTime::Cycles64() - ClassificationRowStart;
|
const uint64 RowCycles = FPlatformTime::Cycles64() - ClassificationRowStart;
|
||||||
const uint64 PerCellCycles = RowCycles
|
if(bAuditMesherStages)AuditCellClassificationCycles+=RowCycles;
|
||||||
/ static_cast<uint64>(ClassificationRowCalls);
|
if(bProfileMesher)
|
||||||
for (int32 cx = 0; cx < CellsPerAxis; ++cx)
|
|
||||||
{
|
{
|
||||||
if (SampleClassificationRow[cx])
|
const uint64 PerCellCycles = RowCycles
|
||||||
|
/ static_cast<uint64>(ClassificationRowCalls);
|
||||||
|
for (int32 cx = 0; cx < CellsPerAxis; ++cx)
|
||||||
{
|
{
|
||||||
VoxelDensityProfile::AddSampledMeasurement(
|
if (SampleClassificationRow[cx])
|
||||||
VoxelDensityProfile::EBucket::MesherCellClassification,
|
{
|
||||||
PerCellCycles);
|
VoxelDensityProfile::AddSampledMeasurement(
|
||||||
|
VoxelDensityProfile::EBucket::MesherCellClassification,
|
||||||
|
PerCellCycles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1537,9 +1584,11 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
}
|
}
|
||||||
if (bSampleCell)
|
if (bSampleCell)
|
||||||
{
|
{
|
||||||
VoxelDensityProfile::AddSampledMeasurement(
|
const uint64 StageCycles=FPlatformTime::Cycles64()-GradientStart;
|
||||||
VoxelDensityProfile::EBucket::MesherGradientNormals,
|
if(bProfileMesher)VoxelDensityProfile::AddSampledMeasurement(
|
||||||
FPlatformTime::Cycles64() - GradientStart);
|
VoxelDensityProfile::EBucket::MesherGradientNormals,StageCycles);
|
||||||
|
if(bAuditMesherStages)
|
||||||
|
{AuditGradientCycles+=StageCycles;++AuditGradientSamples;}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interpolation des positions + normales sur les arêtes traversées. t = point de
|
// Interpolation des positions + normales sur les arêtes traversées. t = point de
|
||||||
@@ -1563,6 +1612,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
if(ShapeWorldContext&&Step==1&&T>=0.375f&&T<=0.625f)
|
if(ShapeWorldContext&&Step==1&&T>=0.375f&&T<=0.625f)
|
||||||
{
|
{
|
||||||
const FVector Midpoint=(Positions[A]+Positions[B])*0.5f;
|
const FVector Midpoint=(Positions[A]+Positions[B])*0.5f;
|
||||||
|
if(OutStageTimings)++OutStageTimings->EdgeMidpointDensityCalls;
|
||||||
const float MidDensity=ShapeWorldContext->DensityAtUnclamped(
|
const float MidDensity=ShapeWorldContext->DensityAtUnclamped(
|
||||||
Midpoint.X/GeometryVoxelSize,Midpoint.Y/GeometryVoxelSize,
|
Midpoint.X/GeometryVoxelSize,Midpoint.Y/GeometryVoxelSize,
|
||||||
Midpoint.Z/GeometryVoxelSize);
|
Midpoint.Z/GeometryVoxelSize);
|
||||||
@@ -1611,9 +1661,11 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
}
|
}
|
||||||
if (bSampleCell)
|
if (bSampleCell)
|
||||||
{
|
{
|
||||||
VoxelDensityProfile::AddSampledMeasurement(
|
const uint64 StageCycles=FPlatformTime::Cycles64()-VertexInterpolationStart;
|
||||||
VoxelDensityProfile::EBucket::MesherVertexInterpolation,
|
if(bProfileMesher)VoxelDensityProfile::AddSampledMeasurement(
|
||||||
FPlatformTime::Cycles64() - VertexInterpolationStart);
|
VoxelDensityProfile::EBucket::MesherVertexInterpolation,StageCycles);
|
||||||
|
if(bAuditMesherStages)
|
||||||
|
{AuditInterpolationCycles+=StageCycles;++AuditInterpolationSamples;}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Génère les triangles avec vertices dédupliqués.
|
// Génère les triangles avec vertices dédupliqués.
|
||||||
@@ -1651,9 +1703,11 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
}
|
}
|
||||||
if (bSampleCell)
|
if (bSampleCell)
|
||||||
{
|
{
|
||||||
VoxelDensityProfile::AddSampledMeasurement(
|
const uint64 StageCycles=FPlatformTime::Cycles64()-StreamBuildingStart;
|
||||||
VoxelDensityProfile::EBucket::MesherStreamBuilding,
|
if(bProfileMesher)VoxelDensityProfile::AddSampledMeasurement(
|
||||||
FPlatformTime::Cycles64() - StreamBuildingStart);
|
VoxelDensityProfile::EBucket::MesherStreamBuilding,StageCycles);
|
||||||
|
if(bAuditMesherStages)
|
||||||
|
{AuditDedupStreamCycles+=StageCycles;++AuditDedupStreamSamples;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1714,6 +1768,7 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
const int32 GroundSurfaceTriangleCount=GroundTris.Num()/3;
|
const int32 GroundSurfaceTriangleCount=GroundTris.Num()/3;
|
||||||
const int32 CapSurfaceTriangleCount=CapTris.Num()/3;
|
const int32 CapSurfaceTriangleCount=CapTris.Num()/3;
|
||||||
TArray<uint8> GroundSkirtFaceMasks,CapSkirtFaceMasks;
|
TArray<uint8> GroundSkirtFaceMasks,CapSkirtFaceMasks;
|
||||||
|
const uint64 SkirtStageStartCycles=OutStageTimings?FPlatformTime::Cycles64():0;
|
||||||
if (bGenerateSkirts && (GroundTris.Num() + CapTris.Num()) > 0)
|
if (bGenerateSkirts && (GroundTris.Num() + CapTris.Num()) > 0)
|
||||||
{
|
{
|
||||||
const float ExtentCm = (float)(CellsPerAxis * Step) * GeometryVoxelSize;
|
const float ExtentCm = (float)(CellsPerAxis * Step) * GeometryVoxelSize;
|
||||||
@@ -1953,6 +2008,10 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
EmitSkirts(GroundTris,GroundSkirtFaceMasks);
|
EmitSkirts(GroundTris,GroundSkirtFaceMasks);
|
||||||
EmitSkirts(CapTris,CapSkirtFaceMasks);
|
EmitSkirts(CapTris,CapSkirtFaceMasks);
|
||||||
}
|
}
|
||||||
|
if(OutStageTimings)
|
||||||
|
OutStageTimings->SkirtMilliseconds=static_cast<double>(
|
||||||
|
FPlatformTime::Cycles64()-SkirtStageStartCycles)
|
||||||
|
*FPlatformTime::GetSecondsPerCycle64()*1000.0;
|
||||||
|
|
||||||
// F17 — concatène sol PUIS sky-cap : un run d'indices contigu par polygroup (voir
|
// F17 — concatène sol PUIS sky-cap : un run d'indices contigu par polygroup (voir
|
||||||
// FVoxelMeshData::NumCeilingTriangles). Mêmes triangles qu'avant, seul l'ordre change.
|
// FVoxelMeshData::NumCeilingTriangles). Mêmes triangles qu'avant, seul l'ordre change.
|
||||||
@@ -1989,5 +2048,34 @@ FVoxelMeshData UVoxelMarchingCubesMesher::GenerateMesh(FIntVector OriginVoxels,
|
|||||||
OutputAllocatedBytes);
|
OutputAllocatedBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(OutStageTimings)
|
||||||
|
{
|
||||||
|
const double CycleToMs=FPlatformTime::GetSecondsPerCycle64()*1000.0;
|
||||||
|
const auto ScaleSampledCycles=[CycleToMs](uint64 Cycles,uint64 Samples,uint64 Calls)
|
||||||
|
{
|
||||||
|
return Samples>0?static_cast<double>(Cycles)*static_cast<double>(Calls)
|
||||||
|
/static_cast<double>(Samples)*CycleToMs:0.0;
|
||||||
|
};
|
||||||
|
OutStageTimings->CellClassificationMilliseconds=
|
||||||
|
static_cast<double>(AuditCellClassificationCycles)*CycleToMs;
|
||||||
|
OutStageTimings->GradientNormalsMilliseconds=ScaleSampledCycles(
|
||||||
|
AuditGradientCycles,AuditGradientSamples,SurfaceCellCalls);
|
||||||
|
OutStageTimings->EdgeInterpolationMilliseconds=ScaleSampledCycles(
|
||||||
|
AuditInterpolationCycles,AuditInterpolationSamples,SurfaceCellCalls);
|
||||||
|
OutStageTimings->VertexDedupStreamMilliseconds=ScaleSampledCycles(
|
||||||
|
AuditDedupStreamCycles,AuditDedupStreamSamples,SurfaceCellCalls);
|
||||||
|
OutStageTimings->SkirtMilliseconds=std::max(0.0,
|
||||||
|
OutStageTimings->SkirtMilliseconds);
|
||||||
|
const double TotalMilliseconds=static_cast<double>(
|
||||||
|
FPlatformTime::Cycles64()-StageMesherStartCycles)*CycleToMs;
|
||||||
|
OutStageTimings->OtherMilliseconds=FMath::Max(0.0,TotalMilliseconds
|
||||||
|
-OutStageTimings->DensityGridMilliseconds
|
||||||
|
-OutStageTimings->CellClassificationMilliseconds
|
||||||
|
-OutStageTimings->GradientNormalsMilliseconds
|
||||||
|
-OutStageTimings->EdgeInterpolationMilliseconds
|
||||||
|
-OutStageTimings->VertexDedupStreamMilliseconds
|
||||||
|
-OutStageTimings->SkirtMilliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
return MeshData;
|
return MeshData;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
// VoxelStrateManager.cpp
|
// VoxelStrateManager.cpp
|
||||||
// Runtime strate layout generation and queries.
|
// Runtime strate layout generation and queries.
|
||||||
|
|
||||||
|
#include "VoxelForgeCore/ThreadLocalStorage.h"
|
||||||
#include "VoxelStrateManager.h"
|
#include "VoxelStrateManager.h"
|
||||||
#include "VoxelSettings.h"
|
#include "VoxelSettings.h"
|
||||||
#include "VoxelSeasonAsset.h"
|
#include "VoxelSeasonAsset.h"
|
||||||
@@ -435,8 +436,8 @@ namespace
|
|||||||
|
|
||||||
FVoxelPassageReliefCache& VF_GetPassageReliefCache()
|
FVoxelPassageReliefCache& VF_GetPassageReliefCache()
|
||||||
{
|
{
|
||||||
thread_local FVoxelPassageReliefCache Cache;
|
thread_local VoxelForgeCoreThreadLocal::FLazy<FVoxelPassageReliefCache> Cache;
|
||||||
return Cache;
|
return Cache.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE float VF_ComputePassageReliefNoise(
|
FORCEINLINE float VF_ComputePassageReliefNoise(
|
||||||
|
|||||||
@@ -41,6 +41,22 @@ struct FVoxelSharedDensityGrid
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Optional, sampled timing output for the research audit; null in production calls.
|
||||||
|
// Mesures echantillonnees facultatives pour l'audit; pointeur nul en production.
|
||||||
|
struct FVoxelMarchingCubesStageTimings
|
||||||
|
{
|
||||||
|
double DensityGridMilliseconds = 0.0;
|
||||||
|
double CellClassificationMilliseconds = 0.0;
|
||||||
|
double GradientNormalsMilliseconds = 0.0;
|
||||||
|
double EdgeInterpolationMilliseconds = 0.0;
|
||||||
|
double VertexDedupStreamMilliseconds = 0.0;
|
||||||
|
double SkirtMilliseconds = 0.0;
|
||||||
|
double OtherMilliseconds = 0.0;
|
||||||
|
uint64 GradientFallbackDensityCalls = 0;
|
||||||
|
uint64 EdgeMidpointDensityCalls = 0;
|
||||||
|
uint64 GradientMemoHits = 0;
|
||||||
|
};
|
||||||
|
|
||||||
// Stable plan data copied onto one worker-owned mesher for hybrid LOD0 generation.
|
// Stable plan data copied onto one worker-owned mesher for hybrid LOD0 generation.
|
||||||
// Donnees stables du plan copiees dans un mailleur de worker pour le mode hybride LOD0.
|
// Donnees stables du plan copiees dans un mailleur de worker pour le mode hybride LOD0.
|
||||||
struct FVoxelHybridSharpFeatureBox
|
struct FVoxelHybridSharpFeatureBox
|
||||||
@@ -91,7 +107,8 @@ public:
|
|||||||
int64* OutDensitySampleCount = nullptr,
|
int64* OutDensitySampleCount = nullptr,
|
||||||
FVoxelSharedDensityGrid* OutPreEditDensityGrid = nullptr,
|
FVoxelSharedDensityGrid* OutPreEditDensityGrid = nullptr,
|
||||||
const FVoxelSharedDensityGrid* InSharedDensityGrid = nullptr,
|
const FVoxelSharedDensityGrid* InSharedDensityGrid = nullptr,
|
||||||
std::vector<float>* OutDebugDensitySamples = nullptr);
|
std::vector<float>* OutDebugDensitySamples = nullptr,
|
||||||
|
FVoxelMarchingCubesStageTimings* OutStageTimings = nullptr);
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// SERVICES (injectés par AVoxelWorld)
|
// SERVICES (injectés par AVoxelWorld)
|
||||||
@@ -161,6 +178,7 @@ public:
|
|||||||
bool bStandaloneSkipUV = false;
|
bool bStandaloneSkipUV = false;
|
||||||
bool bStandaloneSkipColors = false;
|
bool bStandaloneSkipColors = false;
|
||||||
bool bStandaloneSkipMaterialGroups = false;
|
bool bStandaloneSkipMaterialGroups = false;
|
||||||
|
bool bStandaloneEnableGradientMemoization = true;
|
||||||
|
|
||||||
// Seuil de l'isosurface dans le champ de densité.
|
// Seuil de l'isosurface dans le champ de densité.
|
||||||
// Convention MC: densité < IsoLevel = solide, >= = air.
|
// Convention MC: densité < IsoLevel = solide, >= = air.
|
||||||
|
|||||||
@@ -0,0 +1,530 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "OwnerWorldLoader.h"
|
||||||
|
#include "VoxelForgeCore/VoxelForgeCore.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <limits>
|
||||||
|
#include <numeric>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace StandaloneWorldAssemblyPrototype
|
||||||
|
{
|
||||||
|
inline std::int64_t WorldAssemblyFixed(double voxels)
|
||||||
|
{return static_cast<std::int64_t>(std::llround(voxels*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel));}
|
||||||
|
|
||||||
|
inline std::int64_t WorldAssemblyQ16(double value)
|
||||||
|
{return static_cast<std::int64_t>(std::llround(value*65536.0));}
|
||||||
|
|
||||||
|
inline std::int64_t WorldAssemblyWavelength(double frequency,double fallbackVoxels)
|
||||||
|
{
|
||||||
|
const double wavelength=std::isfinite(frequency)&&frequency>0.0?1.0/frequency:fallbackVoxels;
|
||||||
|
return std::max<std::int64_t>(1,WorldAssemblyFixed(wavelength));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64 WorldAssemblyFeatureId(uint32 seed,int64 x,int64 y,uint32 kind)
|
||||||
|
{
|
||||||
|
uint64 hash=14695981039346656037ull;
|
||||||
|
const auto add=[&](uint64 value,int bytes)
|
||||||
|
{
|
||||||
|
for(int i=0;i<bytes;++i){hash^=static_cast<uint8>(value>>(8*i));hash*=1099511628211ull;}
|
||||||
|
};
|
||||||
|
add(seed,4);add(static_cast<uint64>(x),8);add(static_cast<uint64>(y),8);add(kind,4);
|
||||||
|
return hash?hash:1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool BuildFiniteStrateRoute(VoxelForgeCore::WorldAssemblyRecipeV1& recipe,
|
||||||
|
VoxelForgeCore::WorldAssemblyStratumPlanV1& stratum,std::uint64_t& tested,
|
||||||
|
std::uint64_t& gradeRejected,std::uint64_t& sweepRejected,std::string& error)
|
||||||
|
{
|
||||||
|
using namespace VoxelForgeCore;
|
||||||
|
constexpr std::int64_t PlayerRadiusQ=348; // 0.34 m in Core's 0.25 m voxel scale.
|
||||||
|
constexpr std::int64_t PlayerHeightQ=1802; // 1.76 m in Core's 0.25 m voxel scale.
|
||||||
|
constexpr std::int64_t HalfHeightQ=PlayerHeightQ/2;
|
||||||
|
constexpr std::int64_t StepQ=128; // 0.5 Core voxel, finer than the density lattice.
|
||||||
|
constexpr std::int64_t ProbeRadiusQ=174;
|
||||||
|
constexpr std::int64_t SupportDepthQ=256;
|
||||||
|
constexpr std::int64_t GradeQ16=17560; // tan(15 degrees), rounded upward.
|
||||||
|
constexpr std::int64_t RouteRadiusQ=4*WorldAssemblySubvoxelsPerVoxel;
|
||||||
|
struct Direction {std::int32_t x,y;};
|
||||||
|
constexpr std::array<Direction,8> directions{{
|
||||||
|
{65536,0},{46341,46341},{0,65536},{-46341,46341},
|
||||||
|
{-65536,0},{-46341,-46341},{0,-65536},{46341,-46341}}};
|
||||||
|
struct Candidate
|
||||||
|
{
|
||||||
|
std::int64_t score=0;
|
||||||
|
std::int32_t centerX=0,centerY=0,direction=0;
|
||||||
|
std::vector<WorldAssemblyRoutePointV1> points;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto& constraints=stratum.routeConstraints;
|
||||||
|
constraints.version=1;
|
||||||
|
constraints.capsuleRadiusSubvoxels=PlayerRadiusQ;
|
||||||
|
constraints.capsuleHeightSubvoxels=PlayerHeightQ;
|
||||||
|
constraints.maximumGradeQ16=GradeQ16;
|
||||||
|
constraints.sweepSpacingSubvoxels=StepQ;
|
||||||
|
constraints.supportProbeRadiusSubvoxels=ProbeRadiusQ;
|
||||||
|
constraints.supportSearchDepthSubvoxels=SupportDepthQ;
|
||||||
|
constraints.minimumClearanceSubvoxels=8;
|
||||||
|
constraints.minimumSupportProbes=3;
|
||||||
|
|
||||||
|
const Heightfield2D finalField(recipe,stratum);
|
||||||
|
if(!finalField.isValid())
|
||||||
|
{error="route planner received an invalid final composed field";return false;}
|
||||||
|
std::vector<Candidate> candidates;
|
||||||
|
constexpr std::int32_t halfLength=128;
|
||||||
|
constexpr std::int32_t waypointSpacing=8;
|
||||||
|
for(std::int32_t centerY=-256;centerY<=256;centerY+=64)
|
||||||
|
for(std::int32_t centerX=-256;centerX<=256;centerX+=64)
|
||||||
|
for(std::int32_t directionIndex=0;directionIndex<static_cast<std::int32_t>(directions.size());++directionIndex)
|
||||||
|
{
|
||||||
|
Candidate candidate;
|
||||||
|
candidate.centerX=centerX;candidate.centerY=centerY;candidate.direction=directionIndex;
|
||||||
|
candidate.points.reserve(33);
|
||||||
|
std::int64_t previousGround=0,previousX=0,previousY=0;
|
||||||
|
bool gradePass=true;
|
||||||
|
for(std::int32_t index=0;index<=32;++index)
|
||||||
|
{
|
||||||
|
const std::int64_t along=(index-16)*waypointSpacing;
|
||||||
|
const std::int64_t x=centerX+std::llround(
|
||||||
|
static_cast<double>(along)*directions[directionIndex].x/65536.0);
|
||||||
|
const std::int64_t y=centerY+std::llround(
|
||||||
|
static_cast<double>(along)*directions[directionIndex].y/65536.0);
|
||||||
|
const auto column=finalField.point(WorldAssemblyFixed(static_cast<double>(x)),
|
||||||
|
WorldAssemblyFixed(static_cast<double>(y)),0);
|
||||||
|
const std::int64_t horizontalQ=static_cast<std::int64_t>(std::llround(
|
||||||
|
std::hypot(static_cast<double>(x-previousX),static_cast<double>(y-previousY))
|
||||||
|
*WorldAssemblySubvoxelsPerVoxel));
|
||||||
|
if(index>0)
|
||||||
|
{
|
||||||
|
const std::int64_t riseQ=std::abs(column.groundHeightSubvoxels-previousGround);
|
||||||
|
if(horizontalQ==0||riseQ*65536>horizontalQ*GradeQ16)
|
||||||
|
{gradePass=false;break;}
|
||||||
|
candidate.score+=riseQ*65536/std::max<std::int64_t>(1,horizontalQ);
|
||||||
|
}
|
||||||
|
WorldAssemblyRoutePointV1 point;
|
||||||
|
point.positionSubvoxels={WorldAssemblyFixed(static_cast<double>(x)),
|
||||||
|
WorldAssemblyFixed(static_cast<double>(y)),column.groundHeightSubvoxels+HalfHeightQ};
|
||||||
|
point.radiusSubvoxels=RouteRadiusQ;
|
||||||
|
point.stableFeatureId=WorldAssemblyFeatureId(recipe.seed,
|
||||||
|
static_cast<std::int64_t>(x),static_cast<std::int64_t>(y),
|
||||||
|
0x52540000u+static_cast<std::uint32_t>(index));
|
||||||
|
candidate.points.push_back(point);
|
||||||
|
previousGround=column.groundHeightSubvoxels;previousX=x;previousY=y;
|
||||||
|
}
|
||||||
|
++tested;
|
||||||
|
if(gradePass)candidates.push_back(std::move(candidate));
|
||||||
|
else ++gradeRejected;
|
||||||
|
}
|
||||||
|
std::stable_sort(candidates.begin(),candidates.end(),[](const Candidate& a,const Candidate& b)
|
||||||
|
{
|
||||||
|
if(a.score!=b.score)return a.score<b.score;
|
||||||
|
if(a.centerY!=b.centerY)return a.centerY<b.centerY;
|
||||||
|
if(a.centerX!=b.centerX)return a.centerX<b.centerX;
|
||||||
|
return a.direction<b.direction;
|
||||||
|
});
|
||||||
|
std::uint64_t sweepAttempt=0,repairAttempt=0;
|
||||||
|
VoxelForgeCore::WorldAssemblyRouteAuditResult lastAudit{};
|
||||||
|
for(auto& candidate:candidates)
|
||||||
|
{
|
||||||
|
stratum.route=candidate.points;
|
||||||
|
std::int64_t liftQ=0;
|
||||||
|
constexpr std::int64_t RepairStepQ=64;
|
||||||
|
constexpr std::int64_t MaximumRepairLiftQ=SupportDepthQ-RepairStepQ;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(liftQ>0)
|
||||||
|
for(std::size_t pointIndex=0;pointIndex<stratum.route.size();++pointIndex)
|
||||||
|
stratum.route[pointIndex].positionSubvoxels[2]
|
||||||
|
=candidate.points[pointIndex].positionSubvoxels[2]+liftQ;
|
||||||
|
const Heightfield2D candidateField(recipe,stratum);
|
||||||
|
const auto audit=AuditHeightfieldRoute(candidateField);
|
||||||
|
lastAudit=audit;
|
||||||
|
if(audit.passed)
|
||||||
|
{
|
||||||
|
if(liftQ>0)
|
||||||
|
std::printf("[WorldAssemblerRouteRepaired] uniform_lift_q=%lld support_limit_q=%lld\n",
|
||||||
|
static_cast<long long>(liftQ),static_cast<long long>(SupportDepthQ));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(audit.blockedCapsuleSamples==0||liftQ>=MaximumRepairLiftQ)break;
|
||||||
|
const std::int64_t needed=std::max<std::int64_t>(1,
|
||||||
|
constraints.minimumClearanceSubvoxels-audit.minimumClearanceSubvoxels);
|
||||||
|
const std::int64_t steps=(needed+RepairStepQ-1)/RepairStepQ;
|
||||||
|
const std::int64_t nextLift=std::max(liftQ+RepairStepQ,liftQ+steps*RepairStepQ);
|
||||||
|
if(nextLift>MaximumRepairLiftQ)break;
|
||||||
|
liftQ=nextLift;
|
||||||
|
++repairAttempt;
|
||||||
|
}
|
||||||
|
if(sweepAttempt<3)
|
||||||
|
std::printf("[WorldAssemblerRouteCandidateRejected] ordinal=%llu blocked=%llu unsupported=%llu grade_failures=%llu minimum_clearance_q=%lld\n",
|
||||||
|
static_cast<unsigned long long>(sweepAttempt),
|
||||||
|
static_cast<unsigned long long>(lastAudit.blockedCapsuleSamples),
|
||||||
|
static_cast<unsigned long long>(lastAudit.unsupportedCenterSamples),
|
||||||
|
static_cast<unsigned long long>(lastAudit.gradeFailures),
|
||||||
|
static_cast<long long>(lastAudit.minimumClearanceSubvoxels));
|
||||||
|
++sweepAttempt;
|
||||||
|
++sweepRejected;
|
||||||
|
}
|
||||||
|
std::printf("[WorldAssemblerRouteSearchFailed] tested=%llu grade_rejected=%llu sweepable_candidates=%llu sweep_rejected=%llu last_blocked=%llu last_unsupported=%llu last_grade_failures=%llu\n",
|
||||||
|
static_cast<unsigned long long>(tested),static_cast<unsigned long long>(gradeRejected),
|
||||||
|
static_cast<unsigned long long>(candidates.size()),static_cast<unsigned long long>(sweepRejected),
|
||||||
|
static_cast<unsigned long long>(lastAudit.blockedCapsuleSamples),
|
||||||
|
static_cast<unsigned long long>(lastAudit.unsupportedCenterSamples),
|
||||||
|
static_cast<unsigned long long>(lastAudit.gradeFailures));
|
||||||
|
std::printf("[WorldAssemblerRouteRepairSummary] repair_attempts=%llu\n",
|
||||||
|
static_cast<unsigned long long>(repairAttempt));
|
||||||
|
stratum.route.clear();
|
||||||
|
error="finite-strate route candidates failed the composed-field capsule and support sweep";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool AttachRound1WorldAssemblyPrototype(FStandaloneOwnerWorld& owner,VFJson::Value& root,
|
||||||
|
std::string& error,const std::string& manifestOutputPath,
|
||||||
|
VoxelForgeCore::WorldAssemblyManifest* outManifest=nullptr)
|
||||||
|
{
|
||||||
|
if(!owner.Manager||!owner.Generator)
|
||||||
|
{error="world assembler prototype needs the resolved standalone owner world";return false;}
|
||||||
|
int32 surfaceChunkZ=0,topChunkZ=0,bottomChunkZ=0;
|
||||||
|
bool foundSurface=false;
|
||||||
|
for(int32 chunkZ=1024;chunkZ>=-4096;--chunkZ)
|
||||||
|
{
|
||||||
|
if(owner.Manager->GetGeneratorTypeForChunk(FIntVector(0,0,chunkZ))
|
||||||
|
!=ECaveGeneratorType::SurfaceWorld)continue;
|
||||||
|
surfaceChunkZ=chunkZ;
|
||||||
|
foundSurface=owner.Manager->GetStrateChunkZBounds(chunkZ,topChunkZ,bottomChunkZ);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!foundSurface)
|
||||||
|
{error="world assembler prototype could not find a finite SurfaceWorld strate";return false;}
|
||||||
|
const FIntVector chunk(0,0,surfaceChunkZ);
|
||||||
|
const FSurfaceGenerationParams surface=owner.Manager->GetSurfaceParamsForChunk(chunk);
|
||||||
|
const FBiomeContext biomeContext=owner.Manager->GetBiomeContextForChunk(chunk);
|
||||||
|
const std::int64_t bottomVoxel=static_cast<std::int64_t>(bottomChunkZ)*CHUNK_SIZE;
|
||||||
|
const std::int64_t heightVoxels=static_cast<std::int64_t>(topChunkZ-bottomChunkZ+1)*CHUNK_SIZE;
|
||||||
|
const FBiomeMapParams& map=biomeContext.Map;
|
||||||
|
const UVoxelStrateDefinition* definition=owner.Manager->GetStrateForChunk(chunk);
|
||||||
|
|
||||||
|
VoxelForgeCore::WorldAssemblyManifest manifest;
|
||||||
|
auto& recipe=manifest.recipe;
|
||||||
|
recipe.seed=static_cast<uint32>(owner.Seed);
|
||||||
|
recipe.biomeCellSizeSubvoxels=WorldAssemblyFixed(map.CellSize);
|
||||||
|
recipe.biomeWarpSubvoxels=WorldAssemblyFixed(map.WarpStrength);
|
||||||
|
recipe.biomeWarpWavelengthSubvoxels=WorldAssemblyWavelength(map.WarpFrequency,556.0);
|
||||||
|
recipe.biomeBorderBlendSubvoxels=WorldAssemblyFixed(map.BorderBlend);
|
||||||
|
recipe.biomeClimateReliefWavelengthSubvoxels=WorldAssemblyWavelength(map.ReliefFrequency,3333.0);
|
||||||
|
recipe.biomeClimateMoistureWavelengthSubvoxels=WorldAssemblyWavelength(map.MoistureFrequency,2500.0);
|
||||||
|
recipe.biomeClimateReliefContrastQ16=WorldAssemblyQ16(map.ReliefContrast);
|
||||||
|
const auto makeProfile=[&](uint32 stableId,const FSurfaceGenerationParams& params,
|
||||||
|
const FBiomeResolved* climate)
|
||||||
|
{
|
||||||
|
VoxelForgeCore::WorldAssemblyBiomeProfileV1 profile;
|
||||||
|
profile.stableId=stableId;
|
||||||
|
profile.baseHeightSubvoxels=WorldAssemblyFixed(static_cast<double>(bottomVoxel)
|
||||||
|
+static_cast<double>(heightVoxels)*params.BaseGroundRelative);
|
||||||
|
profile.continentAmplitudeSubvoxels=WorldAssemblyFixed(params.ElevationRange);
|
||||||
|
profile.continentWavelengthSubvoxels=WorldAssemblyWavelength(params.ContinentFrequency,1000.0);
|
||||||
|
profile.mountainAmplitudeSubvoxels=WorldAssemblyFixed(params.ElevationRange*params.MountainStrength);
|
||||||
|
profile.mountainWavelengthSubvoxels=WorldAssemblyWavelength(params.MountainFrequency,500.0);
|
||||||
|
profile.detailAmplitudeSubvoxels=WorldAssemblyFixed(params.SurfaceRoughness);
|
||||||
|
profile.detailWavelengthSubvoxels=WorldAssemblyWavelength(params.DetailFrequency,25.0);
|
||||||
|
profile.reliefMinimumQ16=climate?WorldAssemblyQ16(climate->ReliefMin):0;
|
||||||
|
profile.reliefMaximumQ16=climate?WorldAssemblyQ16(climate->ReliefMax):65536;
|
||||||
|
profile.moistureMinimumQ16=climate?WorldAssemblyQ16(climate->MoistureMin):0;
|
||||||
|
profile.moistureMaximumQ16=climate?WorldAssemblyQ16(climate->MoistureMax):65536;
|
||||||
|
profile.reliefStrengthQ16=WorldAssemblyQ16(params.ReliefStrength);
|
||||||
|
profile.reliefContrastQ16=WorldAssemblyQ16(params.ReliefContrast);
|
||||||
|
profile.reliefWavelengthSubvoxels=WorldAssemblyWavelength(params.ReliefFrequency,667.0);
|
||||||
|
profile.heightWarpStrengthSubvoxels=WorldAssemblyFixed(params.HeightWarpStrength);
|
||||||
|
profile.heightWarpWavelengthSubvoxels=WorldAssemblyWavelength(params.HeightWarpFrequency,125.0);
|
||||||
|
profile.beachWidthSubvoxels=WorldAssemblyFixed(params.BeachWidth);
|
||||||
|
profile.cliffStrengthQ16=WorldAssemblyQ16(params.CliffStrength);
|
||||||
|
profile.cliffSlopeThresholdQ16=std::max<std::int64_t>(1,WorldAssemblyQ16(params.CliffSlopeThreshold));
|
||||||
|
profile.cliffSharpnessQ16=WorldAssemblyQ16(params.CliffSharpness);
|
||||||
|
profile.cliffSampleDistanceSubvoxels=WorldAssemblyFixed(std::max(0.5f,params.CliffSampleDist));
|
||||||
|
const double structuralAbsBound=static_cast<double>(params.ElevationRange)
|
||||||
|
+static_cast<double>(params.ElevationRange)*params.MountainStrength
|
||||||
|
+2.0*params.SurfaceRoughness;
|
||||||
|
const double cliffAbsBound=2.0*structuralAbsBound*params.CliffStrength*params.CliffSharpness;
|
||||||
|
profile.cliffMaximumDisplacementSubvoxels=WorldAssemblyFixed(params.CliffStrength>0.0f
|
||||||
|
?std::max(1.0,cliffAbsBound):0.0);
|
||||||
|
profile.hasCapProfile=true;
|
||||||
|
profile.capHeightSubvoxels=WorldAssemblyFixed(static_cast<double>(bottomVoxel)
|
||||||
|
+static_cast<double>(heightVoxels)*params.CeilingRelative);
|
||||||
|
profile.capWarpStrengthSubvoxels=WorldAssemblyFixed(params.CeilingWarpStrength);
|
||||||
|
profile.capWarpWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingWarpFrequency,100.0);
|
||||||
|
profile.capUndulationSubvoxels=WorldAssemblyFixed(params.CeilingUndulation);
|
||||||
|
profile.capWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingUndulationFrequency,500.0);
|
||||||
|
profile.capDetailAmplitudeSubvoxels=WorldAssemblyFixed(params.CeilingRoughness);
|
||||||
|
profile.capDetailWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingRoughnessFrequency,25.0);
|
||||||
|
profile.capRidgeAmplitudeSubvoxels=WorldAssemblyFixed(params.CeilingRidgeStrength);
|
||||||
|
profile.capRidgeWavelengthSubvoxels=WorldAssemblyWavelength(params.CeilingRidgeFrequency,50.0);
|
||||||
|
return profile;
|
||||||
|
};
|
||||||
|
if(biomeContext.IsValid()&&definition)
|
||||||
|
{
|
||||||
|
for(const FBiomeResolved& resolved:biomeContext.Biomes)
|
||||||
|
{
|
||||||
|
const UVoxelBiomeDefinition* biome=definition->Biomes.IsValidIndex(resolved.Index)
|
||||||
|
?definition->Biomes[resolved.Index]:nullptr;
|
||||||
|
FSurfaceGenerationParams params=surface;
|
||||||
|
if(biome&&biome->bOverrideTerrain&&biome->GeneratorType==ECaveGeneratorType::SurfaceWorld)
|
||||||
|
{
|
||||||
|
params=biome->SurfaceParams;
|
||||||
|
params.StrateTopWorldZ=surface.StrateTopWorldZ;
|
||||||
|
params.StrateBottomWorldZ=surface.StrateBottomWorldZ;
|
||||||
|
params.BoundarySealThickness=surface.BoundarySealThickness;
|
||||||
|
params.BaseDensity=surface.BaseDensity;
|
||||||
|
params.WaterLevelRelative=surface.WaterLevelRelative;
|
||||||
|
}
|
||||||
|
recipe.biomes.push_back(makeProfile(0x1001u+static_cast<uint32>(resolved.Index),params,&resolved));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(recipe.biomes.empty())recipe.biomes.push_back(makeProfile(0x1001u,surface,nullptr));
|
||||||
|
|
||||||
|
VoxelForgeCore::WorldAssemblyStratumPlanV1 stratum;
|
||||||
|
stratum.strateIndex=owner.Manager->GetStrateIndex(
|
||||||
|
static_cast<float>((static_cast<double>(surfaceChunkZ*CHUNK_SIZE+CHUNK_SIZE/2))*VOXEL_SIZE));
|
||||||
|
stratum.topChunkZ=topChunkZ;
|
||||||
|
stratum.bottomChunkZ=bottomChunkZ;
|
||||||
|
const double strateBottom=static_cast<double>(bottomVoxel);
|
||||||
|
const double strateHeight=static_cast<double>(heightVoxels);
|
||||||
|
stratum.capHeightSubvoxels=WorldAssemblyFixed(strateBottom+strateHeight*surface.CeilingRelative);
|
||||||
|
stratum.capUndulationSubvoxels=WorldAssemblyFixed(surface.CeilingUndulation);
|
||||||
|
stratum.capWavelengthSubvoxels=WorldAssemblyWavelength(surface.CeilingUndulationFrequency,250.0);
|
||||||
|
stratum.capDetailAmplitudeSubvoxels=WorldAssemblyFixed(surface.CeilingRoughness);
|
||||||
|
stratum.capDetailWavelengthSubvoxels=WorldAssemblyWavelength(surface.CeilingRoughnessFrequency,25.0);
|
||||||
|
stratum.capRidgeAmplitudeSubvoxels=WorldAssemblyFixed(surface.CeilingRidgeStrength);
|
||||||
|
stratum.capRidgeWavelengthSubvoxels=WorldAssemblyWavelength(surface.CeilingRidgeFrequency,50.0);
|
||||||
|
stratum.waterSurfaceSubvoxels=WorldAssemblyFixed(strateBottom+strateHeight*surface.WaterLevelRelative);
|
||||||
|
stratum.waterEnabled=definition&&definition->bHasWater&&surface.WaterLevelRelative>0.0f;
|
||||||
|
|
||||||
|
// Select a deterministic steep edge in the resolved owner field for a bounded shelf.
|
||||||
|
// Selection d'une pente deterministe dans le champ resolu pour une saillie bornee.
|
||||||
|
constexpr int probeSide=49,probeStep=32;
|
||||||
|
std::array<float,probeSide*probeSide> heights{};
|
||||||
|
std::array<uint8,probeSide*probeSide> valid{};
|
||||||
|
for(int y=0;y<probeSide;++y)
|
||||||
|
for(int x=0;x<probeSide;++x)
|
||||||
|
{
|
||||||
|
const float px=static_cast<float>((x-probeSide/2)*probeStep);
|
||||||
|
const float py=static_cast<float>((y-probeSide/2)*probeStep);
|
||||||
|
float ceiling=0.0f;
|
||||||
|
const std::size_t index=static_cast<std::size_t>(y)*probeSide+x;
|
||||||
|
valid[index]=owner.Generator->GetSurfaceHeightAt(px,py,topChunkZ,heights[index],ceiling)?1u:0u;
|
||||||
|
}
|
||||||
|
double steepest=0.0;int cliffX=0,cliffY=0;bool xAxis=true;int downhill=1;
|
||||||
|
for(int y=1;y<probeSide-1;++y)
|
||||||
|
for(int x=1;x<probeSide-1;++x)
|
||||||
|
{
|
||||||
|
const std::size_t center=static_cast<std::size_t>(y)*probeSide+x;
|
||||||
|
if(!valid[center]||!valid[center-1]||!valid[center+1]||!valid[center-probeSide]||!valid[center+probeSide])continue;
|
||||||
|
const double dx=static_cast<double>(heights[center+1]-heights[center-1]);
|
||||||
|
const double dy=static_cast<double>(heights[center+probeSide]-heights[center-probeSide]);
|
||||||
|
const double slope=(std::abs(dx)+std::abs(dy))/(4.0*probeStep);
|
||||||
|
if(slope>steepest){steepest=slope;cliffX=(x-probeSide/2)*probeStep;cliffY=(y-probeSide/2)*probeStep;
|
||||||
|
xAxis=std::abs(dx)>=std::abs(dy);downhill=(xAxis?dx:dy)>=0.0?-1:1;}
|
||||||
|
}
|
||||||
|
if(steepest>0.05)
|
||||||
|
{
|
||||||
|
float ground=0.0f,ceiling=0.0f;
|
||||||
|
if(owner.Generator->GetSurfaceHeightAt(static_cast<float>(cliffX),static_cast<float>(cliffY),
|
||||||
|
topChunkZ,ground,ceiling))
|
||||||
|
{
|
||||||
|
VoxelForgeCore::WorldAssemblyFeatureV1 shelf;
|
||||||
|
shelf.stableId=WorldAssemblyFeatureId(recipe.seed,cliffX,cliffY,0x4f564552u);
|
||||||
|
shelf.type=4;
|
||||||
|
constexpr int reach=72,width=36,height=64,feather=8;
|
||||||
|
const int dirX=xAxis?downhill:0,dirY=xAxis?0:downhill;
|
||||||
|
const int minX=xAxis?(dirX>0?cliffX-feather:cliffX-reach-feather)
|
||||||
|
:cliffX-width-feather;
|
||||||
|
const int maxX=xAxis?(dirX>0?cliffX+reach+feather:cliffX+feather)
|
||||||
|
:cliffX+width+feather;
|
||||||
|
const int minY=xAxis?cliffY-width-feather
|
||||||
|
:(dirY>0?cliffY-feather:cliffY-reach-feather);
|
||||||
|
const int maxY=xAxis?cliffY+width+feather
|
||||||
|
:(dirY>0?cliffY+reach+feather:cliffY+feather);
|
||||||
|
VoxelForgeCore::Heightfield2D baseField(recipe,stratum);
|
||||||
|
double lowestGround=std::numeric_limits<double>::infinity();
|
||||||
|
double highestGround=-std::numeric_limits<double>::infinity();
|
||||||
|
for(int sampleY=minY;sampleY<=maxY;sampleY+=4)
|
||||||
|
for(int sampleX=minX;sampleX<=maxX;sampleX+=4)
|
||||||
|
{
|
||||||
|
const auto sample=baseField.point(WorldAssemblyFixed(sampleX),
|
||||||
|
WorldAssemblyFixed(sampleY),0);
|
||||||
|
const double heightQ=static_cast<double>(sample.groundHeightSubvoxels)
|
||||||
|
/VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||||||
|
lowestGround=std::min(lowestGround,heightQ);
|
||||||
|
highestGround=std::max(highestGround,heightQ);
|
||||||
|
}
|
||||||
|
if(!std::isfinite(lowestGround)||!std::isfinite(highestGround))
|
||||||
|
{error="world assembler cliff shelf could not bound its terrain columns";return false;}
|
||||||
|
shelf.minimumSubvoxels={WorldAssemblyFixed(minX),WorldAssemblyFixed(minY),
|
||||||
|
WorldAssemblyFixed(std::max<double>(bottomVoxel,lowestGround-4.0))};
|
||||||
|
shelf.maximumSubvoxels={WorldAssemblyFixed(maxX),WorldAssemblyFixed(maxY),
|
||||||
|
WorldAssemblyFixed(std::min<double>((topChunkZ+1)*CHUNK_SIZE,
|
||||||
|
highestGround+height+4.0))};
|
||||||
|
shelf.parametersSubvoxels={WorldAssemblyFixed(dirX),WorldAssemblyFixed(dirY),
|
||||||
|
WorldAssemblyFixed(height),WorldAssemblyFixed(reach)};
|
||||||
|
stratum.features.push_back(shelf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::uint64_t routeCandidates=0,routeGradeRejected=0,routeSweepRejected=0;
|
||||||
|
if(!BuildFiniteStrateRoute(recipe,stratum,routeCandidates,routeGradeRejected,
|
||||||
|
routeSweepRejected,error))return false;
|
||||||
|
std::printf("[WorldAssemblerRoutePlan] candidates=%llu grade_rejected=%llu sweep_rejected=%llu accepted_points=%zu capsule_m=0.34x1.76 corridor_radius_vox=4 support_probe_points=5 minimum_support_probes=%u status=PASS\n",
|
||||||
|
static_cast<unsigned long long>(routeCandidates),
|
||||||
|
static_cast<unsigned long long>(routeGradeRejected),
|
||||||
|
static_cast<unsigned long long>(routeSweepRejected),stratum.route.size(),
|
||||||
|
stratum.routeConstraints.minimumSupportProbes);
|
||||||
|
manifest.plan.strates.push_back(std::move(stratum));
|
||||||
|
if(!manifest.finalize(error))return false;
|
||||||
|
if(outManifest)*outManifest=manifest;
|
||||||
|
const std::string manifestText=manifest.ToJson();
|
||||||
|
const auto roundTrip=VoxelForgeCore::WorldAssemblyManifest::FromJson(manifestText,error);
|
||||||
|
if(!roundTrip||!roundTrip->validate(error)||roundTrip->ToJson()!=manifestText
|
||||||
|
||roundTrip->contentHash!=manifest.contentHash)
|
||||||
|
{if(error.empty())error="world assembly canonical plan serialization did not round-trip";return false;}
|
||||||
|
std::printf("[WorldAssemblerPlanSerialization] bytes=%zu canonical_round_trip=true route_points=%zu plan_hash=%016llx manifest_hash=%016llx status=PASS\n",
|
||||||
|
manifestText.size(),manifest.plan.strates.front().route.size(),
|
||||||
|
static_cast<unsigned long long>(manifest.plan.contentHash),
|
||||||
|
static_cast<unsigned long long>(manifest.contentHash));
|
||||||
|
if(!manifestOutputPath.empty())
|
||||||
|
{
|
||||||
|
const std::filesystem::path outputPath(manifestOutputPath);
|
||||||
|
std::error_code directoryError;
|
||||||
|
if(!outputPath.parent_path().empty())
|
||||||
|
std::filesystem::create_directories(outputPath.parent_path(),directoryError);
|
||||||
|
if(directoryError)
|
||||||
|
{error="could not create the world assembly manifest output directory";return false;}
|
||||||
|
std::ofstream output(outputPath,std::ios::binary);
|
||||||
|
if(!output)
|
||||||
|
{error="could not open the world assembly manifest output path";return false;}
|
||||||
|
output.write(manifestText.data(),static_cast<std::streamsize>(manifestText.size()));
|
||||||
|
if(!output)
|
||||||
|
{error="could not write the world assembly manifest payload";return false;}
|
||||||
|
}
|
||||||
|
VFJson::Value manifestJson;
|
||||||
|
if(!VFJson::Parser(manifestText).Parse(manifestJson,error))return false;
|
||||||
|
auto* rootObject=std::get_if<VFJson::Value::Object>(&root.Data);
|
||||||
|
if(!rootObject)
|
||||||
|
{error="owner snapshot root is not a JSON object";return false;}
|
||||||
|
(*rootObject)["world_assembly"]=std::move(manifestJson);
|
||||||
|
std::printf("[WorldAssemblerPrototype] recipe_version=%u evaluator_version=%u strata=%zu biomes=%zu strate_index=%d chunk_z=%d..%d serialized_bytes=%zu recipe_hash=%016llx plan_hash=%016llx manifest_hash=%016llx source=owner_surface_params_and_biome_map route_points=%zu features=%zu\n",
|
||||||
|
manifest.recipe.schemaVersion,manifest.recipe.evaluatorVersion,manifest.plan.strates.size(),
|
||||||
|
manifest.recipe.biomes.size(),manifest.plan.strates.front().strateIndex,topChunkZ,bottomChunkZ,
|
||||||
|
manifestText.size(),static_cast<unsigned long long>(manifest.recipe.contentHash),
|
||||||
|
static_cast<unsigned long long>(manifest.plan.contentHash),
|
||||||
|
static_cast<unsigned long long>(manifest.contentHash),manifest.plan.strates.front().route.size(),
|
||||||
|
manifest.plan.strates.front().features.size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool OverrideStandaloneSeed(VFJson::Value& root,int32 seed,std::string& error)
|
||||||
|
{
|
||||||
|
auto* object=std::get_if<VFJson::Value::Object>(&root.Data);
|
||||||
|
if(!object){error="owner snapshot root is not a JSON object";return false;}
|
||||||
|
(*object)["seed"].Data=static_cast<double>(seed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool OverrideStandaloneRenderDistance(VFJson::Value& root,int32 chunks,std::string& error)
|
||||||
|
{
|
||||||
|
auto* object=std::get_if<VFJson::Value::Object>(&root.Data);
|
||||||
|
if(!object){error="owner snapshot root is not a JSON object";return false;}
|
||||||
|
(*object)["render_distance_chunks"].Data=static_cast<double>(std::max(0,chunks));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SelectTopStrateAsFloatingIslands(VFJson::Value& root,std::string& error)
|
||||||
|
{
|
||||||
|
auto* rootObject=std::get_if<VFJson::Value::Object>(&root.Data);
|
||||||
|
if(!rootObject){error="owner snapshot root is not a JSON object";return false;}
|
||||||
|
auto stratesEntry=rootObject->find("strates");
|
||||||
|
if(stratesEntry==rootObject->end())
|
||||||
|
{error="owner snapshot has no strata array";return false;}
|
||||||
|
auto* strates=std::get_if<VFJson::Value::Array>(&stratesEntry->second.Data);
|
||||||
|
if(!strates||strates->empty())
|
||||||
|
{error="owner snapshot strata array is empty";return false;}
|
||||||
|
auto top=strates->begin();
|
||||||
|
for(auto it=std::next(strates->begin());it!=strates->end();++it)
|
||||||
|
if(it->Get("top_chunk_z").Number()>top->Get("top_chunk_z").Number())top=it;
|
||||||
|
auto* strateObject=std::get_if<VFJson::Value::Object>(&top->Data);
|
||||||
|
if(!strateObject){error="top owner strate is not an object";return false;}
|
||||||
|
auto assetEntry=strateObject->find("asset");
|
||||||
|
if(assetEntry==strateObject->end())
|
||||||
|
{error="top owner strate has no resolved asset";return false;}
|
||||||
|
auto* asset=std::get_if<VFJson::Value::Object>(&assetEntry->second.Data);
|
||||||
|
if(!asset){error="top owner strate asset is not an object";return false;}
|
||||||
|
(*asset)["GeneratorType"].Data=static_cast<double>(
|
||||||
|
static_cast<std::uint8_t>(ECaveGeneratorType::FloatingIslands));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool AttachFloatingIslandWorldAssembly(FStandaloneOwnerWorld& owner,
|
||||||
|
VFJson::Value& root,VoxelForgeCore::WorldAssemblyManifest& assembly,std::string& error)
|
||||||
|
{
|
||||||
|
if(!owner.Manager)
|
||||||
|
{error="floating-island assembly needs the resolved standalone strate manager";return false;}
|
||||||
|
const FStrateSlot* islandSlot=nullptr;
|
||||||
|
for(const FStrateSlot& slot:owner.Manager->GetLayout())
|
||||||
|
if(slot.Definition&&slot.Definition->GeneratorType==ECaveGeneratorType::FloatingIslands)
|
||||||
|
{islandSlot=&slot;break;}
|
||||||
|
if(!islandSlot)
|
||||||
|
{error="floating-island recipe requested but no FloatingIslands strate was resolved";return false;}
|
||||||
|
const std::uint64_t divisor=std::gcd<std::uint64_t>(owner.OwnerVoxelSizeMicrons,
|
||||||
|
owner.CoreVoxelSizeMicrons);
|
||||||
|
if(divisor==0)
|
||||||
|
{error="owner/Core voxel import ratio is invalid for the floating-island recipe";return false;}
|
||||||
|
|
||||||
|
VoxelForgeCore::FloatingIslandRecipeV1 recipe;
|
||||||
|
recipe.seed=static_cast<std::uint32_t>(owner.Seed);
|
||||||
|
recipe.ownerVoxelSizeMicrons=owner.OwnerVoxelSizeMicrons;
|
||||||
|
recipe.coreVoxelSizeMicrons=owner.CoreVoxelSizeMicrons;
|
||||||
|
recipe.ownerToCoreScaleNumerator=owner.OwnerVoxelSizeMicrons/static_cast<std::uint32_t>(divisor);
|
||||||
|
recipe.ownerToCoreScaleDenominator=owner.CoreVoxelSizeMicrons/static_cast<std::uint32_t>(divisor);
|
||||||
|
const std::int64_t coreVoxelsPerOwnerChunk=static_cast<std::int64_t>(CHUNK_SIZE)
|
||||||
|
*recipe.ownerToCoreScaleNumerator/recipe.ownerToCoreScaleDenominator;
|
||||||
|
const std::int64_t minimumZ=static_cast<std::int64_t>(islandSlot->BottomChunkZ)
|
||||||
|
*coreVoxelsPerOwnerChunk*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel
|
||||||
|
+2*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||||||
|
const std::int64_t maximumZ=static_cast<std::int64_t>(islandSlot->TopChunkZ+1)
|
||||||
|
*coreVoxelsPerOwnerChunk*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel
|
||||||
|
-2*VoxelForgeCore::WorldAssemblySubvoxelsPerVoxel;
|
||||||
|
if(maximumZ<=minimumZ)
|
||||||
|
{error="FloatingIslands strate is too short for a bounded Core recipe";return false;}
|
||||||
|
recipe.layoutMinimumZSubvoxels=minimumZ;
|
||||||
|
recipe.layoutMaximumZSubvoxels=maximumZ;
|
||||||
|
recipe.layoutCenterTopZSubvoxels=minimumZ+(maximumZ-minimumZ)/2;
|
||||||
|
|
||||||
|
auto planned=VoxelForgeCore::PlanFloatingIslandCluster(recipe,error);
|
||||||
|
if(!planned)return false;
|
||||||
|
VoxelForgeCore::WorldAssemblyFloatingIslandPlanV1 islands;
|
||||||
|
islands.strateIndex=islandSlot->StrateIndex;
|
||||||
|
islands.topChunkZ=islandSlot->TopChunkZ;
|
||||||
|
islands.bottomChunkZ=islandSlot->BottomChunkZ;
|
||||||
|
islands.manifest=std::move(*planned);
|
||||||
|
assembly.floatingIslands.push_back(std::move(islands));
|
||||||
|
if(!assembly.finalize(error))return false;
|
||||||
|
|
||||||
|
VFJson::Value assemblyJson;
|
||||||
|
if(!VFJson::Parser(assembly.ToJson()).Parse(assemblyJson,error))return false;
|
||||||
|
auto* rootObject=std::get_if<VFJson::Value::Object>(&root.Data);
|
||||||
|
if(!rootObject){error="owner snapshot root is not a JSON object";return false;}
|
||||||
|
(*rootObject)["world_assembly"]=std::move(assemblyJson);
|
||||||
|
std::printf("[FloatingIslandWorldAssembly] seed=%d strate_index=%d chunks=%d..%d island_count=%zu recipe_hash=%016llx status=PASS\n",
|
||||||
|
owner.Seed,islandSlot->StrateIndex,islandSlot->TopChunkZ,islandSlot->BottomChunkZ,
|
||||||
|
assembly.floatingIslands.back().manifest.plan.islands.size(),
|
||||||
|
static_cast<unsigned long long>(assembly.floatingIslands.back().manifest.recipe.contentHash));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace StandaloneWorldAssemblyPrototype
|
||||||
@@ -15,6 +15,8 @@ param(
|
|||||||
[ValidateRange(0, 4096)][int]$StreamingResultBacklogCap = 256,
|
[ValidateRange(0, 4096)][int]$StreamingResultBacklogCap = 256,
|
||||||
[ValidateRange(0, 10)][int]$StreamingReadyQueueDepth = 8,
|
[ValidateRange(0, 10)][int]$StreamingReadyQueueDepth = 8,
|
||||||
[ValidateRange(0, 1)][int]$StreamingBackgroundWorkerCap = 1,
|
[ValidateRange(0, 1)][int]$StreamingBackgroundWorkerCap = 1,
|
||||||
|
[ValidateRange(0, 1)][int]$CoreColumnCacheDirectMapped = 0,
|
||||||
|
[ValidateRange(0, 1)][int]$CoreMCGradientMemoization = 1,
|
||||||
[ValidateRange(0, 900)][int]$Step1MaxMeshApplies = 0,
|
[ValidateRange(0, 900)][int]$Step1MaxMeshApplies = 0,
|
||||||
[ValidateRange(0, 900)][int]$TestTeleportAfterSeconds = 0,
|
[ValidateRange(0, 900)][int]$TestTeleportAfterSeconds = 0,
|
||||||
[ValidateRange(0, 1000000)][int]$TestTeleportDistanceCm = 0,
|
[ValidateRange(0, 1000000)][int]$TestTeleportDistanceCm = 0,
|
||||||
@@ -29,6 +31,7 @@ param(
|
|||||||
[switch]$CoreOffTest,
|
[switch]$CoreOffTest,
|
||||||
[switch]$CorePlanOnly,
|
[switch]$CorePlanOnly,
|
||||||
[switch]$SharedFeatureAuditOnly,
|
[switch]$SharedFeatureAuditOnly,
|
||||||
|
[switch]$CoreMCStageAudit,
|
||||||
[int]$CoreTestSeed = [int]::MinValue
|
[int]$CoreTestSeed = [int]::MinValue
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -105,6 +108,10 @@ if (-not $StreamingTraceOnly -and ($TestMoveSpeedCmPerSecond -ne 600 -or
|
|||||||
$TestTeleportDistanceCm -ne 0)) {
|
$TestTeleportDistanceCm -ne 0)) {
|
||||||
throw 'Streaming, backlog, apply and teleport controls require -StreamingTraceOnly.'
|
throw 'Streaming, backlog, apply and teleport controls require -StreamingTraceOnly.'
|
||||||
}
|
}
|
||||||
|
if (-not $StreamingTraceOnly -and -not $SharedFeatureAuditOnly -and
|
||||||
|
($CoreColumnCacheDirectMapped -ne 0 -or $CoreMCGradientMemoization -ne 1)) {
|
||||||
|
throw 'Column-cache and gradient-memoization controls require a streaming or shared-feature audit.'
|
||||||
|
}
|
||||||
if (($TestTeleportAfterSeconds -eq 0) -ne ($TestTeleportDistanceCm -eq 0)) {
|
if (($TestTeleportAfterSeconds -eq 0) -ne ($TestTeleportDistanceCm -eq 0)) {
|
||||||
throw 'Set both -TestTeleportAfterSeconds and -TestTeleportDistanceCm for the teleport probe.'
|
throw 'Set both -TestTeleportAfterSeconds and -TestTeleportDistanceCm for the teleport probe.'
|
||||||
}
|
}
|
||||||
@@ -180,7 +187,13 @@ if ($SharedFeatureAuditOnly) {
|
|||||||
if ($SelectedModeCount -ne 0) { throw '-SharedFeatureAuditOnly uses the SurfaceWorld owner route.' }
|
if ($SelectedModeCount -ne 0) { throw '-SharedFeatureAuditOnly uses the SurfaceWorld owner route.' }
|
||||||
$RunName = 'shared_feature_audit'
|
$RunName = 'shared_feature_audit'
|
||||||
}
|
}
|
||||||
|
if ($CoreMCStageAudit -and -not $SharedFeatureAuditOnly) {
|
||||||
|
throw '-CoreMCStageAudit requires -SharedFeatureAuditOnly.'
|
||||||
|
}
|
||||||
|
if ($CoreMCStageAudit) { $RunName += '_mc_stages' }
|
||||||
$RunName += if ($StreamingOrder -eq 'Legacy') { '_legacy_order' } else { '_coarse_first' }
|
$RunName += if ($StreamingOrder -eq 'Legacy') { '_legacy_order' } else { '_coarse_first' }
|
||||||
|
$RunName += if ($CoreColumnCacheDirectMapped -eq 1) { '_colcache_direct' } else { '_colcache_4way' }
|
||||||
|
$RunName += if ($CoreMCGradientMemoization -eq 1) { '_gradientmemo_on' } else { '_gradientmemo_off' }
|
||||||
$RunName += switch ($NearReserveMode) {
|
$RunName += switch ($NearReserveMode) {
|
||||||
'Legacy' { '_nearreserve_legacy' }
|
'Legacy' { '_nearreserve_legacy' }
|
||||||
'Dynamic' { '_nearreserve_dynamic' }
|
'Dynamic' { '_nearreserve_dynamic' }
|
||||||
@@ -328,6 +341,8 @@ $BaseArguments += "-voxel.CoreRegionConcurrentAdmission=$CoreRegionConcurrentAdm
|
|||||||
$BaseArguments += "-voxel.StreamingResultBacklogCap=$StreamingResultBacklogCap"
|
$BaseArguments += "-voxel.StreamingResultBacklogCap=$StreamingResultBacklogCap"
|
||||||
$BaseArguments += "-voxel.StreamingReadyQueueDepth=$StreamingReadyQueueDepth"
|
$BaseArguments += "-voxel.StreamingReadyQueueDepth=$StreamingReadyQueueDepth"
|
||||||
$BaseArguments += "-voxel.StreamingBackgroundWorkerCap=$StreamingBackgroundWorkerCap"
|
$BaseArguments += "-voxel.StreamingBackgroundWorkerCap=$StreamingBackgroundWorkerCap"
|
||||||
|
$BaseArguments += "-voxel.CoreColumnCacheDirectMapped=$CoreColumnCacheDirectMapped"
|
||||||
|
$BaseArguments += "-voxel.CoreMCGradientMemoization=$CoreMCGradientMemoization"
|
||||||
if ($Step1MaxMeshApplies -gt 0) {
|
if ($Step1MaxMeshApplies -gt 0) {
|
||||||
$BaseArguments += "-voxel.Step1MaxMeshApplies=$Step1MaxMeshApplies"
|
$BaseArguments += "-voxel.Step1MaxMeshApplies=$Step1MaxMeshApplies"
|
||||||
}
|
}
|
||||||
@@ -350,6 +365,7 @@ if ($StartupTrace -or $StreamingTraceOnly) {
|
|||||||
$BaseArguments += '-voxel.StartupTraceMaxTiles=16384'
|
$BaseArguments += '-voxel.StartupTraceMaxTiles=16384'
|
||||||
}
|
}
|
||||||
if ($SharedFeatureAuditOnly) { $BaseArguments += '-corefeatureauditonly' }
|
if ($SharedFeatureAuditOnly) { $BaseArguments += '-corefeatureauditonly' }
|
||||||
|
if ($CoreMCStageAudit) { $BaseArguments += '-coremcstageaudit' }
|
||||||
if ($HasManifestOverride) {
|
if ($HasManifestOverride) {
|
||||||
$BaseArguments += ('-coreworldassembly="{0}"' -f $StagedWorldAssembly)
|
$BaseArguments += ('-coreworldassembly="{0}"' -f $StagedWorldAssembly)
|
||||||
}
|
}
|
||||||
|
|||||||