17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-05 12:09:02 +01:00

feat(editor): Shift no longer forces a straight while laying

- laying, dragging out of a free end and the curve of a switch go on with the shape chosen; a straight is the straight layout on Shift+wheel, at a diverging end of a switch it also stops the crossover
- hints without Shift: straight
This commit is contained in:
maj00r
2026-10-11 11:50:19 +02:00
parent 55bb48e8bd
commit 3a549e76a9
4 changed files with 12 additions and 55 deletions

View File

@@ -966,7 +966,6 @@ class editor_mode : public application_mode, private editor_track::observer
void lay_finish(editor_track::snap_target const &End); void lay_finish(editor_track::snap_target const &End);
void lay_cancel(); void lay_cancel();
void lay_enter(); void lay_enter();
bool lay_heading(glm::dvec2 &Heading) const;
std::vector<segment_data> lay_pieces(std::vector<glm::dvec3> const &Points, editor_track::snap_target const &End, double &Length, std::string &Error) const; std::vector<segment_data> lay_pieces(std::vector<glm::dvec3> const &Points, editor_track::snap_target const &End, double &Length, std::string &Error) const;
alignment::result lay_shape(std::vector<glm::dvec3> const &Points, glm::dvec2 const &Startdirection, glm::dvec2 const &Enddirection, alignment::design &Design) const; alignment::result lay_shape(std::vector<glm::dvec3> const &Points, glm::dvec2 const &Startdirection, glm::dvec2 const &Enddirection, alignment::design &Design) const;
void render_switch_ui(); void render_switch_ui();
@@ -1019,11 +1018,9 @@ class editor_mode : public application_mode, private editor_track::observer
TTrack const *m_join_track{nullptr}; TTrack const *m_join_track{nullptr};
editor_track::point_ref m_join_point; editor_track::point_ref m_join_point;
mutable alignment::join_result m_join_last; mutable alignment::join_result m_join_last;
bool m_shift_wheel{false};
bool track_wheel(double const Offset); bool track_wheel(double const Offset);
std::string track_shaping(bool const Joined) const; std::string track_shaping(bool const Joined) const;
void render_layout_combo(); void render_layout_combo();
bool shift_straight() const;
double design_speed(TTrack const *From, TTrack const *To) const; double design_speed(TTrack const *From, TTrack const *To) const;
std::vector<segment_data> layout_pieces(glm::dvec3 const &Point, glm::dvec2 const &Direction, double const Grade, glm::dvec3 const &Mouse, double const Radius) const; std::vector<segment_data> layout_pieces(glm::dvec3 const &Point, glm::dvec2 const &Direction, double const Grade, glm::dvec3 const &Mouse, double const Radius) const;
std::vector<segment_data> join_pieces(TTrack const *From, editor_track::point_ref const &Frompoint, glm::dvec3 const &Start, glm::dvec2 const &Direction, editor_track::snap_target const &End, double &Length, std::vector<segment_data> join_pieces(TTrack const *From, editor_track::point_ref const &Frompoint, glm::dvec3 const &Start, glm::dvec2 const &Direction, editor_track::snap_target const &End, double &Length,

View File

@@ -3503,8 +3503,6 @@ std::vector<editor_mode::key_hint> editor_mode::track_key_hints(bool const All)
if (chained || m_lay.mouse_snap.track != nullptr) if (chained || m_lay.mouse_snap.track != nullptr)
hints.insert(hints.end(), {{"Ctrl+wheel", "radius"}, {"Shift+wheel", "arc / straight, at a free end: another shape"}}); hints.insert(hints.end(), {{"Ctrl+wheel", "radius"}, {"Shift+wheel", "arc / straight, at a free end: another shape"}});
hints.insert(hints.end(), {{"Enter", "lay up to the cursor"}, {"Backspace", "take back the point"}, {"Esc", "cancel"}}); hints.insert(hints.end(), {{"Enter", "lay up to the cursor"}, {"Backspace", "take back the point"}, {"Esc", "cancel"}});
if (glm::dvec2 heading; lay_heading(heading))
hints.insert(hints.begin() + 1, {"Shift", "straight on in the direction of the track"});
} }
} }
else if (false == m_straights.detour.empty()) else if (false == m_straights.detour.empty())
@@ -3514,7 +3512,7 @@ std::vector<editor_mode::key_hint> editor_mode::track_key_hints(bool const All)
hints = {{"Shift+click", format("point %zu of 4: %s", step + 1, steps[step])}, {"Esc", "cancel"}}; hints = {{"Shift+click", format("point %zu of 4: %s", step + 1, steps[step])}, {"Esc", "cancel"}};
} }
else if (m_extend.active) else if (m_extend.active)
hints = {{"Drag", "the shape chosen towards the cursor, to a free end: joins it"}, {"Ctrl+wheel", "radius"}, {"Shift+wheel", "arc / straight, at a free end: another shape"}, {"Shift", "straight, joins nothing"}, {"Release", "build"}, {"Esc", "cancel"}}; hints = {{"Drag", "the shape chosen towards the cursor, to a free end: joins it"}, {"Ctrl+wheel", "radius"}, {"Shift+wheel", "arc / straight, at a free end: another shape"}, {"Release", "build"}, {"Esc", "cancel"}};
else if (m_switch.placing) else if (m_switch.placing)
hints = {{"Drag along", "direction of the switch"}, {"Drag sideways", "side of the diverging track"}, {"Esc", "cancel"}}; hints = {{"Drag along", "direction of the switch"}, {"Drag sideways", "side of the diverging track"}, {"Esc", "cancel"}};
else if (m_track_tab == track_tab::lay) else if (m_track_tab == track_tab::lay)
@@ -3837,8 +3835,6 @@ void editor_mode::update_build_tools()
auto const &io{ImGui::GetIO()}; auto const &io{ImGui::GetIO()};
glm::vec2 const cursor{io.MousePos.x, io.MousePos.y}; glm::vec2 const cursor{io.MousePos.x, io.MousePos.y};
m_straights.detour_mouse = ground; m_straights.detour_mouse = ground;
if (false == io.KeyShift)
m_shift_wheel = false;
auto const joining = [&](editor_track::snap_target const &Target) { auto const joining = [&](editor_track::snap_target const &Target) {
if (Target.track == m_join_track && Target.point == m_join_point) if (Target.track == m_join_track && Target.point == m_join_point)
return; return;
@@ -3853,7 +3849,7 @@ void editor_mode::update_build_tools()
glm::dvec3 level; glm::dvec3 level;
m_extend.mouse = projection.on_level(io.MousePos, m_extend.point.y, level) && plan_distance(level, m_extend.point) < static_cast<double>(kMaxPlacementDistance) ? level : ground; m_extend.mouse = projection.on_level(io.MousePos, m_extend.point.y, level) && plan_distance(level, m_extend.point) < static_cast<double>(kMaxPlacementDistance) ? level : ground;
typed_extend(); typed_extend();
m_extend.snap = m_typed.empty() && false == shift_straight() && m_extend.track != nullptr ? snap_free_end(m_extend.mouse, cursor, m_extend.track, m_extend.track->iCategoryFlag & 15, {m_extend.track}) : editor_track::snap_target{}; m_extend.snap = m_typed.empty() && m_extend.track != nullptr ? snap_free_end(m_extend.mouse, cursor, m_extend.track, m_extend.track->iCategoryFlag & 15, {m_extend.track}) : editor_track::snap_target{};
joining(m_extend.snap); joining(m_extend.snap);
} }
if (m_switch.placing) if (m_switch.placing)
@@ -3872,16 +3868,8 @@ void editor_mode::update_build_tools()
mouse = glm::dvec3{m_cursor_override->x, height, m_cursor_override->z}; mouse = glm::dvec3{m_cursor_override->x, height, m_cursor_override->z};
else if (false == lay_projection.on_level(io.MousePos, height, mouse)) else if (false == lay_projection.on_level(io.MousePos, height, mouse))
mouse = ground; mouse = ground;
glm::dvec2 heading;
bool const straight{shift_straight() && lay_heading(heading)};
if (straight)
{
auto const &last{lay.points.back()};
auto const along{std::max(0.0, glm::dot(glm::dvec2{mouse.x - last.x, mouse.z - last.z}, heading))};
mouse = {last.x + heading.x * along, mouse.y, last.z + heading.y * along};
}
lay.mouse = typed_lay(mouse); lay.mouse = typed_lay(mouse);
lay.mouse_snap = straight ? editor_track::snap_target{} : m_typed.empty() ? snap_free_end(lay.mouse, cursor, nullptr, kRailCategory, {}) : editor_track::find_free_end(nullptr, kRailCategory, lay.mouse, kLaySnapRadius, {}); lay.mouse_snap = m_typed.empty() ? snap_free_end(lay.mouse, cursor, nullptr, kRailCategory, {}) : editor_track::find_free_end(nullptr, kRailCategory, lay.mouse, kLaySnapRadius, {});
if (false == m_extend.active) if (false == m_extend.active)
joining(lay.points.empty() ? editor_track::snap_target{} : lay.mouse_snap); joining(lay.points.empty() ? editor_track::snap_target{} : lay.mouse_snap);
if (lay.points.empty()) if (lay.points.empty())
@@ -4195,7 +4183,7 @@ std::vector<segment_data> editor_mode::extend_pieces() const
return join_pieces(tool.track, {tool.path, tool.atend ? editor_track::point_kind::end : editor_track::point_kind::start}, tool.point, tool.direction, target, length, error); return join_pieces(tool.track, {tool.path, tool.atend ? editor_track::point_kind::end : editor_track::point_kind::start}, tool.point, tool.direction, target, length, error);
} }
m_join_last = {}; m_join_last = {};
if (false == shift_straight() && tool.track != nullptr && tool.track->eType == tt_Switch && tool.track->m_paths.size() > 1 && tool.path == 1 && tool.atend) if (m_track_layout != track_layout::straight && tool.track != nullptr && tool.track->eType == tt_Switch && tool.track->m_paths.size() > 1 && tool.path == 1 && tool.atend)
{ {
auto const &diverging{tool.track->m_paths[1]}; auto const &diverging{tool.track->m_paths[1]};
bezier const curve{diverging}; bezier const curve{diverging};
@@ -4217,8 +4205,6 @@ std::vector<segment_data> editor_mode::extend_pieces() const
return pieces; return pieces;
} }
} }
if (shift_straight())
return straight_piece(tool.point, tool.direction, tool.grade, glm::dot(glm::dvec2{tool.mouse.x - tool.point.x, tool.mouse.z - tool.point.z}, tool.direction));
auto radius{m_lay.radius}; auto radius{m_lay.radius};
if (auto const values{typed_values()}; false == values.empty() && (m_track_layout == track_layout::arc_straight || m_track_layout == track_layout::straight_arc) && std::abs(values[0]) >= 1.0) if (auto const values{typed_values()}; false == values.empty() && (m_track_layout == track_layout::arc_straight || m_track_layout == track_layout::straight_arc) && std::abs(values[0]) >= 1.0)
radius = std::abs(values[0]); radius = std::abs(values[0]);
@@ -4364,11 +4350,6 @@ std::vector<segment_data> editor_mode::join_pieces(TTrack const *From, editor_tr
return result.pieces; return result.pieces;
} }
bool editor_mode::shift_straight() const
{
return ImGui::GetIO().KeyShift && false == m_shift_wheel;
}
void editor_mode::finish_extend() void editor_mode::finish_extend()
{ {
auto const &io{ImGui::GetIO()}; auto const &io{ImGui::GetIO()};
@@ -4534,7 +4515,6 @@ bool editor_mode::track_wheel(double const Offset)
m_join_radius = next_radius(m_join_radius); m_join_radius = next_radius(m_join_radius);
return true; return true;
} }
m_shift_wheel = true;
if (joined) if (joined)
m_join_variant += step; m_join_variant += step;
else else
@@ -4795,20 +4775,6 @@ void editor_mode::lay_finish(editor_track::snap_target const &End)
straight_refresh(); straight_refresh();
} }
bool editor_mode::lay_heading(glm::dvec2 &Heading) const
{
auto const &tool{m_lay};
glm::dvec2 direction{0.0};
if (tool.points.size() >= 2)
direction = plan_of(tool.points.back() - tool.points[tool.points.size() - 2]);
else if (tool.points.size() == 1 && tool.start.track != nullptr)
direction = -plan_of(tool.start.direction);
if (glm::length(direction) < 1e-6)
return false;
Heading = glm::normalize(direction);
return true;
}
void editor_mode::lay_enter() void editor_mode::lay_enter()
{ {
auto &tool{m_lay}; auto &tool{m_lay};
@@ -5745,7 +5711,7 @@ void editor_mode::update_curve_fit(glm::dvec3 const &Start, glm::dvec3 const &En
bool editor_mode::plan_crossover(crossover_plan &Plan) const bool editor_mode::plan_crossover(crossover_plan &Plan) const
{ {
auto const &tool{m_extend}; auto const &tool{m_extend};
if (false == tool.active || tool.track == nullptr || tool.track->eType != tt_Switch || tool.track->m_paths.size() < 2 || tool.path != 1 || false == tool.atend || ImGui::GetIO().KeyShift) if (false == tool.active || tool.track == nullptr || tool.track->eType != tt_Switch || tool.track->m_paths.size() < 2 || tool.path != 1 || false == tool.atend || m_track_layout == track_layout::straight)
return false; return false;
auto const &own{*tool.track}; auto const &own{*tool.track};
auto const &main{own.m_paths[0]}; auto const &main{own.m_paths[0]};

View File

@@ -212,7 +212,7 @@ editor_mode::track_intent editor_mode::track_intent_at(int const Mods)
intent.position = lay.mouse_snap.position; intent.position = lay.mouse_snap.position;
auto const diverging{lay.mouse_snap.track->eType == tt_Switch && lay.mouse_snap.point == editor_track::point_ref{1, editor_track::point_kind::end}}; auto const diverging{lay.mouse_snap.track->eType == tt_Switch && lay.mouse_snap.point == editor_track::point_ref{1, editor_track::point_kind::end}};
if (lay.points.empty() && diverging) if (lay.points.empty() && diverging)
return make(kind::lay_end, "Click: start from this free end, drag: the curve of the switch goes on, Shift: straight"); return make(kind::lay_end, "Click: start from this free end, drag: the curve of the switch goes on");
return make(kind::lay_end, lay.points.empty() ? "Click: start from this free end, drag: lead a track out of it" : "Click: join this end and lay"); return make(kind::lay_end, lay.points.empty() ? "Click: start from this free end, drag: lead a track out of it" : "Click: join this end and lay");
} }
intent.position = lay.mouse; intent.position = lay.mouse;
@@ -288,7 +288,7 @@ editor_mode::track_intent editor_mode::track_intent_at(int const Mods)
intent.snap.point = hit; intent.snap.point = hit;
intent.snap.position = intent.position; intent.snap.position = intent.position;
auto const diverging{selected->eType == tt_Switch && hit == editor_track::point_ref{1, editor_track::point_kind::end}}; auto const diverging{selected->eType == tt_Switch && hit == editor_track::point_ref{1, editor_track::point_kind::end}};
return make(kind::extend_end, diverging ? "Drag: the curve of the switch goes on, Shift: straight; Ctrl+drag: move the end" : "Drag: a new track out of this end, as in laying; Ctrl+drag: move the end"); return make(kind::extend_end, diverging ? "Drag: the curve of the switch goes on; Ctrl+drag: move the end" : "Drag: a new track out of this end, as in laying; Ctrl+drag: move the end");
} }
} }
} }
@@ -731,7 +731,7 @@ char const *editor_mode::typed_meaning() const
{ {
auto const &straights{m_straights}; auto const &straights{m_straights};
if (m_extend.active) if (m_extend.active)
return m_track_layout == track_layout::straight || shift_straight() ? "type the length" : m_track_layout == track_layout::arc ? "type the radius, a space, the length" : "type the radius"; return m_track_layout == track_layout::straight ? "type the length" : m_track_layout == track_layout::arc ? "type the radius, a space, the length" : "type the radius";
if (straights.dragging) if (straights.dragging)
return straights.handle == 2 ? "type the shift, + to the right" : "type the length"; return straights.handle == 2 ? "type the shift, + to the right" : "type the length";
if (straights.tool == 1 && (straights.tool_mouse || straights.tool_dragging)) if (straights.tool == 1 && (straights.tool_mouse || straights.tool_dragging))
@@ -800,9 +800,9 @@ void editor_mode::typed_extend()
return; return;
auto &tool{m_extend}; auto &tool{m_extend};
auto const &direction{tool.direction}; auto const &direction{tool.direction};
if (m_track_layout != track_layout::straight && m_track_layout != track_layout::arc && false == shift_straight()) if (m_track_layout != track_layout::straight && m_track_layout != track_layout::arc)
return; return;
if (m_track_layout == track_layout::straight || shift_straight()) if (m_track_layout == track_layout::straight)
{ {
auto const length{std::max(0.0, values[0])}; auto const length{std::max(0.0, values[0])};
tool.mouse = {tool.point.x + direction.x * length, tool.mouse.y, tool.point.z + direction.y * length}; tool.mouse = {tool.point.x + direction.x * length, tool.mouse.y, tool.point.z + direction.y * length};

View File

@@ -2982,12 +2982,6 @@ msgstr "ułóż do kursora"
msgid "Shift" msgid "Shift"
msgstr "Shift" msgstr "Shift"
msgid "straight on in the direction of the track"
msgstr "prosto w kierunku toru"
msgid "straight, joins nothing"
msgstr "prosto, bez łączenia"
msgid "moves the whole track" msgid "moves the whole track"
msgstr "przesuwa cały tor" msgstr "przesuwa cały tor"
@@ -3360,8 +3354,8 @@ msgstr "Wzdłuż trasy, tam gdzie go brak, powstają kawałki terenu edytora z w
msgid "Puts back the terrain as it was before the last shaping, and takes away the terrain it made" msgid "Puts back the terrain as it was before the last shaping, and takes away the terrain it made"
msgstr "Przywraca teren sprzed ostatniego kształtowania i usuwa teren, który przy tym powstał" msgstr "Przywraca teren sprzed ostatniego kształtowania i usuwa teren, który przy tym powstał"
msgid "Click: start from this free end, drag: the curve of the switch goes on, Shift: straight" msgid "Click: start from this free end, drag: the curve of the switch goes on"
msgstr "Kliknij: zacznij od tego wolnego końca, przeciągnij: łuk rozjazdu biegnie dalej, Shift: prosta" msgstr "Kliknij: zacznij od tego wolnego końca, przeciągnij: łuk rozjazdu biegnie dalej"
msgid "%s and %d vehicle(s) behind it stand on %s. It isn't saved with the scenery" msgid "%s and %d vehicle(s) behind it stand on %s. It isn't saved with the scenery"
msgstr "%s i %d pojazd(ów) za nim stoją na %s. Nie zapisuje się ze scenerią" msgstr "%s i %d pojazd(ów) za nim stoją na %s. Nie zapisuje się ze scenerią"