17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-31 18:09:04 +01:00

fix(sleepers): the timbers a switch shares with a track with no model of timbers of its own laid of the model of the switch, not of the one of eu07.ini without the fastenings: the model of a track with none of its own that of the tracks most of its timbers carry with one, and a timber carrying none of them, as under the short tracks between the halves of a slip, of the model of the nearest timber with one up to 1.5 m away; the fastenings and checkseats selftests take the model the same way

This commit is contained in:
maj00r
2026-10-24 02:18:58 +02:00
parent 81a6b855d0
commit 540dae420f
7 changed files with 72 additions and 8 deletions

View File

@@ -156,7 +156,8 @@ editor_mode::selftest_result editor_mode::selftest_sleepers(std::string const &c
std::string name, detail;
words >> name >> detail;
auto *track{simulation::Paths.find(name)};
auto const *model{track != nullptr ? track_sleepers::timber_model(*track) : nullptr};
auto const beams{track != nullptr ? track_sleepers::place(*track) : std::vector<track_sleepers::beam>{}};
auto const *model{track != nullptr ? track_sleepers::timber_model(*track, beams) : nullptr};
if (model == nullptr || false == model->fastened())
{
WriteLog("SELFTEST fastenings: no track " + name + " with the fastenings in the model of its timbers");
@@ -164,7 +165,7 @@ editor_mode::selftest_result editor_mode::selftest_sleepers(std::string const &c
}
track_sleepers::fastened_rails const rails{*track};
std::array<int, track_sleepers::part_count> counts{};
for (auto const &beam : track_sleepers::place(*track))
for (auto const &beam : beams)
{
if (beam.plain)
continue;

View File

@@ -915,14 +915,15 @@ std::vector<fastening_row> check_fastenings() {
if( track == nullptr || track->m_editorremoved || false == track->m_sleepers3d.active ) {
continue;
}
auto const *model { timber_model( *track ) };
auto const beams { place( *track ) };
auto const *model { timber_model( *track, beams ) };
if( model == nullptr || false == model->fastened() ) {
continue;
}
fastening_row row;
row.track = track->name();
std::optional<fastened_rails> rails;
for( auto const &beam : place( *track ) ) {
for( auto const &beam : beams ) {
if( beam.plain ) {
continue;
}
@@ -1036,12 +1037,13 @@ std::vector<check_rail_gap> check_rail_seats() {
if( track == nullptr || track->m_editorremoved || false == track->m_sleepers3d.active ) {
continue;
}
auto const *model { timber_model( *track ) };
auto const beams { place( *track ) };
auto const *model { timber_model( *track, beams ) };
if( model == nullptr || false == model->fastened() ) {
continue;
}
std::optional<fastened_rails> rails;
for( auto const &beam : place( *track ) ) {
for( auto const &beam : beams ) {
if( beam.plain ) {
continue;
}

View File

@@ -152,6 +152,7 @@ public:
keep_apart();
fill_gaps();
keep_apart();
share_panels();
for( auto const &laid : beams ) {
result->beams[ laid.owner ].push_back( laid.value );
}
@@ -553,17 +554,47 @@ private:
// a sleeper of a plain track running alone and square to it, the rest are the timbers of the switches and crossings
auto const carried { std::count_if( bands.begin(), bands.end(), []( band const &Band ) { return Band.carried; } ) };
auto const plain { path.track->eType == tt_Normal && carried == 1 && pieces.size() == 1 && false == pieces.front().clipped && std::abs( glm::dot( forward, along ) ) > 0.9998 && false == crossing_timber( path, Distance ) };
auto const owner { std::find_if( bands.begin(), bands.end(), []( band const &Band ) {
return Band.carried && false == Band.path->track->m_timber_model_name.empty(); } ) };
TTrack const *panel { owner != bands.end() ? owner->path->track : nullptr };
for( std::size_t index = 0; index < pieces.size(); ++index ) {
auto const &piece { pieces[ index ] };
auto const &way { turned[ index ] };
if( way == along ) {
beams.push_back( { path.track, { top + rolledacross * piece.from, top + rolledacross * piece.to, glm::dvec3 { along.x, 0.0, along.y }, plain, piece.corefrom - piece.from, piece.coreto - piece.from } } );
beams.push_back( { path.track, { top + rolledacross * piece.from, top + rolledacross * piece.to, glm::dvec3 { along.x, 0.0, along.y }, plain, piece.corefrom - piece.from, piece.coreto - piece.from, panel } } );
continue;
}
// turned about where the middle of its track crosses the line
auto const centre { top + rolledacross * piece.single->centre };
glm::dvec3 const turnedacross { glm::dvec3 { -way.y, 0.0, way.x } * std::cos( roll ) - up * std::sin( roll ) };
beams.push_back( { path.track, { centre + turnedacross * ( piece.from - piece.single->centre ), centre + turnedacross * ( piece.to - piece.single->centre ), glm::dvec3 { way.x, 0.0, way.y }, false, piece.corefrom - piece.from, piece.coreto - piece.from } } );
beams.push_back( { path.track, { centre + turnedacross * ( piece.from - piece.single->centre ), centre + turnedacross * ( piece.to - piece.single->centre ), glm::dvec3 { way.x, 0.0, way.y }, false, piece.corefrom - piece.from, piece.coreto - piece.from, panel } } );
}
}
// the timbers whose lines carry no track with a model of timbers of its own of the model of the nearest timber with one
void share_panels() {
std::vector<std::pair<glm::dvec2, TTrack const *>> panels;
for( auto const &laid : beams ) {
if( false == laid.value.plain && laid.value.panel != nullptr ) {
panels.emplace_back( plan( 0.5 * ( laid.value.from + laid.value.to ) ), laid.value.panel );
}
}
if( panels.empty() ) {
return;
}
for( auto &laid : beams ) {
if( laid.value.plain || laid.value.panel != nullptr ) {
continue;
}
auto const middle { plan( 0.5 * ( laid.value.from + laid.value.to ) ) };
auto nearest { panel_reach };
for( auto const &[ at, panel ] : panels ) {
if( auto const distance { glm::length( at - middle ) }; distance < nearest ) {
nearest = distance;
laid.value.panel = panel;
}
}
}
}

View File

@@ -216,6 +216,27 @@ beam_model const *timber_model( TTrack const &Track ) {
return timber_model();
}
beam_model const *timber_model( TTrack const &Track, std::vector<beam> const &Beams ) {
if( false == Track.m_timber_model_name.empty() ) {
return timber_model( Track );
}
std::vector<std::pair<TTrack const *, std::size_t>> panels;
for( auto const &beam : Beams ) {
if( beam.plain || beam.panel == nullptr ) {
continue;
}
auto found { std::find_if( panels.begin(), panels.end(), [&]( auto const &Panel ) { return Panel.first == beam.panel; } ) };
if( found == panels.end() ) {
panels.emplace_back( beam.panel, 0 );
found = std::prev( panels.end() );
}
++found->second;
}
auto const most { std::max_element( panels.begin(), panels.end(), []( auto const &Left, auto const &Right ) { return Left.second < Right.second; } ) };
return ( most != panels.end() ? timber_model( *most->first ) : timber_model( Track ) );
}
beam_model const *plain_model( TTrack const &Track ) {
if( Track.m_sleeper_enabled && false == Track.m_sleeper_model_name.empty() ) {

View File

@@ -50,6 +50,9 @@ double constexpr level_tolerance { 1.0 };
// how far around a track the tracks are taken in to lay its beams: those whose beams it carries, or which carry its own, and
// those which set where the beams of these go
double constexpr around_margin { 20.0 };
// a timber whose line carries no track with a model of timbers of its own, as under the short tracks between the halves of a slip,
// is of the model of the nearest timber with one so far from it
double constexpr panel_reach { 1.5 };
// how many beams make a run drawn or left out together
std::size_t constexpr chunk_beams { 16 };
// how far apart the points of the rails are, as the places they lie on the timbers are found

View File

@@ -319,6 +319,7 @@ void lay( TTrack &Track, bool const Fastened ) {
laid.laying = true;
auto beams { in_background() ? std::move( placed ) : place( Track ) };
laid.laying = false;
laid.timbers = timber_model( Track, beams );
// 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 );

View File

@@ -56,6 +56,8 @@ struct beam {
bool plain { false }; // a sleeper of a track running alone, square to it, not a timber of a switch or a crossing
double corefrom { 0.0 }; // the stretch the feet of the rails it carries take, along it from its from end
double coreto { 0.0 };
TTrack const *panel { nullptr }; // of the tracks its line carries, the one with a model of timbers of its own: its own track first; else
// that of the nearest timber with one
};
// a model sleepers or timbers are made of, as found in it
@@ -119,6 +121,9 @@ beam_model const *plain_model();
// the models the track lays its beams of: those set for it with timbermodel and sleepermodel, else the ones of eu07.ini
beam_model const *timber_model( TTrack const &Track );
beam_model const *plain_model( TTrack const &Track );
// the model the track lays the timbers of the beams of: its own, else that of the tracks most of its timbers carry with one of their
// own, as a switch it shares its timbers with, else the one of eu07.ini
beam_model const *timber_model( TTrack const &Track, std::vector<beam> const &Beams );
// how long the plain sleepers of the track are, of the model it lays them of; 2.6 m at the standard gauge where there's none
double plain_length( TTrack const &Track );
// whether the track has the ballast the simulator makes, which the beams are laid on when there's a model of them