Skip to content

Commit

Permalink
Added an alternative camera rotation (look inside the mouseMoveEvent(…
Browse files Browse the repository at this point in the history
…) function: ROTATION AROUND AN AXIS ORTHOGONAL TO THE BACKPROJECTED DIF-VECTOR)
  • Loading branch information
denizdiktas committed Jun 16, 2023
1 parent 493206e commit 782d722
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 7 deletions.
8 changes: 8 additions & 0 deletions Arrangement_on_surface_2/demo/earth/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ void Camera::rotate(float theta, float phi)
m_uz = r * QVector3D(0, 0, 1);
}

void Camera::rotate(QMatrix4x4 rot)
{
m_pos = rot * m_pos;
m_ux = rot * m_ux;
m_uy = rot * m_uy;
m_uz = rot * m_uz;
}

void Camera::move_forward(float distance)
{
// recall that in OpenGL camera model, camera's z-axis points always
Expand Down
1 change: 1 addition & 0 deletions Arrangement_on_surface_2/demo/earth/Camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Camera
// theta: angle around y-axis
// phi: angle from the xz-plane (= rotated x-axis after the above rotation)
void rotate(float theta, float phi);
void rotate(QMatrix4x4 rot);

// move the camera forward around its own z-axis
void move_forward(float distance);
Expand Down
63 changes: 56 additions & 7 deletions Arrangement_on_surface_2/demo/earth/mainwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ MainWidget::~MainWidget()


float theta = 0, phi = 0;
int vp_width=0, vp_height=0;

std::ostream& operator << (std::ostream& os, const QVector2D& v)
{
os << v.x() << ", " << v.y();
return os;
}
std::ostream& operator << (std::ostream& os, const QVector3D& v)
{
os << v.x() << ", " << v.y() << ", " << v.z();
return os;
}


void MainWidget::set_mouse_button_pressed_flag(QMouseEvent* e, bool flag)
{
Expand All @@ -42,14 +55,47 @@ void MainWidget::mouseMoveEvent(QMouseEvent* e)
const auto diff = current_mouse_pos - m_last_mouse_pos;

if (m_left_mouse_button_down)
{
{
const float rotation_scale_factor = 0.1f;
//const float theta_around_x = rotation_scale_factor * diff.y();
//const float theta_around_y = rotation_scale_factor * diff.x();
//m_camera.rotate(theta_around_x, theta_around_y);
theta += rotation_scale_factor * diff.x();
phi += rotation_scale_factor * diff.y();
m_camera.rotate(-theta, -phi);

if(0)
{
// OUR CUSTOM AD-HOC CAMERA ROTATION
//const float theta_around_x = rotation_scale_factor * diff.y();
//const float theta_around_y = rotation_scale_factor * diff.x();
//m_camera.rotate(theta_around_x, theta_around_y);
theta += rotation_scale_factor * diff.x();
phi += rotation_scale_factor * diff.y();
m_camera.rotate(-theta, -phi);
}
else
{
// ROTATION AROUND AN AXIS ORTHOGONAL TO THE BACKPROJECTED DIF-VECTOR!
QVector3D p0(m_last_mouse_pos.x(), vp_height - m_last_mouse_pos.y(), 0);
QVector3D p1(current_mouse_pos.x(), 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, vp_width, 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(rot_matrix);
}

}
else if(m_middle_mouse_button_down)
{
Expand Down Expand Up @@ -146,6 +192,9 @@ std::ostream& operator << (std::ostream& os, const QVector4D& v)

void MainWidget::resizeGL(int w, int h)
{
vp_width = w;
vp_height = h;

// Reset projection
qreal aspect = qreal(w) / qreal(h ? h : 1);
const qreal z_near = 1.0, z_far = 100.0, fov = 45.0;
Expand Down

0 comments on commit 782d722

Please sign in to comment.