mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 03:59:19 +02:00
refactor(editor): split the infrastructure window
This commit is contained in:
@@ -607,6 +607,10 @@ class editor_mode : public application_mode, private editor_track::observer
|
|||||||
void infra_move(infra::binding &Binding);
|
void infra_move(infra::binding &Binding);
|
||||||
void infra_attach(EditorSnapshot &Snapshot);
|
void infra_attach(EditorSnapshot &Snapshot);
|
||||||
void render_infra_window();
|
void render_infra_window();
|
||||||
|
void infra_rebase();
|
||||||
|
void render_infra_search();
|
||||||
|
void render_infra_candidates();
|
||||||
|
void render_infra_bound();
|
||||||
void draw_infra_overlay() const;
|
void draw_infra_overlay() const;
|
||||||
|
|
||||||
bool m_route_gizmo_using{false};
|
bool m_route_gizmo_using{false};
|
||||||
|
|||||||
@@ -1137,31 +1137,7 @@ void editor_mode::render_infra_window()
|
|||||||
{
|
{
|
||||||
state.follow = follow;
|
state.follow = follow;
|
||||||
if (follow)
|
if (follow)
|
||||||
{
|
infra_rebase();
|
||||||
// what changed in the meantime becomes the new starting point
|
|
||||||
for (auto &binding : m_bindings)
|
|
||||||
{
|
|
||||||
std::vector<glm::dvec3> points;
|
|
||||||
std::optional<double> yaw;
|
|
||||||
if (false == alive(binding) || false == object_points(binding, points, yaw) || points.size() != binding.anchors.size())
|
|
||||||
continue;
|
|
||||||
for (std::size_t i = 0; i < points.size(); ++i)
|
|
||||||
{
|
|
||||||
auto &anchor{binding.anchors[i]};
|
|
||||||
if (anchor.at.track == nullptr || anchor.at.track->m_editorremoved || anchor.at.path >= static_cast<int>(anchor.at.track->m_paths.size()))
|
|
||||||
{
|
|
||||||
binding.lost = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double s;
|
|
||||||
bool interior;
|
|
||||||
infra::project(anchor.at.track->m_paths[anchor.at.path], points[i], s, interior);
|
|
||||||
anchor = infra::make_anchor({anchor.at.track, anchor.at.path, s}, points[i]);
|
|
||||||
}
|
|
||||||
if (binding.turns && yaw.has_value())
|
|
||||||
binding.yaw = turn_of(binding, *yaw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
ImGui::SetTooltip("Bound objects keep their chainage along the path, the offset from its axis and the height above the rail top;\n"
|
ImGui::SetTooltip("Bound objects keep their chainage along the path, the offset from its axis and the height above the rail top;\n"
|
||||||
@@ -1176,6 +1152,46 @@ void editor_mode::render_infra_window()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
render_infra_search();
|
||||||
|
render_infra_candidates();
|
||||||
|
render_infra_bound();
|
||||||
|
if (false == state.error.empty())
|
||||||
|
ImGui::TextColored(ImVec4(1.f, 0.4f, 0.35f, 1.f), "%s", state.error.c_str());
|
||||||
|
else if (false == state.status.empty())
|
||||||
|
ImGui::TextWrapped("%s", state.status.c_str());
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// what changed while the bindings did not follow the track becomes their new starting point
|
||||||
|
void editor_mode::infra_rebase()
|
||||||
|
{
|
||||||
|
for (auto &binding : m_bindings)
|
||||||
|
{
|
||||||
|
std::vector<glm::dvec3> points;
|
||||||
|
std::optional<double> yaw;
|
||||||
|
if (false == alive(binding) || false == object_points(binding, points, yaw) || points.size() != binding.anchors.size())
|
||||||
|
continue;
|
||||||
|
for (std::size_t i = 0; i < points.size(); ++i)
|
||||||
|
{
|
||||||
|
auto &anchor{binding.anchors[i]};
|
||||||
|
if (anchor.at.track == nullptr || anchor.at.track->m_editorremoved || anchor.at.path >= static_cast<int>(anchor.at.track->m_paths.size()))
|
||||||
|
{
|
||||||
|
binding.lost = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
double s;
|
||||||
|
bool interior;
|
||||||
|
infra::project(anchor.at.track->m_paths[anchor.at.path], points[i], s, interior);
|
||||||
|
anchor = infra::make_anchor({anchor.at.track, anchor.at.path, s}, points[i]);
|
||||||
|
}
|
||||||
|
if (binding.turns && yaw.has_value())
|
||||||
|
binding.yaw = turn_of(binding, *yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_mode::render_infra_search()
|
||||||
|
{
|
||||||
|
auto &state{m_infra};
|
||||||
static char const *const scopes[] = {"Selected path", "Line through the selected path", "Route of the vertical profile", "Whole scenery"};
|
static char const *const scopes[] = {"Selected path", "Line through the selected path", "Route of the vertical profile", "Whole scenery"};
|
||||||
ImGui::SetNextItemWidth(260.f);
|
ImGui::SetNextItemWidth(260.f);
|
||||||
ImGui::Combo("Look along", &state.scope, scopes, IM_ARRAYSIZE(scopes));
|
ImGui::Combo("Look along", &state.scope, scopes, IM_ARRAYSIZE(scopes));
|
||||||
@@ -1209,7 +1225,17 @@ void editor_mode::render_infra_window()
|
|||||||
if (ImGui::Button("Find objects"))
|
if (ImGui::Button("Find objects"))
|
||||||
infra_recognize();
|
infra_recognize();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_mode::render_infra_candidates()
|
||||||
|
{
|
||||||
|
auto &state{m_infra};
|
||||||
auto &candidates{state.candidates};
|
auto &candidates{state.candidates};
|
||||||
|
auto const choose = [&](std::optional<infra::category> const Group, bool const Chosen) {
|
||||||
|
for (auto &candidate : candidates)
|
||||||
|
if (false == Group.has_value() || candidate.binding.group == *Group)
|
||||||
|
candidate.chosen = Chosen && false == candidate.bound;
|
||||||
|
};
|
||||||
state.hovered = -1;
|
state.hovered = -1;
|
||||||
if (false == candidates.empty())
|
if (false == candidates.empty())
|
||||||
{
|
{
|
||||||
@@ -1221,12 +1247,10 @@ void editor_mode::render_infra_window()
|
|||||||
infra_bind_chosen();
|
infra_bind_chosen();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SmallButton("All"))
|
if (ImGui::SmallButton("All"))
|
||||||
for (auto &candidate : candidates)
|
choose({}, true);
|
||||||
candidate.chosen = (false == candidate.bound);
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SmallButton("None"))
|
if (ImGui::SmallButton("None"))
|
||||||
for (auto &candidate : candidates)
|
choose({}, false);
|
||||||
candidate.chosen = false;
|
|
||||||
|
|
||||||
ImGui::BeginChild("##infracandidates", ImVec2(0.f, 260.f), true);
|
ImGui::BeginChild("##infracandidates", ImVec2(0.f, 260.f), true);
|
||||||
for (auto const group : infra::categories())
|
for (auto const group : infra::categories())
|
||||||
@@ -1239,14 +1263,10 @@ void editor_mode::render_infra_window()
|
|||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SmallButton((std::string{"all##g"} + infra::name(group)).c_str()))
|
if (ImGui::SmallButton((std::string{"all##g"} + infra::name(group)).c_str()))
|
||||||
for (auto &candidate : candidates)
|
choose(group, true);
|
||||||
if (candidate.binding.group == group)
|
|
||||||
candidate.chosen = (false == candidate.bound);
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::SmallButton((std::string{"none##g"} + infra::name(group)).c_str()))
|
if (ImGui::SmallButton((std::string{"none##g"} + infra::name(group)).c_str()))
|
||||||
for (auto &candidate : candidates)
|
choose(group, false);
|
||||||
if (candidate.binding.group == group)
|
|
||||||
candidate.chosen = false;
|
|
||||||
if (false == open)
|
if (false == open)
|
||||||
continue;
|
continue;
|
||||||
// the candidates are sorted by the category
|
// the candidates are sorted by the category
|
||||||
@@ -1282,7 +1302,10 @@ void editor_mode::render_infra_window()
|
|||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_mode::render_infra_bound()
|
||||||
|
{
|
||||||
if (ImGui::TreeNode("Bound objects along the scope"))
|
if (ImGui::TreeNode("Bound objects along the scope"))
|
||||||
{
|
{
|
||||||
auto const scope{infra_scope()};
|
auto const scope{infra_scope()};
|
||||||
@@ -1323,12 +1346,6 @@ void editor_mode::render_infra_window()
|
|||||||
infra_unbind({*unbind});
|
infra_unbind({*unbind});
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false == state.error.empty())
|
|
||||||
ImGui::TextColored(ImVec4(1.f, 0.4f, 0.35f, 1.f), "%s", state.error.c_str());
|
|
||||||
else if (false == state.status.empty())
|
|
||||||
ImGui::TextWrapped("%s", state.status.c_str());
|
|
||||||
ImGui::End();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void editor_mode::draw_infra_overlay() const
|
void editor_mode::draw_infra_overlay() const
|
||||||
|
|||||||
Reference in New Issue
Block a user