17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-30 21:20:28 +01: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