From 568427e5724a53f3ce04467470c2a5429180d0ae Mon Sep 17 00:00:00 2001 From: parker Date: Thu, 26 Jun 2025 16:06:48 +0100 Subject: [PATCH] feat(viewport): camera mouse controls --- src/gui/viewport/Viewport.cpp | 108 +++++++++++++++++++++++++- src/gui/viewport/Viewport.h | 10 +++ src/gui/viewport/ViewportGLWidget.cpp | 10 +-- src/gui/viewport/ViewportGLWidget.h | 2 +- 4 files changed, 119 insertions(+), 11 deletions(-) diff --git a/src/gui/viewport/Viewport.cpp b/src/gui/viewport/Viewport.cpp index 0d20df9..14c0c43 100644 --- a/src/gui/viewport/Viewport.cpp +++ b/src/gui/viewport/Viewport.cpp @@ -1,16 +1,20 @@ #include "gui/viewport/Viewport.h" +#include "gui/viewport/GLCamera.h" +#include #include +#include +#include #include #include #include #include +#include Viewport::Viewport(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) { mainLayout_=new QVBoxLayout(); - openGLWidget_ = new ViewportGLWidget(this); - mainLayout_->addWidget(openGLWidget_); + openGLWidget_ = new ViewportGLWidget(this); mainLayout_->addWidget(openGLWidget_); openGLWidget_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // mainLayout_->addWidget(new QPushButton("hello world")); @@ -31,3 +35,103 @@ void Viewport::resizeEvent(QResizeEvent *event) QRegion region = QRegion(path.toFillPolygon().toPolygon()); this->setMask(region); } + +bool Viewport::event(QEvent *event) +{ + switch(event->type()) + { + case QEvent::Wheel: + case QEvent::MouseMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + std::cout << "camera controls\n"; + handleCamera(event); + break; + default: + std::cout << "event " << event->type() << "\n"; + break; + } + + + return true; +} + +void Viewport::handleCamera(QEvent *event) +{ + switch(event->type()) + { + case QEvent::Wheel: + { + QWheelEvent* wheelEvent = static_cast(event); + float delta = wheelEvent->angleDelta().y(); + constexpr float mouseSpeed = 0.7; + openGLWidget_->curCamera.changeRadius(-glm::sign(delta)*mouseSpeed); + break; + } + case QEvent::MouseMove: + { + QMouseEvent* mouseEvent = static_cast(event); + QPointF mousePos = mouseEvent->position(); + GLCamera& camera = openGLWidget_->curCamera; + constexpr float rotateSpeed = 0.01; + constexpr float panSpeed = 0.01; + constexpr float zoomSpeed = 0.01; + + if(leftMouseDown_) + { + QPointF delta = mousePos-leftStartPos_; + delta*=rotateSpeed; + camera.rotateAroundCenter(delta.x(), {0,1,0}); + camera.rotateAroundCenter(delta.y(), + camera.getRight() * glm::vec3(1.0f,0.0f,1.0f)); + leftStartPos_=mousePos; + } + if(middleMouseDown_) + { + QPointF delta = mousePos-middleStartPos_; + delta *= panSpeed; + glm::vec3 up = camera.getUp()*static_cast(-delta.y()); + glm::vec3 right = camera.getRight()*static_cast(-delta.x()); + + camera.changeCenter(up.x+right.x, up.y+right.y, up.z+right.z); + camera.movePos(up.x+right.x, up.y+right.y, up.z+right.z); + middleStartPos_=mousePos; + } + if(rightMouseDown_) + { + QPointF delta = mousePos-rightStartPos_; + delta*=zoomSpeed; + camera.changeRadius(-delta.x()+delta.y()); + rightStartPos_=mousePos; + } + break; + } + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + { + bool isDown=event->type()==QEvent::MouseButtonPress; + QMouseEvent* mouseEvent = static_cast(event); + switch(mouseEvent->button()) + { + case Qt::LeftButton: + leftMouseDown_=isDown; + if(isDown) leftStartPos_=mouseEvent->position(); + break; + case Qt::MiddleButton: + middleMouseDown_=isDown; + if(isDown) middleStartPos_=mouseEvent->position(); + break; + case Qt::RightButton: + rightMouseDown_=isDown; + if(isDown) rightStartPos_=mouseEvent->position(); + break; + default: + break; + } + break; + } + default: + break; + } + std::cout << "event " << event->type() << "\n"; +} diff --git a/src/gui/viewport/Viewport.h b/src/gui/viewport/Viewport.h index 7022f2a..7ed71a9 100644 --- a/src/gui/viewport/Viewport.h +++ b/src/gui/viewport/Viewport.h @@ -12,5 +12,15 @@ private: QVBoxLayout* mainLayout_; ViewportGLWidget* openGLWidget_; void resizeEvent(QResizeEvent *event) override; + bool event(QEvent *event) override; + Qt::Key cameraMod_ = Qt::Key_Space; + void handleCamera(QEvent *event); + // TODO: maybe simplify positions to mouseDownPos + bool middleMouseDown_=false; + QPointF middleStartPos_; + bool leftMouseDown_=false; + QPointF leftStartPos_; + bool rightMouseDown_=false; + QPointF rightStartPos_; }; diff --git a/src/gui/viewport/ViewportGLWidget.cpp b/src/gui/viewport/ViewportGLWidget.cpp index 5d603a4..9880200 100644 --- a/src/gui/viewport/ViewportGLWidget.cpp +++ b/src/gui/viewport/ViewportGLWidget.cpp @@ -20,7 +20,7 @@ void ViewportGLWidget::initializeGL() loopTimer->start(16); // init camera - camera_ = GLCamera(); + curCamera = GLCamera(); @@ -133,13 +133,7 @@ void ViewportGLWidget::paintGL() ); - // glm::mat4 viewMatrix = glm::lookAt( - // glm::vec3(sin(angle_)*5, 1, cos(angle_)*5), - // glm::vec3(0,0,0), - // glm::vec3(0,1,0) - // ); - camera_.rotateAroundCenter(0.01, glm::vec3(0,1,0)); - glm::mat4 viewMatrix = camera_.getViewMatrix(); + glm::mat4 viewMatrix = curCamera.getViewMatrix(); GLint projMLoc = glGetUniformLocation(shaderProgram, "uProj"); diff --git a/src/gui/viewport/ViewportGLWidget.h b/src/gui/viewport/ViewportGLWidget.h index cc3f50f..11325b1 100644 --- a/src/gui/viewport/ViewportGLWidget.h +++ b/src/gui/viewport/ViewportGLWidget.h @@ -12,7 +12,7 @@ public: QSize sizeHint() const override { return QSize(-1, -1); } GLuint vao; GLuint shaderProgram; - GLCamera camera_; + GLCamera curCamera; protected: void initializeGL() override;