17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-30 20:10:29 +01:00

feat(editor): track editor driven by what the cursor is over: the outline and a label show what a click or a drag does, snapping to free ends on the screen, handles and ends dragged directly, no rotation gizmo; laying from a free end the same in every mode, straight with Shift, the curve of a switch going on past its diverging end; height 0 where there's no terrain; placed switch leaves the switch mode, double slips listed apart, a drive of the switch placed with it by the //$e switch description of its template; compound curves of any number of radii; dragged end of a straight fits the curve beside it; name of a path, followed by the memory cells and the includes taking it; turntable placed from a template described as one, tracks led out of it and the tracks around fitted to it, its positions written to the include; infrastructure bound to the path whose events read its memory cell; terrain made where the route has none and shaped to the formation under the ballast; models along the track over the selected path and on along the joined ones while dragged, rarely used settings folded; vehicles and trainsets placed on any path, switches included, facing the way the arrow shows; joined paths spread into the selection; New scenery in the File menu starts the editor again with the wizard; ortho zoom towards the cursor; scripted self tests; Polish translation

This commit is contained in:
maj00r
2026-10-06 22:19:54 +02:00
parent 0a3cd55e59
commit 24923dd472
26 changed files with 9991 additions and 468 deletions

View File

@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
#include <algorithm>
#include <cmath>
#include <vector>
#include <glm/glm.hpp>
#include "world/Segment.h"
@@ -56,6 +57,36 @@ inline double grade_of(glm::dvec3 const &Direction)
return Direction.y / std::max(1e-9, std::hypot(Direction.x, Direction.z));
}
inline std::vector<segment_data> arc_pieces(glm::dvec3 const &Point, glm::dvec2 const &Direction, double const Grade, double const Radius, double const Angle, int const Side)
{
std::vector<segment_data> result;
double const side{static_cast<double>(Side)};
glm::dvec2 const centre{plan_of(Point) + glm::dvec2{-Direction.y, Direction.x} * (side * Radius)};
auto const count{std::max(1, static_cast<int>(std::ceil(Angle / glm::radians(90.0) - 1e-9)))};
auto const step{Angle / count};
auto const handle{4.0 / 3.0 * std::tan(step / 4.0) * Radius};
glm::dvec2 const radial{plan_of(Point) - centre};
for (int i = 0; i < count; ++i)
{
auto const a0{side * step * i};
auto const a1{side * step * (i + 1)};
auto const p0{centre + turned(radial, a0)};
auto const p3{centre + turned(radial, a1)};
auto const d0{turned(Direction, a0)};
auto const d3{turned(Direction, a1)};
auto const y0{Point.y + Grade * Radius * step * i};
auto const y3{Point.y + Grade * Radius * step * (i + 1)};
segment_data path;
path.points[segment_data::point::start] = {p0.x, y0, p0.y};
path.points[segment_data::point::end] = {p3.x, y3, p3.y};
path.points[segment_data::point::control1] = {d0.x * handle, Grade * handle, d0.y * handle};
path.points[segment_data::point::control2] = {-d3.x * handle, -Grade * handle, -d3.y * handle};
path.radius = static_cast<float>(Radius);
result.push_back(path);
}
return result;
}
// path as a cubic Bezier curve; a path without control points is a straight with evenly spread parameter
struct bezier
{