streaming: speed-aware scheduler with hysteresis (L80); arrival near-first, fast travel keeps the horizon

Policy 3 (headless + Unreal): walkable ring always first; at rest/arrival LOD0-2 before far;
walking interleaves near:far ~4:1 toward heading; fast travel admits far coarse tiles right after
the walkable ring. Hysteresis: walking 0.75/0.35 m/s, fast 12/8 m/s.
Headless, far holes while moving 30 m/s: L77 9.0% / L79 77.2% / L80 8.9%. Cold LOD0-2 ready
(one clean protocol, medians): SW 1.30, FI 3.61, TN 3.07, VS 1.43 s.
Unreal 30 m/s traces end 2,233/2,237 loaded (commandlet readiness exit 1) for all policies.
Passage zero-padding cut: ~50% fewer passage iterations on active tiles, max 6.6 cm surface
displacement, no sign flips; not adopted yet (padding sweep next). World unchanged (v213).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-27 21:39:21 +01:00
1 parent 2c8a26c0d0
commit b06397df9c
10 files changed
+830 -25

No files matched your search

+16 -6
View File
@@ -38,6 +38,8 @@ namespace StandaloneStreamBenchmark
double sumAbsoluteDelta=0.0;
double maxSurfaceDisplacementVoxels=0.0;
double sumSurfaceDisplacementVoxels=0.0;
std::array<std::int32_t,3> maxSurfaceDisplacementStartVoxel{};
std::int32_t maxSurfaceDisplacementAxis=-1;
bool valid=false;
};
@@ -94,7 +96,7 @@ namespace StandaloneStreamBenchmark
}
const auto CompareEdge=[&](std::int32_t X0,std::int32_t Y0,std::int32_t Z0,
std::int32_t X1,std::int32_t Y1,std::int32_t Z1)
std::int32_t X1,std::int32_t Y1,std::int32_t Z1,std::int32_t Axis)
{
const bool CrossA=EdgeCrosses(A.debugDensitySamples,X0,Y0,Z0,X1,Y1,Z1);
const bool CrossB=EdgeCrosses(B.debugDensitySamples,X0,Y0,Z0,X1,Y1,Z1);
@@ -107,8 +109,13 @@ namespace StandaloneStreamBenchmark
const double TA=static_cast<double>(A0)/(static_cast<double>(A0)-A1);
const double TB=static_cast<double>(B0)/(static_cast<double>(B0)-B1);
const double Displacement=std::abs(TA-TB)*Step;
Result.maxSurfaceDisplacementVoxels=std::max(
Result.maxSurfaceDisplacementVoxels,Displacement);
if(Displacement>Result.maxSurfaceDisplacementVoxels)
{
Result.maxSurfaceDisplacementVoxels=Displacement;
Result.maxSurfaceDisplacementStartVoxel={
Origin.X+(X0-1)*Step,Origin.Y+(Y0-1)*Step,Origin.Z+(Z0-1)*Step};
Result.maxSurfaceDisplacementAxis=Axis;
}
Result.sumSurfaceDisplacementVoxels+=Displacement;
++Result.sharedCrossingEdges;
};
@@ -116,9 +123,9 @@ namespace StandaloneStreamBenchmark
for(std::int32_t Y=0;Y<Dim;++Y)
for(std::int32_t X=0;X<Dim;++X)
{
if(X+1<Dim)CompareEdge(X,Y,Z,X+1,Y,Z);
if(Y+1<Dim)CompareEdge(X,Y,Z,X,Y+1,Z);
if(Z+1<Dim)CompareEdge(X,Y,Z,X,Y,Z+1);
if(X+1<Dim)CompareEdge(X,Y,Z,X+1,Y,Z,0);
if(Y+1<Dim)CompareEdge(X,Y,Z,X,Y+1,Z,1);
if(Z+1<Dim)CompareEdge(X,Y,Z,X,Y,Z+1,2);
}
Result.valid=true;
return Result;
@@ -5014,6 +5021,9 @@ namespace StandaloneStreamBenchmark
const double MovingSeconds=std::min(MovingCameraDurationSeconds,ElapsedSeconds);
FVector Camera=CameraPositionVoxels;
Camera.X+=static_cast<float>(MovingCameraSpeedMetersPerSecond*MovingSeconds/VoxelMetres);
Streamer.SetSchedulerMotionSpeedMetersPerSecond(
ElapsedSeconds<MovingCameraDurationSeconds
?MovingCameraSpeedMetersPerSecond:0.0);
DrainReady();
if(SampleIndex==0)
{