mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 08:39:19 +02:00
feat(editor): laying with no ground under the cursor takes the height of the ground around
- with nothing under the cursor the height is the mean of the ground found on the nearest ring around the point, 10 to 400 m out, plus the depth of the ballast, instead of 0; the ray of the cursor meets that height - the ground under the cursor is looked for up to the height of the camera, not only 50 m over the last point
This commit is contained in:
@@ -3994,21 +3994,55 @@ glm::dvec3 editor_mode::cursor_terrain(double const Height)
|
||||
for (int i = 0; i < 5 && std::isfinite(point.x) && std::isfinite(point.z); ++i)
|
||||
{
|
||||
std::vector<char> found;
|
||||
auto const heights{ground_heights({point}, true, &found)};
|
||||
auto ground{ground_heights({glm::dvec3{point.x, std::max(point.y, static_cast<double>(Global.pCamera.Pos.y)), point.z}}, true, &found).front()};
|
||||
if (found[0] == 0)
|
||||
ground = nearby_ground(point);
|
||||
if (std::isnan(ground))
|
||||
return point;
|
||||
auto const next{cursor_level(heights[0])};
|
||||
auto const next{cursor_level(ground)};
|
||||
auto const settled{plan_distance(next, point) < 0.01};
|
||||
point = {next.x, heights[0], next.z};
|
||||
point = {next.x, ground, next.z};
|
||||
if (settled)
|
||||
break;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
double editor_mode::nearby_ground(glm::dvec3 const &Point) const
|
||||
{
|
||||
auto const ceiling{std::max(Point.y, static_cast<double>(Global.pCamera.Pos.y))};
|
||||
for (double const radius : {10.0, 25.0, 50.0, 100.0, 200.0, 400.0})
|
||||
{
|
||||
std::vector<glm::dvec3> probes;
|
||||
for (int i = 0; i < 12; ++i)
|
||||
{
|
||||
auto const angle{glm::two_pi<double>() * i / 12.0};
|
||||
probes.push_back({Point.x + radius * std::cos(angle), ceiling, Point.z + radius * std::sin(angle)});
|
||||
}
|
||||
std::vector<char> found;
|
||||
auto const heights{ground_heights(probes, true, &found)};
|
||||
double sum{0.0};
|
||||
int count{0};
|
||||
for (std::size_t i = 0; i < probes.size(); ++i)
|
||||
if (found[i] != 0)
|
||||
{
|
||||
sum += heights[i];
|
||||
++count;
|
||||
}
|
||||
if (count > 0)
|
||||
return sum / count;
|
||||
}
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
std::pair<double, double> editor_mode::trackbed(TTrack const *Style)
|
||||
{
|
||||
return Style != nullptr ? profile_ballast(*Style) : std::pair<double, double>{0.2, 0.5 * 1.435 + 0.5 + 1.1};
|
||||
}
|
||||
|
||||
std::vector<double> editor_mode::bed_heights(std::vector<glm::dvec3> const &Points, std::vector<glm::dvec2> const &Directions, TTrack const *Style) const
|
||||
{
|
||||
auto const [depth, half]{Style != nullptr ? profile_ballast(*Style) : std::pair<double, double>{0.2, 0.5 * 1.435 + 0.5 + 1.1}};
|
||||
auto const [depth, half]{trackbed(Style)};
|
||||
std::vector<glm::dvec3> probes;
|
||||
probes.reserve(Points.size() * 3);
|
||||
for (std::size_t i = 0; i < Points.size(); ++i)
|
||||
@@ -4040,7 +4074,10 @@ std::vector<double> editor_mode::bed_heights(std::vector<glm::dvec3> const &Poin
|
||||
double editor_mode::bed_height(glm::dvec3 const &Point, glm::dvec2 const &Direction, TTrack const *Style) const
|
||||
{
|
||||
auto const height{bed_heights({Point}, {Direction}, Style).front()};
|
||||
return std::isnan(height) ? Point.y : height;
|
||||
if (false == std::isnan(height))
|
||||
return height;
|
||||
auto const nearby{nearby_ground(Point)};
|
||||
return std::isnan(nearby) ? Point.y : nearby + trackbed(Style).first;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user