mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-17 23:39:18 +02:00
cross switch detection for map manual control
This commit is contained in:
@@ -1197,6 +1197,14 @@ multi_event::init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> multi_event::dump_children_names() const {
|
||||||
|
std::vector<std::string> result;
|
||||||
|
for (auto const &childevent : m_children) {
|
||||||
|
result.push_back(std::get<std::string>(childevent));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// event type string
|
// event type string
|
||||||
std::string
|
std::string
|
||||||
multi_event::type() const {
|
multi_event::type() const {
|
||||||
|
|||||||
2
Event.h
2
Event.h
@@ -330,6 +330,8 @@ public:
|
|||||||
// prepares event for use
|
// prepares event for use
|
||||||
void init() override;
|
void init() override;
|
||||||
|
|
||||||
|
std::vector<std::string> dump_children_names() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
// wrapper for binding between editor-supplied name, event, and execution conditional flag
|
// wrapper for binding between editor-supplied name, event, and execution conditional flag
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ struct map_colored_paths {
|
|||||||
std::vector<gfx::geometrybank_handle> switches;
|
std::vector<gfx::geometrybank_handle> switches;
|
||||||
std::vector<gfx::geometrybank_handle> occupied;
|
std::vector<gfx::geometrybank_handle> occupied;
|
||||||
std::vector<gfx::geometrybank_handle> future;
|
std::vector<gfx::geometrybank_handle> future;
|
||||||
|
std::vector<gfx::geometrybank_handle> highlighted;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct segment_data {
|
struct segment_data {
|
||||||
|
|||||||
@@ -1209,6 +1209,14 @@ void TTrack::get_map_active_paths(map_colored_paths &handles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTrack::get_map_paths_for_state(map_colored_paths &handles, int state)
|
||||||
|
{
|
||||||
|
if (iCategoryFlag != 1 || eType != tt_Switch)
|
||||||
|
return;
|
||||||
|
|
||||||
|
handles.highlighted.push_back(SwitchExtension->map_geometry[state]);
|
||||||
|
}
|
||||||
|
|
||||||
void TTrack::get_map_future_paths(map_colored_paths &handles) {
|
void TTrack::get_map_future_paths(map_colored_paths &handles) {
|
||||||
if (iCategoryFlag != 1)
|
if (iCategoryFlag != 1)
|
||||||
return;
|
return;
|
||||||
|
|||||||
1
Track.h
1
Track.h
@@ -286,6 +286,7 @@ public:
|
|||||||
void create_geometry( gfx::geometrybank_handle const &Bank ); // wypełnianie VBO
|
void create_geometry( gfx::geometrybank_handle const &Bank ); // wypełnianie VBO
|
||||||
void create_map_geometry(std::vector<gfx::basic_vertex> &Bank, const gfx::geometrybank_handle Extra);
|
void create_map_geometry(std::vector<gfx::basic_vertex> &Bank, const gfx::geometrybank_handle Extra);
|
||||||
void get_map_active_paths(map_colored_paths &handles);
|
void get_map_active_paths(map_colored_paths &handles);
|
||||||
|
void get_map_paths_for_state(map_colored_paths &handles, int state);
|
||||||
void get_map_future_paths(map_colored_paths &handles);
|
void get_map_future_paths(map_colored_paths &handles);
|
||||||
glm::vec3 get_nearest_point(const glm::dvec3 &point) const;
|
glm::vec3 get_nearest_point(const glm::dvec3 &point) const;
|
||||||
void RenderDynSounds(); // odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
|
void RenderDynSounds(); // odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
|
||||||
|
|||||||
@@ -53,11 +53,55 @@ node_groups::close()
|
|||||||
return handle();
|
return handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool node_groups::assign_cross_switch(map::track_switch& sw, TTrack* track, std::string const &id, size_t idx)
|
||||||
|
{
|
||||||
|
std::string sw_name = track->name();
|
||||||
|
sw_name.pop_back();
|
||||||
|
|
||||||
|
sw.action[idx] = simulation::Events.FindEvent(sw_name + ":" + id);
|
||||||
|
|
||||||
|
if (!sw.action[idx])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
multi_event *multi = dynamic_cast<multi_event*>(sw.action[idx]);
|
||||||
|
|
||||||
|
if (!multi)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto names = multi->dump_children_names();
|
||||||
|
for (auto it = names.begin(); it != names.end(); it++) {
|
||||||
|
int pos_a = it->find_last_of('a');
|
||||||
|
int pos_b = it->find_last_of('b');
|
||||||
|
int pos_c = it->find_last_of('c');
|
||||||
|
int pos_d = it->find_last_of('d');
|
||||||
|
|
||||||
|
int pos_0 = it->find_last_of('0');
|
||||||
|
int pos_1 = it->find_last_of('1');
|
||||||
|
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
if (pos_a > pos_b && pos_a > pos_c && pos_a > pos_d)
|
||||||
|
pos = 0;
|
||||||
|
else if (pos_b > pos_a && pos_b > pos_c && pos_b > pos_d)
|
||||||
|
pos = 1;
|
||||||
|
else if (pos_c > pos_a && pos_c > pos_b && pos_c > pos_d)
|
||||||
|
pos = 2;
|
||||||
|
else
|
||||||
|
pos = 3;
|
||||||
|
|
||||||
|
sw.preview[idx][pos] = ((pos_0 > pos_1) ? '0' : '1');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
node_groups::update_map()
|
node_groups::update_map()
|
||||||
{
|
{
|
||||||
map::Objects.entries.clear();
|
map::Objects.entries.clear();
|
||||||
|
|
||||||
|
std::shared_ptr<map::track_switch> last_switch;
|
||||||
|
|
||||||
for (auto const &pair : m_groupmap) {
|
for (auto const &pair : m_groupmap) {
|
||||||
auto const &group = pair.second;
|
auto const &group = pair.second;
|
||||||
|
|
||||||
@@ -92,22 +136,60 @@ node_groups::update_map()
|
|||||||
if (track->eType != tt_Switch)
|
if (track->eType != tt_Switch)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
basic_event *sw_straight = simulation::Events.FindEvent(track->name() + "+");
|
basic_event *sw_p = simulation::Events.FindEvent(track->name() + "+");
|
||||||
basic_event *sw_divert = simulation::Events.FindEvent(track->name() + "-");
|
basic_event *sw_m = simulation::Events.FindEvent(track->name() + "-");
|
||||||
|
|
||||||
if (sw_straight && sw_divert) {
|
if (sw_p && sw_m) {
|
||||||
auto map_launcher = std::make_shared<map::launcher>();
|
auto map_launcher = std::make_shared<map::track_switch>();
|
||||||
map::Objects.entries.push_back(map_launcher);
|
map::Objects.entries.push_back(map_launcher);
|
||||||
|
|
||||||
map_launcher->location = node->location();
|
map_launcher->location = node->location();
|
||||||
map_launcher->name = node->name();
|
map_launcher->name = node->name();
|
||||||
map_launcher->first_event = sw_straight;
|
map_launcher->action[0] = sw_p;
|
||||||
map_launcher->second_event = sw_divert;
|
map_launcher->action[1] = sw_m;
|
||||||
if (map_launcher->name.empty())
|
map_launcher->track[0] = track;
|
||||||
map_launcher->name = sw_straight->name();
|
map_launcher->preview[0][0] = '0';
|
||||||
|
map_launcher->preview[1][0] = '1';
|
||||||
|
|
||||||
map_launcher->type = map::launcher::track_switch;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string sw_name = track->name();
|
||||||
|
if (sw_name.size() <= 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char lastc = sw_name.back();
|
||||||
|
sw_name.pop_back();
|
||||||
|
|
||||||
|
if (!simulation::Events.FindEvent(sw_name + ":ac"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!last_switch || last_switch->name != sw_name) {
|
||||||
|
last_switch = std::make_shared<map::track_switch>();
|
||||||
|
last_switch->name = sw_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastc < 'a' || lastc > 'd')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
last_switch->track[lastc - 'a'] = track;
|
||||||
|
for (auto trk : last_switch->track)
|
||||||
|
if (!trk)
|
||||||
|
goto skip_e;
|
||||||
|
|
||||||
|
if (!assign_cross_switch(*last_switch, track, "ac", 0))
|
||||||
|
skip_e: continue;
|
||||||
|
if (!assign_cross_switch(*last_switch, track, "ad", 1))
|
||||||
|
continue;
|
||||||
|
if (!assign_cross_switch(*last_switch, track, "bc", 2))
|
||||||
|
continue;
|
||||||
|
if (!assign_cross_switch(*last_switch, track, "bd", 3))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
last_switch->location = (last_switch->track[0]->location() + last_switch->track[1]->location() + last_switch->track[2]->location() + last_switch->track[3]->location()) / 4.0;
|
||||||
|
map::Objects.entries.push_back(last_switch);
|
||||||
|
|
||||||
|
last_switch.reset();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (TEventLauncher *launcher = dynamic_cast<TEventLauncher*>(node)) {
|
if (TEventLauncher *launcher = dynamic_cast<TEventLauncher*>(node)) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "scenenode.h"
|
#include "scenenode.h"
|
||||||
|
#include "widgets/map_objects.h"
|
||||||
|
|
||||||
namespace scene {
|
namespace scene {
|
||||||
|
|
||||||
@@ -63,6 +64,8 @@ private:
|
|||||||
// creates handle for a new group
|
// creates handle for a new group
|
||||||
group_handle
|
group_handle
|
||||||
create_handle();
|
create_handle();
|
||||||
|
bool
|
||||||
|
assign_cross_switch(map::track_switch&sw, TTrack *track, const std::string &id, size_t idx);
|
||||||
// members
|
// members
|
||||||
group_map m_groupmap; // map of established node groups
|
group_map m_groupmap; // map of established node groups
|
||||||
std::stack<scene::group_handle> m_activegroup; // helper, group to be assigned to newly created nodes
|
std::stack<scene::group_handle> m_activegroup; // helper, group to be assigned to newly created nodes
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_si
|
|||||||
m_colored_paths.switches.clear();
|
m_colored_paths.switches.clear();
|
||||||
m_colored_paths.occupied.clear();
|
m_colored_paths.occupied.clear();
|
||||||
m_colored_paths.future.clear();
|
m_colored_paths.future.clear();
|
||||||
|
m_colored_paths.highlighted.clear();
|
||||||
m_section_handles.clear();
|
m_section_handles.clear();
|
||||||
|
|
||||||
for (int row = 0; row < scene::EU07_REGIONSIDESECTIONCOUNT; row++)
|
for (int row = 0; row < scene::EU07_REGIONSIDESECTIONCOUNT; row++)
|
||||||
@@ -112,6 +113,11 @@ void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_si
|
|||||||
track->get_map_future_paths(m_colored_paths);
|
track->get_map_future_paths(m_colored_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (std::pair<TTrack*, int> &entry : highlighted_switches) {
|
||||||
|
if (entry.first)
|
||||||
|
entry.first->get_map_paths_for_state(m_colored_paths, entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
if (Global.iMultisampling)
|
if (Global.iMultisampling)
|
||||||
{
|
{
|
||||||
@@ -138,6 +144,12 @@ void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_si
|
|||||||
|
|
||||||
gl33->Draw_Geometry(m_section_handles.begin(), m_section_handles.end());
|
gl33->Draw_Geometry(m_section_handles.begin(), m_section_handles.end());
|
||||||
|
|
||||||
|
glLineWidth(4.0f);
|
||||||
|
scene_ubs.cascade_end = glm::vec4(0.3f, 0.3f, 1.0f, 0.0f);
|
||||||
|
scene_ubo->update(scene_ubs);
|
||||||
|
gl33->Draw_Geometry(m_colored_paths.highlighted.begin(), m_colored_paths.highlighted.end());
|
||||||
|
|
||||||
|
glLineWidth(1.5f);
|
||||||
scene_ubs.cascade_end = glm::vec4(0.7f, 0.7f, 0.0f, 0.0f);
|
scene_ubs.cascade_end = glm::vec4(0.7f, 0.7f, 0.0f, 0.0f);
|
||||||
scene_ubo->update(scene_ubs);
|
scene_ubo->update(scene_ubs);
|
||||||
gl33->Draw_Geometry(m_colored_paths.future.begin(), m_colored_paths.future.end());
|
gl33->Draw_Geometry(m_colored_paths.future.begin(), m_colored_paths.future.end());
|
||||||
@@ -349,6 +361,10 @@ void ui::handle_map_object_click(ui_panel &parent, std::shared_ptr<map::map_obje
|
|||||||
{
|
{
|
||||||
parent.register_popup(std::make_unique<launcher_window>(parent, std::move(track)));
|
parent.register_popup(std::make_unique<launcher_window>(parent, std::move(track)));
|
||||||
}
|
}
|
||||||
|
else if (auto track_switch = std::dynamic_pointer_cast<map::track_switch>(obj))
|
||||||
|
{
|
||||||
|
parent.register_popup(std::make_unique<track_switch_window>(parent, std::move(track_switch)));
|
||||||
|
}
|
||||||
else if (auto obstacle = std::dynamic_pointer_cast<map::obstacle>(obj))
|
else if (auto obstacle = std::dynamic_pointer_cast<map::obstacle>(obj))
|
||||||
{
|
{
|
||||||
parent.register_popup(std::make_unique<obstacle_remove_window>(parent, std::move(obstacle)));
|
parent.register_popup(std::make_unique<obstacle_remove_window>(parent, std::move(obstacle)));
|
||||||
@@ -506,6 +522,34 @@ void ui::launcher_window::render_content()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui::track_switch_window::track_switch_window(ui_panel &panel, std::shared_ptr<map::track_switch> &&sw) : popup(panel), m_switch(sw) {}
|
||||||
|
|
||||||
|
void ui::track_switch_window::render_content()
|
||||||
|
{
|
||||||
|
auto &highlight = dynamic_cast<map_panel&>(m_parent).highlighted_switches;
|
||||||
|
|
||||||
|
ImGui::TextUnformatted(m_switch->name.c_str());
|
||||||
|
|
||||||
|
highlight.clear();
|
||||||
|
|
||||||
|
std::array<std::string, 4> names = { "ac", "ad", "bc", "bd" };
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
if (m_switch->action[i]) {
|
||||||
|
if (ImGui::Button(names[i].c_str()))
|
||||||
|
m_relay.post(user_command::queueevent, 0.0, 0.0, GLFW_PRESS, 0, glm::vec3(0.0f), &m_switch->action[i]->name());
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
for (size_t j = 0; j < 4; j++) {
|
||||||
|
if ((names[i][0] - 'a') != j && (names[i][1] - 'a') != j)
|
||||||
|
continue;
|
||||||
|
highlight.push_back(std::make_pair(m_switch->track[j], m_switch->preview[i][j] == '1' ? 1 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui::obstacle_insert_window::obstacle_insert_window(ui_panel &panel, glm::dvec3 const &pos) : popup(panel), m_position(pos)
|
ui::obstacle_insert_window::obstacle_insert_window(ui_panel &panel, glm::dvec3 const &pos) : popup(panel), m_position(pos)
|
||||||
{
|
{
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
|
|||||||
@@ -46,6 +46,17 @@ class launcher_window : public popup
|
|||||||
virtual void render_content() override;
|
virtual void render_content() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class track_switch_window : public popup
|
||||||
|
{
|
||||||
|
std::shared_ptr<map::track_switch> m_switch;
|
||||||
|
command_relay m_relay;
|
||||||
|
|
||||||
|
public:
|
||||||
|
track_switch_window(ui_panel &panel, std::shared_ptr<map::track_switch> &&sw);
|
||||||
|
|
||||||
|
virtual void render_content() override;
|
||||||
|
};
|
||||||
|
|
||||||
class obstacle_insert_window : public popup
|
class obstacle_insert_window : public popup
|
||||||
{
|
{
|
||||||
glm::dvec3 m_position;
|
glm::dvec3 m_position;
|
||||||
@@ -86,6 +97,8 @@ class vehicle_click_window : public popup
|
|||||||
|
|
||||||
class map_panel : public ui_panel
|
class map_panel : public ui_panel
|
||||||
{
|
{
|
||||||
|
friend class track_switch_window;
|
||||||
|
|
||||||
std::unique_ptr<gl::program> m_track_shader;
|
std::unique_ptr<gl::program> m_track_shader;
|
||||||
std::unique_ptr<gl::program> m_poi_shader;
|
std::unique_ptr<gl::program> m_poi_shader;
|
||||||
std::unique_ptr<gl::framebuffer> m_msaa_fb;
|
std::unique_ptr<gl::framebuffer> m_msaa_fb;
|
||||||
@@ -101,7 +114,7 @@ class map_panel : public ui_panel
|
|||||||
std::vector<gfx::geometrybank_handle> m_section_handles;
|
std::vector<gfx::geometrybank_handle> m_section_handles;
|
||||||
map_colored_paths m_colored_paths;
|
map_colored_paths m_colored_paths;
|
||||||
|
|
||||||
const int fb_size = 1024;
|
const int fb_size = 1024;
|
||||||
|
|
||||||
glm::vec2 translate;
|
glm::vec2 translate;
|
||||||
float zoom = 1.0f / 1000.0f;
|
float zoom = 1.0f / 1000.0f;
|
||||||
@@ -113,7 +126,7 @@ class map_panel : public ui_panel
|
|||||||
|
|
||||||
bool init_done = false;
|
bool init_done = false;
|
||||||
|
|
||||||
std::optional<map::semaphore> active;
|
std::vector<std::pair<TTrack*, int>> highlighted_switches;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
map_panel();
|
map_panel();
|
||||||
|
|||||||
@@ -53,6 +53,18 @@ struct launcher : public map_object
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// switch description (only for minimap purposes)
|
||||||
|
struct track_switch : public map_object
|
||||||
|
{
|
||||||
|
std::array<basic_event*, 4> action = { nullptr };
|
||||||
|
std::array<char[4], 4> preview;
|
||||||
|
std::array<TTrack*, 4> track = { nullptr };
|
||||||
|
|
||||||
|
virtual gfx::basic_vertex vertex() {
|
||||||
|
return gfx::basic_vertex(location, glm::vec3(), glm::vec2(0.4f, 0.6f));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// training obstacle description
|
// training obstacle description
|
||||||
struct obstacle : public map_object
|
struct obstacle : public map_object
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user