17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-22 05:16:25 +02:00

fix(editor): a slip goes to the crossing under the cursor or nowhere, shown before the click

A slip went to the crossing of the selected straight with another straight within 40 m of the click. When the track under the cursor wasn't taken as a straight (a slight curve, a switch), the slip silently went to another crossing up to 40 m away. A double slip within 25 m of the click was replaced, even when the click was on a free crossing.

- The crossing nearest the cursor, within 12 m, is found among all the rail tracks. A slip goes only there; when that track is a curve or a switch, the tool says so.
- A double slip is replaced only when it is nearer the cursor than any crossing.
- The cursor is taken at the height of the straight under it, so on a grade the 3D view doesn't put the click metres away from the track.
- Before the click, the view marks the crossing the slip goes to, with its two straights, or the reason it can't go there.
This commit is contained in:
maj00r
2026-10-19 18:20:41 +02:00
parent 59ee32da58
commit 93a45fb632
5 changed files with 204 additions and 53 deletions

View File

@@ -2107,6 +2107,48 @@ void editor_mode::draw_build_overlay() const
drawlist->AddText(ImVec2(screen.x + 18.0f, screen.y + 12.0f), valid ? (plan.warning.empty() ? overlay_color::highlight : overlay_color::warning) : overlay_color::invalid, text.c_str());
}
}
else if (auto const *selected{selected_track()}; false == m_switch.placing && m_track_tab == track_tab::turnout && m_switch.connection < 0 && m_switch.armed >= 0 && m_switch.armed < static_cast<int>(m_switch.templates.size()) &&
m_switch.templates[m_switch.armed].double_slip && selected != nullptr && selected == m_straights.current_for && false == m_straights.current.tracks.empty() &&
false == ImGui::GetIO().WantCaptureMouse)
{
// where the slip goes for a click there, before the click
auto const &line{m_straights.current};
auto const cursor{cursor_on_straight(line)};
auto const along{std::clamp(line.along(cursor), 0.0, line.length)};
if (plan_distance(line.start + glm::dvec3{line.direction.x, line.grade, line.direction.y} * along, cursor) <= kSwitchReach)
{
slip_plan plan;
auto const valid{plan_double_slip(line, cursor, m_switch.templates[m_switch.armed], plan)};
std::string text{plan.problem};
glm::dvec3 marker{cursor};
ImU32 colour{overlay_color::invalid};
if (valid && plan.replaces != nullptr)
{
marker = plan.replaces->location();
colour = overlay_color::highlight;
text = STR_C("Click: this double slip is replaced by the one chosen");
}
else if (valid)
{
for (int i = 0; i < 4; i += 2)
{
segment_data path;
path.points[segment_data::point::start] = plan.points[i];
path.points[segment_data::point::end] = plan.points[i + 1];
drawpath(path, overlay_color::marked);
}
marker = {plan.crossing.x, line.start.y + line.grade * plan.alongfirst, plan.crossing.y};
colour = overlay_color::highlight;
text = plan.note.empty() ? std::string{STR_C("Click: it goes here")} : plan.note;
}
ImVec2 screen;
if (projection.project(marker, screen))
{
drawlist->AddCircle(screen, 12.0f, colour, 20, 2.5f);
drawlist->AddText({screen.x + 16.0f, screen.y - 8.0f}, colour, text.c_str());
}
}
}
else if (m_switch.placing)
{
for (auto const &piece : switch_preview())