16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-18 22:39:18 +02:00
Files
maszyna/scene/scenenodegroups.h
maj00r 1160bfecac 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>
2026-06-23 17:11:39 +02:00

86 lines
3.0 KiB
C++

/*
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "scene/scenenode.h"
#include "widgets/map_objects.h"
namespace scene {
struct basic_group {
// members
std::vector<scene::basic_node *> nodes;
std::vector<basic_event *> events;
};
// holds lists of grouped scene nodes
class node_groups {
// NOTE: during scenario deserialization encountering *.inc file causes creation of a new group on the group stack
// this allows all nodes listed in this *.inc file to be grouped and potentially modified together by the editor.
public:
// constructors
node_groups() = default;
// methods
// requests creation of a new node group. returns: handle to the group
group_handle
create();
// indicates creation of current group ended. returns: handle to the parent group or null_handle if group stack is empty
group_handle
close();
// update minimap objects
void
update_map();
// returns current active group, or null_handle if group stack is empty
group_handle
handle() const;
// makes Group the active group for subsequent inserts, without creating a new group.
// used by deferred (camera-ordered) visual loading to re-attach a node to the group it
// was originally read under during the enumeration pass. must be paired with pop_active().
void
push_active( scene::group_handle const Group ) { m_activegroup.push( Group ); }
void
pop_active() { if( false == m_activegroup.empty() ) { m_activegroup.pop(); } }
// places provided node in specified group
void
insert( scene::group_handle const Group, scene::basic_node *Node );
// places provided event in specified group
void
insert( scene::group_handle const Group, basic_event *Event );
// grants direct access to specified group
scene::basic_group &
group( scene::group_handle const Group ) {
return m_groupmap[ Group ]; }
// sends basic content of the class in legacy (text) format to provided stream
void
export_as_text( std::ostream &Output, bool const Dirty ) const;
private:
// types
using group_map = std::unordered_map<scene::group_handle, scene::basic_group>;
// methods
// removes specified group from the group list and group information from the group's nodes
void
erase( group_map::const_iterator Group );
// creates handle for a new group
group_handle
create_handle();
bool
assign_cross_switch(map::track_switch&sw, std::string &sw_name, const std::string &id, size_t idx);
// members
group_map m_groupmap; // map of established node groups
std::stack<scene::group_handle> m_activegroup; // helper, group to be assigned to newly created nodes
};
extern node_groups Groups;
} // scene
//---------------------------------------------------------------------------