wip(assembler): round L3 -- Core forces FP contraction off and refuses to generate if it can't
CoreNamespacePreamble.h applies per-compiler contraction-off pragmas (Clang, MSVC, GCC; unknown compiler = #error) and a fused-multiply-add self-test that World::compile runs before building. Clang -ffp-contract=on and GCC's default (fast) now reproduce the L1/Windows hashes (they diverged in L2); Clang -ffp-contract=fast ignores the pragma and is refused at startup (negative control). Seed sweep with every cube on real terrain: 48 seeds x 2 recipes x 3 builds x W1/W12, 576 runs, 0 mismatches, 0 empty meshes. Cost +0.5% (2.326 -> 2.337 s, interleaved). World unchanged. MSVC/UBT not compiled here: Windows to-do list in Linux3/REPORT.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
303b7b9f24
commit
046f2af495
10 files changed
+1051
-2
No files matched your search
@@ -7,12 +7,15 @@
|
||||
|
||||
#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>
|
||||
@@ -33,6 +36,7 @@ namespace
|
||||
bool StreamHash=false;
|
||||
bool ProfileColumnOverlap=false;
|
||||
bool ForceGenerate=false;
|
||||
bool MeshCoverage=false;
|
||||
bool HasSeedOverride=false;
|
||||
int SeedOverride=0;
|
||||
bool HasRenderDistanceOverride=false;
|
||||
@@ -41,6 +45,7 @@ namespace
|
||||
bool TlsProbeRequested=false;
|
||||
int TlsProbeWorkers=0;
|
||||
bool HasCamera=false;
|
||||
bool AutoSurfaceCamera=false;
|
||||
FVector CameraMeters=FVector::ZeroVector;
|
||||
};
|
||||
|
||||
@@ -81,6 +86,8 @@ namespace
|
||||
" --camera=X,Y,Z,YAW,PITCH (position in metres) --stream-hash\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"
|
||||
" --render-distance-chunks=N (0 disables the extra far ring)\n"
|
||||
" --tls-probe=N (Linux worker TLS/stack measurement; N=0..12)\n"
|
||||
" --process-affinity=MASK --process-priority=Normal --frame-limit=FPS (viewer compatibility only)\n",
|
||||
@@ -93,6 +100,8 @@ namespace
|
||||
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=="--auto-surface-camera")options.AutoSurfaceCamera=true;
|
||||
else if(arg.starts_with("--recipe="))
|
||||
{
|
||||
const std::string_view recipe=arg.substr(std::string_view("--recipe=").size());
|
||||
@@ -221,6 +230,48 @@ int main(int argc,char** argv)
|
||||
&&!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());
|
||||
|
||||
@@ -233,5 +284,6 @@ int main(int argc,char** argv)
|
||||
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.ProfileColumnOverlap,options.FarHorizonLOD8InteriorStepVoxels,
|
||||
options.MeshCoverage);
|
||||
}
|
||||
Reference in new issue
Block a user