mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-06 18:38:36 +01:00
Merge remote-tracking branch 'origin/feat/switch-fastenings' into feat/renderers-cleanup
This commit is contained in:
@@ -75,6 +75,7 @@ editor_mode::selftest_result editor_mode::selftest_dispatch(std::string const &c
|
||||
// railtime lays out the rails of every track, as when its geometry is made, and logs how long it took
|
||||
// throw <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 and of what kind (acute, obtuse, middle acute or obtuse, wide), checks that each acute crossing has one partner and one nose
|
||||
// fastentour [cell] [frames] the camera over each cell of the grid with switches laying timbers in turn, for a fastencheck after of the whole scenery
|
||||
// switchtimbers <model|none> the model of the timbers set on all the switches and crossings, as the buttons of the switch tool do it
|
||||
// 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; exact: the bits of every value, userdata and tread materials too
|
||||
|
||||
@@ -49,6 +49,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "application/editormodeselftest.h"
|
||||
|
||||
#include "world/TrackSleepers.h"
|
||||
#include "world/SleeperFastenings.h"
|
||||
|
||||
editor_mode::selftest_result editor_mode::selftest_sleepers(std::string const &command, std::istringstream &words)
|
||||
{
|
||||
@@ -149,6 +150,128 @@ editor_mode::selftest_result editor_mode::selftest_sleepers(std::string const &c
|
||||
}
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "fastenings")
|
||||
{
|
||||
// the fastenings on the timbers of the track: along the track, the part and where across it, which way its +x goes
|
||||
std::string name, detail;
|
||||
words >> name >> detail;
|
||||
auto *track{simulation::Paths.find(name)};
|
||||
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");
|
||||
return selftest_result::handled;
|
||||
}
|
||||
track_sleepers::fastened_rails const rails{*track};
|
||||
std::array<int, track_sleepers::part_count> counts{};
|
||||
for (auto const &beam : beams)
|
||||
{
|
||||
if (beam.plain)
|
||||
continue;
|
||||
auto const middle{0.5 * (beam.from + beam.to)};
|
||||
std::string text{format("SELFTEST fastenings %s at %.2f %.2f:", track->name().c_str(), middle.x, middle.z)};
|
||||
if (detail == "rails")
|
||||
{
|
||||
auto const span{beam.to - beam.from};
|
||||
auto const length{glm::length(glm::dvec2{span.x, span.z})};
|
||||
text += " rails";
|
||||
for (auto const &rail : rails.lying(beam))
|
||||
{
|
||||
auto const at{beam.from + span * (rail.at / length)};
|
||||
text += format(" %.3f %.3f k%d r%.3f;", at.x, at.z, static_cast<int>(rail.kind), rail.rise);
|
||||
}
|
||||
text += " parts";
|
||||
}
|
||||
for (auto const &fastening : rails.on(beam, *model))
|
||||
{
|
||||
text += format(" %s%s %.3f %.3f %+.0f", fastening.pad ? "pad:" : "", track_sleepers::part_names[fastening.part], fastening.point.x, fastening.point.z, glm::degrees(std::atan2(fastening.across.y, fastening.across.x)));
|
||||
if (fastening.lift != 0.f)
|
||||
text += format(" ^%.3f", fastening.lift);
|
||||
if (detail == "rails" && (fastening.scale != 1.f || fastening.shift != 0.f))
|
||||
text += format(" s%.3f/%.3f/%.3f", fastening.scale, fastening.pivot, fastening.shift);
|
||||
if (false == fastening.pad)
|
||||
++counts[fastening.part];
|
||||
}
|
||||
WriteLog(text);
|
||||
}
|
||||
WriteLog(format("SELFTEST fastenings %s: %d plates, %d chairs, %d checks", track->name().c_str(), counts[track_sleepers::part_plate], counts[track_sleepers::part_chair], counts[track_sleepers::part_check]));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "fastentour")
|
||||
{
|
||||
// the camera over each cell of the grid with switches or crossings laying timbers, in turn, as the tracks get their beams only
|
||||
// near it: the steps of the tour go in after this one, a fastencheck after them takes the whole scenery
|
||||
double cell{400.0};
|
||||
int frames{40};
|
||||
words >> cell >> frames;
|
||||
std::map<std::pair<long, long>, glm::dvec3> stops;
|
||||
for (auto *track : simulation::Paths.sequence())
|
||||
{
|
||||
if (track == nullptr || track->m_editorremoved || (track->eType != tt_Switch && track->m_crossings.empty()) || false == track_sleepers::lays(*track))
|
||||
continue;
|
||||
auto const at{track->location()};
|
||||
stops.emplace(std::make_pair(std::lround(std::floor(at.x / cell)), std::lround(std::floor(at.z / cell))), at);
|
||||
}
|
||||
std::vector<std::string> steps;
|
||||
for (auto const &stop : stops)
|
||||
{
|
||||
auto const &at{stop.second};
|
||||
steps.push_back(format("camera %.2f %.2f %.2f %.2f %.2f %.2f", at.x, at.y + 60.0, at.z + 1.0, at.x, at.y, at.z));
|
||||
steps.push_back("wait " + std::to_string(frames));
|
||||
}
|
||||
m_selftest.lines.insert(m_selftest.lines.begin() + static_cast<std::ptrdiff_t>(m_selftest.next), steps.begin(), steps.end());
|
||||
WriteLog(format("SELFTEST fastentour: %zu stops of %.0f m", stops.size(), cell));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "fastencheck")
|
||||
{
|
||||
// the fastenings of all the tracks laying timbers with them: of each kind, and those over one another on a timber
|
||||
std::string mode;
|
||||
words >> mode;
|
||||
auto const verbose{mode == "all"};
|
||||
auto const start{std::chrono::steady_clock::now()};
|
||||
auto const rows{track_sleepers::check_fastenings()};
|
||||
std::size_t beams{0}, overlaps{0}, tracks{0}, bare{0};
|
||||
std::array<std::size_t, track_sleepers::part_count> parts{};
|
||||
for (auto const &row : rows)
|
||||
{
|
||||
beams += row.beams;
|
||||
overlaps += row.overlaps;
|
||||
bare += row.bares.size();
|
||||
tracks += (row.overlaps > 0 ? 1 : 0);
|
||||
for (int part = 0; part < track_sleepers::part_count; ++part)
|
||||
parts[part] += row.parts[part];
|
||||
WriteLog(format("SELFTEST fastencheck %s: %zu timbers, %zu plates, %zu chairs, %zu checks, %zu bare rails, %zu overlaps%s",
|
||||
row.track.c_str(), row.beams, row.parts[track_sleepers::part_plate], row.parts[track_sleepers::part_chair], row.parts[track_sleepers::part_check], row.bares.size(), row.overlaps,
|
||||
row.overlaps > 0 ? format(", worst %.3f m %s at %.2f %.2f", row.worst, row.worstparts.c_str(), row.worstat.x, row.worstat.z).c_str() : ""));
|
||||
if (verbose)
|
||||
for (auto const &at : row.bares)
|
||||
WriteLog(format("SELFTEST fastencheck bare %s at %.3f %.3f", row.track.c_str(), at.x, at.y));
|
||||
if (verbose)
|
||||
for (auto const &overlap : row.cases)
|
||||
WriteLog(format("SELFTEST fastencheck overlap %s %d %d apart %.3f over %.3f at %.2f %.2f", row.track.c_str(), overlap.parts[0], overlap.parts[1], overlap.apart, overlap.over, overlap.at.x, overlap.at.z));
|
||||
}
|
||||
WriteLog(format("SELFTEST fastencheck: %zu tracks, %zu timbers, %zu plates, %zu chairs, %zu checks, %zu bare rails, %zu overlaps on %zu tracks; in %.1f ms",
|
||||
rows.size(), beams, parts[track_sleepers::part_plate], parts[track_sleepers::part_chair], parts[track_sleepers::part_check], bare, overlaps, tracks,
|
||||
std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start).count()));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "checkseats")
|
||||
{
|
||||
// the check rails with timbers under them and no fastening seating them, along how much of them
|
||||
auto const gaps{track_sleepers::check_rail_seats()};
|
||||
double bare{0.0};
|
||||
std::size_t unsupported{0};
|
||||
for (auto const &gap : gaps)
|
||||
{
|
||||
bare += gap.bare;
|
||||
unsupported += gap.unsupported;
|
||||
WriteLog(format("SELFTEST checkseats %s path %d side %+d %.2f-%.2f: %.0f of %zu timbers bare, %zu with nothing under, first at %.2f %.2f", gap.track.c_str(), gap.path, gap.side, gap.from, gap.to, gap.bare, gap.timbers, gap.unsupported, gap.at.x, gap.at.y));
|
||||
}
|
||||
WriteLog(format("SELFTEST checkseats: %zu check rails with %.0f timbers bare, %zu with nothing under", gaps.size(), bare, unsupported));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "sleepercheck")
|
||||
{
|
||||
auto const start{std::chrono::steady_clock::now()};
|
||||
|
||||
Reference in New Issue
Block a user