From 71bdf8e2844243025de7eaf66d1f254d33bf80fc Mon Sep 17 00:00:00 2001 From: maj00r Date: Sun, 11 Oct 2026 20:32:59 +0200 Subject: [PATCH] fix(editor): a switch drive stands at the height given in its //$e description, switch: {height: ...} above the start point of the switch (rail foot): placed with a new switch, swapped for another drive or side, or following its switch; drive_headers.py writes height 0.15 for ele and ele1 and 0.05 for mech and mech1, whose models reach that far below the origin, so they stand on the sleepers; the drives with a counterweight (mech_*, mech2, 0.57 m down) keep 0, as all 1965 drives of the digitized lines do --- application/editormode.h | 1 + application/editormodetrack.cpp | 13 ++++++++++--- editor/editorIncludeInfo.cpp | 1 + editor/editorIncludeInfo.hpp | 1 + tools/editor/drive_headers.py | 3 ++- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/application/editormode.h b/application/editormode.h index 380922c2..d8089832 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -933,6 +933,7 @@ class editor_mode : public application_mode, private editor_track::observer { std::string name; std::array files; + std::array heights{}; bool preferred{false}; }; std::vector drives; diff --git a/application/editormodetrack.cpp b/application/editormodetrack.cpp index 7df8358c..9eee716e 100644 --- a/application/editormodetrack.cpp +++ b/application/editormodetrack.cpp @@ -6633,6 +6633,7 @@ void editor_mode::scan_switch_drives() family = std::prev(tool.drives.end()); } family->files[hand * 2 + drive] = entry.file; + family->heights[hand * 2 + drive] = info.switch_height; family->preferred |= info.switch_default; } std::sort(tool.drives.begin(), tool.drives.end(), [](switch_tool::drive_family const &A, switch_tool::drive_family const &B) { return A.name < B.name; }); @@ -6714,6 +6715,7 @@ void editor_mode::switch_drives_committed(std::vector const &Tracks) std::string error; if (included.file == nullptr || false == editor_includes::load(*included.file, info, error)) continue; + location.y += m_switch.drives[family].heights[variant]; auto const local{location - included.context.offset}; auto values{drive.values}; for (auto const ¶meter : info.parameters) @@ -6754,14 +6756,15 @@ bool editor_mode::place_switch_drive(TTrack &Switch) return false; bool const driveright{(tool.drive_side == 0) == rightswitch}; auto const &family{tool.drives[tool.drive]}; + auto const index{(rightswitch ? 2 : 0) + (driveright ? 1 : 0)}; template_item item; - item.file = family.files[(rightswitch ? 2 : 0) + (driveright ? 1 : 0)]; + item.file = family.files[index]; if (item.file.empty()) { tool.status = format(STR_C("The drive %s has no variant for a %s switch with the drive on the %s"), family.name.c_str(), rightswitch ? STR_C("right") : STR_C("left"), driveright ? STR_C("right") : STR_C("left")); return false; } - item.location = location; + item.location = location + glm::dvec3{0.0, family.heights[index], 0.0}; item.yaw = yaw; item.described = true; item.track = Switch.name(); @@ -6840,7 +6843,11 @@ bool editor_mode::replace_switch_drive(TTrack &Switch, int const Family, bool co } if (drive_file(item.file) == found.file) return false; - item.location = found.location; + glm::dvec3 location; + double yaw; + glm::dvec2 tilt; + bool rightswitch; + item.location = switch_drive_spot(Switch, location, yaw, tilt, rightswitch) ? location + glm::dvec3{0.0, tool.drives[family].heights[index], 0.0} : found.location; item.yaw = found.yaw; item.described = true; item.track = Switch.name(); diff --git a/editor/editorIncludeInfo.cpp b/editor/editorIncludeInfo.cpp index f0dbdf9d..f613323c 100644 --- a/editor/editorIncludeInfo.cpp +++ b/editor/editorIncludeInfo.cpp @@ -251,6 +251,7 @@ bool parse(template_text const &Text, include_info &Info, std::string &Error) Info.switch_hand = drive["hand"].as(""); Info.switch_drive = drive["drive"].as(""); Info.switch_default = drive["default"].as(false); + Info.switch_height = drive["height"].as(0.0); } if (auto const signal{document["signal"]}; signal.IsDefined() && signal.IsMap()) { diff --git a/editor/editorIncludeInfo.hpp b/editor/editorIncludeInfo.hpp index 67059bb7..f60e2fb3 100644 --- a/editor/editorIncludeInfo.hpp +++ b/editor/editorIncludeInfo.hpp @@ -38,6 +38,7 @@ struct include_info std::string switch_hand; // a switch drive: side of the diverging track, left or right, looking from the start of the switch std::string switch_drive; // and the side the drive stands on bool switch_default{false}; // the drive put with a new switch until another is picked + double switch_height{0.0}; double turntable_length{0.0}; int turntable_angles{0}; int turntable_positions{0}; diff --git a/tools/editor/drive_headers.py b/tools/editor/drive_headers.py index 7c95a0f9..b6f7242a 100644 --- a/tools/editor/drive_headers.py +++ b/tools/editor/drive_headers.py @@ -17,6 +17,7 @@ FOLDER = 'scenery/tory/napedy' PATTERN = re.compile(r'^(ele1?|mech[12]?)-rz([lp])-([lp])((?:_[a-z]+)*)\.inc$') KINDS = {'ele': 'elektryczny', 'mech': 'mechaniczny'} DEFAULT = 'ele' +HEIGHTS = {'ele': 0.15, 'ele1': 0.15, 'mech': 0.05, 'mech1': 0.05} def examine(path, file): @@ -49,7 +50,7 @@ def examine(path, file): 'name: ' + family, 'category: switch drive', 'description: "' + description + '"', - 'switch: {hand: %s, drive: %s%s}' % (hand, side, ', default: true' if family == DEFAULT else ''), + 'switch: {hand: %s, drive: %s, height: %s%s}' % (hand, side, HEIGHTS.get(family, 0), ', default: true' if family == DEFAULT else ''), 'params:', ' - {id: 1, role: track, label: Switch}', ' - {id: 2, role: pos.x}',