mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 12:29:18 +02:00
Store model position in the v7 node marker for O(1) ring skipping
The camera-ring visual load replays the twin once per distance ring, and each pass had to read every node's header + X Y Z tokens (~8 tokens through the cParser pipeline) just to decide whether the node is in the current ring -- expensive when a scenery has a million flora instances. Bump the twin format to v7: a visual model node's marker now carries its local position (3 f32), captured at bake time from the node's first three numbers. The reader hands the position out (scenery_binary_reader::node_position), and the deserializer ring-tests a model and skips it in O(1) over the marker span, straight from the dispatch loop, without deserialize_node decoding any of its tokens. deserialize_model uses the same marker position for its own ring test so the two decisions agree exactly (a node near a ring boundary can't be dropped by both adjacent rings). Shapes/older twins have no marker position and fall back to the token-based test. The per-frame visual budget is factored into VISUAL_BUDGET_MS. Verified: td.scn rebakes to v7, no duplicates, no unexpected tokens, completes ~1s. tomaszewo (1M+ flora) stays memory-bounded with no duplicates; full streaming is still paced by walking every node per ring (the remaining cost is the replay pipeline itself, which a spatial section index would address). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -62,6 +62,10 @@ class cParser //: public std::stringstream
|
||||
// false if the skip can't be done here (e.g. a text include with no binary twin), so the
|
||||
// caller can fall back to a token-by-token skip. used by the camera-ring visual load.
|
||||
bool skipReplayNode();
|
||||
// local position of the node about to be replayed (the "node" token just read), if its
|
||||
// v7 marker carried one (visual model nodes). lets the camera-ring load distance-test and
|
||||
// skip a node without decoding its body. returns false for shapes / non-replay / older twins.
|
||||
bool currentNodePosition( double &X, double &Y, double &Z );
|
||||
// methods:
|
||||
template <typename Type_>
|
||||
cParser &
|
||||
@@ -214,6 +218,10 @@ class cParser //: public std::stringstream
|
||||
int m_bakenode_count { 0 }; // entries captured since "node" (1=node,...,5=type)
|
||||
bool m_bakenode_visual { false };
|
||||
std::string m_bakenode_end; // terminator token; empty until type classified
|
||||
// v7: a model node's local position (entries 6,7,8 = X,Y,Z), stored in its marker so the
|
||||
// camera-ring load can distance-test it without decoding the node body
|
||||
bool m_bakenode_haspos { false };
|
||||
double m_bakenode_pos[ 3 ] { 0.0, 0.0, 0.0 };
|
||||
// flushes a node still open at end-of-file (or unknown type), so its buffer is written
|
||||
void bakeFinishNode();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user