feat(viewport): camera mouse controls

This commit is contained in:
parker
2025-06-26 16:06:48 +01:00
parent 02af45a073
commit 568427e572
4 changed files with 119 additions and 11 deletions

View File

@@ -1,16 +1,20 @@
#include "gui/viewport/Viewport.h" #include "gui/viewport/Viewport.h"
#include "gui/viewport/GLCamera.h"
#include <glm/common.hpp>
#include <qboxlayout.h> #include <qboxlayout.h>
#include <qevent.h>
#include <qnamespace.h>
#include <qpushbutton.h> #include <qpushbutton.h>
#include <iostream> #include <iostream>
#include <QTimer> #include <QTimer>
#include <QPainterPath> #include <QPainterPath>
#include <QEvent>
Viewport::Viewport(QWidget *parent, Qt::WindowFlags f) Viewport::Viewport(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f) : QWidget(parent, f)
{ {
mainLayout_=new QVBoxLayout(); mainLayout_=new QVBoxLayout();
openGLWidget_ = new ViewportGLWidget(this); openGLWidget_ = new ViewportGLWidget(this); mainLayout_->addWidget(openGLWidget_);
mainLayout_->addWidget(openGLWidget_);
openGLWidget_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); openGLWidget_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// mainLayout_->addWidget(new QPushButton("hello world")); // mainLayout_->addWidget(new QPushButton("hello world"));
@@ -31,3 +35,103 @@ void Viewport::resizeEvent(QResizeEvent *event)
QRegion region = QRegion(path.toFillPolygon().toPolygon()); QRegion region = QRegion(path.toFillPolygon().toPolygon());
this->setMask(region); 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<QWheelEvent*>(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<QMouseEvent*>(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<float>(-delta.y());
glm::vec3 right = camera.getRight()*static_cast<float>(-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<QMouseEvent*>(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";
}

View File

@@ -12,5 +12,15 @@ private:
QVBoxLayout* mainLayout_; QVBoxLayout* mainLayout_;
ViewportGLWidget* openGLWidget_; ViewportGLWidget* openGLWidget_;
void resizeEvent(QResizeEvent *event) override; 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_;
}; };

View File

@@ -20,7 +20,7 @@ void ViewportGLWidget::initializeGL()
loopTimer->start(16); loopTimer->start(16);
// init camera // init camera
camera_ = GLCamera(); curCamera = GLCamera();
@@ -133,13 +133,7 @@ void ViewportGLWidget::paintGL()
); );
// glm::mat4 viewMatrix = glm::lookAt( glm::mat4 viewMatrix = curCamera.getViewMatrix();
// 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();
GLint projMLoc = glGetUniformLocation(shaderProgram, "uProj"); GLint projMLoc = glGetUniformLocation(shaderProgram, "uProj");

View File

@@ -12,7 +12,7 @@ public:
QSize sizeHint() const override { return QSize(-1, -1); } QSize sizeHint() const override { return QSize(-1, -1); }
GLuint vao; GLuint vao;
GLuint shaderProgram; GLuint shaderProgram;
GLCamera camera_; GLCamera curCamera;
protected: protected:
void initializeGL() override; void initializeGL() override;