17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-28 14:37:29 +01:00

feat(editor): an end of a track dragged, and an end of a straight dragged by its handle, goes onto the ground at the height of the ballast, as a point laid; with Shift held it keeps its height

Selftest trackends: the ends of a track against the ground under them.
This commit is contained in:
maj00r
2026-10-24 18:45:47 +02:00
parent 9625b4b3d9
commit 11d1342181
7 changed files with 42 additions and 6 deletions

View File

@@ -1730,7 +1730,8 @@ class editor_mode : public application_mode, private editor_track::observer, pri
};
handle_drag m_handle_drag;
void handle_drag_start(glm::dvec3 const &Anchor);
bool handle_drag_step(glm::dvec3 &Position);
// Ground: the handle goes onto the ground, at the height of the ballast of the track, unless Shift is held
bool handle_drag_step(glm::dvec3 &Position, TTrack const *Ground = nullptr);
void point_drag_start(editor_track::point_ref const &Point);
void point_drag_update();
void point_drag_finish();

View File

@@ -283,7 +283,7 @@ void editor_mode::handle_drag_start(glm::dvec3 const &Anchor)
m_handle_drag.offset = {Anchor.x - level.x, 0.0, Anchor.z - level.z};
}
bool editor_mode::handle_drag_step(glm::dvec3 &Position)
bool editor_mode::handle_drag_step(glm::dvec3 &Position, TTrack const *Ground)
{
auto &drag{m_handle_drag};
auto const &io{ImGui::GetIO()};
@@ -301,7 +301,13 @@ bool editor_mode::handle_drag_step(glm::dvec3 &Position)
screen_projection const projection;
glm::dvec3 level;
if (projection.on_level(io.MousePos, drag.height, level) && (Global.editor_tracks || glm::distance(level, glm::dvec3{Global.pCamera.Pos}) <= static_cast<double>(kMaxPlacementDistance)))
{
drag.position = level + drag.offset;
if (Ground != nullptr && false == io.KeyShift)
drag.position.y = bed_height(drag.position, {0.0, 0.0}, Ground);
else
drag.position.y = drag.height;
}
Position = drag.position;
return true;
}
@@ -376,6 +382,13 @@ void editor_mode::point_drag_update()
glm::dvec3 position;
if (false == projection.on_level(io.MousePos, drag.height, position) || (false == Global.editor_tracks && glm::distance(position, glm::dvec3{Global.pCamera.Pos}) > static_cast<double>(kMaxPlacementDistance)))
return;
// an end goes onto the ground at the height of the ballast, as a point laid; with Shift it keeps its height
if (editor_track::is_end(m_track_point.kind) && false == io.KeyShift)
{
auto const &path{track->m_paths[m_track_point.path]};
auto const tangent{geometry::bezier{path}.first(m_track_point.kind == editor_track::point_kind::end ? 1.0 : 0.0)};
position.y = bed_height(position, plan_of(tangent), track);
}
m_track_snap = {};
if (editor_track::is_end(m_track_point.kind) && m_track_drag_points.empty())
{

View File

@@ -65,6 +65,7 @@ editor_mode::selftest_result editor_mode::selftest_dispatch(std::string const &c
// camera <x> <y> <z> <x> <y> <z> from the first point, looking at the second
// select <track name>
// selectat <x> <z> the path nearest the point, within 3 m, as a click on it
// trackends <name> logs the ends of the first path of the track against the ground under them
// kbreak <x> <z> K on the track nearest the point: split there, a break of the grade at the height of the ground
// blade [name] logs the blades of each switch cut from the rails: tip, 50 mm head, full head, heel, drop of the head, open flangeway, the gauge lines apart against x^2/2R, vertices in both positions
// frog [name] logs where the inner rails of each switch cross: distance on both paths, 1:n, throat, nose, check rails

View File

@@ -93,6 +93,26 @@ editor_mode::selftest_result editor_mode::selftest_scene(std::string const &comm
WriteLog(format("SELFTEST selectat %.1f %.1f: %s", point.x, point.z, m_node != nullptr ? m_node->name().c_str() : "nothing"));
return selftest_result::handled;
}
if (command == "trackends")
{
// the ends of the first path of the track, against the ground under them
std::string name;
words >> name;
auto const *track{simulation::Paths.find(name)};
if (track == nullptr || track->m_paths.empty())
{
WriteLog("SELFTEST trackends " + name + ": no such track");
return selftest_result::handled;
}
for (auto const end : {segment_data::point::start, segment_data::point::end})
{
auto const &point{track->m_paths.front().points[end]};
std::vector<char> found;
auto const ground{ground_heights({glm::dvec3{point.x, point.y + 50.0, point.z}}, true, &found).front()};
WriteLog(format("SELFTEST trackends %s %s: %.2f %.3f %.2f, ground %.3f (found %d)", name.c_str(), end == segment_data::point::start ? "start" : "end", point.x, point.y, point.z, ground, found[0]));
}
return selftest_result::handled;
}
if (command == "kbreak")
{
// K on the track nearest the point: split there, the point between at the height of the ground and the ballast

View File

@@ -604,7 +604,8 @@ void editor_mode::render_straight_gizmo()
glm::dvec3 const anchors[] = {line.start, line.end, (line.start + line.end) * 0.5};
glm::dvec3 handled{anchors[state.handle]};
bool const held{handle_drag_step(handled)};
// the ends go onto the ground, the middle moves the line in plan alone
bool const held{handle_drag_step(handled, state.handle == 2 ? nullptr : line.tracks.front())};
if (false == held && false == state.dragging)
return;

View File

@@ -1781,7 +1781,7 @@ std::vector<editor_mode::key_hint> editor_mode::track_key_hints(bool const All)
action = "rings about the point: direction, grade, cant; the joined tracks follow";
else if (m_gizmo_op == gizmo_operation::scale && selected != nullptr && track_gizmo_operation(*selected, true) == gizmo_operation::scale)
action = "lengthens the track at this end, the curve keeps its radius";
hints = {{"Drag a point", "moves it, an end dropped on a free end joins it"}, {"Gizmo", action}, {"Q W E", "gizmo: move, turn, lengthen"}, {"Esc", "releases the point"}};
hints = {{"Drag a point", "moves it, an end onto the ground (Shift: keeps its height), dropped on a free end joins it"}, {"Gizmo", action}, {"Q W E", "gizmo: move, turn, lengthen"}, {"Esc", "releases the point"}};
gizmo = true;
}
else

View File

@@ -2204,8 +2204,8 @@ msgstr "koniec się z nim łączy"
msgid "done"
msgstr "gotowe"
msgid "moves it, an end dropped on a free end joins it"
msgstr "przesuwa go, koniec upuszczony na wolny koniec łączy się"
msgid "moves it, an end onto the ground (Shift: keeps its height), dropped on a free end joins it"
msgstr "przesuwa go, koniec na teren (Shift: zostaje na swojej wysokości), upuszczony na wolny koniec łączy się"
msgid "Gizmo"
msgstr "Gizmo"