From 6533914024579150900627f304cf3752b49c5e56 Mon Sep 17 00:00:00 2001 From: maj00r Date: Tue, 27 Oct 2026 19:21:40 +0100 Subject: [PATCH] fix(track): the blades of a slip laid in the editor are shaped from their templates as the ones of a switch are, from the tip where their planed nose ends, so they start where the view marks the tips of the blades and the drive stands, not at the joint before them: the crossings of the diamond the blades end short of were looked for only among the tracks with their rails cut, which the simulator never cuts, so the slips kept the blades laid from the start of the switch. They're found now among the tracks with their rails whole too, for the blades of a slip only. Selftest bladetips: the blades of the four switches of an Rkpd 49E1-190-1:9 from 1.248 m to 7.55 m, as the drives; Rz 60E1-300-1:9 unchanged, 1.5 to 12.69 m --- world/RailCrossings.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/world/RailCrossings.cpp b/world/RailCrossings.cpp index 8d399eaf..e9cca18b 100644 --- a/world/RailCrossings.cpp +++ b/world/RailCrossings.cpp @@ -96,6 +96,16 @@ bool cut_rails( TTrack const &Track ) { Track.eType == tt_Switch && Track.SwitchExtension && Track.SwitchExtension->m_frogs && Track.SwitchExtension->Segments[ 0 ] && Track.SwitchExtension->Segments[ 1 ] ); } +// a track with rails laid, cut or whole +bool railed( TTrack const &Track ) { + + return ( Track.iCategoryFlag & 15 ) == 1 + && Track.m_material1 != null_handle + && false == Track.m_editorremoved + && ( Track.eType == tt_Normal ? Track.Segment != nullptr : + Track.eType == tt_Switch && Track.SwitchExtension && Track.SwitchExtension->Segments[ 0 ] && Track.SwitchExtension->Segments[ 1 ] ); +} + bool shaped_blades( TTrack const &Track ) { if( cut_rails( Track ) ) { @@ -105,8 +115,7 @@ bool shaped_blades( TTrack const &Track ) { && ( Track.iCategoryFlag & 15 ) == 1 && Track.m_material1 != null_handle && false == Track.m_editorremoved - && Track.eType == tt_Switch && Track.SwitchExtension && Track.SwitchExtension->m_frogs && Track.SwitchExtension->Segments[ 0 ] && Track.SwitchExtension->Segments[ 1 ] - && false == Track.DoubleSlip(); + && Track.eType == tt_Switch && Track.SwitchExtension && Track.SwitchExtension->m_frogs && Track.SwitchExtension->Segments[ 0 ] && Track.SwitchExtension->Segments[ 1 ]; } int blade_steps( TTrack const &Track, int const Path ) { @@ -252,7 +261,8 @@ struct rail_run { double length { 0.0 }; }; -std::vector nearby_rails( TTrack &Track ) { +// the tracks with rails around the track: the ones whose rails are cut, or with Whole all of them +std::vector nearby_rails( TTrack &Track, bool const Whole = false ) { std::vector others; auto const sections { simulation::Region->sections( Track.location(), static_cast( Track.radius() + 50.0 ) ) }; @@ -262,7 +272,7 @@ std::vector nearby_rails( TTrack &Track ) { continue; } for( auto *other : cell.m_directories.paths ) { - if( other == nullptr || other == &Track || false == cut_rails( *other ) ) { + if( other == nullptr || other == &Track || false == ( Whole ? railed( *other ) : cut_rails( *other ) ) ) { continue; } if( glm::length( other->location() - Track.location() ) > other->radius() + Track.radius() + 1.0 ) { @@ -427,11 +437,12 @@ std::vector own_crossings( TTrack &Track ) { // with the blades of the other parts left out of the account, as they're yet to be made as short; at the latest short of their throats, // the check rails then cut to begin past the heels // crossings of the rails of the track with the rails of the tracks around, with the blades of switches left out of the account -std::vector unbladed_crossings( TTrack const &Track ) { +// Whole: the rails of the tracks around taken whole too, where they aren't cut +std::vector unbladed_crossings( TTrack const &Track, bool const Whole = false ) { auto &track { const_cast( Track ) }; std::vector found; - for( auto *other : nearby_rails( track ) ) { + for( auto *other : nearby_rails( track, Whole ) ) { for( int otherpath = 0; otherpath < path_count( *other ); ++otherpath ) { rail_run theirs { other, otherpath }; theirs.length = path_segment( *other, otherpath ).GetLength(); @@ -453,7 +464,8 @@ std::pair slip_blade_reach( TTrack const &Track ) { auto reach { 1e9 }; auto latest { 1e9 }; - for( auto const &crossing : unbladed_crossings( Track ) ) { + // the crossings of the diamond end the blades whether its rails are cut there or laid whole + for( auto const &crossing : unbladed_crossings( Track, true ) ) { if( crossing.angle <= middle_angle ) { auto const slope { std::tan( crossing.angle ) }; reach = std::min( reach, crossing.at - 0.25 - 0.5 * check_length( slope ) - 0.3 );