mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-20 19:37:44 +02:00
editormodeselftest.cpp keeps the dispatch, the list of the commands and the step; the groups go to
editormodeselftest{scene,sleepers,sweep,track,switch,join,signal,terrain,rails}.cpp, the sleeper commands (beams,
sharedzones, sleepersbg, beamsnear, sleepercheck) in a group of their own; the frame count and one_line shared through
editormodeselftest.h. The output of geomhash, sleepercheck, wings, space, guards, crossings and switches is the same on the
seven sceneries of the regression.
165 lines
6.7 KiB
C++
165 lines
6.7 KiB
C++
/*
|
|
This Source Code Form is subject to the
|
|
terms of the Mozilla Public License, v.
|
|
2.0. If a copy of the MPL was not
|
|
distributed with this file, You can
|
|
obtain one at
|
|
http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "application/editormode.h"
|
|
#include "editor/editorSettings.hpp"
|
|
#include "editor/editorGeometry.hpp"
|
|
#include "application/application.h"
|
|
#include "application/editoruilayer.h"
|
|
#include "application/editorprojection.h"
|
|
|
|
#include "simulation/simulation.h"
|
|
#include "simulation/simulationtime.h"
|
|
#include "scene/scenelayers.h"
|
|
#include "utilities/Globals.h"
|
|
#include "utilities/Logs.h"
|
|
#include "world/Track.h"
|
|
#include "world/TrackRails.h"
|
|
#include "world/MemCell.h"
|
|
#include "world/Event.h"
|
|
#include "vehicle/DynObj.h"
|
|
#include "model/AnimModel.h"
|
|
#include "model/Model3d.h"
|
|
#include "rendering/renderer.h"
|
|
#include "world/Sweep.h"
|
|
#include "input/keyboardinput.h"
|
|
#include "launcher/textures_scanner.h"
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
#include <algorithm>
|
|
#include "editor/editorFormat.hpp"
|
|
#include "editor/editorAlignmentStore.hpp"
|
|
#include "editor/editorSwitchStore.hpp"
|
|
#include "scene/sceneterrain.h"
|
|
#include "editor/editorSpeed.hpp"
|
|
|
|
#include <chrono>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <fstream>
|
|
#include <map>
|
|
#include <sstream>
|
|
#include "application/editormodeselftest.h"
|
|
|
|
#include "world/TrackSleepers.h"
|
|
|
|
editor_mode::selftest_result editor_mode::selftest_sleepers(std::string const &command, std::istringstream &words)
|
|
{
|
|
if (command == "beams")
|
|
{
|
|
// the beams the track lays, between two distances along it: their middles, lengths and the way they lie square to
|
|
std::string name;
|
|
double from{-1e9}, to{1e9};
|
|
words >> name >> from >> to;
|
|
auto *track{simulation::Paths.find(name)};
|
|
if (track == nullptr || false == track->m_sleepers3d.active)
|
|
{
|
|
WriteLog("SELFTEST beams: no track with beams " + name);
|
|
return selftest_result::handled;
|
|
}
|
|
std::string text;
|
|
for (auto const &beam : track_sleepers::place(*track))
|
|
{
|
|
auto const middle{0.5 * (beam.from + beam.to)};
|
|
if (middle.z < from || middle.z > to)
|
|
continue;
|
|
text += format(" [%.2f %.2f L%.2f a%.2f%s]", middle.x, middle.z, glm::length(beam.to - beam.from), glm::degrees(std::atan2(beam.along.x, beam.along.z)), beam.plain ? " p" : "");
|
|
}
|
|
WriteLog("SELFTEST beams " + name + ":" + text);
|
|
return selftest_result::handled;
|
|
}
|
|
if (command == "sharedzones")
|
|
{
|
|
// how far the timbers shared with other tracks reach along the paths of the track and of the tracks joined to its ends
|
|
std::string name;
|
|
words >> name;
|
|
auto *track{simulation::Paths.find(name)};
|
|
if (track == nullptr)
|
|
{
|
|
WriteLog("SELFTEST sharedzones: no track " + name);
|
|
return selftest_result::handled;
|
|
}
|
|
auto const zones_text = [](TTrack const &Track, int const Path) {
|
|
std::string text;
|
|
for (auto const &zone : track_sleepers::shared_zones(Track, Path))
|
|
text += format(" %.2f..%.2f", zone.first, zone.second);
|
|
return text.empty() ? std::string{" none"} : text;
|
|
};
|
|
auto const paths{track->eType == tt_Switch ? 2 : 1};
|
|
for (int path = 0; path < paths; ++path)
|
|
{
|
|
auto const length{track->eType == tt_Switch ? track->SwitchExtension->Segments[path]->GetLength() : track->Segment->GetLength()};
|
|
WriteLog(format("SELFTEST sharedzones %s path %d (%.2f m):%s", name.c_str(), path, length, zones_text(*track, path).c_str()));
|
|
// the track going on from the end of the path, and how far past the end the shared timbers reach along it
|
|
auto *next{track->eType == tt_Switch ? track->SwitchExtension->pNexts[path] : track->trNext};
|
|
if (next == nullptr || next->eType != tt_Normal || next->Segment == nullptr)
|
|
continue;
|
|
glm::dvec3 end, start, unused;
|
|
glm::vec3 angles;
|
|
(track->eType == tt_Switch ? track->SwitchExtension->Segments[path] : track->Segment)->RaPositionGet(length, end, angles);
|
|
next->Segment->RaPositionGet(0.0, start, angles);
|
|
auto const fromstart{glm::length(start - end) < 0.1};
|
|
auto past{0.0};
|
|
for (auto const &zone : track_sleepers::shared_zones(*next, 0))
|
|
{
|
|
if (fromstart && zone.first < 0.05)
|
|
past = zone.second;
|
|
else if (false == fromstart && zone.second > next->Segment->GetLength() - 0.05)
|
|
past = next->Segment->GetLength() - zone.first;
|
|
}
|
|
WriteLog(format("SELFTEST sharedzones %s path %d goes on into %s:%s; shared timbers reach %.2f m past the end", name.c_str(), path, next->name().c_str(), zones_text(*next, 0).c_str(), past));
|
|
}
|
|
return selftest_result::handled;
|
|
}
|
|
if (command == "sleepersbg")
|
|
{
|
|
// the sleepers worked out in the background as in the simulation, to see they come out the same, or back to as they're needed
|
|
int on{1};
|
|
words >> on;
|
|
track_sleepers::lay_in_background(on != 0);
|
|
for (auto *track : simulation::Paths.sequence())
|
|
if (track != nullptr)
|
|
track->m_sleepers3d.dirty = true;
|
|
track_sleepers::unsettle_around(*simulation::Paths.sequence().front());
|
|
WriteLog(format("SELFTEST sleepersbg %d", on));
|
|
return selftest_result::handled;
|
|
}
|
|
if (command == "beamsnear")
|
|
{
|
|
double x{0.0}, z{0.0}, radius{3.0};
|
|
words >> x >> z >> radius;
|
|
for (auto *track : simulation::Paths.sequence())
|
|
{
|
|
if (track == nullptr || track->m_editorremoved || false == track->m_sleepers3d.active)
|
|
continue;
|
|
for (auto const &beam : track_sleepers::place(*track))
|
|
{
|
|
auto const middle{0.5 * (beam.from + beam.to)};
|
|
if (glm::length(glm::dvec2{middle.x - x, middle.z - z}) > radius)
|
|
continue;
|
|
WriteLog(format("SELFTEST beam %s: %.2f %.2f -> %.2f %.2f, %.2f m, along %.1f deg%s", track->name().c_str(), beam.from.x, beam.from.z, beam.to.x, beam.to.z, glm::length(beam.to - beam.from), glm::degrees(std::atan2(beam.along.x, beam.along.z)), beam.plain ? " plain" : ""));
|
|
}
|
|
}
|
|
return selftest_result::handled;
|
|
}
|
|
if (command == "sleepercheck")
|
|
{
|
|
auto const start{std::chrono::steady_clock::now()};
|
|
auto const result{track_sleepers::check()};
|
|
WriteLog(format("SELFTEST sleepercheck: %zu beams, %zu overlaps, %zu gaps, %zu bare rails, %zu too long (longest %.2f m), widest spacing %.2f m at %s; %zu shared off one plane, %zu switch panels off one plane, %zu ends clipped, %zu beams dropped, slowest cluster %.1f ms of %zu tracks; digest %016llx; in %.1f ms",
|
|
result.beams, result.overlaps, result.gaps, result.bare, result.toolong, result.longest, result.widest, result.widestat.c_str(), result.offplane, result.panels, result.clipped, result.dropped, result.slowest, result.biggest, static_cast<unsigned long long>(result.digest),
|
|
std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start).count()));
|
|
for (auto const &example : result.examples)
|
|
WriteLog("SELFTEST sleepercheck " + example);
|
|
return selftest_result::handled;
|
|
}
|
|
return selftest_result::unhandled;
|
|
}
|