wip(assembler): round S5 -- streaming gates + trace; coarse-first order kept opt-in (no win)
Walkable/enclosed/refined gates defined; JSONL trace joins request, worker start, build/apply and discards. Coarse-first + dynamic near reserve behind voxel.StreamingCoarseFirst / voxel.StreamingDynamicNearReserve (default 0 = S4 order): matched runs showed no walkability or full-view win and slower LOD0/1 refinement. Instruments settled: 3.1 s standalone reproduced (16.7 s was another generation route); black early captures were clear-only frames. Hashes equal S4; Core-off, M2, SurfaceWorld/FloatingIslands BuildHost pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
9d3c50ca95
commit
c0596c5f24
32 files changed
+1049
-65
No files matched your search
@@ -1635,6 +1635,9 @@ namespace
|
||||
uint64 GpuFarProtectedThinSamples=0,GpuFarProtectedSolidSamples=0;
|
||||
uint64 GpuFarProtectedSealSamples=0,GpuFarProtectedOverlaySamples=0;
|
||||
uint64 PresentCallCount=0;
|
||||
uint64 LastCapturedFrameOrdinal=0,LastCapturedPresentOrdinal=0;
|
||||
int32 LastCapturedSequenceIndex=-1;
|
||||
bool bLastCapturedSequenceIsFlight=false;
|
||||
uint64 StartupNonBlockingPresentCalls=0,StartupNonBlockingPresentSkips=0;
|
||||
double GpuFarGpuDispatchMs=0.0;
|
||||
double GpuFarGpuDispatchMaxMs=0.0;
|
||||
@@ -1692,6 +1695,10 @@ namespace
|
||||
float FlightSpeedMps=16.0f;
|
||||
std::string FlightCaptureSequencePrefix;
|
||||
int32 FlightCaptureSequenceIndex=0;
|
||||
int32 FlightCaptureCloseIndex=-1;
|
||||
std::string SpawnCaptureSequencePrefix;
|
||||
int32 SpawnCaptureSequenceIndex=0;
|
||||
bool bQuitAfterSpawnCaptures=false,bSpawnCaptureClosePosted=false;
|
||||
bool bFlightStarted=false;
|
||||
bool bFlightFinished=false;
|
||||
bool bFlightClosePosted=false;
|
||||
@@ -5509,6 +5516,71 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
|
||||
void CaptureRenderedFrame()
|
||||
{
|
||||
auto LogCaptureFrameAudit=[&](const char* Mode,int32 Index,double ElapsedSeconds)
|
||||
{
|
||||
std::size_t ReadyTiles=0;
|
||||
for(const FVoxelTileKey& Key:DesiredTiles)
|
||||
if(IsRenderedTileReady(Key))++ReadyTiles;
|
||||
uint64 DrawIndices=0;
|
||||
uint64 DrawBatches=0;
|
||||
for(const auto& Pair:StreamingBatches)
|
||||
{
|
||||
const FStreamingGpuBatch& Batch=Pair.second;
|
||||
if(!bShowLevel[Pair.first.Level]
|
||||
||(CaptureOnlyLod>=0&&Pair.first.Level!=CaptureOnlyLod)
|
||||
||!Batch.VertexBuffer||!Batch.IndexBuffer||!Batch.IndexCount
|
||||
||(bDrawOnlyTile&&Batch.DrawOnlyIndexCount==0))continue;
|
||||
DrawIndices+=bDrawOnlyTile?Batch.DrawOnlyIndexCount:Batch.IndexCount;
|
||||
++DrawBatches;
|
||||
}
|
||||
std::printf("[CaptureFrameAudit] mode=%s index=%d elapsed_s=%.3f capture_phase=pre_present frame=%llu presents_completed=%llu next_present=%llu resident_tiles=%zu/%zu resident_meshes=%zu draw_batches=%llu draw_triangles=%llu queued_upload_batches=%zu gpu_far_tiles=%zu\n",
|
||||
Mode,Index,ElapsedSeconds,
|
||||
static_cast<unsigned long long>(ColdTimelineFrame()),
|
||||
static_cast<unsigned long long>(PresentCallCount),
|
||||
static_cast<unsigned long long>(PresentCallCount+1),
|
||||
ReadyTiles,DesiredTiles.size(),ResidentTiles.size(),
|
||||
static_cast<unsigned long long>(DrawBatches),
|
||||
static_cast<unsigned long long>(DrawIndices/3),DirtyBatchSet.size(),GpuFarTiles.size());
|
||||
std::fflush(stdout);
|
||||
};
|
||||
|
||||
// Capturer apres le rendu, avant le present imminent du meme frame.
|
||||
// Capture after rendering, before this same frame's imminent present.
|
||||
if(!SpawnCaptureSequencePrefix.empty()&&SpawnCaptureSequenceIndex<3
|
||||
&&GenerationStart.time_since_epoch().count()!=0)
|
||||
{
|
||||
static constexpr std::array<double,3> CaptureSeconds={0.5,1.0,2.0};
|
||||
const double SpawnElapsed=std::chrono::duration<double>(
|
||||
std::chrono::steady_clock::now()-GenerationStart).count();
|
||||
if(SpawnElapsed>=CaptureSeconds[SpawnCaptureSequenceIndex])
|
||||
{
|
||||
LogCaptureFrameAudit("spawn",SpawnCaptureSequenceIndex,SpawnElapsed);
|
||||
char Suffix[16]{};
|
||||
std::snprintf(Suffix,sizeof(Suffix),"_%02d.png",SpawnCaptureSequenceIndex);
|
||||
const std::string Path=SpawnCaptureSequencePrefix+Suffix;
|
||||
if(SaveBackBufferPng(Path))
|
||||
{
|
||||
LastCapturedFrameOrdinal=ColdTimelineFrame();
|
||||
LastCapturedPresentOrdinal=PresentCallCount+1;
|
||||
LastCapturedSequenceIndex=SpawnCaptureSequenceIndex;
|
||||
bLastCapturedSequenceIsFlight=false;
|
||||
std::printf("[SpawnSequenceCapture] index=%d elapsed_s=%.3f path=%s\n",
|
||||
SpawnCaptureSequenceIndex,SpawnElapsed,Path.c_str());
|
||||
}
|
||||
else
|
||||
std::fprintf(stderr,"[SpawnSequenceCapture] index=%d elapsed_s=%.3f failed path=%s\n",
|
||||
SpawnCaptureSequenceIndex,SpawnElapsed,Path.c_str());
|
||||
++SpawnCaptureSequenceIndex;
|
||||
std::fflush(stdout);
|
||||
if(bQuitAfterSpawnCaptures&&SpawnCaptureSequenceIndex>=3
|
||||
&&!bSpawnCaptureClosePosted)
|
||||
{
|
||||
bSpawnCaptureClosePosted=true;
|
||||
PostMessageA(Window,WM_CLOSE,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Capturer le vol dans la boucle de rendu conserve les transitions LOD.
|
||||
// Capture the flight inside the render loop to retain LOD transition frames.
|
||||
if(!FlightCaptureSequencePrefix.empty()&&bFlightStarted)
|
||||
@@ -5519,17 +5591,30 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
if(FlightCaptureSequenceIndex<static_cast<int32>(CaptureSeconds.size())
|
||||
&&FlightElapsed>=CaptureSeconds[FlightCaptureSequenceIndex])
|
||||
{
|
||||
LogCaptureFrameAudit("flight",FlightCaptureSequenceIndex,FlightElapsed);
|
||||
char Suffix[16]{};
|
||||
std::snprintf(Suffix,sizeof(Suffix),"_%02d.png",FlightCaptureSequenceIndex);
|
||||
const std::string Path=FlightCaptureSequencePrefix+Suffix;
|
||||
const int32 CapturedIndex=FlightCaptureSequenceIndex;
|
||||
if(SaveBackBufferPng(Path))
|
||||
{
|
||||
LastCapturedFrameOrdinal=ColdTimelineFrame();
|
||||
LastCapturedPresentOrdinal=PresentCallCount+1;
|
||||
LastCapturedSequenceIndex=CapturedIndex;
|
||||
bLastCapturedSequenceIsFlight=true;
|
||||
std::printf("[FlightSequenceCapture] index=%d elapsed_s=%.3f path=%s\n",
|
||||
FlightCaptureSequenceIndex,FlightElapsed,Path.c_str());
|
||||
CapturedIndex,FlightElapsed,Path.c_str());
|
||||
}
|
||||
else
|
||||
std::fprintf(stderr,"[FlightSequenceCapture] index=%d failed path=%s\n",
|
||||
FlightCaptureSequenceIndex,Path.c_str());
|
||||
CapturedIndex,Path.c_str());
|
||||
++FlightCaptureSequenceIndex;
|
||||
std::fflush(stdout);
|
||||
if(FlightCaptureCloseIndex==CapturedIndex&&!bFlightClosePosted)
|
||||
{
|
||||
bFlightClosePosted=true;
|
||||
PostMessageA(Window,WM_CLOSE,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
const bool bReadyToCapture=bCaptureAfterClipmap?bInitialClipmapReported:IsFullDetailUploaded();
|
||||
@@ -5816,7 +5901,6 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
bGpuSkirtDrawAuditReported=true;
|
||||
std::fflush(stdout);
|
||||
}
|
||||
CaptureRenderedFrame();
|
||||
const bool bHoldFrontBufferForGpuWarmup=bHoldCpuFrameDuringGpuWarmup
|
||||
&&bCpuReadyFramePresentedBeforeGpu&&bGpuFarEnabled
|
||||
&&GpuFarTilesSubmitted>0&&!bInitialClipmapReported;
|
||||
@@ -5864,6 +5948,8 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
std::chrono::duration<double,std::milli>(GpuPumpEnd-CpuPumpEnd).count());
|
||||
return;
|
||||
}
|
||||
const bool bDidPresent=!bGpuFarNoPresent||bDeferGpuUntilCpuFrame;
|
||||
if(bDidPresent)CaptureRenderedFrame();
|
||||
const auto BeforePresent=std::chrono::steady_clock::now();
|
||||
const bool bNonBlockingStartupPresent=bGpuFarEnabled&&!bInitialClipmapReported
|
||||
&&!bForceBlockingStartupPresent;
|
||||
@@ -5872,10 +5958,23 @@ float3 Lit=Rock*(Ambient+0.88*Diffuse)+float3(0.50,0.69,0.82)*Head*0.75;
|
||||
const auto PresentCallStart=std::chrono::steady_clock::now();
|
||||
// The CPU-ready frame is the ownership handoff gate for this route.
|
||||
// Keep that one presentation, then suppress presents while GPU work runs.
|
||||
const bool bDidPresent=!bGpuFarNoPresent||bDeferGpuUntilCpuFrame;
|
||||
const HRESULT PresentResult=bDidPresent
|
||||
?SwapChain->Present(PresentSyncInterval,PresentFlags):S_FALSE;
|
||||
const auto PresentCallEnd=std::chrono::steady_clock::now();
|
||||
if(LastCapturedFrameOrdinal==FrameOrdinal)
|
||||
{
|
||||
std::printf("[CaptureFramePresentation] mode=%s index=%d frame=%llu present_ordinal=%llu hr=0x%08lx present_called=%d status_succeeded=%d occluded=%d window_visible=%d\n",
|
||||
bLastCapturedSequenceIsFlight?"flight":"spawn",LastCapturedSequenceIndex,
|
||||
static_cast<unsigned long long>(LastCapturedFrameOrdinal),
|
||||
static_cast<unsigned long long>(LastCapturedPresentOrdinal),
|
||||
static_cast<unsigned long>(PresentResult),
|
||||
bDidPresent?1:0,SUCCEEDED(PresentResult)?1:0,
|
||||
PresentResult==DXGI_STATUS_OCCLUDED?1:0,IsWindowVisible(Window)?1:0);
|
||||
std::fflush(stdout);
|
||||
LastCapturedFrameOrdinal=0;
|
||||
LastCapturedPresentOrdinal=0;
|
||||
LastCapturedSequenceIndex=-1;
|
||||
}
|
||||
if(!bDidPresent&&!bGpuFarNoPresentReported)
|
||||
{
|
||||
bGpuFarNoPresentReported=true;
|
||||
@@ -9399,6 +9498,7 @@ int main(int Argc,char** Argv)
|
||||
std::string WorldAssemblyManifestOutputPath;
|
||||
bool bStreamBenchmark=false;
|
||||
bool bStreamPipeline=false;
|
||||
bool bCoarseFirstStreamOrder=false;
|
||||
bool bProfileDetailBand=false;
|
||||
bool bPassageDetailAuditOnly=false;
|
||||
bool bGridStairAudit=false;
|
||||
@@ -9423,6 +9523,13 @@ int main(int Argc,char** Argv)
|
||||
else if(Arg.starts_with("--capture-flight-sequence-prefix="))
|
||||
App.FlightCaptureSequencePrefix=std::string(
|
||||
Arg.substr(std::string_view("--capture-flight-sequence-prefix=").size()));
|
||||
else if(Arg.starts_with("--flight-capture-close-index="))
|
||||
App.FlightCaptureCloseIndex=std::atoi(
|
||||
std::string(Arg.substr(std::string_view("--flight-capture-close-index=").size())).c_str());
|
||||
else if(Arg.starts_with("--capture-spawn-sequence-prefix="))
|
||||
App.SpawnCaptureSequencePrefix=std::string(
|
||||
Arg.substr(std::string_view("--capture-spawn-sequence-prefix=").size()));
|
||||
else if(Arg=="--quit-after-spawn-captures")App.bQuitAfterSpawnCaptures=true;
|
||||
else if(Arg=="--no-vsync")App.bDisableVSync=true;
|
||||
else if(Arg.starts_with("--frame-limit="))
|
||||
{FrameLimitHz=std::clamp(std::atoi(std::string(Arg.substr(14)).c_str()),1,60);bFrameLimitSpecified=true;}
|
||||
@@ -9521,6 +9628,8 @@ int main(int Argc,char** Argv)
|
||||
else if(Arg=="--round-tunnels-legacy")
|
||||
{App.bRoundTunnels=true;App.bRoundTunnelEnhanced=false;}
|
||||
else if(Arg=="--stream-benchmark")bStreamBenchmark=true;
|
||||
else if(Arg=="--legacy-stream-order")bCoarseFirstStreamOrder=false;
|
||||
else if(Arg=="--coarse-first-stream-order")bCoarseFirstStreamOrder=true;
|
||||
else if(Arg=="--stream-pipeline")
|
||||
{bStreamPipeline=true;bStreamBenchmark=true;App.bShapeWorld=true;App.bForceGenerate=true;}
|
||||
else if(Arg=="--edit-benchmark")
|
||||
@@ -9613,6 +9722,10 @@ int main(int Argc,char** Argv)
|
||||
}
|
||||
else if(!Arg.empty()&&Arg.front()!='-')App.DataPath=std::string(Arg);
|
||||
}
|
||||
FStandaloneStreamingGenerator::SetCoarseFirstSchedulingEnabled(bCoarseFirstStreamOrder);
|
||||
std::printf("[StandaloneStreamOrder] mode=%s negative_control=%s\n",
|
||||
bCoarseFirstStreamOrder?"walkable_coarse_refine":"legacy_distance_lod",
|
||||
bCoarseFirstStreamOrder?"--legacy-stream-order":"none");
|
||||
std::printf("[FrameLimiter] target_fps=%d maximum=true vsync=%s source=%s\n",FrameLimitHz,
|
||||
App.bDisableVSync?"off":"on",bFrameLimitSpecified?"argument":"default");
|
||||
if(App.bCaptureOnlyTile&&App.bGpuFarEnabled)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <atomic>
|
||||
#include <bit>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
@@ -409,6 +410,11 @@ namespace StandaloneWorldMesher
|
||||
class FStandaloneStreamingGenerator
|
||||
{
|
||||
public:
|
||||
static void SetCoarseFirstSchedulingEnabled(bool bEnabled)
|
||||
{bCoarseFirstSchedulingEnabled.store(bEnabled,std::memory_order_relaxed);}
|
||||
static bool IsCoarseFirstSchedulingEnabled()
|
||||
{return bCoarseFirstSchedulingEnabled.load(std::memory_order_relaxed);}
|
||||
|
||||
explicit FStandaloneStreamingGenerator(FStandaloneOwnerWorld& InWorld,int32 InWorkerCount=8,
|
||||
bool bInHashDensity=false,
|
||||
const FStandaloneMeshCache* InMeshCache=nullptr,
|
||||
@@ -448,6 +454,7 @@ public:
|
||||
bStop=false;
|
||||
}
|
||||
for(int32 I=0;I<WorkerCount;++I)Workers.emplace_back([this](){WorkerLoop();});
|
||||
bHasLastCameraPosition=false;TravelDirection=FVector::ZeroVector;
|
||||
return UpdateDesired(CameraPositionVoxels,ResidentKeys,CrossingIndex);
|
||||
}
|
||||
|
||||
@@ -461,6 +468,7 @@ public:
|
||||
bStop=false;
|
||||
}
|
||||
for(int32 I=0;I<WorkerCount;++I)Workers.emplace_back([this](){WorkerLoop();});
|
||||
bHasLastCameraPosition=false;TravelDirection=FVector::ZeroVector;
|
||||
return UpdateDesiredSet(InitialDesired,ResidentKeys,CrossingIndex);
|
||||
}
|
||||
|
||||
@@ -507,6 +515,23 @@ public:
|
||||
const FVector& CameraPositionVoxels,const std::vector<FVoxelTileKey>& ResidentKeys,
|
||||
uint64 CrossingIndex=0)
|
||||
{
|
||||
if(bHasLastCameraPosition)
|
||||
{
|
||||
const FVector Delta=CameraPositionVoxels-LastCameraPositionVoxels;
|
||||
const double LengthSquared=static_cast<double>(Delta.X)*Delta.X
|
||||
+static_cast<double>(Delta.Y)*Delta.Y;
|
||||
if(LengthSquared>1.0e-12)
|
||||
{
|
||||
const double InverseLength=1.0/std::sqrt(LengthSquared);
|
||||
TravelDirection=FVector(static_cast<float>(Delta.X*InverseLength),
|
||||
static_cast<float>(Delta.Y*InverseLength),0.0f);
|
||||
}
|
||||
else TravelDirection=FVector::ZeroVector;
|
||||
}
|
||||
else
|
||||
TravelDirection=FVector::ZeroVector;
|
||||
LastCameraPositionVoxels=CameraPositionVoxels;
|
||||
bHasLastCameraPosition=true;
|
||||
FStandaloneDesiredTileSet NewDesired=StandaloneWorldMesher::BuildDesiredSet(*World,CameraPositionVoxels);
|
||||
if(CoreWorld)
|
||||
{
|
||||
@@ -652,17 +677,60 @@ private:
|
||||
Stats.CancelledByCrossing.reserve(CancelledByCrossing.size());
|
||||
for(const auto& Pair:CancelledByCrossing)Stats.CancelledByCrossing.push_back(Pair);
|
||||
|
||||
std::vector<VoxelForgeCore::TileKey> Unordered;Unordered.reserve(NewDesired.Tiles.size());
|
||||
for(const FVoxelTileKey& Key:NewDesired.Tiles)
|
||||
Unordered.push_back({{Key.Coord.X,Key.Coord.Y,Key.Coord.Z},Key.Level});
|
||||
const auto Prioritized=VoxelForgeCore::World::prioritizeTiles(Unordered,
|
||||
{NewDesired.CenterChunk.X,NewDesired.CenterChunk.Y,NewDesired.CenterChunk.Z});
|
||||
std::vector<FVoxelTileKey> Prioritized=NewDesired.Tiles;
|
||||
if(IsCoarseFirstSchedulingEnabled())
|
||||
{
|
||||
// The local walkable ring leads, the coarse enclosure follows, then target-detail work.
|
||||
// L'anneau praticable local passe d'abord, puis l'enveloppe grossiere, puis le detail cible.
|
||||
const int32 FirstCoarseLevel=FMath::Max(2,World->FullResClipLevels);
|
||||
auto Tier=[&](const FVoxelTileKey& Key)
|
||||
{
|
||||
if(Key.Level==0&&std::abs(Key.Coord.X-NewDesired.CenterChunk.X)<=1
|
||||
&&std::abs(Key.Coord.Y-NewDesired.CenterChunk.Y)<=1
|
||||
&&std::abs(Key.Coord.Z-NewDesired.CenterChunk.Z)<=1)return 0;
|
||||
return Key.Level>=FirstCoarseLevel?1:2;
|
||||
};
|
||||
auto IsAhead=[&](const FVoxelTileKey& Key)
|
||||
{
|
||||
if(TravelDirection.X*TravelDirection.X+TravelDirection.Y*TravelDirection.Y<=1.0e-12f)
|
||||
return false;
|
||||
const double Scale=static_cast<double>(1<<Key.Level);
|
||||
const double OffsetX=(static_cast<double>(Key.Coord.X)+0.5)*Scale-NewDesired.CenterChunk.X;
|
||||
const double OffsetY=(static_cast<double>(Key.Coord.Y)+0.5)*Scale-NewDesired.CenterChunk.Y;
|
||||
return OffsetX*TravelDirection.X+OffsetY*TravelDirection.Y>0.0;
|
||||
};
|
||||
std::sort(Prioritized.begin(),Prioritized.end(),[&](const FVoxelTileKey& A,const FVoxelTileKey& B)
|
||||
{
|
||||
const int32 TierA=Tier(A),TierB=Tier(B);
|
||||
if(TierA!=TierB)return TierA<TierB;
|
||||
if(TierA==1&&A.Level!=B.Level)return A.Level>B.Level;
|
||||
const bool bAheadA=IsAhead(A),bAheadB=IsAhead(B);
|
||||
if(bAheadA!=bAheadB)return bAheadA;
|
||||
const double DA=StandaloneWorldMesher::TileDistanceSquaredChunks(A,NewDesired.CenterChunk);
|
||||
const double DB=StandaloneWorldMesher::TileDistanceSquaredChunks(B,NewDesired.CenterChunk);
|
||||
if(DA!=DB)return DA<DB;
|
||||
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;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<VoxelForgeCore::TileKey> Unordered;Unordered.reserve(NewDesired.Tiles.size());
|
||||
for(const FVoxelTileKey& Key:NewDesired.Tiles)
|
||||
Unordered.push_back({{Key.Coord.X,Key.Coord.Y,Key.Coord.Z},Key.Level});
|
||||
const auto CorePrioritized=VoxelForgeCore::World::prioritizeTiles(Unordered,
|
||||
{NewDesired.CenterChunk.X,NewDesired.CenterChunk.Y,NewDesired.CenterChunk.Z});
|
||||
Prioritized.clear();Prioritized.reserve(CorePrioritized.size());
|
||||
for(const auto& Key:CorePrioritized)
|
||||
Prioritized.emplace_back(FIntVector(Key.coordinate.x,Key.coordinate.y,Key.coordinate.z),Key.lod);
|
||||
}
|
||||
std::unordered_map<FVoxelTileKey,size_t,FStandaloneTileKeyHash> PriorityRanks;
|
||||
PriorityRanks.reserve(Prioritized.size()*2+1);
|
||||
for(size_t Rank=0;Rank<Prioritized.size();++Rank)
|
||||
{
|
||||
const auto& Key=Prioritized[Rank];
|
||||
PriorityRanks.emplace(FVoxelTileKey(FIntVector(Key.coordinate.x,Key.coordinate.y,Key.coordinate.z),Key.lod),Rank);
|
||||
PriorityRanks.emplace(Prioritized[Rank],Rank);
|
||||
}
|
||||
for(FStandaloneTileJob& Job:Queue)Job.PriorityRank=PriorityRanks.at(Job.Key);
|
||||
|
||||
@@ -884,6 +952,10 @@ private:
|
||||
TimelineMilliseconds(Started),TimelineMilliseconds(Finished),WorkerMs);
|
||||
}
|
||||
FStandaloneOwnerWorld* World=nullptr;
|
||||
inline static std::atomic<bool> bCoarseFirstSchedulingEnabled{true};
|
||||
FVector LastCameraPositionVoxels=FVector::ZeroVector;
|
||||
FVector TravelDirection=FVector::ZeroVector;
|
||||
bool bHasLastCameraPosition=false;
|
||||
int32 WorkerCount=8;
|
||||
bool bHashDensity=false;
|
||||
const FStandaloneMeshCache* MeshCache=nullptr;
|
||||
|
||||
Reference in new issue
Block a user