app: keep the stream-probe fan out of map loads
This commit is contained in:
parent
c0ba909c86
commit
87b27dc2a9
1 changed files with 40 additions and 8 deletions
|
|
@ -49,6 +49,7 @@
|
||||||
#include <rex/cvar.h>
|
#include <rex/cvar.h>
|
||||||
#include <rex/input/input.h>
|
#include <rex/input/input.h>
|
||||||
#include <rex/input/input_system.h>
|
#include <rex/input/input_system.h>
|
||||||
|
#include <rex/kernel/guest_presence.h>
|
||||||
#include <rex/logging.h>
|
#include <rex/logging.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
@ -458,6 +459,23 @@ extern "C" REX_FUNC(sub_8247B3A0) {
|
||||||
const float fx = LoadGuestF32(base, focus + 0);
|
const float fx = LoadGuestF32(base, focus + 0);
|
||||||
const float fz = LoadGuestF32(base, focus + 8);
|
const float fz = LoadGuestF32(base, focus + 8);
|
||||||
ProbeCache& cache = g_probe_cache[focus_type == 2 ? 1 : 0];
|
ProbeCache& cache = g_probe_cache[focus_type == 2 ? 1 : 0];
|
||||||
|
// A focus more than two cells from where the fan last ran was teleported
|
||||||
|
// (map switch, fast travel): the focus object survives the transition, but
|
||||||
|
// its cached neighbourhood belongs to the departed position, and merging
|
||||||
|
// it below would make the arrival load wait on the old area's collections.
|
||||||
|
// Gameplay movement cannot cover two cells between gather cycles, so a
|
||||||
|
// jump this large is never ordinary mid-stream drift.
|
||||||
|
if (cache.focus == focus && cache.count > 0 &&
|
||||||
|
(std::abs(fx - cache.x) > float(cell_size) * 2.0f ||
|
||||||
|
std::abs(fz - cache.z) > float(cell_size) * 2.0f)) {
|
||||||
|
if (debug) {
|
||||||
|
REXLOG_INFO(
|
||||||
|
"draw_distance: stream probe type={} focus teleported "
|
||||||
|
"({}, {}) -> ({}, {}); cache dropped",
|
||||||
|
focus_type, cache.x, cache.z, fx, fz);
|
||||||
|
}
|
||||||
|
cache = {};
|
||||||
|
}
|
||||||
const bool cache_usable = cache.focus == focus && cache.radius == probe;
|
const bool cache_usable = cache.focus == focus && cache.radius == probe;
|
||||||
const bool cache_valid = cache_usable &&
|
const bool cache_valid = cache_usable &&
|
||||||
std::abs(fx - cache.x) < float(cell_size) * 0.5f &&
|
std::abs(fx - cache.x) < float(cell_size) * 0.5f &&
|
||||||
|
|
@ -467,14 +485,22 @@ extern "C" REX_FUNC(sub_8247B3A0) {
|
||||||
// probe burst there multiplies the load time for content that is not
|
// probe burst there multiplies the load time for content that is not
|
||||||
// visible yet. The focus tracks loaded-vs-total descriptor counts from
|
// visible yet. The focus tracks loaded-vs-total descriptor counts from
|
||||||
// its per-cycle rescan; once the vanilla set is resident the fan runs
|
// its per-cycle rescan; once the vanilla set is resident the fan runs
|
||||||
// and the neighbourhood trickles in during play. A stale cache (moved
|
// and the neighbourhood trickles in during play. The counts alone are
|
||||||
// more than half a cell while additions are still streaming) keeps being
|
// not a sufficient gate: right after a teleport they still describe the
|
||||||
// merged rather than refanned, so in-flight probe records are not
|
// previous position's fully-loaded set, so the fan additionally requires
|
||||||
// dropped and re-requested by the differ.
|
// the gameplay presence context (0 = frontend/pause/loading) - loading
|
||||||
|
// flows always stream the pure vanilla set. A stale cache (moved more
|
||||||
|
// than half a cell while additions are still streaming, or paused with
|
||||||
|
// the context out of gameplay) keeps being merged rather than refanned,
|
||||||
|
// so in-flight probe records are not dropped and re-requested by the
|
||||||
|
// differ.
|
||||||
const uint32_t desc_total = LoadGuestU32(base, focus + 336);
|
const uint32_t desc_total = LoadGuestU32(base, focus + 336);
|
||||||
const uint32_t desc_loaded = LoadGuestU32(base, focus + 340);
|
const uint32_t desc_loaded = LoadGuestU32(base, focus + 340);
|
||||||
const bool set_resident = desc_total > 0 && desc_loaded >= desc_total;
|
const bool set_resident = desc_total > 0 && desc_loaded >= desc_total;
|
||||||
if (cache_valid || (cache_usable && cache.count > 0 && !set_resident)) {
|
const bool in_gameplay =
|
||||||
|
rex::kernel::guest_presence::GameplayContextValue() == 1;
|
||||||
|
if (cache_valid || (cache_usable && cache.count > 0 &&
|
||||||
|
(!set_resident || !in_gameplay))) {
|
||||||
// The neighbourhood cannot have changed (cell membership is quantized
|
// The neighbourhood cannot have changed (cell membership is quantized
|
||||||
// to the grid): merge the cached probe results instead of re-running
|
// to the grid): merge the cached probe results instead of re-running
|
||||||
// the gather fan. Cached distances are slightly stale; they are only
|
// the gather fan. Cached distances are slightly stale; they are only
|
||||||
|
|
@ -499,9 +525,10 @@ extern "C" REX_FUNC(sub_8247B3A0) {
|
||||||
++record_count;
|
++record_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!set_resident) {
|
} else if (!set_resident || !in_gameplay) {
|
||||||
// Initial load (or a fresh focus): let the vanilla set finish
|
// Initial load, a fresh focus, or outside gameplay (loading screen /
|
||||||
// streaming first; the fan starts on a later cycle.
|
// frontend): let the vanilla set finish streaming first; the fan
|
||||||
|
// starts on a later cycle.
|
||||||
} else {
|
} else {
|
||||||
// Full probe fan: every grid cell within the probe radius, stepped in
|
// Full probe fan: every grid cell within the probe radius, stepped in
|
||||||
// cell multiples. The 7x7 cap bounds the fan at 48 gather calls; the
|
// cell multiples. The 7x7 cap bounds the fan at 48 gather calls; the
|
||||||
|
|
@ -543,6 +570,11 @@ extern "C" REX_FUNC(sub_8247B3A0) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (record_count == vanilla_count) {
|
||||||
|
// Nothing beyond the vanilla set this cycle (the fan held off, or it
|
||||||
|
// found no new cells): leave the game's own gather output untouched.
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::sort(records, records + record_count,
|
std::sort(records, records + record_count,
|
||||||
[](const ProbeRecord& a, const ProbeRecord& b) {
|
[](const ProbeRecord& a, const ProbeRecord& b) {
|
||||||
return a.dist < b.dist;
|
return a.dist < b.dist;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue