diff --git a/application/editormodeselftest.cpp b/application/editormodeselftest.cpp index a7bc68fb..fe43cfce 100644 --- a/application/editormodeselftest.cpp +++ b/application/editormodeselftest.cpp @@ -48,6 +48,7 @@ http://mozilla.org/MPL/2.0/. // frog [name] logs where the inner rails of each switch cross: distance on both paths, 1:n, throat, nose, check rails // guards [name] logs each guard rail and what each of its ends and breaks is cut along; a fault when a cut is not along a rail or a glued end not on the guard rail of the other track // railtime lays out the rails of every track, as when its geometry is made, and logs how long it took +// switches <0|1> sets every switch to the path and moves its blades there at once // crossings [name] logs where rails of tracks cross rails of other tracks, checks that each acute crossing has one partner and one nose // frogkey name [on|off] sets or clears the frogs key of a switch (one undo step); logs the key, whether it is written, the frog and the crossings // geomhash [name] logs the number of vertices and a hash of the drawn geometry of each rail track (rails, trackbed, cut faces), to compare builds @@ -345,6 +346,22 @@ void editor_mode::selftest_step() } WriteLog(format("SELFTEST guards: %d guard rails, %d faults", count, faults)); } + else if (command == "switches") + { + int path{0}; + words >> path; + int count{0}; + for (auto *track : simulation::Paths.sequence()) + { + if (track == nullptr || track->m_editorremoved || track->eType != tt_Switch || track->SwitchExtension == nullptr) + continue; + track->Switch(path); + track->SwitchExtension->fOffset = track->SwitchExtension->fDesiredOffset; + track->RaAnimate(); + ++count; + } + WriteLog(format("SELFTEST switches: %d switches set to path %d", count, path)); + } else if (command == "railtime") { track_rails::forget(); diff --git a/world/Track.cpp b/world/Track.cpp index b2db24f3..a1a1ca16 100644 --- a/world/Track.cpp +++ b/world/Track.cpp @@ -2145,6 +2145,15 @@ TTrack * TTrack::RaAnimate() gfx::vertex_array vertices; auto const bladelength { track_rails::blade_steps( *this ) }; auto const nnumPts { track_rail_profile( m_profile1.second ).size() / 2 }; + auto const replace_blade = [&]( geometryhandle_sequence const &Geometry, geometryhandle_sequence const &Cuts ) { + if( false == Cuts.empty() ) { + gfx::vertex_array triangles; + track_rails::cap_loft( vertices, nnumPts, true, false, triangles ); + auto userdata { track_rails::worn_userdata( triangles.size() ) }; + GfxRenderer->Replace( triangles, userdata, Cuts[ 0 ], GL_TRIANGLES ); + } + GfxRenderer->Replace( vertices, empty_userdata, Geometry[ 0 ], GL_TRIANGLE_STRIP ); + vertices.clear(); }; if (SwitchExtension->RightSwitch) { // nowa wersja z SPKS, ale odwrotnie lewa/prawa if( m_material1 ) { @@ -2153,14 +2162,7 @@ TTrack * TTrack::RaAnimate() // composed from two parts: transition from blade to regular rail, and regular rail SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { SwitchExtension->fOffset2, SwitchExtension->fOffset2 / 2 } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { SwitchExtension->fOffset2 / 2, 0.f } ); - if( false == GeometryCut1.empty() ) { - gfx::vertex_array triangles; - track_rails::cap_loft( vertices, nnumPts, true, false, triangles ); - auto userdata { track_rails::worn_userdata( triangles.size() ) }; - GfxRenderer->Replace(triangles, userdata, GeometryCut1[0], GL_TRIANGLES); - } - GfxRenderer->Replace(vertices, empty_userdata, Geometry1[0], GL_TRIANGLE_STRIP); - vertices.clear(); + replace_blade( Geometry1, GeometryCut1 ); } if( m_material2 ) { auto const texturelength { texture_length( m_material2 ) }; @@ -2168,14 +2170,7 @@ TTrack * TTrack::RaAnimate() // composed from two parts: transition from blade to regular rail, and regular rail SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -fMaxOffset + SwitchExtension->fOffset1, ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2 } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2, 0.f } ); - if( false == GeometryCut2.empty() ) { - gfx::vertex_array triangles; - track_rails::cap_loft( vertices, nnumPts, true, false, triangles ); - auto userdata { track_rails::worn_userdata( triangles.size() ) }; - GfxRenderer->Replace(triangles, userdata, GeometryCut2[0], GL_TRIANGLES); - } - GfxRenderer->Replace(vertices, empty_userdata, Geometry2[0], GL_TRIANGLE_STRIP); - vertices.clear(); + replace_blade( Geometry2, GeometryCut2 ); } } else { // lewa działa lepiej niż prawa @@ -2185,14 +2180,7 @@ TTrack * TTrack::RaAnimate() // composed from two parts: transition from blade to regular rail, and regular rail SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -SwitchExtension->fOffset2, -SwitchExtension->fOffset2 / 2 } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { -SwitchExtension->fOffset2 / 2, 0.f } ); - if( false == GeometryCut1.empty() ) { - gfx::vertex_array triangles; - track_rails::cap_loft( vertices, nnumPts, true, false, triangles ); - auto userdata { track_rails::worn_userdata( triangles.size() ) }; - GfxRenderer->Replace(triangles, userdata, GeometryCut1[0], GL_TRIANGLES); - } - GfxRenderer->Replace(vertices, empty_userdata, Geometry1[0], GL_TRIANGLE_STRIP); - vertices.clear(); + replace_blade( Geometry1, GeometryCut1 ); } if( m_material2 ) { auto const texturelength { texture_length( m_material2 ) }; @@ -2200,14 +2188,7 @@ TTrack * TTrack::RaAnimate() // composed from two parts: transition from blade to regular rail, and regular rail SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { fMaxOffset - SwitchExtension->fOffset1, ( fMaxOffset - SwitchExtension->fOffset1 ) / 2 } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { ( fMaxOffset - SwitchExtension->fOffset1 ) / 2, 0.f } ); - if( false == GeometryCut2.empty() ) { - gfx::vertex_array triangles; - track_rails::cap_loft( vertices, nnumPts, true, false, triangles ); - auto userdata { track_rails::worn_userdata( triangles.size() ) }; - GfxRenderer->Replace(triangles, userdata, GeometryCut2[0], GL_TRIANGLES); - } - GfxRenderer->Replace(vertices, empty_userdata, Geometry2[0], GL_TRIANGLE_STRIP); - vertices.clear(); + replace_blade( Geometry2, GeometryCut2 ); } } }