mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-06 08:08:36 +01:00
feat(editor): the track laid on the terrain gets its grade line from the profile solver
In place of a line bent every ten metres to keep within 0.1 m of every bump, the grades and the vertical curves are fitted to the ground the way the profile fits them. Where the formation is made in the terrain model the line keeps to the radius of the norms and cuts and fills; over the ground left as it is it bends as sharply as it has to. The joints keep the height and the grade of the track joined, no grade is capped and no piece is under 5 m.
This commit is contained in:
@@ -406,6 +406,8 @@ class editor_mode : public application_mode, private editor_track::observer, pri
|
||||
void nmt_follow_tracks();
|
||||
// the height the ground will have where the terrain is made ahead of the track laid and isn't there yet
|
||||
bool nmt_ahead(double const X, double const Z, double &Height) const;
|
||||
// a track laid through the points gets its formation from the terrain of the model: it needn't keep to every bump of it
|
||||
bool nmt_formed(std::vector<glm::dvec2> const &Points) const;
|
||||
// the squares of the model under the rectangle are in, none of them waiting to be asked for again
|
||||
bool nmt_ready(glm::dvec2 const &Min, glm::dvec2 const &Max);
|
||||
// Only: the paths of these tracks are shaped anew, the modifiers of those removed taken away; null: all of them. the number
|
||||
|
||||
@@ -640,6 +640,20 @@ bool editor_mode::nmt_ahead(double const X, double const Z, double &Height) cons
|
||||
return true;
|
||||
}
|
||||
|
||||
bool editor_mode::nmt_formed(std::vector<glm::dvec2> const &Points) const
|
||||
{
|
||||
auto const &state{m_nmt_state};
|
||||
if (false == state.shape || false == m_nmt.placed() || false == m_streamer.active())
|
||||
return false;
|
||||
bool foreign{false};
|
||||
if (nmt_terrain_offset(Points, foreign).has_value())
|
||||
return true;
|
||||
if (foreign)
|
||||
return false;
|
||||
double height;
|
||||
return std::all_of(Points.begin(), Points.end(), [&](glm::dvec2 const &Point) { return false == m_streamer.height_at(Point.x, Point.y, height) && nmt_ahead(Point.x, Point.y, height); });
|
||||
}
|
||||
|
||||
editor_mode::nmt_chunk editor_mode::add_chunk_from_nmt(heightmap::chunk_key const &Key, std::optional<double> const Offset)
|
||||
{
|
||||
auto const low{heightmap::chunk_corner(Key)};
|
||||
|
||||
@@ -25,6 +25,11 @@ namespace
|
||||
using geometry::plan_distance;
|
||||
using geometry::plan_of;
|
||||
|
||||
double constexpr kSteepest{1000.0}; // per mille: the grades of the user's own track aren't capped
|
||||
double constexpr kFormed{0.5}; // m, how closely the line keeps to the ground the formation is made in
|
||||
double constexpr kBare{0.1}; // m, to the ground left as it is
|
||||
double constexpr kBareRadius{300.0}; // m, the vertical curves over it
|
||||
|
||||
} // namespace
|
||||
|
||||
glm::dvec3 editor_mode::cursor_terrain(double const Height)
|
||||
@@ -124,7 +129,30 @@ double editor_mode::bed_height(glm::dvec3 const &Point, glm::dvec2 const &Direct
|
||||
|
||||
void editor_mode::follow_ground(std::vector<segment_data> &Pieces, double const Height0, double const Grade0, double const Height1, double const Grade1, TTrack const *Style) const
|
||||
{
|
||||
ground_follow::follow(Pieces, {Height0, Grade0, Height1, Grade1}, [&](std::vector<glm::dvec3> const &Points, std::vector<glm::dvec2> const &Directions) { return bed_heights(Points, Directions, Style); });
|
||||
std::vector<glm::dvec2> points;
|
||||
for (auto const &piece : Pieces)
|
||||
{
|
||||
geometry::bezier const curve{piece};
|
||||
auto const count{std::max(6, static_cast<int>(std::ceil(curve.plan_length() / 10.0)))};
|
||||
for (int i = 0; i <= count; ++i)
|
||||
points.push_back(plan_of(curve.point(static_cast<double>(i) / count)));
|
||||
}
|
||||
// the ground the formation is made in lets the line keep to the norms of the profile, cutting and filling; the ground left as
|
||||
// it is the line follows, bending as sharply as it has to
|
||||
auto const formed{nmt_formed(points)};
|
||||
ground_follow::grading grading;
|
||||
grading.settings.norms = m_profile.line.norms;
|
||||
grading.settings.norms.grade_max = kSteepest;
|
||||
grading.settings.norms.curve_threshold = 0.0;
|
||||
if (false == formed)
|
||||
{
|
||||
grading.settings.norms.radius_factor = 0.0;
|
||||
grading.settings.norms.radius_min = kBareRadius;
|
||||
}
|
||||
grading.settings.speed = design_speed(Style, nullptr);
|
||||
grading.fit.grade_max = kSteepest;
|
||||
grading.fit.tolerance = formed ? kFormed : kBare;
|
||||
ground_follow::follow(Pieces, {Height0, Grade0, Height1, Grade1}, [&](std::vector<glm::dvec3> const &Points, std::vector<glm::dvec2> const &Directions) { return bed_heights(Points, Directions, Style); }, grading);
|
||||
}
|
||||
|
||||
glm::dvec3 editor_mode::lay_bed(glm::dvec3 const &Point)
|
||||
|
||||
Reference in New Issue
Block a user