16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-21 12:29:18 +02:00

Stream deferred visual nodes in camera-distance order (nearest first)

The progressive load previously streamed the deferred visual nodes (3d model
instances + terrain shapes/lines) in file order, so distant scenery could load
before the player's surroundings. This builds them nearest-camera first instead.

The visual pass now runs in two steps. Enumeration replays the twin and captures
each visual node verbatim (its resolved tokens as text -- numbers round-trip
losslessly through cParser) together with the transform/group context it was read
under and, for models, its transformed world position. Once the replay is
exhausted the records are sorted by squared distance to the camera (terrain shapes
first so the ground appears before the props on it), then built a budgeted slice
per frame through the normal node path with the captured transform and group
restored -- so placement, grouping and the per-cell instance buckets come out
identical to an in-order load.

Two supporting fixes make out-of-order/late insertion correct:
- a cell/section whose geometry was already baked (the renderer finalised it
  before a deferred node arrived) now appends the new shape/lines straight into
  its live geometry bank instead of merging into vertex-freed geometry, which
  would silently drop it; create_geometry() remembers the bank for every cell.
- events that bind to visual model instances (lights/animation/texture/visible)
  are deferred from InitEvents() to a new InitInstanceEvents() run after the
  visual nodes are built, so their target models exist when they initialise.

Verified on td.scn: playable ~2s, 540 deferred nodes enumerated and built
nearest-first ~0.5s later, no duplicate instances.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
maj00r
2026-06-23 17:11:39 +02:00
parent c10fadbfc9
commit 1160bfecac
8 changed files with 326 additions and 4 deletions

View File

@@ -2493,6 +2493,21 @@ void
event_manager::InitEvents() {
//łączenie eventów z pozostałymi obiektami
for( auto *event : m_events ) {
// events binding to model instances are deferred: with progressive loading their
// target models stream in after this (infrastructure) pass, so binding them now
// would fail. InitInstanceEvents() initialises them once the visuals are in place.
if( true == event->binds_to_instances() ) { continue; }
event->init();
if( event->m_delay < 0 ) { AddToQuery( event, nullptr ); }
}
}
// initializes the events deferred by InitEvents() (those binding to model instances),
// after the (progressively loaded) visual nodes have been built so the models exist.
void
event_manager::InitInstanceEvents() {
for( auto *event : m_events ) {
if( false == event->binds_to_instances() ) { continue; }
event->init();
if( event->m_delay < 0 ) { AddToQuery( event, nullptr ); }
}

View File

@@ -55,6 +55,13 @@ public:
virtual
void
init() = 0;
// true for events that bind to visual model instances (lights/animation/texture/
// visible). With progressive loading these models are streamed in after the
// infrastructure pass, so such events must be initialised only once the deferred
// visual nodes exist -- not during the early InitEvents() of the infrastructure pass.
virtual
bool
binds_to_instances() const { return false; }
// executes event
virtual
void
@@ -393,6 +400,7 @@ public:
// methods
// prepares event for use
void init() override;
bool binds_to_instances() const override { return true; }
private:
// types
@@ -427,6 +435,7 @@ public:
// methods
// prepares event for use
void init() override;
bool binds_to_instances() const override { return true; }
private:
// methods
@@ -456,6 +465,7 @@ public:
// methods
// prepares event for use
void init() override;
bool binds_to_instances() const override { return true; }
private:
// methods
@@ -550,6 +560,7 @@ public:
// methods
// prepares event for use
void init() override;
bool binds_to_instances() const override { return true; }
private:
// methods
@@ -690,9 +701,15 @@ public:
// legacy method, executes queued events
bool
CheckQuery();
// legacy method, initializes events after deserialization from scenario file
// legacy method, initializes events after deserialization from scenario file.
// events that bind to visual model instances are skipped here and initialised later
// by InitInstanceEvents(), once the (progressively loaded) visual nodes are in place.
void
InitEvents();
// initializes the events skipped by InitEvents() (those binding to model instances).
// called once the deferred visual nodes have been built, so their target models exist.
void
InitInstanceEvents();
// legacy method, initializes event launchers after deserialization from scenario file
void
InitLaunchers();