mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-02 23:16:22 +01:00
refactor(editor): split the track mode into its gizmo, kept records, switch drive, switch slide and track bed files; path geometry shared in editorGeometry instead of four copies of the reversed path, track shape rules (stretching, rolls at joints, middle, switch axis, drive spot) in editor_track, fitting the track to the ground in ground_follow with the terrain query passed in, the record layer and the switch classification in the stores; long gizmo, record watch and switch slide functions broken up, out-parameters replaced by optional results
This commit is contained in:
@@ -159,4 +159,72 @@ inline double chord_length(segment_data const &Path)
|
||||
return glm::length(plan_of(Path.points[segment_data::point::end] - Path.points[segment_data::point::start]));
|
||||
}
|
||||
|
||||
inline bool has_controls(segment_data const &Path)
|
||||
{
|
||||
return Path.points[segment_data::point::control1] != glm::dvec3{} || Path.points[segment_data::point::control2] != glm::dvec3{};
|
||||
}
|
||||
|
||||
inline segment_data reversed(segment_data const &Path)
|
||||
{
|
||||
segment_data result{Path};
|
||||
result.points[segment_data::point::start] = Path.points[segment_data::point::end];
|
||||
result.points[segment_data::point::end] = Path.points[segment_data::point::start];
|
||||
result.points[segment_data::point::control1] = Path.points[segment_data::point::control2];
|
||||
result.points[segment_data::point::control2] = Path.points[segment_data::point::control1];
|
||||
result.rolls = {-Path.rolls[1], -Path.rolls[0]};
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::vector<segment_data> straight_piece(glm::dvec3 const &Point, glm::dvec2 const &Direction, double const Grade, double const Length)
|
||||
{
|
||||
if (Length < 0.5)
|
||||
return {};
|
||||
segment_data path;
|
||||
path.points[segment_data::point::start] = Point;
|
||||
path.points[segment_data::point::end] = {Point.x + Direction.x * Length, Point.y + Grade * Length, Point.z + Direction.y * Length};
|
||||
return {path};
|
||||
}
|
||||
|
||||
inline segment_data part_of(segment_data const &Piece, double const From, double const To)
|
||||
{
|
||||
bezier const curve{Piece};
|
||||
segment_data result{Piece};
|
||||
result.points[segment_data::point::start] = curve.point(From);
|
||||
result.points[segment_data::point::end] = curve.point(To);
|
||||
if (has_controls(Piece))
|
||||
{
|
||||
result.points[segment_data::point::control1] = curve.first(From) * ((To - From) / 3.0);
|
||||
result.points[segment_data::point::control2] = -curve.first(To) * ((To - From) / 3.0);
|
||||
}
|
||||
result.rolls = {glm::mix(Piece.rolls[0], Piece.rolls[1], static_cast<float>(From)), glm::mix(Piece.rolls[0], Piece.rolls[1], static_cast<float>(To))};
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::vector<segment_data> arc_through(glm::dvec3 const &Point, glm::dvec2 const &Direction, double const Grade, glm::dvec2 const &Offset)
|
||||
{
|
||||
auto const along{glm::dot(Offset, Direction)};
|
||||
auto const lateral{cross(Direction, Offset)};
|
||||
auto const chord{glm::length(Offset)};
|
||||
if (along <= 0.0 || chord < 0.5)
|
||||
return {};
|
||||
if (std::abs(lateral) < 0.005 * chord + 0.05)
|
||||
return straight_piece(Point, Direction, Grade, along);
|
||||
auto const angle{2.0 * std::atan2(std::abs(lateral), along)};
|
||||
return arc_pieces(Point, Direction, Grade, chord / (2.0 * std::sin(angle * 0.5)), angle, lateral > 0.0 ? 1 : -1);
|
||||
}
|
||||
|
||||
inline double hermite(double const Length, double const Height0, double const Grade0, double const Height1, double const Grade1, double const T, double &Grade)
|
||||
{
|
||||
auto const t2{T * T};
|
||||
auto const t3{t2 * T};
|
||||
Grade = (6.0 * t2 - 6.0 * T) * (Height0 - Height1) / Length + (3.0 * t2 - 4.0 * T + 1.0) * Grade0 + (3.0 * t2 - 2.0 * T) * Grade1;
|
||||
return (2.0 * t3 - 3.0 * t2 + 1.0) * Height0 + (t3 - 2.0 * t2 + T) * Length * Grade0 + (3.0 * t2 - 2.0 * t3) * Height1 + (t3 - t2) * Length * Grade1;
|
||||
}
|
||||
|
||||
inline glm::dvec3 level(glm::dvec3 const &Vector)
|
||||
{
|
||||
glm::dvec3 const flat{Vector.x, 0.0, Vector.z};
|
||||
return glm::length(flat) > 1e-9 ? glm::normalize(flat) : glm::dvec3{0.0, 0.0, 1.0};
|
||||
}
|
||||
|
||||
} // namespace geometry
|
||||
|
||||
Reference in New Issue
Block a user