improve nearest track-point search

This commit is contained in:
milek7
2019-03-15 01:18:23 +01:00
parent 1b508954e7
commit 7ca562211a
8 changed files with 104 additions and 24 deletions

View File

@@ -541,3 +541,24 @@ void TSegment::render_lines(std::vector<gfx::basic_vertex> &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<float>::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;
}

View File

@@ -131,7 +131,10 @@ public:
return ( fTsBuffer.empty() ? 1 : iSegCount ); };
void
render_lines(std::vector<gfx::basic_vertex> &out, float quality) const;
render_lines(std::vector<gfx::basic_vertex> &out, float quality = 1.0f) const;
glm::vec3
get_nearest_point(const glm::dvec3 &point, float quality = 1.0f) const;
};
//---------------------------------------------------------------------------

View File

@@ -1167,6 +1167,30 @@ void TTrack::get_map_active_switches(std::vector<gfx::geometrybank_handle> &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<float>::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 ) {

View File

@@ -278,6 +278,7 @@ public:
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 get_map_active_switches(std::vector<gfx::geometrybank_handle> &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 ) {

View File

@@ -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;

View File

@@ -624,22 +624,26 @@ void basic_cell::get_map_active_switches(std::vector<gfx::geometrybank_handle> &
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<float>::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<gfx::geometrybank_handle
cell.get_map_active_switches(handles);
}
glm::vec3 basic_section::find_nearest_track_point(const glm::dvec3 &point)
{
glm::vec3 nearest(NAN);
float min = std::numeric_limits<float>::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<int>( std::floor( ( Location.x - ( m_area.center.x - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) );
auto const row = static_cast<int>( std::floor( ( Location.z - ( m_area.center.z - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) );
auto const column = static_cast<int>( std::floor( ( Location.x - ( m_area.center.x - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) ) + offset.x;
auto const row = static_cast<int>( std::floor( ( Location.z - ( m_area.center.z - EU07_SECTIONSIZE / 2 ) ) / EU07_CELLSIZE ) ) + offset.y;
return
m_cells[

View File

@@ -157,7 +157,7 @@ public:
create_map_geometry(std::vector<gfx::basic_vertex> &Bank, const gfx::geometrybank_handle Extra);
void
get_map_active_switches(std::vector<gfx::geometrybank_handle> &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:

View File

@@ -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.