From faea3b0737dcfb0decbe8bb46f396145e9ebcb8a Mon Sep 17 00:00:00 2001 From: Anakin Date: Tue, 27 Dec 2016 14:05:39 +0100 Subject: [PATCH] removed timer rotation, now the user has full control, added keyboard support, reset rotation with space --- QtMeshViewer/Header/OglViewerWidget.h | 17 +++--- QtMeshViewer/Source/OglViewerWidget.cpp | 71 +++++++++++++------------ 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/QtMeshViewer/Header/OglViewerWidget.h b/QtMeshViewer/Header/OglViewerWidget.h index 7cb8bfc..4b62ae0 100644 --- a/QtMeshViewer/Header/OglViewerWidget.h +++ b/QtMeshViewer/Header/OglViewerWidget.h @@ -24,7 +24,8 @@ public: protected: void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; - void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *e) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *e) Q_DECL_OVERRIDE; void initializeGL() Q_DECL_OVERRIDE; void resizeGL(int w, int h) Q_DECL_OVERRIDE; @@ -34,17 +35,17 @@ protected: void initTextures(); private: - QBasicTimer timer; + struct { + bool left = false; + bool right = false; + QVector2D position; + } m_mouse; QOpenGLShaderProgram program; GeometryEngine *geometries; QOpenGLTexture *texture; - QMatrix4x4 projection; - - QVector2D mousePressPosition; - QVector3D rotationAxis; - qreal angularSpeed; - QQuaternion rotation; + QMatrix4x4 m_projection; + QQuaternion m_rotation; }; diff --git a/QtMeshViewer/Source/OglViewerWidget.cpp b/QtMeshViewer/Source/OglViewerWidget.cpp index e83c85f..76554c2 100644 --- a/QtMeshViewer/Source/OglViewerWidget.cpp +++ b/QtMeshViewer/Source/OglViewerWidget.cpp @@ -2,13 +2,14 @@ #include #include +#include OglViewerWidget::OglViewerWidget(QWidget *parent) : QOpenGLWidget(parent), geometries(0), - texture(0), - angularSpeed(0) + texture(0) { + setFocus(); } OglViewerWidget::~OglViewerWidget() @@ -24,45 +25,49 @@ OglViewerWidget::~OglViewerWidget() void OglViewerWidget::mousePressEvent(QMouseEvent *e) { // Save mouse press position - mousePressPosition = QVector2D(e->localPos()); + m_mouse.position = QVector2D(e->localPos()); + + // Which button has been pressed? + if (e->button() == Qt::LeftButton) + m_mouse.left = true; + else if (e->button() == Qt::RightButton) + m_mouse.right = true; } void OglViewerWidget::mouseReleaseEvent(QMouseEvent *e) { - // Mouse release position - mouse press position - QVector2D diff = QVector2D(e->localPos()) - mousePressPosition; - - // Rotation axis is perpendicular to the mouse position difference - // vector - QVector3D n = QVector3D(diff.y(), diff.x(), 0.0).normalized(); - - // Accelerate angular speed relative to the length of the mouse sweep - qreal acc = diff.length() / 100.0; - - // Calculate new rotation axis as weighted sum - rotationAxis = (rotationAxis * angularSpeed + n * acc).normalized(); - - // Increase angular speed - angularSpeed += acc; + if (e->button() == Qt::LeftButton) + m_mouse.left = false; + else if (e->button() == Qt::RightButton) + m_mouse.right = false; } -void OglViewerWidget::timerEvent(QTimerEvent *) +void OglViewerWidget::mouseMoveEvent(QMouseEvent *e) { - // Decrease angular speed (friction) - angularSpeed *= 0.99; + if (m_mouse.left) + { + // get the difference between last press and now + QVector2D diff = QVector2D(e->localPos()) - m_mouse.position; - // Stop rotation when speed goes below threshold - if (angularSpeed < 0.01) { - angularSpeed = 0.0; - } else { - // Update rotation - rotation = QQuaternion::fromAxisAndAngle(rotationAxis, angularSpeed) * rotation; + // update the new position + m_mouse.position = QVector2D(e->localPos()); - // Request an update + // calculate the rotation axis and rotate + m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(diff.y(), diff.x(), 0.0).normalized(), diff.length() * 0.5) * m_rotation; + + // request an update update(); } } +void OglViewerWidget::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Space) + m_rotation = QQuaternion(); + + update(); +} + void OglViewerWidget::initializeGL() { initializeOpenGLFunctions(); @@ -80,8 +85,6 @@ void OglViewerWidget::initializeGL() geometries = new GeometryEngine; - // Use QBasicTimer because its faster than QTimer - timer.start(12, this); } void OglViewerWidget::initShaders() @@ -128,10 +131,10 @@ void OglViewerWidget::resizeGL(int w, int h) const qreal zNear = 3.0, zFar = 7.0, fov = 45.0; // Reset projection - projection.setToIdentity(); + m_projection.setToIdentity(); // Set perspective projection - projection.perspective(fov, aspect, zNear, zFar); + m_projection.perspective(fov, aspect, zNear, zFar); } void OglViewerWidget::paintGL() @@ -144,10 +147,10 @@ void OglViewerWidget::paintGL() // Calculate model view transformation QMatrix4x4 matrix; matrix.translate(0.0, 0.0, -5.0); - matrix.rotate(rotation); + matrix.rotate(m_rotation); // Set modelview-projection matrix - program.setUniformValue("mvp_matrix", projection * matrix); + program.setUniformValue("mvp_matrix", m_projection * matrix); // Use texture unit 0 which contains cube.png program.setUniformValue("texture", 0);