17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 06:19:19 +02:00

feat(editor): infrastructure bound to the paths follows their changes

This commit is contained in:
maj00r
2026-10-04 00:14:03 +02:00
parent 7371b18910
commit 8778353b22
15 changed files with 2083 additions and 1 deletions

View File

@@ -344,6 +344,7 @@ editor_mode::editor_mode() {
m_orthophoto.ground_source([](glm::dvec2 const &Min, glm::dvec2 const &Max, std::vector<world_triangle> &Out) {
gather_ground_triangles(Min, Max, true, 50.0f, Out);
});
infra_hooks();
}
editor_ui *editor_mode::ui() const
@@ -869,6 +870,9 @@ bool editor_mode::update()
simulation::State.update_clocks();
simulation::Environment.update();
// bindings are matched with the objects by their locations, before anything gets moved
if (false == m_bindings_loaded && simulation::is_ready)
infra_load();
auto const deltarealtime = Timer::GetDeltaRenderTime();
@@ -1023,6 +1027,8 @@ bool editor_mode::update()
render_track_window();
draw_profile_overlay();
render_profile_window();
draw_infra_overlay();
render_infra_window();
}
// --- area fill: outline overlay while the mode is active (its settings are drawn in the node bank window) ---
@@ -1637,6 +1643,7 @@ void editor_mode::save()
if (m_profile.changed)
profile_store();
infra_store();
auto const result = scene::Layers.save(rootstatements);
if (result.success && false == rootstatements.empty())
{

View File

@@ -22,6 +22,7 @@ http://mozilla.org/MPL/2.0/.
#include "editor/editorTrack.hpp"
#include "editor/editorAlignment.hpp"
#include "editor/editorProfile.hpp"
#include "editor/editorInfra.hpp"
#include <array>
#include <chrono>
@@ -107,7 +108,7 @@ class editor_mode : public application_mode
std::vector<std::pair<TTrack *, editor_track::state>> tracks;
std::vector<TTrack *> created;
std::vector<TTrack *> removed;
std::vector<infra::object_state> infra; // objects which followed the paths
};
void push_snapshot(scene::basic_node *node, EditorSnapshot::Action Action = EditorSnapshot::Action::Move, std::string const &Serialized = std::string());
@@ -545,6 +546,57 @@ class editor_mode : public application_mode
void render_profile_point();
void draw_profile_overlay() const;
// infrastructure along the track: objects bound to the paths follow their changes. bindings are kept in the
// scenery files as "//$b" comment lines
struct infra_candidate
{
infra::binding binding;
double offset{0.0}; // sideways from the axis
std::string reason;
bool chosen{false};
bool bound{false};
};
struct infra_window
{
bool open{false};
int scope{1}; // 0: the selected path, 1: the line through it, 2: the route of the vertical profile
float reach{1500.0f};
float corridor{8.0f};
bool follow{true};
bool show{true};
std::vector<infra::rule> rules{infra::default_rules()};
std::vector<TTrack *> tracks; // of the scope
std::vector<infra_candidate> candidates;
int hovered{-1};
std::string status;
std::string error;
};
infra_window m_infra;
std::vector<infra::binding> m_bindings;
std::vector<std::pair<scene::layer_handle, std::string>> m_bindings_unresolved; // lines kept as they are
bool m_bindings_loaded{false};
bool m_bindings_changed{false};
std::vector<infra::object_state> m_infra_buffer; // states of the objects before the change in progress
bool m_infra_suspended{false};
void infra_hooks();
void infra_load();
void infra_store();
std::vector<TTrack *> infra_scope() const;
void infra_recognize();
void infra_bind_chosen();
void infra_unbind(std::vector<std::size_t> Indices);
infra::binding *infra_find(infra::binding const &Binding);
infra::object_state infra_state_of(infra::binding const &Binding) const;
void infra_restore_state(infra::object_state const &State);
void infra_buffer(infra::binding const &Binding, bool const Refresh);
void infra_capture(TTrack const &Track);
void infra_follow(std::vector<TTrack *> const &Tracks);
void infra_split(TTrack &Original, TTrack &Created, segment_data const &First);
void infra_move(infra::binding &Binding);
void infra_attach(EditorSnapshot &Snapshot);
void render_infra_window();
void draw_infra_overlay() const;
bool m_route_gizmo_using{false};
glm::mat4 m_route_gizmo{1.0f};
float m_track_snap_radius{1.0f};

File diff suppressed because it is too large Load Diff

View File

@@ -342,6 +342,7 @@ void editor_mode::push_track_snapshot(std::vector<std::pair<TTrack *, editor_tra
snap.uuid = track->uuid;
snap.tracks = std::move(States);
snap.created = std::move(Created);
infra_attach(snap);
m_history.push_back(std::move(snap));
g_redo.clear();
}
@@ -354,6 +355,7 @@ void editor_mode::restore_track_snapshot(EditorSnapshot const &Snapshot, std::ve
std::vector<TTrack *> tracks;
for (auto const &entry : Snapshot.tracks)
tracks.emplace_back(entry.first);
m_infra_suspended = true;
EditorSnapshot current{Snapshot};
current.tracks.clear();
auto involved{tracks};
@@ -361,6 +363,10 @@ void editor_mode::restore_track_snapshot(EditorSnapshot const &Snapshot, std::ve
involved.insert(involved.end(), Snapshot.created.begin(), Snapshot.created.end());
for (auto *track : involved)
current.tracks.emplace_back(track, editor_track::capture(*track));
current.infra.clear();
for (auto const &entry : Snapshot.infra)
if (auto const *binding{infra_find(entry.saved)})
current.infra.push_back(infra_state_of(*binding));
Opposite.push_back(std::move(current));
if (Undo)
@@ -383,6 +389,10 @@ void editor_mode::restore_track_snapshot(EditorSnapshot const &Snapshot, std::ve
for (auto const &entry : Snapshot.tracks)
editor_track::apply(*entry.first, entry.second);
editor_track::commit(tracks);
for (auto const &entry : Snapshot.infra)
infra_restore_state(entry);
m_infra_buffer.clear();
m_infra_suspended = false;
if (false == m_route.chain.tracks.empty())
{
std::string error;
@@ -420,6 +430,9 @@ void editor_mode::render_track_ui()
profile_open_run(*track);
m_profile.open = true;
}
ImGui::SameLine();
if (ImGui::Button("Infrastructure"))
m_infra.open = true;
if (ImGui::CollapsingHeader("Straights in the scenery"))
render_straights_ui();
render_switch_ui();
@@ -470,6 +483,13 @@ void editor_mode::render_track_window()
}
if (ImGui::SmallButton("Vertical profile along this line") && selected_track() != nullptr)
profile_open_run(*selected_track());
ImGui::SameLine();
if (ImGui::SmallButton("Infrastructure along this line"))
{
m_infra.open = true;
m_infra.scope = 1;
infra_recognize();
}
ImGui::End();
}