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

feat(editor): a scenery begun from nothing is asked for its terrain as the first track is laid

With the lay tool on, a scenery with no tracks nor terrain chunks gets the offer of the terrain model and the aerial photos
around the camera; without a place yet it asks for the PUWG 1992 coordinates of this point, as geoportal.gov.pl gives them,
and keeps them as the place of its orthophoto. The offer can be turned off (editor setting terrain_offer). Self-test
nmtoffer.
This commit is contained in:
maj00r
2026-10-18 13:02:01 +02:00
parent 5af699fba4
commit 5a00d88be9
7 changed files with 129 additions and 0 deletions

View File

@@ -1481,6 +1481,7 @@ bool editor_mode::update()
render_open_scenery_popup();
render_shortcuts_window();
render_first_steps();
render_nmt_prompt();
render_orthophoto_window();
render_switch_designer();
render_environment_window();

View File

@@ -348,6 +348,10 @@ class editor_mode : public application_mode, private editor_track::observer
std::size_t shaped{0};
std::string status;
std::string error;
bool offered{false}; // the terrain was offered to the scenery begun without it
bool prompt{false}; // the offer is shown
double north{0.0}; // the place typed into the offer, PUWG 1992
double east{0.0};
};
editor_nmt m_nmt;
nmt_state m_nmt_state;
@@ -362,6 +366,10 @@ class editor_mode : public application_mode, private editor_track::observer
void nmt_shape_tracks();
void nmt_update();
void render_nmt_ui();
// a scenery begun from nothing, with no tracks nor terrain, is asked as the first track is laid whether it wants the terrain
void nmt_offer();
void render_nmt_prompt();
void nmt_accept_offer();
// the tool of the terrain the left mouse button works
enum class terrain_tool
{

View File

@@ -16,6 +16,8 @@ http://mozilla.org/MPL/2.0/.
#include "application/editormodeshared.h"
#include "editor/editorFormat.hpp"
#include "editor/editorGeometry.hpp"
#include "editor/editorSettings.hpp"
#include "utilities/Globals.h"
#include "simulation/simulation.h"
#include "utilities/Logs.h"
#include "utilities/translation.h"
@@ -248,6 +250,7 @@ void editor_mode::nmt_shape_tracks()
void editor_mode::nmt_update()
{
auto &state{m_nmt_state};
nmt_offer();
if (state.fitting)
{
bool all{true};
@@ -335,3 +338,80 @@ void editor_mode::render_nmt_ui()
ImGui::TextColored(ImVec4(1.0f, 0.5f, 0.3f, 1.0f), "%s", state.error.c_str());
ImGui::TextDisabled("%s", STR_C("Terrain model: GUGiK, geoportal.gov.pl"));
}
void editor_mode::nmt_offer()
{
auto &state{m_nmt_state};
if (state.offered || false == m_lay.active || false == EditorSettings.terrain_offer())
return;
state.offered = true;
if (m_streamer.resident() > 0 || std::any_of(simulation::Paths.sequence().begin(), simulation::Paths.sequence().end(), [](TTrack const *Track) { return Track != nullptr && rail(*Track); }))
return;
nmt_locate();
state.north = m_orthophoto.settings().north;
state.east = m_orthophoto.settings().east;
state.prompt = true;
}
void editor_mode::nmt_accept_offer()
{
auto &state{m_nmt_state};
if (false == m_nmt.placed())
{
auto config{m_orthophoto.settings()};
config.north = state.north;
config.east = state.east;
m_orthophoto.settings(config);
m_orthophoto_origin_edit = {config.north, config.east};
save_orthophoto_settings();
}
// no tracks to fit to: the heights of the model as they are
state.offset = 0.0;
nmt_make(nmt_keys_around());
state.prompt = false;
}
void editor_mode::render_nmt_prompt()
{
auto &state{m_nmt_state};
if (false == state.prompt)
return;
char const *const title{STR_C("Terrain for the new scenery###nmtoffer")};
if (false == ImGui::IsPopupOpen(title))
ImGui::OpenPopup(title);
ImGui::SetNextWindowSize(ImVec2(520.0f * Global.ui_scale, 0.0f));
if (false == ImGui::BeginPopupModal(title, nullptr, ImGuiWindowFlags_NoResize))
return;
ImGui::TextWrapped("%s", STR_C("The scenery has no terrain yet. Load the terrain model and the aerial photos around here? The tracks laid then go along the real ground."));
bool const placed{m_nmt.placed()};
if (false == placed)
{
ImGui::TextWrapped("%s", STR_C("Where is it? PUWG 1992 of this point, X to the north and Y to the east, as geoportal.gov.pl gives them:"));
ImGui::SetNextItemWidth(150.0f);
ImGui::InputDouble("X##nmtnorth", &state.north, 0.0, 0.0, "%.0f");
ImGui::SameLine();
ImGui::SetNextItemWidth(150.0f);
ImGui::InputDouble("Y##nmteast", &state.east, 0.0, 0.0, "%.0f");
}
auto const known{placed || (state.north > 100000.0 && state.east > 100000.0)};
ImGui::BeginDisabled(false == known);
if (ImGui::Button(STR_C("Load the terrain")))
{
nmt_accept_offer();
ImGui::CloseCurrentPopup();
}
ImGui::EndDisabled();
ImGui::SameLine();
if (ImGui::Button(STR_C("Without terrain")))
{
state.prompt = false;
ImGui::CloseCurrentPopup();
}
bool ask{EditorSettings.terrain_offer()};
if (ImGui::Checkbox(STR_C("Ask with every new scenery"), &ask))
{
EditorSettings.terrain_offer(ask);
EditorSettings.save();
}
ImGui::EndPopup();
}

View File

@@ -82,6 +82,21 @@ editor_mode::selftest_result editor_mode::selftest_terrain(std::string const &co
WriteLog("SELFTEST nmtmake " + where + ": " + m_nmt_state.status);
return selftest_result::handled;
}
if (command == "nmtoffer")
{
// the offer of the terrain to a scenery begun from nothing: logged, and taken with the place given, if any
double north{0.0}, east{0.0};
words >> north >> east;
WriteLog(format("SELFTEST nmtoffer: shown %d", m_nmt_state.prompt ? 1 : 0));
if (north > 0.0 && east > 0.0 && m_nmt_state.prompt)
{
m_nmt_state.north = north;
m_nmt_state.east = east;
nmt_accept_offer();
WriteLog("SELFTEST nmtoffer taken: " + m_nmt_state.status);
}
return selftest_result::handled;
}
if (command == "nmtwait")
{
// till the model is in and the chunks waiting for it are made

View File

@@ -104,6 +104,8 @@ bool editorSettings::load()
parse(value, m_palette);
else if (key == "first_steps")
m_first_steps = (value == "1");
else if (key == "terrain_offer")
m_terrain_offer = (value == "1");
else if (key == "track_tools_all")
m_track_tools_more = (value == "1");
else if (key.rfind(origin_prefix, 0) == 0)
@@ -150,6 +152,7 @@ bool editorSettings::save()
stream << "nodebank_card " << m_nodebank_card << "\n";
stream << "colours " << m_palette << "\n";
stream << "first_steps " << (m_first_steps ? 1 : 0) << "\n";
stream << "terrain_offer " << (m_terrain_offer ? 1 : 0) << "\n";
stream << "track_tools_all " << (m_track_tools_more ? 1 : 0) << "\n";
stream << std::fixed << std::setprecision(3);
for (auto const &origin : m_orthophoto_origins)

View File

@@ -56,6 +56,9 @@ public:
bool first_steps() const { return m_first_steps; }
void first_steps(bool Show) { m_first_steps = Show; }
// a scenery begun with no terrain is offered the terrain model as the first track is laid
bool terrain_offer() const { return m_terrain_offer; }
void terrain_offer(bool Offer) { m_terrain_offer = Offer; }
bool track_tools_more() const { return m_track_tools_more; }
void track_tools_more(bool Show) { m_track_tools_more = Show; }
@@ -69,6 +72,7 @@ private:
int m_nodebank_card{96};
int m_palette{0};
bool m_first_steps{true};
bool m_terrain_offer{true};
bool m_track_tools_more{false};
};

View File

@@ -7121,3 +7121,21 @@ msgstr ". To za dużo: położenie scenerii jest pewnie złe, sprawdź ortofotom
msgid "There's terrain there already"
msgstr "Tam już jest teren"
msgid "Terrain for the new scenery###nmtoffer"
msgstr "Teren dla nowej scenerii###nmtoffer"
msgid "The scenery has no terrain yet. Load the terrain model and the aerial photos around here? The tracks laid then go along the real ground."
msgstr "Sceneria nie ma jeszcze terenu. Wczytać teren z NMT i zdjęcia lotnicze wokół tego miejsca? Tory układane potem pójdą po prawdziwym terenie."
msgid "Where is it? PUWG 1992 of this point, X to the north and Y to the east, as geoportal.gov.pl gives them:"
msgstr "Gdzie to jest? Współrzędne PUWG 1992 tego miejsca, X na północ i Y na wschód, jak podaje geoportal.gov.pl:"
msgid "Load the terrain"
msgstr "Wczytaj teren"
msgid "Without terrain"
msgstr "Bez terenu"
msgid "Ask with every new scenery"
msgstr "Pytaj przy każdej nowej scenerii"