diff --git a/world/RailCrossings.cpp b/world/RailCrossings.cpp index 1b94e94c..8d399eaf 100644 --- a/world/RailCrossings.cpp +++ b/world/RailCrossings.cpp @@ -96,6 +96,19 @@ bool cut_rails( TTrack const &Track ) { Track.eType == tt_Switch && Track.SwitchExtension && Track.SwitchExtension->m_frogs && Track.SwitchExtension->Segments[ 0 ] && Track.SwitchExtension->Segments[ 1 ] ); } +bool shaped_blades( TTrack const &Track ) { + + if( cut_rails( Track ) ) { + return true; + } + return track_features::blades + && ( 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(); +} + int blade_steps( TTrack const &Track, int const Path ) { return static_cast( std::ceil( Track.SwitchExtension->Segments[ Path ]->RaSegCount() * 0.65 ) ); @@ -131,7 +144,7 @@ TTrack const *runon_track( TTrack const &Switch, int const Path ) { double blade_runon( TTrack const &Track, int const Side ) { auto const *owner { Track.trPrev }; - if( Track.eType != tt_Normal || Track.Segment == nullptr || owner == nullptr || owner->eType != tt_Switch || false == cut_rails( *owner ) ) { + if( Track.eType != tt_Normal || Track.Segment == nullptr || owner == nullptr || owner->eType != tt_Switch || false == shaped_blades( *owner ) ) { return 0.0; } for( int path = 0; path < 2; ++path ) { @@ -831,7 +844,7 @@ track_rails::switch_blade const &TTrack::blade( int const Path ) const { } cached = switch_blade {}; auto &result { *cached }; - if( eType != tt_Switch || false == cut_rails( *this ) || m_profiles.empty() ) { + if( eType != tt_Switch || false == shaped_blades( *this ) || m_profiles.empty() ) { return result; } auto const side { blade_side( Path ) }; diff --git a/world/Track.cpp b/world/Track.cpp index 771ae2e8..f13e6f97 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -1637,7 +1637,13 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) { continue; } vertices.clear(); // reuse the scratchpad - Segment->RenderLoft( vertices, m_origin, profile, iTrapezoid > 0, texturelength ); + // the rail starts behind the heel of a blade running on into the track from the switch before it + if( auto const runon { eType == tt_Normal && iTrapezoid == 0 ? track_rails::blade_runon( *this, side ) : 0.0 }; runon > 0.0 ) { + Segment->RenderLoftSpan( vertices, m_origin, profile, { .side = side, .halfwidth = 0.5f * std::abs( fTrackWidth ), .texturelength = texturelength, .from = runon, .to = Segment->GetLength() } ); + } + else { + Segment->RenderLoft( vertices, m_origin, profile, iTrapezoid > 0, texturelength ); + } if( open ) { cut_faces( vertices, nnumPts, trPrev == nullptr, trNext == nullptr, GeometryCut1 ); } diff --git a/world/TrackFeatures.h b/world/TrackFeatures.h index e9b13768..366a91a2 100644 --- a/world/TrackFeatures.h +++ b/world/TrackFeatures.h @@ -17,5 +17,8 @@ namespace track_features { bool constexpr crossings { false }; // the 3D sleepers and switch timbers of sleepers3d; off, the tracks keep their ballast whatever eu07.ini sets bool constexpr sleepers { false }; +// the blades of the switches with the key frogs shaped as their templates have them, from the tip their planed nose ends at to the heel, +// with the rails left whole where the crossings are off; off with the crossings too, they're laid from the start of the switch as before +bool constexpr blades { true }; } // namespace track_features diff --git a/world/TrackRails.h b/world/TrackRails.h index 92c68c61..de1c69e2 100644 --- a/world/TrackRails.h +++ b/world/TrackRails.h @@ -33,6 +33,9 @@ double check_length( double const Slope ); double movable_nose_length( double const Slope ); // the rails of the track are cut where they cross other rails: plain tracks, and switches whose frog is made from the rails bool cut_rails( TTrack const &Track ); +// the blades of the switch are shaped from the tip to the heel: with the rails cut, or alone where only the blades are on, but for the +// switches of a double slip, whose blades end short of crossings found only with the rails cut +bool shaped_blades( TTrack const &Track ); int blade_steps( TTrack const &Track, int const Path ); double blade_length( TTrack const &Track, int const Path ); // the plain track a path of a switch goes on into at its end, laid the same way, which the blade of the path may run on into