mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-29 04:37:30 +01:00
feat(editor): the station schematic generalized: each station track on a row of its own, the stretches between the switches shortened, the connections slanted between the rows, the signals and the useful lengths on the drawn tracks
This commit is contained in:
@@ -834,6 +834,7 @@ void srk_tool::open(TTrack &Track)
|
||||
return;
|
||||
}
|
||||
m_layout = std::move(found);
|
||||
m_plot = station::generalize(*m_layout);
|
||||
m_hover = -1;
|
||||
m_view_state.exaggeration = 0.0f;
|
||||
m_history_revision = m_history.history_revision();
|
||||
@@ -3656,6 +3657,18 @@ void srk_tool::survey_signals()
|
||||
auto const ahead{station::project(*m_layout, signal.position + glm::dvec3{travel.x, 0.0, travel.y} * 5.0)};
|
||||
auto const unfit{std::any_of(m_heads.begin(), m_heads.end(), [&](head_check const &Head) { return Head.instance == signal.instance && (false == Head.fits || false == Head.problems.empty()); })};
|
||||
m_signal_marks.push_back({at, ahead.x > at.x, signal_shown(signal.name, stem), signal.position + glm::dvec3{0.0, signal.kind == "shunt" ? 3.0 : 7.0, 0.0}, unfit});
|
||||
// in the plot on the track it stands by, to its side
|
||||
auto &mark{m_signal_marks.back()};
|
||||
mark.drawn = m_plot.at(at);
|
||||
auto nearest{6.0};
|
||||
for (std::size_t path = 0; path < m_layout->paths.size(); ++path)
|
||||
for (std::size_t k = 0; k < m_layout->paths[path].schematic.size(); ++k)
|
||||
if (auto const &point{m_layout->paths[path].schematic[k]}; glm::distance(point, at) < nearest)
|
||||
{
|
||||
nearest = glm::distance(point, at);
|
||||
mark.drawn = m_plot.paths[path][k];
|
||||
mark.side = at.y > point.y ? 1.0f : -1.0f;
|
||||
}
|
||||
if (signal.kind != "main" && signal.kind != "shunt")
|
||||
continue;
|
||||
station::signal stop;
|
||||
@@ -4095,6 +4108,7 @@ void srk_tool::survey()
|
||||
m_circuit_of.assign(m_layout.has_value() ? m_layout->paths.size() : 0, -1);
|
||||
m_circuits.clear();
|
||||
m_ticks.clear();
|
||||
m_ticks_drawn.clear();
|
||||
m_lengths.clear();
|
||||
m_measured = false;
|
||||
m_numbered = false;
|
||||
@@ -4143,6 +4157,7 @@ void srk_tool::survey()
|
||||
nearest = distance;
|
||||
on = layout.paths[path].schematic[k];
|
||||
mark.world = layout.paths[path].points[k];
|
||||
mark.drawn = m_plot.paths[path][k];
|
||||
}
|
||||
mark.at = on;
|
||||
auto const entry{entry_circuit(mark.text, stem)};
|
||||
@@ -4161,6 +4176,7 @@ void srk_tool::survey()
|
||||
glm::dvec3 point;
|
||||
glm::dvec3 way;
|
||||
int circuit;
|
||||
glm::dvec2 drawn;
|
||||
};
|
||||
std::vector<end> ends;
|
||||
for (std::size_t index = 0; index < layout.paths.size(); ++index)
|
||||
@@ -4169,8 +4185,8 @@ void srk_tool::survey()
|
||||
if (points.size() < 2)
|
||||
continue;
|
||||
auto const circuit{m_circuit_of[index]};
|
||||
ends.push_back({points.front(), points[1] - points.front(), circuit});
|
||||
ends.push_back({points.back(), points.back() - points[points.size() - 2], circuit});
|
||||
ends.push_back({points.front(), points[1] - points.front(), circuit, m_plot.paths[index].front()});
|
||||
ends.push_back({points.back(), points.back() - points[points.size() - 2], circuit, m_plot.paths[index].back()});
|
||||
}
|
||||
m_joints.clear();
|
||||
for (std::size_t i = 0; i < ends.size(); ++i)
|
||||
@@ -4179,6 +4195,7 @@ void srk_tool::survey()
|
||||
std::none_of(m_joints.begin(), m_joints.end(), [&](joint_mark const &Joint) { return glm::distance(Joint.at, ends[i].point) < 0.05; }))
|
||||
{
|
||||
m_ticks.push_back(station::project(layout, ends[i].point));
|
||||
m_ticks_drawn.push_back(ends[i].drawn);
|
||||
glm::dvec2 const way{glm::normalize(glm::dvec2{ends[i].way.x, ends[i].way.z} + glm::dvec2{1e-12, 0.0})};
|
||||
m_joints.push_back({ends[i].point, glm::dvec3{-way.y, 0.0, way.x}});
|
||||
}
|
||||
@@ -4203,12 +4220,25 @@ void srk_tool::fit_view(float const Width, float const Height)
|
||||
from = std::min(from, row.chainage + row.outward * row.length);
|
||||
to = std::max(to, row.chainage + row.outward * row.length);
|
||||
}
|
||||
from = m_plot.x(from);
|
||||
to = m_plot.x(to);
|
||||
auto const span{std::max(50.0, to - from)};
|
||||
view.from = from - span * 0.04 - 30.0;
|
||||
view.to = to + span * 0.04 + 30.0;
|
||||
view.centre = (layout.low + layout.high) * 0.5;
|
||||
auto low{std::numeric_limits<double>::max()};
|
||||
auto high{std::numeric_limits<double>::lowest()};
|
||||
for (std::size_t index = 0; index < layout.paths.size() && index < m_plot.paths.size(); ++index)
|
||||
if (false == layout.paths[index].approach)
|
||||
for (auto const &point : m_plot.paths[index])
|
||||
{
|
||||
low = std::min(low, point.y);
|
||||
high = std::max(high, point.y);
|
||||
}
|
||||
if (low > high)
|
||||
low = high = 0.0;
|
||||
view.centre = (low + high) * 0.5;
|
||||
auto const across{(view.to - view.from) / std::max(1.0f, Width)};
|
||||
auto const vertical{(layout.high - layout.low + 20.0) / std::max(1.0f, Height * 0.75f)};
|
||||
auto const vertical{(high - low + 2.0 * station::row_height) / std::max(1.0f, Height * 0.85f)};
|
||||
view.exaggeration = static_cast<float>(std::clamp(across / vertical, 1.0, 500.0));
|
||||
}
|
||||
|
||||
@@ -4245,9 +4275,16 @@ void srk_tool::render_canvas(float const Height)
|
||||
view.to -= io.MouseDelta.x * across;
|
||||
view.centre += io.MouseDelta.y * vertical;
|
||||
}
|
||||
auto const x_of = [&](double const Chainage) { return corner.x + static_cast<float>((Chainage - view.from) / across); };
|
||||
auto const y_of = [&](double const Offset) { return corner.y + size.y * 0.5f - static_cast<float>((Offset - view.centre) / vertical); };
|
||||
auto const screen_of = [&](glm::dvec2 const &Point) { return ImVec2(x_of(Point.x), y_of(Point.y)); };
|
||||
// the plot draws the generalized schematic: its x shortens the chainage between the switches, its height puts the tracks on rows
|
||||
auto const plot_x = [&](double const X) { return corner.x + static_cast<float>((X - view.from) / across); };
|
||||
auto const plot_y = [&](double const Height) { return corner.y + size.y * 0.5f - static_cast<float>((Height - view.centre) / vertical); };
|
||||
auto const x_of = [&](double const Chainage) { return plot_x(m_plot.x(Chainage)); };
|
||||
auto const screen_of = [&](glm::dvec2 const &Point) { return ImVec2(plot_x(Point.x), plot_y(Point.y)); };
|
||||
auto const chainage_at = [&](float const Mouse) { return m_plot.chainage(view.from + (Mouse - corner.x) * across); };
|
||||
auto const drawn_of = [&](std::size_t const Index) -> std::vector<glm::dvec2> const & {
|
||||
static std::vector<glm::dvec2> const none;
|
||||
return Index < m_plot.paths.size() ? m_plot.paths[Index] : none;
|
||||
};
|
||||
|
||||
// the path under the mouse
|
||||
if (hovered && false == m_dragging)
|
||||
@@ -4257,7 +4294,7 @@ void srk_tool::render_canvas(float const Height)
|
||||
auto const &mouse{io.MousePos};
|
||||
for (int index = 0; index < static_cast<int>(layout.paths.size()); ++index)
|
||||
{
|
||||
auto const &points{layout.paths[index].schematic};
|
||||
auto const &points{drawn_of(index)};
|
||||
for (std::size_t i = 1; i < points.size(); ++i)
|
||||
{
|
||||
auto const a{screen_of(points[i - 1])};
|
||||
@@ -4286,8 +4323,8 @@ void srk_tool::render_canvas(float const Height)
|
||||
for (std::size_t index = 0; index < m_lines.size() && index < m_line_ways.size() && line_hover < 0; ++index)
|
||||
{
|
||||
auto const &row{m_lines[index]};
|
||||
auto const distance{(view.from + (io.MousePos.x - corner.x) * across - row.chainage) * row.outward};
|
||||
if (std::abs(io.MousePos.y - y_of(row.offset)) < 6.0f && distance >= 0.0 && distance <= row.length)
|
||||
auto const distance{(chainage_at(io.MousePos.x) - row.chainage) * row.outward};
|
||||
if (std::abs(io.MousePos.y - plot_y(m_plot.at({row.chainage, row.offset}).y)) < 6.0f && distance >= 0.0 && distance <= row.length)
|
||||
{
|
||||
line_hover = static_cast<int>(index);
|
||||
line_at = distance;
|
||||
@@ -4318,37 +4355,44 @@ void srk_tool::render_canvas(float const Height)
|
||||
draw->PushClipRect(corner, corner_end, true);
|
||||
// the km, or the chainage, along the top
|
||||
{
|
||||
auto const metres{across * 90.0};
|
||||
auto const first{chainage_at(corner.x)};
|
||||
auto const last{chainage_at(corner_end.x)};
|
||||
auto const metres{(last - first) / size.x * 90.0};
|
||||
double step{10.0};
|
||||
for (auto const candidate : {10.0, 20.0, 50.0, 100.0, 200.0, 500.0, 1000.0, 2000.0, 5000.0})
|
||||
if ((step = candidate) >= metres)
|
||||
break;
|
||||
// the km of the station where it has them, else the chainage
|
||||
// the km of the station where it has them, else the chainage; the shortened stretches skip the marks too near
|
||||
double km_from{0.0};
|
||||
double km_to{0.0};
|
||||
auto const kilometrage{km_of_open(view.from, km_from) && km_of_open(view.to, km_to) && std::abs(km_to - km_from) > 1e-6};
|
||||
auto const low{kilometrage ? std::min(km_from, km_to) * 1000.0 : view.from};
|
||||
auto const high{kilometrage ? std::max(km_from, km_to) * 1000.0 : view.to};
|
||||
auto const kilometrage{km_of_open(first, km_from) && km_of_open(last, km_to) && std::abs(km_to - km_from) > 1e-6};
|
||||
auto const low{kilometrage ? std::min(km_from, km_to) * 1000.0 : first};
|
||||
auto const high{kilometrage ? std::max(km_from, km_to) * 1000.0 : last};
|
||||
auto shown{std::numeric_limits<float>::lowest()};
|
||||
for (auto mark{std::ceil(low / step) * step}; mark <= high; mark += step)
|
||||
{
|
||||
auto const x{x_of(kilometrage ? view.from + (mark / 1000.0 - km_from) / (km_to - km_from) * (view.to - view.from) : mark)};
|
||||
draw->AddLine(ImVec2(x, corner.y), ImVec2(x, corner_end.y), IM_COL32(255, 255, 255, 16));
|
||||
auto const x{x_of(kilometrage ? first + (mark / 1000.0 - km_from) / (km_to - km_from) * (last - first) : mark)};
|
||||
auto const label{kilometrage ? format("km %.3f", mark / 1000.0) : format("%.0f m", mark)};
|
||||
if (std::abs(x - shown) < ImGui::CalcTextSize(label.c_str()).x + 12.0f)
|
||||
continue;
|
||||
shown = x;
|
||||
draw->AddLine(ImVec2(x, corner.y), ImVec2(x, corner_end.y), IM_COL32(255, 255, 255, 16));
|
||||
draw->AddText(ImVec2(x + 3.0f, corner.y + 2.0f), IM_COL32(150, 155, 165, 255), label.c_str());
|
||||
}
|
||||
}
|
||||
auto const *selected{m_selection.selected_track()};
|
||||
auto const draw_path = [&](station::path const &Path, ImU32 const Colour, float const Width) {
|
||||
for (std::size_t i = 1; i < Path.schematic.size(); ++i)
|
||||
draw->AddLine(screen_of(Path.schematic[i - 1]), screen_of(Path.schematic[i]), Colour, Width);
|
||||
auto const draw_path = [&](std::size_t const Index, ImU32 const Colour, float const Width) {
|
||||
auto const &points{drawn_of(Index)};
|
||||
for (std::size_t i = 1; i < points.size(); ++i)
|
||||
draw->AddLine(screen_of(points[i - 1]), screen_of(points[i]), Colour, Width);
|
||||
};
|
||||
for (auto const &path : layout.paths)
|
||||
if (path.approach)
|
||||
draw_path(path, kApproach, 2.0f);
|
||||
for (std::size_t index = 0; index < layout.paths.size(); ++index)
|
||||
if (layout.paths[index].approach)
|
||||
draw_path(index, kApproach, 2.0f);
|
||||
for (std::size_t index = 0; index < layout.paths.size(); ++index)
|
||||
if (auto const &path{layout.paths[index]}; false == path.approach || m_circuit_of[index] >= 0)
|
||||
draw_path(path, m_circuit_of[index] >= 0 ? m_circuits[m_circuit_of[index]].colour : is_switch(*path.track) ? kSwitch : kPlain, 2.5f);
|
||||
for (auto const &tick : m_ticks)
|
||||
draw_path(index, m_circuit_of[index] >= 0 ? m_circuits[m_circuit_of[index]].colour : is_switch(*path.track) ? kSwitch : kPlain, 2.5f);
|
||||
for (auto const &tick : m_ticks_drawn)
|
||||
{
|
||||
auto const at{screen_of(tick)};
|
||||
draw->AddLine(ImVec2(at.x, at.y - 5.0f), ImVec2(at.x, at.y + 5.0f), IM_COL32(255, 255, 255, 220), 2.0f);
|
||||
@@ -4358,7 +4402,7 @@ void srk_tool::render_canvas(float const Height)
|
||||
for (std::size_t index = 0; index < m_lines.size(); ++index)
|
||||
{
|
||||
auto const &row{m_lines[index]};
|
||||
auto const y{y_of(row.offset)};
|
||||
auto const y{plot_y(m_plot.at({row.chainage, row.offset}).y)};
|
||||
draw->AddLine(ImVec2(line_x(row, 0.0), y), ImVec2(line_x(row, row.length), y), kApproach, 2.0f);
|
||||
for (std::size_t k = 0; k < row.sections.size(); ++k)
|
||||
{
|
||||
@@ -4376,11 +4420,11 @@ void srk_tool::render_canvas(float const Height)
|
||||
draw->AddTriangleFilled(ImVec2(x - 4.0f * way, y - 4.0f), ImVec2(x - 4.0f * way, y + 4.0f), ImVec2(x + 4.0f * way, y), kSignal);
|
||||
}
|
||||
}
|
||||
for (auto const &path : layout.paths)
|
||||
if (path.track == selected)
|
||||
draw_path(path, overlay_color::selected, 4.0f);
|
||||
for (std::size_t index = 0; index < layout.paths.size(); ++index)
|
||||
if (layout.paths[index].track == selected)
|
||||
draw_path(index, overlay_color::selected, 4.0f);
|
||||
if (m_hover >= 0)
|
||||
draw_path(layout.paths[m_hover], kHovered, 4.0f);
|
||||
draw_path(static_cast<std::size_t>(m_hover), kHovered, 4.0f);
|
||||
// the useful lengths of the station track shown: of the trains to the right over it, to the left under it, an arrowhead where
|
||||
// they stop
|
||||
std::vector<std::pair<std::string, ImVec2>> useful;
|
||||
@@ -4396,7 +4440,7 @@ void srk_tool::render_canvas(float const Height)
|
||||
std::vector<ImVec2> line;
|
||||
for (auto const &point : stretch_of(track, part.rear.along, part.head.along))
|
||||
{
|
||||
auto at{screen_of(station::project(layout, point))};
|
||||
auto at{screen_of(m_plot.at(station::project(layout, point)))};
|
||||
at.y += shift;
|
||||
line.push_back(at);
|
||||
}
|
||||
@@ -4433,7 +4477,10 @@ void srk_tool::render_canvas(float const Height)
|
||||
for (std::size_t index = 0; index < layout.switches.size(); ++index)
|
||||
{
|
||||
auto const *track{layout.switches[index]};
|
||||
auto const at{screen_of(station::project(layout, track->m_paths.front().points[segment_data::point::start]))};
|
||||
auto at{screen_of(m_plot.at(station::project(layout, track->m_paths.front().points[segment_data::point::start])))};
|
||||
for (std::size_t path = 0; path < layout.paths.size(); ++path)
|
||||
if (layout.paths[path].track == track && layout.paths[path].index == 0 && false == drawn_of(path).empty())
|
||||
at = screen_of(drawn_of(path).front());
|
||||
draw->AddCircleFilled(at, 3.5f, kSwitch);
|
||||
auto text{track->name()};
|
||||
if (false == stem.empty() && text.size() > stem.size() && text.compare(0, stem.size(), stem) == 0)
|
||||
@@ -4448,7 +4495,8 @@ void srk_tool::render_canvas(float const Height)
|
||||
// the signals: a flag pointing the way of the trains they face
|
||||
for (auto const &mark : m_signal_marks)
|
||||
{
|
||||
auto const at{screen_of(mark.at)};
|
||||
auto at{screen_of(mark.drawn)};
|
||||
at.y -= mark.side * 6.0f;
|
||||
auto const way{mark.ahead ? 1.0f : -1.0f};
|
||||
auto const colour{mark.unfit ? kUnfit : kSignal};
|
||||
draw->AddTriangleFilled(ImVec2(at.x - 4.0f * way, at.y - 4.0f), ImVec2(at.x - 4.0f * way, at.y + 4.0f), ImVec2(at.x + 4.0f * way, at.y), colour);
|
||||
@@ -4458,7 +4506,7 @@ void srk_tool::render_canvas(float const Height)
|
||||
// track of a double-track one, under the lower
|
||||
for (auto const &row : m_lines)
|
||||
{
|
||||
auto const y{y_of(row.offset)};
|
||||
auto const y{plot_y(m_plot.at({row.chainage, row.offset}).y)};
|
||||
auto const up{row.partner < 0 || row.partner >= static_cast<int>(m_lines.size()) || row.offset >= m_lines[row.partner].offset};
|
||||
auto const outside = [&](float const Tall, float const Level) { return up ? y - 5.0f - (Tall + 3.0f) * Level + 3.0f : y + 5.0f + (Tall + 3.0f) * (Level - 1.0f); };
|
||||
auto const tall{height * (row.km_known ? 2.0f : 1.0f)};
|
||||
@@ -4483,14 +4531,14 @@ void srk_tool::render_canvas(float const Height)
|
||||
for (auto const index : order)
|
||||
{
|
||||
auto const &mark{m_circuits[index]};
|
||||
auto const at{screen_of(mark.at)};
|
||||
auto const at{screen_of(mark.drawn)};
|
||||
label(mark.text, mark.colour, {ImVec2(at.x, at.y + 4.0f), ImVec2(at.x, at.y - height - 4.0f)});
|
||||
}
|
||||
draw->PopClipRect();
|
||||
if (hovered && m_hover >= 0 && false == m_dragging)
|
||||
{
|
||||
auto const &path{layout.paths[m_hover]};
|
||||
auto const along{view.from + (io.MousePos.x - corner.x) * across};
|
||||
auto const along{chainage_at(io.MousePos.x)};
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::TextUnformatted(path.track->name().empty() ? STR_C("(no name)") : path.track->name().c_str());
|
||||
ImGui::TextDisabled("%s, %.1f m", is_switch(*path.track) ? STR_C("switch") : path.approach ? STR_C("line out of the station") : STR_C("track"), path.length);
|
||||
@@ -5057,6 +5105,66 @@ editor_selftest_result srk_tool::selftest(std::string const &Command, std::istri
|
||||
WriteLog(format("SELFTEST srkfix: %zu problems before, status %s", before, m_status.c_str()));
|
||||
return editor_selftest_result::handled;
|
||||
}
|
||||
if (Command == "srkdrawing")
|
||||
{
|
||||
// srkdrawing [track=<circuit>]: the schematic as the plot draws it: the rows of the tracks, the shortened chainage, the points
|
||||
// on the rows, on slants, the corners; the points of the paths of the circuit, offset > row
|
||||
if (false == m_layout.has_value())
|
||||
{
|
||||
WriteLog("SELFTEST srkdrawing: no station open");
|
||||
return editor_selftest_result::handled;
|
||||
}
|
||||
auto const &layout{*m_layout};
|
||||
std::map<int, std::string> rows;
|
||||
for (auto const &run : m_plot.runs)
|
||||
if (false == run.paths.empty())
|
||||
rows[run.row] += format(" %s@%.1f", layout.paths[run.paths.front()].track->name().c_str(), run.offset);
|
||||
std::string list;
|
||||
for (auto const &[row, names] : rows)
|
||||
list += format(" |%d:", row) + names;
|
||||
WriteLog(format("SELFTEST srkdrawing tracks %zu, rows %zu, spacing %.2f", m_plot.runs.size(), rows.size(), m_plot.spacing));
|
||||
WriteLog("SELFTEST srkdrawing rows" + list);
|
||||
WriteLog(format("SELFTEST srkdrawing switches over %.0f..%.0f m drawn %.0f..%.0f, back %.1f..%.1f", layout.from, layout.to, m_plot.x(layout.from), m_plot.x(layout.to), m_plot.chainage(m_plot.x(layout.from)), m_plot.chainage(m_plot.x(layout.to))));
|
||||
std::size_t on_rows{0};
|
||||
std::size_t between{0};
|
||||
std::size_t bends{0};
|
||||
std::size_t backwards{0};
|
||||
for (std::size_t index = 0; index < layout.paths.size(); ++index)
|
||||
{
|
||||
if (layout.paths[index].approach)
|
||||
continue;
|
||||
auto const &points{m_plot.paths[index]};
|
||||
for (auto const &point : points)
|
||||
{
|
||||
auto const rows{point.y / station::row_height};
|
||||
if (std::abs(rows - std::round(rows)) < 1e-6)
|
||||
++on_rows;
|
||||
else
|
||||
++between;
|
||||
}
|
||||
for (std::size_t k = 2; k < points.size(); ++k)
|
||||
{
|
||||
auto const a{points[k - 1] - points[k - 2]};
|
||||
auto const b{points[k] - points[k - 1]};
|
||||
if (std::abs(a.x) > 1e-6 && std::abs(b.x) > 1e-6 && (std::abs(a.y) > 1e-6 || std::abs(b.y) > 1e-6) && std::abs(a.y / a.x - b.y / b.x) > 1e-3)
|
||||
++bends;
|
||||
}
|
||||
for (std::size_t k = 1; k < points.size(); ++k)
|
||||
if ((points[k].x - points[k - 1].x) * (layout.paths[index].schematic[k].x - layout.paths[index].schematic[k - 1].x) < 0.0)
|
||||
++backwards;
|
||||
}
|
||||
WriteLog(format("SELFTEST srkdrawing points on rows %zu, between %zu, bends %zu, x backwards %zu", on_rows, between, bends, backwards));
|
||||
if (auto const values{selftest_values(Words)}; values.count("track"))
|
||||
for (std::size_t index = 0; index < layout.paths.size(); ++index)
|
||||
if (auto const &path{layout.paths[index]}; false == path.track->Isolated.empty() && path.track->Isolated.front()->asName == values.at("track"))
|
||||
{
|
||||
std::string list;
|
||||
for (std::size_t k = 0; k < path.schematic.size(); k += 4)
|
||||
list += format(" %.0f/%.2f>%.2f", path.schematic[k].x, path.schematic[k].y, m_plot.paths[index][k].y / station::row_height);
|
||||
WriteLog(format("SELFTEST srkdrawing %s/%d:", path.track->name().c_str(), path.index) + list);
|
||||
}
|
||||
return editor_selftest_result::handled;
|
||||
}
|
||||
if (Command == "srkstrip")
|
||||
{
|
||||
// srkstrip shown=0: the schematic hidden, the 3d view whole for a screenshot
|
||||
|
||||
@@ -96,6 +96,7 @@ class srk_tool final : public editor_tool
|
||||
bool m_changed{false};
|
||||
std::vector<record> m_records;
|
||||
std::optional<station::layout> m_layout;
|
||||
station::drawing m_plot; // the schematic of the layout as the plot draws it
|
||||
int m_record{-1}; // of the open station, -1 while it has none
|
||||
TTrack *m_anchor{nullptr}; // the switch the open station was found from
|
||||
bool m_reversed{false}; // the switches numbered from the right end of the schematic
|
||||
@@ -114,10 +115,12 @@ class srk_tool final : public editor_tool
|
||||
ImU32 colour{0};
|
||||
double length{0.0};
|
||||
bool labelled{true}; // the circuits of the switches go without, named after them
|
||||
glm::dvec2 drawn{0.0}; // in the plot
|
||||
};
|
||||
std::vector<int> m_circuit_of; // of each path of the layout, an index into m_circuits, -1 for none
|
||||
std::vector<circuit_mark> m_circuits;
|
||||
std::vector<glm::dvec2> m_ticks; // the joints between the circuits, in the schematic
|
||||
std::vector<glm::dvec2> m_ticks_drawn; // the same in the plot
|
||||
struct joint_mark
|
||||
{
|
||||
glm::dvec3 at{0.0};
|
||||
@@ -131,6 +134,8 @@ class srk_tool final : public editor_tool
|
||||
std::string text;
|
||||
glm::dvec3 head{0.0}; // above its lamps, in the scenery
|
||||
bool unfit{false}; // its lights don't show what its routes need
|
||||
glm::dvec2 drawn{0.0}; // on its track in the plot
|
||||
float side{0.0f}; // 1: it stands to the left of the track in the plot, -1: to the right
|
||||
};
|
||||
std::vector<signal_mark> m_signal_marks;
|
||||
bool m_signals_known{false}; // the signals standing surveyed, once their templates are found
|
||||
|
||||
Reference in New Issue
Block a user