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:
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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};
|
||||
|
||||
1390
application/editormodeinfra.cpp
Normal file
1390
application/editormodeinfra.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user