From 7ca562211a8d1895766a196b6b06eacb7d2b4d6d Mon Sep 17 00:00:00 2001 From: milek7 Date: Fri, 15 Mar 2019 01:18:23 +0100 Subject: [PATCH] improve nearest track-point search --- Segment.cpp | 21 +++++++++++++++++++++ Segment.h | 5 ++++- Track.cpp | 24 ++++++++++++++++++++++++ Track.h | 1 + renderer.cpp | 18 ++++++++++++++---- scene.cpp | 44 +++++++++++++++++++++++++++++++++----------- scene.h | 9 ++++----- widgets/map.cpp | 6 +++--- 8 files changed, 104 insertions(+), 24 deletions(-) diff --git a/Segment.cpp b/Segment.cpp index 847f2101..197ae304 100644 --- a/Segment.cpp +++ b/Segment.cpp @@ -541,3 +541,24 @@ void TSegment::render_lines(std::vector &out, float quality) previous = glm::vec3(FastGetPoint(1.0)); out.push_back(gfx::basic_vertex(previous, glm::vec3(0.0f), glm::vec2(0.0f))); } + +glm::vec3 TSegment::get_nearest_point(const glm::dvec3 &point, float quality) const +{ + float step = 1.0f / iSegCount / quality; + + float x; + + glm::vec3 nearest; + float min = std::numeric_limits::max(); + + for (x = step; x <= 1.0f; x += step) { + glm::vec3 p = FastGetPoint(x); + float dist2 = glm::distance2(p, (glm::vec3)point); + if (dist2 < min) { + nearest = p; + min = dist2; + } + } + + return nearest; +} diff --git a/Segment.h b/Segment.h index 2a7d0429..937b56ff 100644 --- a/Segment.h +++ b/Segment.h @@ -131,7 +131,10 @@ public: return ( fTsBuffer.empty() ? 1 : iSegCount ); }; void - render_lines(std::vector &out, float quality) const; + render_lines(std::vector &out, float quality = 1.0f) const; + + glm::vec3 + get_nearest_point(const glm::dvec3 &point, float quality = 1.0f) const; }; //--------------------------------------------------------------------------- diff --git a/Track.cpp b/Track.cpp index 1219a95a..1de11962 100644 --- a/Track.cpp +++ b/Track.cpp @@ -1167,6 +1167,30 @@ void TTrack::get_map_active_switches(std::vector &hand handles.push_back(SwitchExtension->map_geometry[1]); } +glm::vec3 TTrack::get_nearest_point(const glm::dvec3 &point) const +{ + if (eType == tt_Normal) { + return Segment->get_nearest_point(point); + } + else if (eType == tt_Switch) { + glm::vec3 nearest; + float min = std::numeric_limits::max(); + + for (size_t i = 0; i < 2; i++) { + glm::dvec3 p = SwitchExtension->Segments[i]->get_nearest_point(point); + float dist2 = glm::distance2(p, point); + if (dist2 < min) { + nearest = p; + min = dist2; + } + } + + return nearest; + } + + return glm::vec3(NAN); +} + // wypełnianie tablic VBO void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) { diff --git a/Track.h b/Track.h index f381073c..5899b4ce 100644 --- a/Track.h +++ b/Track.h @@ -278,6 +278,7 @@ public: void create_geometry( gfx::geometrybank_handle const &Bank ); // wypełnianie VBO void create_map_geometry(std::vector &Bank, const gfx::geometrybank_handle Extra); void get_map_active_switches(std::vector &handles); + 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 RaOwnerSet( scene::basic_cell *o ) { diff --git a/renderer.cpp b/renderer.cpp index 00953bee..597d1da3 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -445,7 +445,7 @@ bool opengl_renderer::Render() m_debugstats = debug_stats(); for (auto &viewport : m_viewports) { - Render_pass(*viewport.get(), rendermode::color); + Render_pass(*viewport, rendermode::color); } glfwMakeContextCurrent(m_window); @@ -586,6 +586,11 @@ void opengl_renderer::Render_pass(viewport_config &vp, rendermode const Mode) glClearColor(0.0f, 0.0f, 0.0f, 0.0f); setup_drawing(false); + + glm::ivec2 target_size(vp.width, vp.height); + if (vp.main) // TODO: update window sizes also for extra viewports + target_size = glm::ivec2(Global.iWindowWidth, Global.iWindowHeight); + if (!Global.gfx_skippipeline) { vp.msaa_fb->bind(); @@ -604,7 +609,7 @@ void opengl_renderer::Render_pass(viewport_config &vp, rendermode const Mode) if (!Global.gfx_usegles && !Global.gfx_shadergamma) glEnable(GL_FRAMEBUFFER_SRGB); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, vp.width, vp.height); + glViewport(0, 0, target_size.x, target_size.y); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -709,7 +714,8 @@ void opengl_renderer::Render_pass(viewport_config &vp, rendermode const Mode) if (!Global.gfx_usegles && !Global.gfx_shadergamma) glEnable(GL_FRAMEBUFFER_SRGB); - glViewport(0, 0, vp.width, vp.height); + + glViewport(0, 0, target_size.x, target_size.y); m_pfx_tonemapping->apply(*vp.main2_tex, nullptr); opengl_texture::reset_unit_cache(); } @@ -1050,8 +1056,12 @@ void opengl_renderer::setup_pass(viewport_config &Viewport, renderpass_config &C glm::mat4 frustumtest_proj; + glm::ivec2 target_size(Viewport.width, Viewport.height); + if (Viewport.main) // TODO: update window sizes also for extra viewports + target_size = glm::ivec2(Global.iWindowWidth, Global.iWindowHeight); + float const fovy = glm::radians(Global.FieldOfView / Global.ZoomFactor); - float const aspect = std::max(1.f, (float)Viewport.width) / std::max(1.f, (float)Viewport.height); + float const aspect = (float)target_size.x / std::max(1.f, (float)target_size.y); Config.viewport_camera.position() = Global.pCamera.Pos; diff --git a/scene.cpp b/scene.cpp index 5b7d6fca..4dd64df6 100644 --- a/scene.cpp +++ b/scene.cpp @@ -624,22 +624,26 @@ void basic_cell::get_map_active_switches(std::vector & path->get_map_active_switches(handles); } -TTrack* basic_cell::find_nearest_track_point(const glm::dvec3 &pos) +glm::vec3 basic_cell::find_nearest_track_point(const glm::dvec3 &pos) { float min = std::numeric_limits::max(); TTrack *nearest = nullptr; + glm::vec3 point; for (auto *path : m_paths) { - for (auto &ep : path->endpoints()) { - float dist2 = glm::distance2(ep, pos); - if (dist2 < min) { - min = dist2; - nearest = path; - } + glm::dvec3 ep = path->get_nearest_point(pos); + + float dist2 = glm::distance2(ep, pos); + if (dist2 < min) { + point = ep; + min = dist2; + nearest = path; } } - return nearest; + if (!nearest) + return glm::vec3(NAN); + return point; } // executes event assigned to specified launcher @@ -962,12 +966,30 @@ void basic_section::get_map_active_switches(std::vector::max(); + + for (int x = -1; x < 2; x++) + for (int y = -1; y < 2; y++) { + glm::vec3 p = cell(point, glm::ivec2(x, y)).find_nearest_track_point(point); + float dist2 = glm::distance2(p, (glm::vec3)point); + if (dist2 < min) { + min = dist2; + nearest = p; + } + } + + return nearest; +} + // provides access to section enclosing specified point basic_cell & -basic_section::cell( glm::dvec3 const &Location ) { +basic_section::cell( glm::dvec3 const &Location, const glm::ivec2 &offset ) { - auto const column = static_cast( std::floor( ( Location.x - ( m_area.center.x - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) ); - auto const row = static_cast( std::floor( ( Location.z - ( m_area.center.z - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) ); + auto const column = static_cast( std::floor( ( Location.x - ( m_area.center.x - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) ) + offset.x; + auto const row = static_cast( std::floor( ( Location.z - ( m_area.center.z - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) ) + offset.y; return m_cells[ diff --git a/scene.h b/scene.h index e8b39d26..a42b0e73 100644 --- a/scene.h +++ b/scene.h @@ -157,7 +157,7 @@ public: create_map_geometry(std::vector &Bank, const gfx::geometrybank_handle Extra); void get_map_active_switches(std::vector &handles); - TTrack *find_nearest_track_point(const glm::dvec3 &pos); + glm::vec3 find_nearest_track_point(const glm::dvec3 &pos); // provides access to bounding area data bounding_area const & area() const { @@ -291,8 +291,7 @@ public: return m_area; } const gfx::geometrybank_handle get_map_geometry() { return m_map_geometryhandle;} - TTrack* find_nearest_track_point(const glm::dvec3 &pos) - { return cell(pos).find_nearest_track_point(pos); } + glm::vec3 find_nearest_track_point(const glm::dvec3 &point); private: // types @@ -301,7 +300,7 @@ private: // methods // provides access to section enclosing specified point basic_cell & - cell( glm::dvec3 const &Location ); + cell(glm::dvec3 const &Location, const glm::ivec2 &offset = glm::ivec2(0)); // members // placement and visibility @@ -410,7 +409,7 @@ public: { return m_sections[section]; } gfx::geometrybank_handle get_map_poi_geometry() { return m_map_poipoints; } - TTrack* find_nearest_track_point(const glm::dvec3 &pos) + glm::vec3 find_nearest_track_point(const glm::dvec3 &pos) { return section(pos).find_nearest_track_point(pos); } private: diff --git a/widgets/map.cpp b/widgets/map.cpp index 4efa58d3..e9126ffd 100644 --- a/widgets/map.cpp +++ b/widgets/map.cpp @@ -260,9 +260,9 @@ void ui::map_panel::render_contents() else if (objects.size() == 1) handle_map_object_click(*this, objects.begin()->second); - TTrack *nearest = simulation::Region->find_nearest_track_point(world_pos); - if (nearest) { - WriteLog(nearest->name()); + glm::vec3 nearest = simulation::Region->find_nearest_track_point(world_pos); + if (!glm::isnan(nearest.x)) { + WriteLog(glm::to_string(nearest)); } //scene::basic_section &clicked_section = simulation::Region->section(world_pos); //clicked_section.