mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 20:19:20 +02:00
feat(editor): switch drive placed with a switch leans with the grade and the cant of the track at the points, raised as the simulation raises a canted track
This commit is contained in:
@@ -1042,6 +1042,7 @@ class editor_mode : public application_mode, private editor_track::observer
|
||||
std::vector<std::string> rest; // parameters after the rotation
|
||||
bool described{false};
|
||||
std::string track;
|
||||
glm::dvec2 tilt{0.0}; // rot.x and rot.z of a described template, degrees
|
||||
};
|
||||
struct standing_template
|
||||
{
|
||||
|
||||
@@ -288,7 +288,7 @@ std::size_t editor_mode::place_templates(std::vector<template_item> const &Items
|
||||
include_info info;
|
||||
if (false == editor_includes::load(item.file, info, Error))
|
||||
continue;
|
||||
directive = editor_includes::directive(item.file, info, editor_includes::parameter_count(item.file), local, static_cast<float>(item.yaw), item.track);
|
||||
directive = editor_includes::directive(item.file, info, editor_includes::parameter_count(item.file), local, static_cast<float>(item.yaw), item.track, item.tilt);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -350,6 +350,38 @@ void editor_mode::selftest_step()
|
||||
WriteLog(format("SELFTEST frame %s %.2f: %.3f %.3f %.3f widening %.4f cant %.4f setback %.4f", name.c_str(), station, at.position.x, at.position.y, at.position.z, at.widening[side], at.cant[side], sweep->setback(at)));
|
||||
}
|
||||
}
|
||||
else if (command == "switchdrive")
|
||||
{
|
||||
int index{-1}, side{0};
|
||||
words >> index >> side;
|
||||
scan_switch_drives();
|
||||
m_switch.drive = index;
|
||||
m_switch.drive_side = side;
|
||||
WriteLog("SELFTEST switchdrive: " + (index >= 0 && index < static_cast<int>(m_switch.drives.size()) ? m_switch.drives[index].name : std::string{"none"}));
|
||||
}
|
||||
else if (command == "drivetilt")
|
||||
{
|
||||
std::string name;
|
||||
words >> name;
|
||||
auto *model{simulation::Instances.find(name)};
|
||||
auto *track{simulation::Paths.find(name.substr(0, name.find('_')))};
|
||||
if (model == nullptr || track == nullptr)
|
||||
{
|
||||
WriteLog("SELFTEST drivetilt: no " + name);
|
||||
continue;
|
||||
}
|
||||
auto const &path{track->m_paths[0]};
|
||||
auto const transform{glm::dmat3(model->rotation_scale())};
|
||||
auto const across{transform * glm::dvec3{1.0, 0.0, 0.0}};
|
||||
auto const forward{transform * glm::dvec3{0.0, 0.0, 1.0}};
|
||||
auto const direction{glm::normalize(glm::dvec2{forward.x, forward.z})};
|
||||
auto const lateral{across.x * -direction.y + across.z * direction.x};
|
||||
auto const cone{-lateral * std::tan(glm::radians(static_cast<double>(path.rolls[0])))};
|
||||
auto const control{path.points[segment_data::point::control1]};
|
||||
auto const grade{control.y / std::hypot(control.x, control.z)};
|
||||
WriteLog(format("SELFTEST drivetilt %s: angles %.3f %.3f %.3f, +x rises %.4f (cone %.4f), +z rises %.4f (grade %.4f), origin %.3f %.3f %.3f, points %.3f", name.c_str(), model->Angles().x, model->Angles().y, model->Angles().z, across.y, cone, forward.y, grade,
|
||||
model->location().x, model->location().y, model->location().z, path.points[segment_data::point::start].y));
|
||||
}
|
||||
else if (command == "fouling")
|
||||
{
|
||||
std::map<std::string, std::string> values;
|
||||
|
||||
@@ -4747,6 +4747,14 @@ bool editor_mode::place_switch_drive(TTrack &Switch)
|
||||
item.yaw = yaw < 0.0 ? yaw + 360.0 : yaw;
|
||||
item.described = true;
|
||||
item.track = Switch.name();
|
||||
{
|
||||
auto const along{control != glm::dvec3{} ? control : main.points[segment_data::point::end] - start};
|
||||
auto const run{glm::length(plan_of(along))};
|
||||
auto const roll{static_cast<double>(main.rolls[0])};
|
||||
item.tilt = {run > 1e-9 ? -glm::degrees(std::atan(along.y / run)) : 0.0, roll};
|
||||
if (Global.bRollFix)
|
||||
item.location.y += 0.75 * std::abs(std::sin(glm::radians(roll)));
|
||||
}
|
||||
std::string error;
|
||||
if (place_templates({item}, error) == 0)
|
||||
{
|
||||
|
||||
@@ -644,7 +644,7 @@ std::string compose_directive(std::string const &File, std::vector<std::string>
|
||||
return text + " end";
|
||||
}
|
||||
|
||||
std::string directive(std::string const &File, include_info const &Info, int const Parameters, glm::dvec3 const &Location, std::optional<float> Yaw, std::string const &Track)
|
||||
std::string directive(std::string const &File, include_info const &Info, int const Parameters, glm::dvec3 const &Location, std::optional<float> Yaw, std::string const &Track, glm::dvec2 const &Tilt)
|
||||
{
|
||||
std::vector<std::string> values;
|
||||
for (auto id = 1; id <= Parameters; ++id)
|
||||
@@ -668,6 +668,14 @@ std::string directive(std::string const &File, include_info const &Info, int con
|
||||
{
|
||||
value = number(*Yaw);
|
||||
}
|
||||
else if (role == "rot.x" && Tilt.x != 0.0)
|
||||
{
|
||||
value = number(Tilt.x);
|
||||
}
|
||||
else if (role == "rot.z" && Tilt.y != 0.0)
|
||||
{
|
||||
value = number(Tilt.y);
|
||||
}
|
||||
else if (role.starts_with("rot.") && value.empty())
|
||||
{
|
||||
value = "0";
|
||||
|
||||
@@ -71,7 +71,7 @@ bool complete(include_info const &Info, int Parameters, std::string *Issue = nul
|
||||
// builds include directive which places specified template. Location and Yaw are the placement to pass through
|
||||
// the parameters with matching roles, in the coordinates of the place the directive goes to; without Yaw the
|
||||
// rotation parameters receive their default values
|
||||
std::string directive(std::string const &File, include_info const &Info, int Parameters, glm::dvec3 const &Location, std::optional<float> Yaw, std::string const &Track = {});
|
||||
std::string directive(std::string const &File, include_info const &Info, int Parameters, glm::dvec3 const &Location, std::optional<float> Yaw, std::string const &Track = {}, glm::dvec2 const &Tilt = glm::dvec2{0.0});
|
||||
|
||||
// splits include directive into the name of the included file and the values of the parameters, both as they're
|
||||
// written. returns: false if the text isn't a complete include directive
|
||||
|
||||
Reference in New Issue
Block a user