From 96c81a07940a82345e4a8d82254054ba968cbd5c Mon Sep 17 00:00:00 2001 From: denizdiktas Date: Thu, 13 Jul 2023 18:44:18 +0300 Subject: [PATCH] Refactor: camera manipulator bpa moved to its own class by deriving from camera_manip --- .../demo/earth/CMakeLists.txt | 1 + .../demo/earth/Camera_manip.cpp | 4 ++ .../demo/earth/Camera_manip.h | 10 +-- .../demo/earth/Camera_manip_rot.cpp | 8 --- .../demo/earth/Camera_manip_rot.h | 9 +-- .../demo/earth/Camera_manip_rot_bpa.cpp | 59 ++++++++++++++++ .../demo/earth/Camera_manip_rot_bpa.h | 26 +++++++ .../demo/earth/Main_widget.cpp | 70 ++++--------------- .../demo/earth/Main_widget.h | 2 +- 9 files changed, 112 insertions(+), 77 deletions(-) create mode 100644 Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.cpp create mode 100644 Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.h diff --git a/Arrangement_on_surface_2/demo/earth/CMakeLists.txt b/Arrangement_on_surface_2/demo/earth/CMakeLists.txt index ae29e80229e..643d2a03c2a 100644 --- a/Arrangement_on_surface_2/demo/earth/CMakeLists.txt +++ b/Arrangement_on_surface_2/demo/earth/CMakeLists.txt @@ -57,6 +57,7 @@ file(GLOB source_files_graphics Camera.h Camera.cpp Camera_manip.h Camera_manip.cpp Camera_manip_rot.h Camera_manip_rot.cpp + Camera_manip_rot_bpa.h Camera_manip_rot_bpa.cpp Shader_program.h Shader_program.cpp ) source_group( "Graphics" FILES ${source_files_graphics} ) diff --git a/Arrangement_on_surface_2/demo/earth/Camera_manip.cpp b/Arrangement_on_surface_2/demo/earth/Camera_manip.cpp index a887a245c8f..eeb7354f454 100644 --- a/Arrangement_on_surface_2/demo/earth/Camera_manip.cpp +++ b/Arrangement_on_surface_2/demo/earth/Camera_manip.cpp @@ -46,4 +46,8 @@ void Camera_manip::mouseReleaseEvent(QMouseEvent* e) // call the function overridden by the derived class mouse_release_event(e); } +void Camera_manip::resizeGL(int w, int h) +{ + resize(w, h); +} diff --git a/Arrangement_on_surface_2/demo/earth/Camera_manip.h b/Arrangement_on_surface_2/demo/earth/Camera_manip.h index 9778c7f5207..3ae653d41dc 100644 --- a/Arrangement_on_surface_2/demo/earth/Camera_manip.h +++ b/Arrangement_on_surface_2/demo/earth/Camera_manip.h @@ -17,16 +17,18 @@ class Camera_manip void mousePressEvent(QMouseEvent* e); void mouseMoveEvent(QMouseEvent* e); void mouseReleaseEvent(QMouseEvent* e); + void resizeGL(int w, int h); protected: void set_mouse_button_pressed_flag(QMouseEvent* e, bool flag); - virtual void mouse_press_event(QMouseEvent* e) = 0; - virtual void mouse_move_event(QMouseEvent* e) = 0; - virtual void mouse_release_event(QMouseEvent* e) = 0; + virtual void mouse_press_event(QMouseEvent* e) {} + virtual void mouse_move_event(QMouseEvent* e) {} + virtual void mouse_release_event(QMouseEvent* e) {} + virtual void resize(int w, int h) {} + Camera& m_camera; - float m_theta = 0, m_phi = 0; bool m_left_mouse_button_down = false; bool m_middle_mouse_button_down = false; diff --git a/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.cpp b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.cpp index be5cb1fbc74..04287d57e1e 100644 --- a/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.cpp +++ b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.cpp @@ -7,11 +7,6 @@ Camera_manip_rot::Camera_manip_rot(Camera& camera) : { } -void Camera_manip_rot::mouse_press_event(QMouseEvent* e) -{ - set_mouse_button_pressed_flag(e, true); - m_mouse_press_pos = m_last_mouse_pos = QVector2D(e->position()); -} void Camera_manip_rot::mouse_move_event(QMouseEvent* e) { if (m_left_mouse_button_down) @@ -25,7 +20,4 @@ void Camera_manip_rot::mouse_move_event(QMouseEvent* e) m_camera.rotate_from_init_config(-m_theta, -m_phi); } } -void Camera_manip_rot::mouse_release_event(QMouseEvent* e) -{ -} diff --git a/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.h b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.h index 60e8ba4a3bf..7be915b1a05 100644 --- a/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.h +++ b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot.h @@ -14,17 +14,10 @@ class Camera_manip_rot : public Camera_manip Camera_manip_rot(Camera& camera); protected: - void mouse_press_event(QMouseEvent* e) override; - void mouse_move_event(QMouseEvent* e) override; - void mouse_release_event(QMouseEvent* e) override; + virtual void mouse_move_event(QMouseEvent* e) override; private: float m_theta = 0, m_phi = 0; - - //bool m_left_mouse_button_down = false; - //QVector2D m_last_mouse_pos; - //QVector2D m_mouse_press_pos; }; - #endif diff --git a/Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.cpp b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.cpp new file mode 100644 index 00000000000..a980f5e66b3 --- /dev/null +++ b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.cpp @@ -0,0 +1,59 @@ + +#include "Camera_manip_rot_bpa.h" + + +Camera_manip_rot_bpa::Camera_manip_rot_bpa(Camera& camera) : + Camera_manip(camera) +{ +} + +void Camera_manip_rot_bpa::mouse_press_event(QMouseEvent* e) +{ + // for the backprojected diff-vector method: + if (m_left_mouse_button_down) + { + m_camera.save_config(); + } +} +void Camera_manip_rot_bpa::mouse_move_event(QMouseEvent* e) +{ + auto current_mouse_pos = QVector2D(e->position()); + const auto diff = current_mouse_pos - m_last_mouse_pos; + const float rotation_scale_factor = 0.1f; + + // ROTATION AROUND AN AXIS ORTHOGONAL TO THE BACKPROJECTED DIF-VECTOR + //QVector3D p0(m_last_mouse_pos.x(), m_vp_height - m_last_mouse_pos.y(), 0); + QVector3D p0(m_mouse_press_pos.x(), m_vp_height - m_mouse_press_pos.y(), 0); + QVector3D p1(current_mouse_pos.x(), m_vp_height - current_mouse_pos.y(), 0); + auto dp = p1 - p0; // difference vector in OpenGL window coords. + QVector3D rdp(-dp.y(), dp.x(), 0); // rotate diff-vector CCW by 90-deg + QVector3D rp = p0 + rdp; // r1 rotated CCW by 90 deg + + QMatrix4x4 model; // this is different from Sphere's model matrix!!! + auto proj = m_camera.get_projection_matrix(); + auto view = m_camera.get_view_matrix(); + auto model_view = view * model; + QRect viewport(0, 0, m_vp_width, m_vp_height); + auto wp0 = p0.unproject(model_view, proj, viewport); + auto wrp = rp.unproject(model_view, proj, viewport); + + // rotation axis & angle + auto rot_axis = wrp - wp0; + rot_axis.normalize(); + const auto rot_angle = rotation_scale_factor * dp.length(); + + QMatrix4x4 rot_matrix; + rot_matrix.rotate(-rot_angle, rot_axis); + + m_camera.rotate_from_saved_config(rot_matrix); + +} +void Camera_manip_rot_bpa::mouse_release_event(QMouseEvent* e) +{ +} +void Camera_manip_rot_bpa::resize(int w, int h) +{ + m_vp_width = w; + m_vp_height = h; +} + diff --git a/Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.h b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.h new file mode 100644 index 00000000000..4fe93ad6243 --- /dev/null +++ b/Arrangement_on_surface_2/demo/earth/Camera_manip_rot_bpa.h @@ -0,0 +1,26 @@ + +#ifndef CAMERA_MANIP_ROT_BPA_H +#define CAMERA_MANIP_ROT_BPA_H + +#include +#include + +#include "Camera_manip.h" + + +class Camera_manip_rot_bpa : public Camera_manip +{ +public: + Camera_manip_rot_bpa(Camera& camera); + +protected: + virtual void mouse_press_event(QMouseEvent* e) override; + virtual void mouse_move_event(QMouseEvent* e) override; + virtual void mouse_release_event(QMouseEvent* e) override; + virtual void resize(int w, int h) override; + +private: + int m_vp_width, m_vp_height; +}; + +#endif diff --git a/Arrangement_on_surface_2/demo/earth/Main_widget.cpp b/Arrangement_on_surface_2/demo/earth/Main_widget.cpp index 31cf6cd8593..7fb7db20239 100644 --- a/Arrangement_on_surface_2/demo/earth/Main_widget.cpp +++ b/Arrangement_on_surface_2/demo/earth/Main_widget.cpp @@ -8,6 +8,8 @@ #include #include "Aos.h" +#include "Camera_manip_rot.h" +#include "Camera_manip_rot_bpa.h" #include "Kml_reader.h" #include "Shapefile.h" #include "Tools.h" @@ -36,68 +38,22 @@ void Main_widget::set_mouse_button_pressed_flag(QMouseEvent* e, bool flag) void Main_widget::mousePressEvent(QMouseEvent* e) { // forward the event to the camera manipulator - m_camera_manip_rot->mousePressEvent(e); + m_camera_manip->mousePressEvent(e); set_mouse_button_pressed_flag(e, true); m_mouse_press_pos = m_last_mouse_pos = QVector2D(e->position()); - - // for the backprojected diff-vector method: - if (m_left_mouse_button_down) - { - m_camera.save_config(); - } } void Main_widget::mouseMoveEvent(QMouseEvent* e) { // forward the event to the camera manipulator - m_camera_manip_rot->mouseMoveEvent(e); + m_camera_manip->mouseMoveEvent(e); auto current_mouse_pos = QVector2D(e->position()); const auto diff = current_mouse_pos - m_last_mouse_pos; - if (m_left_mouse_button_down) + if(m_middle_mouse_button_down) { - const float rotation_scale_factor = 0.1f; - - if(1) - { - // OUR CUSTOM AD-HOC CAMERA ROTATION - //m_theta += rotation_scale_factor * diff.x(); - //m_phi += rotation_scale_factor * diff.y(); - //m_camera.rotate_from_init_config(-m_theta, -m_phi); - } - else - { - // ROTATION AROUND AN AXIS ORTHOGONAL TO THE BACKPROJECTED DIF-VECTOR - //QVector3D p0(m_last_mouse_pos.x(), m_vp_height - m_last_mouse_pos.y(), 0); - QVector3D p0(m_mouse_press_pos.x(), m_vp_height - m_mouse_press_pos.y(), 0); - QVector3D p1(current_mouse_pos.x(), m_vp_height - current_mouse_pos.y(), 0); - auto dp = p1 - p0; // difference vector in OpenGL window coords. - QVector3D rdp(-dp.y(), dp.x(), 0); // rotate diff-vector CCW by 90-deg - QVector3D rp = p0 + rdp; // r1 rotated CCW by 90 deg - - QMatrix4x4 model; // this is different from Sphere's model matrix!!! - auto proj = m_camera.get_projection_matrix(); - auto view = m_camera.get_view_matrix(); - auto model_view = view * model; - QRect viewport(0, 0, m_vp_width, m_vp_height); - auto wp0 = p0.unproject(model_view, proj, viewport); - auto wrp = rp.unproject(model_view, proj, viewport); - - // rotation axis & angle - auto rot_axis = wrp - wp0; - rot_axis.normalize(); - const auto rot_angle = rotation_scale_factor * dp.length(); - - QMatrix4x4 rot_matrix; - rot_matrix.rotate(-rot_angle, rot_axis); - - m_camera.rotate_from_saved_config(rot_matrix); - } - } - else if(m_middle_mouse_button_down) - { - const float zoom_scale_factor = 0.001f; + const float zoom_scale_factor = 0.01f; const auto distance = zoom_scale_factor * diff.y(); m_camera.move_forward(distance); } @@ -107,7 +63,7 @@ void Main_widget::mouseMoveEvent(QMouseEvent* e) void Main_widget::mouseReleaseEvent(QMouseEvent* e) { // forward the event to the camera manipulator - m_camera_manip_rot->mouseReleaseEvent(e); + m_camera_manip->mouseReleaseEvent(e); set_mouse_button_pressed_flag(e, false); } @@ -208,8 +164,8 @@ void Main_widget::initializeGL() //Shapefile::read(shape_file_name); //const auto file_name = data_path + "world_countries.kml"; - //const auto file_name = data_path + "ne_110m_admin_0_countries.kml"; - const auto file_name = data_path + "ne_110m_admin_0_countries_africa.kml"; + const auto file_name = data_path + "ne_110m_admin_0_countries.kml"; + //const auto file_name = data_path + "ne_110m_admin_0_countries_africa.kml"; m_countries = Kml::read(file_name); auto dup_nodes = Kml::get_duplicates(m_countries); @@ -217,7 +173,7 @@ void Main_widget::initializeGL() //auto all_nodes = Kml::generate_ids(m_countries); // initialize rendering of DUPLICATE VERTICES - if(0) + if(1) { std::vector vertices; for (const auto& node : dup_nodes) @@ -286,12 +242,12 @@ void Main_widget::initializeGL() m_timer.start(12, this); } -#include "Camera_manip_rot.h" void Main_widget::init_camera() { m_camera.set_pos(0, 0, 3); - m_camera_manip_rot = std::make_unique(m_camera); + //m_camera_manip = std::make_unique(m_camera); + m_camera_manip = std::make_unique(m_camera); } void Main_widget::init_geometry() { @@ -428,6 +384,8 @@ void Main_widget::find_minimum_projected_error_on_sphere(float we) void Main_widget::resizeGL(int w, int h) { + m_camera_manip->resizeGL(w, h); + m_vp_width = w; m_vp_height = h; diff --git a/Arrangement_on_surface_2/demo/earth/Main_widget.h b/Arrangement_on_surface_2/demo/earth/Main_widget.h index 28306a831ce..69b9b0f85fe 100644 --- a/Arrangement_on_surface_2/demo/earth/Main_widget.h +++ b/Arrangement_on_surface_2/demo/earth/Main_widget.h @@ -84,7 +84,7 @@ class Main_widget : public QOpenGLWidget, protected OpenGLFunctionsBase // Camera & controls Camera m_camera; - std::unique_ptr m_camera_manip_rot; + std::unique_ptr m_camera_manip; bool m_left_mouse_button_down = false; bool m_middle_mouse_button_down = false;