17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-26 19:24:54 +01:00

feat(editor): the design speed the norms lay for is shown by the cursor with the track it comes from, and can be the one set for the laying

Laid to the norms, the readout says the design speed of the transition curves and of the cant: that of the track the laying goes on from or joins, or the one set for the laying. A new option takes the set speed also on from a track with its own, the new tracks get it; Ctrl+Shift+wheel steps it while laying and turns the option on. The panel shows the speed the laying under way is designed for.
This commit is contained in:
maj00r
2026-10-21 20:28:34 +02:00
parent 415c7484ec
commit 9fedbaf6a8
6 changed files with 105 additions and 12 deletions

View File

@@ -1341,6 +1341,7 @@ class editor_mode : public application_mode, private editor_track::observer, pri
double piece_length{100.0};
bool copy_selected{false};
editor_track::path_style style;
bool own_speed{false}; // the speed of the style also where the track goes on from one with its own, the new tracks given it
std::string status;
double status_time{-100.0};
std::string skew; // what Alt turned the straight to
@@ -1501,6 +1502,12 @@ class editor_mode : public application_mode, private editor_track::observer, pri
std::string track_shaping(bool const Joined) const;
void render_layout_combo();
double design_speed(TTrack const *From, TTrack const *To) const;
// the track whose speed the design takes, none where it's the one set for the laying
TTrack const *speed_track(TTrack const *From, TTrack const *To) const;
// the tracks the laying under way goes on from and to
std::pair<TTrack const *, TTrack const *> laying_ends() const;
std::string design_speed_of(TTrack const *From, TTrack const *To) const;
void give_own_speed(std::vector<TTrack *> const &Created) 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::string &Error) const;
double m_extend_length{25.0};

View File

@@ -490,20 +490,50 @@ std::vector<segment_data> editor_mode::extend_pieces() const
return pieces;
}
TTrack const *editor_mode::speed_track(TTrack const *From, TTrack const *To) const
{
if (m_lay.own_speed && m_lay.style.velocity > 0.0)
return nullptr;
TTrack const *result{nullptr};
for (auto const *track : {From, To})
if (track != nullptr && editor_track::velocity(*track) > 0.0 && (result == nullptr || editor_track::velocity(*track) < editor_track::velocity(*result)))
result = track;
return result;
}
double editor_mode::design_speed(TTrack const *From, TTrack const *To) const
{
double speed{0.0};
for (auto const *track : {From, To})
if (auto const *track{speed_track(From, To)}; track != nullptr)
return editor_track::velocity(*track);
return m_lay.style.velocity > 0.0 ? m_lay.style.velocity : 100.0;
}
std::pair<TTrack const *, TTrack const *> editor_mode::laying_ends() const
{
if (m_extend.active)
{
if (track == nullptr)
continue;
auto const velocity{editor_track::velocity(*track)};
if (velocity > 0.0)
speed = speed > 0.0 ? std::min(speed, velocity) : velocity;
editor_track::snap_target target;
return {m_extend.track, extend_snap(target) ? target.track : nullptr};
}
if (speed <= 0.0)
speed = m_lay.style.velocity > 0.0 ? m_lay.style.velocity : 100.0;
return speed;
if (m_lay.active && false == m_lay.points.empty())
return {m_lay.start.track, m_lay.points.size() == 1 ? m_lay.mouse_snap.track : nullptr};
return {nullptr, nullptr};
}
std::string editor_mode::design_speed_of(TTrack const *From, TTrack const *To) const
{
auto const speed{design_speed(From, To)};
if (auto const *track{speed_track(From, To)}; track != nullptr)
return format(STR_C("design speed %.0f km/h, that of the track %s"), speed, name_of(*track).c_str());
return format(STR_C("design speed %.0f km/h, set for the laying"), speed);
}
void editor_mode::give_own_speed(std::vector<TTrack *> const &Created) const
{
if (false == m_lay.own_speed || m_lay.style.velocity <= 0.0)
return;
for (auto *track : Created)
editor_track::velocity(*track, m_lay.style.velocity);
}
std::vector<segment_data> editor_mode::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,
@@ -601,6 +631,7 @@ void editor_mode::finish_extend()
std::vector<TTrack *> created;
for (auto const &piece : pieces)
created.push_back(editor_track::create_path(*style, piece));
give_own_speed(created);
editor_track::commit(created);
digitize_drawn(created);
push_track_snapshot({}, created);
@@ -817,6 +848,21 @@ bool editor_mode::track_wheel(double const Offset)
return radii[0];
};
first_step_done(io.KeyCtrl ? first_step::wheel : first_step::shape);
if (io.KeyCtrl && io.KeyShift)
{
static double const speeds[]{20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 120.0, 140.0, 160.0, 200.0, 250.0};
auto const [from, to]{laying_ends()};
auto const current{design_speed(from, to)};
int index{0};
for (int i = 0; i < static_cast<int>(std::size(speeds)); ++i)
if (speeds[i] <= current + 1e-6)
index = i;
if (step < 0 && speeds[index] < current - 1e-6)
++index;
m_lay.style.velocity = speeds[std::clamp(index + step, 0, static_cast<int>(std::size(speeds)) - 1)];
m_lay.own_speed = true;
return true;
}
if (io.KeyCtrl)
{
if (false == joined)
@@ -1073,6 +1119,7 @@ void editor_mode::lay_finish(editor_track::snap_target const &End)
std::vector<TTrack *> created;
for (auto const &piece : pieces)
created.push_back(style != nullptr ? editor_track::create_path(*style, piece) : editor_track::create_path(tool.style, piece));
give_own_speed(created);
editor_track::commit(created);
digitize_drawn(created);
push_track_snapshot({}, created);
@@ -1470,6 +1517,11 @@ void editor_mode::render_lay_ui()
value_chips("speeds", tool.style.velocity, {40.0, 60.0, 80.0, 100.0, 120.0, 160.0}, "%.0f");
tool.style.velocity = std::clamp(tool.style.velocity, 0.0, 400.0);
ImGui::PopItemWidth();
ImGui::Checkbox(STR_C("This speed also on from a track with its own"), &tool.own_speed);
item_tooltip(m_norms_free ? "Off: a track laid on from another one, or joined to it, takes the speed of that track.\nOn: the new tracks get the speed above"
: "Off: a track laid on from another one, or joined to it, is designed for the speed of that track and takes it.\nOn: it's designed for the speed above and the new tracks get it.\nWhile laying: Ctrl+Shift+wheel");
if (auto const [from, to]{laying_ends()}; false == m_norms_free && (from != nullptr || to != nullptr))
ImGui::TextDisabled("%s", design_speed_of(from, to).c_str());
if (auto *track{selected_track()}; track != nullptr)
{
std::string reason;

View File

@@ -122,6 +122,7 @@ editor_mode::selftest_result editor_mode::selftest_dispatch(std::string const &c
// join <x> <z> <x> <z> [radius] [variant] [transitions 0|1] the free ends at the points joined, as a drag from one to the other
// layto <x> <z> <x> <z> <layout 0..3> <radius> from the free end at the first point towards the second, as a drag in the layout
// layclicks <layout 0..3> <radius> <x> <z>... clicks of the lay tool at the points, a free end within 3 m joined
// layspeed <km/h> <own 0|1> the speed set for the laying, and whether it goes also on from a track with its own
// joints <x> <z>... the joints check over the scenery, the issues around the points logged, every issue with free ends without points
// route <x> <z> <single 0|1> the route design of the path nearest the point, a curve or the whole line
// routevertex <i> <R> <L in> <L out> <cant>, routearc <i> <R> <L> <share>, routeshare <i> <share>, routekm <km>

View File

@@ -130,6 +130,14 @@ editor_mode::selftest_result editor_mode::selftest_join(std::string const &comma
WriteLog(std::string{"SELFTEST norms: "} + (m_norms_free ? "free" : "plk"));
return selftest_result::handled;
}
if (command == "layspeed")
{
int own{0};
words >> m_lay.style.velocity >> own;
m_lay.own_speed = own != 0;
WriteLog(format("SELFTEST layspeed: %.0f km/h, own %d", m_lay.style.velocity, m_lay.own_speed ? 1 : 0));
return selftest_result::handled;
}
if (command == "tracktab")
{
std::string key;

View File

@@ -1795,6 +1795,8 @@ std::string editor_mode::track_readout() const
auto text{radius > 0.0 ? format("L %.2f m R %.0f m", length, radius) + speed_of(radius, laying_norms()) : format("L %.2f m %s", length, STR_C("straight"))};
if (auto const eased{eased_of(m_eased_last)}; false == eased.empty())
text += "\n" + eased;
if (false == m_norms_free)
text += "\n" + design_speed_of(m_extend.track, snapped ? target.track : nullptr);
if (auto const vertical{vertical_of(pieces)}; false == vertical.empty())
text += "\n" + vertical;
if (snapped)
@@ -1829,6 +1831,11 @@ std::string editor_mode::track_readout() const
text = format("L %.1f m %s", lay.preview_length, STR_C("straight"));
if (auto const eased{eased_of(m_eased_last)}; false == eased.empty())
text += "\n" + eased;
if (false == m_norms_free)
{
auto const [from, to]{laying_ends()};
text += "\n" + design_speed_of(from, to);
}
if (auto const vertical{vertical_of(lay.preview)}; false == vertical.empty())
text += "\n" + vertical;
}
@@ -1943,7 +1950,7 @@ std::string editor_mode::track_shaping(bool const Joined) const
auto text{std::string{STR_C(names[static_cast<int>(m_track_layout)])}};
if (m_track_layout == track_layout::arc_straight || m_track_layout == track_layout::straight_arc)
text += format(" R %.0f m", m_lay.radius);
return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: arc / straight");
return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: arc / straight") + (m_norms_free ? std::string{} : STR(", Ctrl+Shift+wheel: speed"));
}
auto const &join{m_join_last};
char const *const kinds[]{"", "straight", "arc", "curve", "reverse curve", "free curve"};
@@ -1958,7 +1965,7 @@ std::string editor_mode::track_shaping(bool const Joined) const
text += format(" V %.0f km/h", join.speed);
if (join.variants > 1)
text += format(" %d/%d", (m_join_variant % join.variants + join.variants) % join.variants + 1, join.variants);
return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: another shape");
return text + "\n" + STR("Ctrl+wheel: radius, Shift+wheel: another shape") + (m_norms_free ? std::string{} : STR(", Ctrl+Shift+wheel: speed"));
}
void editor_mode::draw_empty_scenery_hint()

View File

@@ -10243,3 +10243,21 @@ msgstr "Krzywe przejściowe skrócone do %.0f%% długości wg norm, nie ma na wi
msgid "The cant is lowered to %.0f mm, what the transition curves ramp"
msgstr "Przechyłka obniżona do %.0f mm, tyle zdążą podnieść krzywe przejściowe"
msgid "design speed %.0f km/h, that of the track %s"
msgstr "prędkość projektowa %.0f km/h, jak tor %s"
msgid "design speed %.0f km/h, set for the laying"
msgstr "prędkość projektowa %.0f km/h, ustawiona do kładzenia"
msgid ", Ctrl+Shift+wheel: speed"
msgstr ", Ctrl+Shift+kółko: prędkość"
msgid "This speed also on from a track with its own"
msgstr "Ta prędkość także od toru z własną"
msgid "Off: a track laid on from another one, or joined to it, takes the speed of that track.\nOn: the new tracks get the speed above"
msgstr "Wyłączone: tor kładziony od innego toru albo dołączany do niego bierze prędkość tamtego toru.\nWłączone: nowe tory dostają prędkość z pola powyżej"
msgid "Off: a track laid on from another one, or joined to it, is designed for the speed of that track and takes it.\nOn: it's designed for the speed above and the new tracks get it.\nWhile laying: Ctrl+Shift+wheel"
msgstr "Wyłączone: tor kładziony od innego toru albo dołączany do niego jest projektowany na prędkość tamtego toru i ją dostaje.\nWłączone: jest projektowany na prędkość z pola powyżej i nowe tory ją dostają.\nW trakcie kładzenia: Ctrl+Shift+kółko"