mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-31 00:50:29 +01:00
feat(editor): the top view draws the tracks whole, without the ballast or the rails alone, in a colour of their own over the imagery and the map: both rails close up, one line further out; a choice by the extent and in the View menu, kept in the settings
This commit is contained in:
@@ -645,7 +645,7 @@ editor_ui *editor_mode::ui() const
|
||||
bool editor_mode::init()
|
||||
{
|
||||
EditorSettings.load();
|
||||
Global.EditorOrthoBallast = EditorSettings.top_ballast();
|
||||
Global.EditorOrthoTracks = EditorSettings.top_tracks();
|
||||
set_norms_free(EditorSettings.norms() == editorSettings::track_norms::free_laying);
|
||||
EditorModelSets.load();
|
||||
Camera.Init({0, 15, 0}, {glm::radians(-30.0), glm::radians(180.0), 0}, nullptr);
|
||||
@@ -1486,6 +1486,8 @@ bool editor_mode::update()
|
||||
draw_track_labels();
|
||||
draw_track_legend();
|
||||
}
|
||||
else if (Global.EditorOrtho && Global.EditorOrthoTracks > 1)
|
||||
draw_track_lines();
|
||||
if (selected_track())
|
||||
draw_track_overlay();
|
||||
if (route_active())
|
||||
@@ -3627,13 +3629,11 @@ void editor_mode::render_view_menu()
|
||||
toggle_ortho();
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C("The view straight down without perspective, as on a map; again for the camera as it was"));
|
||||
if (ImGui::MenuItem(STR_C("Ballast in the top view"), nullptr, &Global.EditorOrthoBallast))
|
||||
if (ImGui::BeginMenu(STR_C("Tracks in the top view")))
|
||||
{
|
||||
EditorSettings.top_ballast(Global.EditorOrthoBallast);
|
||||
EditorSettings.save();
|
||||
render_top_tracks_choice(false);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C("Off: the top view draws the rails and sleepers of the tracks without the ballast, so the ground under them shows"));
|
||||
if (ImGui::BeginMenu(STR_C("Track colours")))
|
||||
{
|
||||
char const *const names[]{"Plain", "By the radius", "By the speed", "By the grade"};
|
||||
@@ -5656,13 +5656,7 @@ void editor_mode::render_gizmo_options()
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C("Wheel zooms. Hold the wheel and drag to pan."));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Checkbox(STR_C("Ballast"), &Global.EditorOrthoBallast))
|
||||
{
|
||||
EditorSettings.top_ballast(Global.EditorOrthoBallast);
|
||||
EditorSettings.save();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C("Off: the top view draws the rails and sleepers of the tracks without the ballast, so the ground under them shows"));
|
||||
render_top_tracks_choice(true);
|
||||
}
|
||||
if (ui()->mode() == nodebank_panel::TRACK && m_track_tab != track_tab::path && m_track_tab != track_tab::turnout && m_track_tab != track_tab::turntable && m_track_tab != track_tab::srk &&
|
||||
m_track_tab != track_tab::lineside)
|
||||
@@ -6999,3 +6993,51 @@ void editor_mode::starter_trainset(std::vector<std::string> &Trailing)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void editor_mode::render_top_tracks_choice(bool const Combo)
|
||||
{
|
||||
static char const *const labels[]{"Whole", "Without ballast", "Rails only"};
|
||||
static char const *const tooltips[]{"The tracks as in the 3D view", "The rails and the sleepers, the ground under them shows", "The rails alone, without the sleepers and the timbers of the switches, as on a plan"};
|
||||
auto chosen{std::clamp(Global.EditorOrthoTracks, 0, 2)};
|
||||
auto const pick = [&](int const Choice) {
|
||||
Global.EditorOrthoTracks = Choice;
|
||||
EditorSettings.top_tracks(Choice);
|
||||
EditorSettings.save();
|
||||
};
|
||||
if (false == Combo)
|
||||
{
|
||||
for (int choice = 0; choice < 3; ++choice)
|
||||
{
|
||||
if (ImGui::MenuItem(STR_C(labels[choice]), nullptr, chosen == choice))
|
||||
pick(choice);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C(tooltips[choice]));
|
||||
}
|
||||
return;
|
||||
}
|
||||
ImGui::SetNextItemWidth(130.0f);
|
||||
if (ImGui::BeginCombo(STR_C("Tracks"), STR_C(labels[chosen])))
|
||||
{
|
||||
for (int choice = 0; choice < 3; ++choice)
|
||||
{
|
||||
if (ImGui::Selectable(STR_C(labels[choice]), chosen == choice))
|
||||
pick(choice);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C(tooltips[choice]));
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C("How the top view draws the tracks"));
|
||||
if (chosen < 2)
|
||||
return;
|
||||
ImGui::SameLine();
|
||||
auto colour{ImGui::ColorConvertU32ToFloat4(EditorSettings.top_rails())};
|
||||
if (ImGui::ColorEdit3("##toprails", &colour.x, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel))
|
||||
{
|
||||
EditorSettings.top_rails(ImGui::ColorConvertFloat4ToU32(ImVec4(colour.x, colour.y, colour.z, 1.0f)));
|
||||
EditorSettings.save();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("%s", STR_C("The colour of the rails, to stand out on the imagery and the map"));
|
||||
}
|
||||
|
||||
@@ -765,6 +765,8 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void render_gizmo();
|
||||
// gizmo settings, drawn in the toolset window
|
||||
void render_gizmo_options();
|
||||
// how the top view draws the tracks: as a combo with the colour of the rails, or as items of a menu
|
||||
void render_top_tracks_choice(bool const Combo);
|
||||
// the tools of the field of work in the toolbar under the menu
|
||||
void render_toolbar();
|
||||
// an edit mode of the node bank as the field of work, from the toolbar or its key (1-5)
|
||||
|
||||
@@ -283,8 +283,8 @@ editor_mode::selftest_result editor_mode::selftest_scene(std::string const &comm
|
||||
if (extent > 0.0f)
|
||||
Global.EditorOrthoExtent = std::clamp(extent, 5.0f, 50000.0f);
|
||||
if (false == ballast.empty())
|
||||
Global.EditorOrthoBallast = ballast != "noballast";
|
||||
WriteLog(format("SELFTEST ortho extent %.0f ballast %d", Global.EditorOrthoExtent, Global.EditorOrthoBallast ? 1 : 0));
|
||||
Global.EditorOrthoTracks = ballast == "rails" ? 2 : ballast == "noballast" ? 1 : 0;
|
||||
WriteLog(format("SELFTEST ortho extent %.0f tracks %d", Global.EditorOrthoExtent, Global.EditorOrthoTracks));
|
||||
return selftest_result::handled;
|
||||
}
|
||||
if (command == "mapstate")
|
||||
|
||||
@@ -15,6 +15,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "application/editormodetrackshared.h"
|
||||
#include "editor/editorFormat.hpp"
|
||||
#include "editor/editorGeometry.hpp"
|
||||
#include "editor/editorSettings.hpp"
|
||||
#include "editor/editorSwitchStore.hpp"
|
||||
|
||||
#include "utilities/Globals.h"
|
||||
@@ -201,14 +202,18 @@ void editor_mode::update_track_hover()
|
||||
void editor_mode::draw_track_lines() const
|
||||
{
|
||||
auto const metres{ortho_metres_per_pixel()};
|
||||
auto const colouring{m_track_colouring};
|
||||
if (metres < kLinesFrom && colouring == track_colouring::plain)
|
||||
auto const colouring{ui()->mode() == nodebank_panel::TRACK ? m_track_colouring : track_colouring::plain};
|
||||
// the top view of the rails alone draws them in a colour of their own, as on a plan: both rails where they're apart on the screen
|
||||
auto const rails{metres > 0.0 && Global.EditorOrthoTracks > 1 && colouring == track_colouring::plain};
|
||||
if (metres < kLinesFrom && colouring == track_colouring::plain && false == rails)
|
||||
return;
|
||||
auto const &io{ImGui::GetIO()};
|
||||
screen_projection const projection;
|
||||
glm::dvec2 const centre{Global.pCamera.Pos.x, Global.pCamera.Pos.z};
|
||||
auto const reach{Global.EditorOrtho ? 0.5 * metres * std::hypot(static_cast<double>(io.DisplaySize.x), static_cast<double>(io.DisplaySize.y)) : kColouredReach};
|
||||
auto const width{colouring == track_colouring::plain ? 1.5f : 3.0f};
|
||||
auto const width{rails ? std::max(2.0f, static_cast<float>(0.07 / metres)) : colouring == track_colouring::plain ? 1.5f : 3.0f};
|
||||
auto const railcolour{EditorSettings.top_rails()};
|
||||
std::vector<glm::dvec3> points;
|
||||
auto *drawlist{ImGui::GetBackgroundDrawList(ImGui::GetMainViewport())};
|
||||
for (auto *track : simulation::Paths.sequence())
|
||||
{
|
||||
@@ -220,7 +225,7 @@ void editor_mode::draw_track_lines() const
|
||||
bezier const curve{path};
|
||||
if (false == plan_near(curve, centre, reach))
|
||||
continue;
|
||||
auto colour{IM_COL32(235, 235, 235, 150)};
|
||||
auto colour{rails ? railcolour : IM_COL32(235, 235, 235, 150)};
|
||||
if (colouring == track_colouring::radius)
|
||||
{
|
||||
auto const radius{::track_mode::piece_plan_radius(path)};
|
||||
@@ -229,7 +234,24 @@ void editor_mode::draw_track_lines() const
|
||||
else if (colouring == track_colouring::speed)
|
||||
colour = velocity > 0.0 ? band_colour(kSpeedBands, velocity) : kUncoloured;
|
||||
auto const length{curve.plan_length(4)};
|
||||
auto const count{std::clamp(static_cast<int>(length / std::max(metres, 0.5) / 8.0), colouring == track_colouring::grade ? std::clamp(static_cast<int>(length / 10.0), 1, 8) : 1, 32)};
|
||||
auto const count{std::clamp(static_cast<int>(length / std::max(metres, 0.5) / 8.0), colouring == track_colouring::grade ? std::clamp(static_cast<int>(length / 10.0), 1, 8) : 1, rails ? 128 : 32)};
|
||||
if (rails && track->fTrackWidth / metres > 6.0)
|
||||
{
|
||||
points.clear();
|
||||
for (int k = 0; k <= count; ++k)
|
||||
points.push_back(curve.point(static_cast<double>(k) / count));
|
||||
auto const half{(track->fTrackWidth + 0.07) * 0.5};
|
||||
auto const across = [&](std::size_t const K) {
|
||||
auto const along{points[std::min(K + 1, points.size() - 1)] - points[K > 0 ? K - 1 : 0]};
|
||||
auto const normal{glm::dvec3{-along.z, 0.0, along.x}};
|
||||
auto const size{glm::length(normal)};
|
||||
return size > 1e-9 ? normal * (half / size) : glm::dvec3{0.0};
|
||||
};
|
||||
for (auto const side : {-1.0, 1.0})
|
||||
for (std::size_t k = 1; k < points.size(); ++k)
|
||||
projection.line(drawlist, points[k - 1] + across(k - 1) * side, points[k] + across(k) * side, colour, width);
|
||||
continue;
|
||||
}
|
||||
auto previous{curve.point(0.0)};
|
||||
for (int k = 1; k <= count; ++k)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user