From 1fb916f0499e6a9e46bd27ebc56b6e0e7a786f95 Mon Sep 17 00:00:00 2001
From: Oliver Bock <oliver.bock@aei.mpg.de>
Date: Sun, 30 Nov 2008 19:36:52 +0100
Subject: [PATCH] Added interactive zoom and spherical pan/tilt control

* Zoom: right mouse button + move up/down
* Pan: left mouse button + move left/right (pending, possible fix: upvector?)
* Tilt: left mouse button + move up/down  (pending, possible fix: upvector?)
---
 src/pulsaranimationwidget.cpp | 61 ++++++++++++++++++++++++++++++++++-
 src/pulsaranimationwidget.h   | 24 +++++++++++---
 2 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/src/pulsaranimationwidget.cpp b/src/pulsaranimationwidget.cpp
index 1e5e25d..9dca1f7 100644
--- a/src/pulsaranimationwidget.cpp
+++ b/src/pulsaranimationwidget.cpp
@@ -42,6 +42,15 @@ PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) :
 	setOrbitFrequency(0.2f);
 	setOrbitRadius(4.0f);
 	m_orbitRotationAngle = 0.0f;
+
+	m_mouseLastX = 0;
+	m_mouseLastY = 0;
+	m_mouseAngleH = 90;
+	m_mouseAngleV = 30;
+	m_cameraZoom = 10.0f;
+	m_cameraZoomLBound = 2.0f;
+
+	updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
 }
 
 PulsarAnimationWidget::~PulsarAnimationWidget()
@@ -106,7 +115,9 @@ void PulsarAnimationWidget::paintGL()
 	glMatrixMode(GL_MODELVIEW);
 	glLoadIdentity();
 
-	gluLookAt(0.0, 6.0, 10.0, 0.0, 0.0, 0.0, 0.0, 2.0, -5.0);
+	gluLookAt(m_cameraPosX, m_cameraPosY, m_cameraPosZ,
+			  0.0, 0.0, 0.0,
+			  0.0, 2.0, -5.0);
 
 	// TODO: should be located elsewhere
 	static GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 };
@@ -199,6 +210,54 @@ void PulsarAnimationWidget::updateOrbit()
 	}
 }
 
+void PulsarAnimationWidget::mouseMoveEvent(QMouseEvent *event)
+{
+	Qt::MouseButtons buttons = event->buttons();
+	if((buttons & Qt::LeftButton) == Qt::LeftButton) {
+		if(m_mouseLastX != 0) {
+			m_mouseAngleH -= (m_mouseLastX - event->x()) / 2;
+			m_mouseAngleH = m_mouseAngleH < 360? m_mouseAngleH : 0;
+
+		}
+		if(m_mouseLastY != 0) {
+			m_mouseAngleV -= (m_mouseLastY - event->y()) / 2;
+			m_mouseAngleV = m_mouseAngleV < 90? m_mouseAngleV : 90;
+			m_mouseAngleV = m_mouseAngleV > -90? m_mouseAngleV : -90;
+		}
+
+		m_mouseLastX = event->x();
+		m_mouseLastY = event->y();
+	}
+	else if((buttons & Qt::RightButton) == Qt::RightButton) {
+		if(m_mouseLastY != 0) {
+			m_cameraZoom -= (m_mouseLastY - event->y()) / 2;
+			m_cameraZoom = m_cameraZoom >= m_cameraZoomLBound? m_cameraZoom : m_cameraZoomLBound;
+			updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
+		}
+
+		m_mouseLastY = event->y();
+	}
+
+	updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
+}
+
+void PulsarAnimationWidget::mouseReleaseEvent(QMouseEvent *event)
+{
+	m_mouseLastX = 0;
+	m_mouseLastY = 0;
+}
+
+void PulsarAnimationWidget::updateCameraPosition(const int angleH, const int angleV, const float zoom)
+{
+	static const float deg2rad = PI/180.0f;
+
+	m_cameraPosX = sin(angleH * deg2rad) * zoom;
+	m_cameraPosY = sin(angleV * deg2rad) * zoom;
+	m_cameraPosZ = cos(angleH * deg2rad) * cos(abs(angleV * deg2rad)) * zoom;
+
+	updateGL();
+}
+
 void PulsarAnimationWidget::setFramePerSecond(const unsigned int fps)
 {
 	m_framesPerSecond = fps;
diff --git a/src/pulsaranimationwidget.h b/src/pulsaranimationwidget.h
index b16dd99..3dc5fa0 100644
--- a/src/pulsaranimationwidget.h
+++ b/src/pulsaranimationwidget.h
@@ -21,8 +21,13 @@
 #ifndef PULSARANIMATIONWIDGET_H_
 #define PULSARANIMATIONWIDGET_H_
 
+#include <cmath>
+
 #include <QGLWidget>
 #include <QTimer>
+#include <QMouseEvent>
+
+#define PI 3.14159265
 
 class PulsarAnimationWidget : public QGLWidget
 {
@@ -47,14 +52,15 @@ public slots:
 	void updateOrbit();
 
 protected:
-
     void initializeGL();
-
     void resizeGL(int w, int h);
-
     void paintGL();
 
-private:
+    void mouseMoveEvent(QMouseEvent *event);
+    void mouseReleaseEvent(QMouseEvent *event);
+
+    void updateCameraPosition(const int angleH, const int angleV, const float zoom);
+
     QTimer m_frameTimer;
     QTimer m_pulsarSpinTimer;
     QTimer m_orbitTimer;
@@ -71,6 +77,16 @@ private:
 	float m_orbitRadius;
 	float m_orbitFrequency;
 	float m_orbitRotationAngle;
+
+	int m_mouseLastX;
+	int m_mouseLastY;
+	int m_mouseAngleH;
+	int m_mouseAngleV;
+	float m_cameraZoom;
+	float m_cameraZoomLBound;
+	float m_cameraPosX;
+	float m_cameraPosY;
+	float m_cameraPosZ;
 };
 
 #endif /* PULSARANIMATIONWIDGET_H_ */
-- 
GitLab