mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-20 11:34:53 +02:00
feat(editor): the terrain of a scenery begun from nothing grows where the track is laid
The terrain model was made once around the camera when a new scenery took it; tracks laid on past it went over nothing. While a track is laid or dragged out, the chunks missing within 400 m of the cursor are now made from the model too, the nearest first, in a scenery with the heightmap terrain placed on the map. The formations aren't made anew after such chunks. A chip in the terrain panel turns it off.
This commit is contained in:
@@ -345,6 +345,9 @@ class editor_mode : public application_mode, private editor_track::observer
|
||||
std::size_t samples{0};
|
||||
double band{300.0}; // m from the tracks the chunks made along them reach
|
||||
bool shape{true}; // the formation and the slopes of the tracks as modifiers of the terrain
|
||||
bool grow{true}; // while a track is laid, the terrain is made around the cursor where there's none
|
||||
bool grown{false}; // the chunks waiting were all asked for by growing: the formations aren't made anew after them
|
||||
double grow_time{-10.0};
|
||||
double slope{1.5};
|
||||
double reach{60.0};
|
||||
std::vector<heightmap::chunk_key> pending; // chunks to make once their model is in
|
||||
@@ -406,6 +409,7 @@ class editor_mode : public application_mode, private editor_track::observer
|
||||
// of the modifiers laid
|
||||
std::size_t nmt_shape_tracks(std::vector<TTrack *> const *Only = nullptr);
|
||||
void nmt_update();
|
||||
void nmt_grow();
|
||||
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();
|
||||
|
||||
@@ -452,6 +452,8 @@ void editor_mode::nmt_make(std::vector<heightmap::chunk_key> const &Keys, bool c
|
||||
++queued;
|
||||
}
|
||||
state.made = 0;
|
||||
if (queued > 0)
|
||||
state.grown = false;
|
||||
// the terrain comes with its photos
|
||||
if (queued > 0 && false == m_orthophoto.enabled())
|
||||
m_orthophoto.enabled(true);
|
||||
@@ -597,6 +599,7 @@ void editor_mode::nmt_update()
|
||||
nmt_finish_fit();
|
||||
return;
|
||||
}
|
||||
nmt_grow();
|
||||
if (state.pending.empty())
|
||||
return;
|
||||
// a few chunks a frame, those whose model is in
|
||||
@@ -623,7 +626,7 @@ void editor_mode::nmt_update()
|
||||
state.status = format(STR_C("Chunks made from the terrain model: %zu, waiting for it: %zu"), state.made, state.pending.size());
|
||||
if (state.pending.empty())
|
||||
{
|
||||
if (state.shape)
|
||||
if (state.shape && false == state.grown)
|
||||
{
|
||||
nmt_shape_tracks();
|
||||
state.status += format(STR_P("; the formation of %zu path shaped", "; the formation of %zu paths shaped", state.shaped), state.shaped);
|
||||
@@ -637,6 +640,44 @@ void editor_mode::nmt_update()
|
||||
state.error = STR(error);
|
||||
}
|
||||
|
||||
void editor_mode::nmt_grow()
|
||||
{
|
||||
auto &state{m_nmt_state};
|
||||
auto const now{ImGui::GetTime()};
|
||||
if (false == state.grow || now - state.grow_time < 0.5 || (false == m_lay.active && false == m_extend.active) || m_streamer.resident() == 0 || false == m_nmt.placed())
|
||||
return;
|
||||
state.grow_time = now;
|
||||
auto const at{m_extend.active ? m_extend.mouse : m_lay.mouse};
|
||||
glm::dvec2 const cursor{at.x, at.z};
|
||||
double constexpr grow_reach{400.0}; // m around the cursor
|
||||
auto const reach{static_cast<int>(std::ceil(grow_reach / heightmap::chunk_size))};
|
||||
auto const centre{heightmap::chunk_at(at.x, at.z)};
|
||||
std::vector<std::pair<double, heightmap::chunk_key>> missing;
|
||||
for (int dz = -reach; dz <= reach; ++dz)
|
||||
for (int dx = -reach; dx <= reach; ++dx)
|
||||
{
|
||||
heightmap::chunk_key const key{centre.first + dx, centre.second + dz};
|
||||
auto const low{heightmap::chunk_corner(key)};
|
||||
glm::dvec2 const nearest{std::clamp(cursor.x, low.x, low.x + heightmap::chunk_size), std::clamp(cursor.y, low.y, low.y + heightmap::chunk_size)};
|
||||
auto const distance{glm::distance(nearest, cursor)};
|
||||
if (distance <= grow_reach && false == m_streamer.exists(key) && std::find(state.pending.begin(), state.pending.end(), key) == state.pending.end())
|
||||
missing.emplace_back(distance, key);
|
||||
}
|
||||
if (missing.empty())
|
||||
return;
|
||||
std::sort(missing.begin(), missing.end());
|
||||
if (state.pending.empty())
|
||||
{
|
||||
state.grown = true;
|
||||
state.made = 0;
|
||||
}
|
||||
for (auto const &chunk : missing)
|
||||
state.pending.push_back(chunk.second);
|
||||
if (false == m_orthophoto.enabled())
|
||||
m_orthophoto.enabled(true);
|
||||
WriteLog(format("Editor: NMT - %zu chunks around the cursor to make", missing.size()), logtype::generic);
|
||||
}
|
||||
|
||||
void editor_mode::render_nmt_ui()
|
||||
{
|
||||
auto &state{m_nmt_state};
|
||||
@@ -748,6 +789,7 @@ void editor_mode::render_nmt_ui()
|
||||
STR_C("Loads the terrain model, the real relief of the ground, around the camera")};
|
||||
ImGui::SetTooltip("%s\n%s", text, STR_C("Terrain model: GUGiK, geoportal.gov.pl"));
|
||||
}
|
||||
toggle_chips("nmtgrow", {{STR_C("Make the terrain ahead while laying"), &state.grow, "Where a track is laid past the edge of the terrain, the terrain model is made around the cursor as it goes"}});
|
||||
// how far it got
|
||||
if (state.stage == nmt_state::automatic::fetching || state.fitting)
|
||||
{
|
||||
|
||||
@@ -9943,3 +9943,9 @@ msgstr "równolegle do %s"
|
||||
|
||||
msgid "%.0f deg to %s"
|
||||
msgstr "%.0f° do %s"
|
||||
|
||||
msgid "Make the terrain ahead while laying"
|
||||
msgstr "Dobudowuj teren przy układaniu"
|
||||
|
||||
msgid "Where a track is laid past the edge of the terrain, the terrain model is made around the cursor as it goes"
|
||||
msgstr "Gdy tor wychodzi poza teren, NMT dobudowuje się wokół kursora na bieżąco"
|
||||
|
||||
Reference in New Issue
Block a user