mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-01 23:59:12 +01:00
perf(sleepers): the rails of each track for the fastenings worked out once and kept until its geometry is made again, it goes far or the crossings change, not again for every track laid around it; the fastenings laid only out to 30 m past where they're drawn, the tracks further out keeping their beams to lay them on as they come near; out past 50 m the tracks laid while the laying in a frame took under 2 ms, the rest in the frames after
This commit is contained in:
@@ -123,29 +123,22 @@ std::pair<double, double> shared_zone( TTrack const &Track, int const Path ) {
|
||||
return { zones.front().first, zones.back().second };
|
||||
}
|
||||
|
||||
void lay( TTrack &Track ) {
|
||||
namespace {
|
||||
|
||||
// the beams as instances of the parts of the model of the track: those of the fastenings with them, or left for later and the beams
|
||||
// kept for them meanwhile
|
||||
void instance( TTrack &Track, std::vector<beam> &&Beams, bool const Fastened ) {
|
||||
|
||||
auto &laid { Track.m_sleepers3d };
|
||||
std::vector<beam> placed;
|
||||
if( laid.active && in_background() && timber_model( Track ) != nullptr ) {
|
||||
// worked out in the background; till then the track keeps what it has, and tries again
|
||||
auto beams { laid_out( Track ) };
|
||||
if( false == beams.has_value() ) {
|
||||
ask_layout( Track );
|
||||
return;
|
||||
}
|
||||
placed = std::move( *beams );
|
||||
}
|
||||
laid.dirty = false;
|
||||
for( auto &instances : laid.instances ) {
|
||||
instances.clear();
|
||||
}
|
||||
laid.whole.clear();
|
||||
laid.plain.clear();
|
||||
laid.chunks.clear();
|
||||
laid.timbers = timber_model( Track );
|
||||
laid.plains = plain_model( Track );
|
||||
if( false == laid.active || laid.timbers == nullptr ) {
|
||||
laid.fastened = true;
|
||||
std::vector<beam> {}.swap( laid.beams );
|
||||
if( laid.timbers == nullptr ) {
|
||||
return;
|
||||
}
|
||||
// the sleepers of the model of the track itself (sleepermodel) at the height they're drawn at without the 3D sleepers: the
|
||||
@@ -153,16 +146,6 @@ void lay( TTrack &Track ) {
|
||||
auto const ownplains { laid.plains != nullptr && Track.m_sleeper_enabled && laid.plains != plain_model() };
|
||||
auto const plainlift { ownplains ? Track.rail_height() + Track.m_sleeper_offset.z : 0.f };
|
||||
auto const &parts { *laid.timbers };
|
||||
if( auto const panel { panel_off_plane( Track ) }; panel.first > coplanar_tolerance ) {
|
||||
WriteLog(
|
||||
"sleepers3d: switch \"" + Track.name() + "\" has its paths " + to_string( panel.first * 1000.0, 1 ) + " mm off one plane "
|
||||
+ to_string( panel.second, 2 ) + " m along, where they share the timbers of its panel" );
|
||||
}
|
||||
laid.laying = true;
|
||||
auto const beams { in_background() ? std::move( placed ) : place( Track ) };
|
||||
laid.laying = false;
|
||||
// the layout of the cluster isn't needed by this track any more, the instances below are what's drawn
|
||||
forget_layout( Track );
|
||||
|
||||
// the rails around, where they lie on the timbers, for the fastenings of the model; found at the first timber, none for plain sleepers
|
||||
std::optional<fastened_rails> rails;
|
||||
@@ -199,7 +182,7 @@ void lay( TTrack &Track ) {
|
||||
runbeams.clear();
|
||||
};
|
||||
|
||||
for( auto const &beam : beams ) {
|
||||
for( auto const &beam : Beams ) {
|
||||
if( runbeams.empty() ) {
|
||||
for( int part = 0; part < part_count; ++part ) {
|
||||
run.first[ part ] = static_cast<std::uint32_t>( laid.instances[ part ].size() );
|
||||
@@ -265,7 +248,7 @@ void lay( TTrack &Track ) {
|
||||
put( part_end, scale, parts.spans[ part_end ].x, -half );
|
||||
put( part_begin, scale, parts.spans[ part_begin ].y, half );
|
||||
}
|
||||
if( parts.fastened() && false == ( beam.plain && laid.plains != nullptr ) ) {
|
||||
if( Fastened && parts.fastened() && false == ( beam.plain && laid.plains != nullptr ) ) {
|
||||
if( false == rails.has_value() ) {
|
||||
rails.emplace( Track );
|
||||
}
|
||||
@@ -296,6 +279,55 @@ void lay( TTrack &Track ) {
|
||||
laid.whole.shrink_to_fit();
|
||||
laid.plain.shrink_to_fit();
|
||||
laid.chunks.shrink_to_fit();
|
||||
if( false == Fastened && parts.fastened() ) {
|
||||
laid.fastened = false;
|
||||
laid.beams = std::move( Beams );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void lay( TTrack &Track, bool const Fastened ) {
|
||||
|
||||
auto &laid { Track.m_sleepers3d };
|
||||
std::vector<beam> placed;
|
||||
if( laid.active && in_background() && timber_model( Track ) != nullptr ) {
|
||||
// worked out in the background; till then the track keeps what it has, and tries again
|
||||
auto beams { laid_out( Track ) };
|
||||
if( false == beams.has_value() ) {
|
||||
ask_layout( Track );
|
||||
return;
|
||||
}
|
||||
placed = std::move( *beams );
|
||||
}
|
||||
laid.dirty = false;
|
||||
laid.timbers = timber_model( Track );
|
||||
laid.plains = plain_model( Track );
|
||||
if( false == laid.active || laid.timbers == nullptr ) {
|
||||
instance( Track, {}, true );
|
||||
return;
|
||||
}
|
||||
if( auto const panel { panel_off_plane( Track ) }; panel.first > coplanar_tolerance ) {
|
||||
WriteLog(
|
||||
"sleepers3d: switch \"" + Track.name() + "\" has its paths " + to_string( panel.first * 1000.0, 1 ) + " mm off one plane "
|
||||
+ to_string( panel.second, 2 ) + " m along, where they share the timbers of its panel" );
|
||||
}
|
||||
laid.laying = true;
|
||||
auto beams { in_background() ? std::move( placed ) : place( Track ) };
|
||||
laid.laying = false;
|
||||
// the layout of the cluster isn't needed by this track any more, the instances below are what's drawn
|
||||
forget_layout( Track );
|
||||
instance( Track, std::move( beams ), Fastened );
|
||||
}
|
||||
|
||||
void fasten( TTrack &Track ) {
|
||||
|
||||
auto &laid { Track.m_sleepers3d };
|
||||
if( laid.fastened || laid.dirty ) {
|
||||
return;
|
||||
}
|
||||
auto beams { std::move( laid.beams ) };
|
||||
instance( Track, std::move( beams ), true );
|
||||
}
|
||||
|
||||
void release_far( glm::dvec3 const &Camera, double const Range ) {
|
||||
@@ -309,15 +341,19 @@ void release_far( glm::dvec3 const &Camera, double const Range ) {
|
||||
next = 0;
|
||||
}
|
||||
auto *track { tracks[ next++ ] };
|
||||
if( track == nullptr || false == track->m_sleepers3d.active || track->m_sleepers3d.laying ) {
|
||||
if( track == nullptr || track->m_sleepers3d.laying ) {
|
||||
continue;
|
||||
}
|
||||
if( glm::length( track->location() - Camera ) - track->radius() <= Range ) {
|
||||
continue;
|
||||
}
|
||||
forget_rails( *track );
|
||||
if( false == track->m_sleepers3d.active ) {
|
||||
continue;
|
||||
}
|
||||
auto &laid { track->m_sleepers3d };
|
||||
forget_layout( *track );
|
||||
auto const holds { laid.chunks.capacity() > 0 || laid.whole.capacity() > 0 || laid.plain.capacity() > 0
|
||||
auto const holds { laid.chunks.capacity() > 0 || laid.whole.capacity() > 0 || laid.plain.capacity() > 0 || laid.beams.capacity() > 0
|
||||
|| std::any_of( laid.instances.begin(), laid.instances.end(), []( std::vector<glm::mat4> const &Instances ) { return Instances.capacity() > 0; } ) };
|
||||
if( false == holds ) {
|
||||
continue;
|
||||
@@ -328,6 +364,7 @@ void release_far( glm::dvec3 const &Camera, double const Range ) {
|
||||
std::vector<glm::mat4> {}.swap( laid.whole );
|
||||
std::vector<glm::mat4> {}.swap( laid.plain );
|
||||
std::vector<chunk> {}.swap( laid.chunks );
|
||||
std::vector<beam> {}.swap( laid.beams );
|
||||
laid.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user