mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 17:09:19 +02:00
Section-index visual streaming (no per-cycle twin re-scan)
Replaces the camera-distance ring passes with section-following streaming and a persistent section index, so a million-node scenery no longer re-scans the whole twin every time the camera moves into new ground. - v9 node marker also stores range_max; a model visible from beyond the stream radius (or unlimited) is built once up front, the rest stream by section so distant landmarks/traction/buildings don't pop out while flora stays local. - Reader gains node_offset()/seek_node(); cParser exposes the deepest twin's file/path/offset/params and seekReplayNode/setReplayParams to rebuild one node. - First visual pass indexes every deferred node (models via the dispatch fast path, origin-placed flora/shapes in deserialize_node) under its region section while building the spawn area; later cycles rebuild only the newly-wanted sections by seeking straight to their nodes -- O(visible), not O(whole twin). - Build-all fallback retained for ghostview with no camera centre. Known: absolute terrain triangles (no origin) still build in the first pass; only origin-placed content section-streams. Untested in-game (format bump needs a rebake).
This commit is contained in:
@@ -64,7 +64,7 @@ namespace scene {
|
||||
// in the visual pass, swallowed the following endorigin -> the origin stack accumulated
|
||||
// and flung terrain/models across the map. bumping invalidates those bad twins.
|
||||
// bumping the version invalidates older twins so they are recompiled rather than misread.
|
||||
constexpr std::uint32_t SCENERYBINARY_MAGIC { MAKE_ID4( 'e', 'u', '7', 8 ) };
|
||||
constexpr std::uint32_t SCENERYBINARY_MAGIC { MAKE_ID4( 'e', 'u', '7', 9 ) };
|
||||
|
||||
// which entries a reader serves in a given load pass; nodes outside the requested class
|
||||
// are skipped (directives/includes are always served, to keep transform/group state)
|
||||
@@ -124,7 +124,7 @@ public:
|
||||
// Haspos/X/Y/Z give a model node's local position so the camera-ring load can skip it
|
||||
// without reading its tokens.
|
||||
void begin_node();
|
||||
void end_node( bool Visual, bool Haspos = false, double X = 0.0, double Y = 0.0, double Z = 0.0 );
|
||||
void end_node( bool Visual, bool Haspos = false, double X = 0.0, double Y = 0.0, double Z = 0.0, double Range = -1.0 );
|
||||
std::size_t entry_count() const { return m_count; }
|
||||
// serializes header + string table + encoded entries. returns false on stream failure.
|
||||
bool write( std::ostream &Output, scenery_file_kind Kind ) const;
|
||||
@@ -162,11 +162,20 @@ public:
|
||||
// node; returns false (no-op) otherwise. used by the camera-ring visual load to drop a
|
||||
// node outside the current distance ring once its position has been read.
|
||||
bool skip_to_node_end() { if( m_nodeend == nullptr ) { return false; } m_cursor = m_nodeend; m_nodeend = nullptr; return true; }
|
||||
// local position of the node currently being served, if its marker carried one (visual
|
||||
// model nodes, v7+). returns false for shapes / infrastructure / older twins.
|
||||
bool node_position( double &X, double &Y, double &Z ) const {
|
||||
// local position + visibility range (range_max) of the node currently being served, if its
|
||||
// marker carried one (visual model nodes, v8+). returns false for shapes / infrastructure /
|
||||
// older twins. Range lets the streamer build far-but-large-range models (range_max beyond
|
||||
// the stream radius) eagerly instead of dropping them when their section is out of range.
|
||||
bool node_position( double &X, double &Y, double &Z, double &Range ) const {
|
||||
if( false == m_nodehaspos ) { return false; }
|
||||
X = m_nodepos[ 0 ]; Y = m_nodepos[ 1 ]; Z = m_nodepos[ 2 ]; return true; }
|
||||
X = m_nodepos[ 0 ]; Y = m_nodepos[ 1 ]; Z = m_nodepos[ 2 ]; Range = m_noderange; return true; }
|
||||
// byte offset of the node currently being served, for the section-index streamer to seek back
|
||||
std::size_t node_offset() const { return m_nodeoffset; }
|
||||
// reposition at a node's marker (recorded via node_offset()) so the next next() re-serves it;
|
||||
// used to rebuild a section's nodes on demand without re-scanning the twin
|
||||
void seek_node( std::size_t Offset ) {
|
||||
m_cursor = ( m_begin + Offset <= m_end ) ? m_begin + Offset : m_end;
|
||||
m_nodeend = nullptr; m_nodehaspos = false; }
|
||||
bool exhausted() const { return m_cursor >= m_end; }
|
||||
// fraction of bytes consumed so far, 0..100, for the loading bar
|
||||
int progress() const { return ( m_size == 0 ? 100 : static_cast<int>( ( m_cursor - m_begin ) * 100 / m_size ) ); }
|
||||
@@ -177,7 +186,9 @@ private:
|
||||
char const *m_cursor { nullptr };
|
||||
char const *m_end { nullptr };
|
||||
char const *m_nodeend { nullptr }; // end of the node currently being served (for skip_to_node_end)
|
||||
double m_nodepos[ 3 ] { 0.0, 0.0, 0.0 }; // local position of the current node (v7 model marker)
|
||||
double m_nodepos[ 3 ] { 0.0, 0.0, 0.0 }; // local position of the current node (v8 model marker)
|
||||
double m_noderange { -1.0 }; // range_max of the current node (v9 model marker)
|
||||
std::size_t m_nodeoffset { 0 }; // byte offset of the current node's marker (for seek_node)
|
||||
bool m_nodehaspos { false }; // whether the current node's marker carried a position
|
||||
std::ptrdiff_t m_size { 0 }; // entry section byte length
|
||||
scenery_load_pass m_pass { scenery_load_pass::all };
|
||||
|
||||
Reference in New Issue
Block a user