Commit 333eca25 authored by Anakin's avatar Anakin

use class for camera handling,

orbit does not work. Need to figure out why
parent b17ab3f8
#pragma once
#include <QMatrix4x4>
class CameraInterface
{
public:
explicit CameraInterface() {};
virtual ~CameraInterface() {};
// attributes
protected:
QMatrix4x4 m_matrix;
double m_zSpeed = 1.0;
// functions
public:
virtual void setZoomSpeed(int percent) { m_zSpeed = (double) percent / 100; };
virtual void rotateAction(QVector2D diff) = 0;
virtual void moveAction(QVector2D diff) = 0;
virtual void wheelAction(double value) = 0;
virtual void resetView() { m_matrix = QMatrix4x4(); m_zSpeed = 1.0; };
virtual void recalculateMatrix() = 0;
virtual QMatrix4x4 getMatrix() { recalculateMatrix(); return m_matrix; };
};
\ No newline at end of file
#pragma once
#include "CameraInterface.h"
class FreeCamera : public CameraInterface
{
public:
explicit FreeCamera();
virtual ~FreeCamera();
// attributes
private:
QVector3D m_translation;
QQuaternion m_rotation;
// functions
public:
virtual void rotateAction(QVector2D diff) Q_DECL_OVERRIDE;
virtual void moveAction(QVector2D diff) Q_DECL_OVERRIDE;
virtual void wheelAction(double value) Q_DECL_OVERRIDE;
virtual void recalculateMatrix() Q_DECL_OVERRIDE;
virtual void resetView() Q_DECL_OVERRIDE;
};
\ No newline at end of file
#pragma once
#include "CameraInterface.h"
class MoveCamera : public CameraInterface
{
public:
explicit MoveCamera();
virtual ~MoveCamera();
// attributes
private:
// functions
public:
virtual void rotateAction(QVector2D diff) Q_DECL_OVERRIDE;
virtual void moveAction(QVector2D diff) Q_DECL_OVERRIDE;
virtual void wheelAction(double value) Q_DECL_OVERRIDE;
virtual void recalculateMatrix() Q_DECL_OVERRIDE;
virtual void resetView() Q_DECL_OVERRIDE;
};
\ No newline at end of file
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <QMatrix4x4> #include <QMatrix4x4>
#include "GeometryEngine.h" #include "GeometryEngine.h"
#include "SettingsWindow.h" #include "SettingsWindow.h"
#include "CameraInterface.h"
class GeometryEngine; class GeometryEngine;
...@@ -37,25 +38,16 @@ private: ...@@ -37,25 +38,16 @@ private:
bool headlight = false; bool headlight = false;
} m_light; } m_light;
SettingsWindow* m_settings;
struct { struct {
bool left = false; bool left = false;
bool right = false; bool right = false;
QVector2D position; QVector2D position;
} m_mouse; } m_mouse;
struct {
bool x = true;
bool y = true;
bool z = true;
} m_rotDirections;
QMatrix4x4 m_projection; QMatrix4x4 m_projection;
QVector3D m_translation; CameraInterface* m_camera;
QQuaternion m_rotation;
double m_zSpeed = 1.0; SettingsWindow* m_settings;
// functions // functions
private: private:
...@@ -81,10 +73,13 @@ protected: ...@@ -81,10 +73,13 @@ protected:
// slots // slots
public slots: public slots:
void loadFile(QString name); void loadFile(QString name);
void toggleAxis(int axis); void useFreeCamera();
void useOrbitCamera();
void useMoveCamera();
void toggleWireframe(); void toggleWireframe();
void toggleLight(); void toggleLight();
void showSettings(); void showSettings();
void setBGColorOff(QVector3D value); void setBGColorOff(QVector3D value);
void setBGColorOn(QVector3D value); void setBGColorOn(QVector3D value);
void setLightColor(QVector3D value); void setLightColor(QVector3D value);
...@@ -92,7 +87,6 @@ public slots: ...@@ -92,7 +87,6 @@ public slots:
void setAmbCoef(double value); void setAmbCoef(double value);
void setHeadlight(bool value); void setHeadlight(bool value);
void setBackfaceCulling(bool value); void setBackfaceCulling(bool value);
void setZoomSpeed(int percent);
}; };
#pragma once
#include "CameraInterface.h"
class OrbitCamera : public CameraInterface
{
public:
explicit OrbitCamera();
virtual ~OrbitCamera();
// attributes
private:
double m_phi;
double m_theta;
double m_roh;
// functions
public:
virtual void rotateAction(QVector2D diff) Q_DECL_OVERRIDE;
virtual void moveAction(QVector2D diff) Q_DECL_OVERRIDE;
virtual void wheelAction(double value) Q_DECL_OVERRIDE;
virtual void recalculateMatrix() Q_DECL_OVERRIDE;
virtual void resetView() Q_DECL_OVERRIDE;
};
\ No newline at end of file
...@@ -15,17 +15,11 @@ ...@@ -15,17 +15,11 @@
<file>info.png</file> <file>info.png</file>
<file>about.png</file> <file>about.png</file>
<file>open.png</file> <file>open.png</file>
<file>X.png</file>
<file>Y.png</file>
<file>Z.png</file>
<file>screenshot.png</file> <file>screenshot.png</file>
<file>wireframe.png</file> <file>wireframe.png</file>
<file>light_off.png</file> <file>light_off.png</file>
<file>light_on.png</file> <file>light_on.png</file>
<file>solid.png</file> <file>solid.png</file>
<file>X_disabled.png</file>
<file>Y_disabled.png</file>
<file>Z_disabled.png</file>
<file>settings.png</file> <file>settings.png</file>
</qresource> </qresource>
</RCC> </RCC>
...@@ -37,30 +37,6 @@ QToolButton#screenshot { ...@@ -37,30 +37,6 @@ QToolButton#screenshot {
image: url(:/images/toolbar/screenshot.png); image: url(:/images/toolbar/screenshot.png);
} }
QToolButton#x {
image: url(:/images/toolbar/X_disabled.png);
}
QToolButton#x:checked {
image: url(:/images/toolbar/X.png);
}
QToolButton#y {
image: url(:/images/toolbar/Y_disabled.png);
}
QToolButton#y:checked {
image: url(:/images/toolbar/Y.png);
}
QToolButton#z {
image: url(:/images/toolbar/Z_disabled.png);
}
QToolButton#z:checked {
image: url(:/images/toolbar/Z.png);
}
QToolButton#wireframe { QToolButton#wireframe {
image: url(:/images/toolbar/solid.png); image: url(:/images/toolbar/solid.png);
} }
......
#include "..\Header\FreeCamera.h"
#include <QVector2D>
#include <QVector3D>
#include <QQuaternion>
/////////////////////////////////////////////////////////////////////////
// constructor/destructor
FreeCamera::FreeCamera()
{
resetView();
}
FreeCamera::~FreeCamera()
{
}
/////////////////////////////////////////////////////////////////////////
// functions
void FreeCamera::rotateAction(QVector2D diff)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(diff.y(), diff.x(), 0.0).normalized(), diff.length() * 0.5) * m_rotation;
}
void FreeCamera::moveAction(QVector2D diff)
{
m_translation += {(float)(diff.x() * 0.01), (float)(diff.y() * -0.01), 0.0};
}
void FreeCamera::wheelAction(double value)
{
m_translation += {0.0, 0.0, (float) (m_zSpeed * value / 240)};
}
void FreeCamera::recalculateMatrix()
{
m_matrix = QMatrix4x4();
m_matrix.translate(m_translation);
m_matrix.rotate(m_rotation);
}
void FreeCamera::resetView()
{
m_translation = { 0, 0, -4 };
m_rotation = QQuaternion();
CameraInterface::resetView();
}
...@@ -90,41 +90,26 @@ void MainWindow::setupWidgets() ...@@ -90,41 +90,26 @@ void MainWindow::setupWidgets()
////////////////////////////////////////////////// //////////////////////////////////////////////////
ui->mainToolBar->addSeparator(); ui->mainToolBar->addSeparator();
QSignalMapper* signalMapper = new QSignalMapper(this); // Free Camera
QToolButton *freeCamera = new QToolButton(this);
// X freeCamera->setObjectName("freeCamera");
QToolButton *x = new QToolButton(this); freeCamera->setToolTip("free camera");
x->setObjectName("x"); connect(freeCamera, &QToolButton::pressed, viewer, &OglViewerWidget::useFreeCamera);
x->setToolTip("x-direction"); ui->mainToolBar->addWidget(freeCamera);
x->setCheckable(true);
x->setChecked(true); // Orbital Camera
ui->mainToolBar->addWidget(x); QToolButton *orbitCamera = new QToolButton(this);
orbitCamera->setObjectName("orbitalCamera");
// Y orbitCamera->setToolTip("orbital camera");
QToolButton *y = new QToolButton(this); connect(orbitCamera, &QToolButton::pressed, viewer, &OglViewerWidget::useOrbitCamera);
y->setObjectName("y"); ui->mainToolBar->addWidget(orbitCamera);
y->setToolTip("y-direction");
y->setCheckable(true); // Move Camera
y->setChecked(true); QToolButton *moveCamera = new QToolButton(this);
ui->mainToolBar->addWidget(y); moveCamera->setObjectName("moveCamera");
moveCamera->setToolTip("move camera");
// Z connect(moveCamera, &QToolButton::pressed, viewer, &OglViewerWidget::useMoveCamera);
QToolButton *z = new QToolButton(this); ui->mainToolBar->addWidget(moveCamera);
z->setObjectName("z");
z->setToolTip("z-direction");
z->setCheckable(true);
z->setChecked(true);
ui->mainToolBar->addWidget(z);
connect(x, SIGNAL(pressed()), signalMapper, SLOT(map()));
connect(y, SIGNAL(pressed()), signalMapper, SLOT(map()));
connect(z, SIGNAL(pressed()), signalMapper, SLOT(map()));
signalMapper->setMapping(x, 1);
signalMapper->setMapping(y, 2);
signalMapper->setMapping(z, 3);
connect(signalMapper, SIGNAL(mapped(int)), viewer, SLOT(toggleAxis(int)));
////////////////////////////////////////////////// //////////////////////////////////////////////////
ui->mainToolBar->addSeparator(); ui->mainToolBar->addSeparator();
......
#include "..\Header\MoveCamera.h"
#include <QVector2D>
/////////////////////////////////////////////////////////////////////////
// constructor/destructor
MoveCamera::MoveCamera()
{
resetView();
}
MoveCamera::~MoveCamera()
{
}
/////////////////////////////////////////////////////////////////////////
// functions
void MoveCamera::rotateAction(QVector2D diff)
{
}
void MoveCamera::moveAction(QVector2D diff)
{
}
void MoveCamera::wheelAction(double value)
{
}
void MoveCamera::recalculateMatrix()
{
}
void MoveCamera::resetView()
{
CameraInterface::resetView();
}
#include "..\Header\OglViewerWidget.h" #include "..\Header\OglViewerWidget.h"
#include "..\Header\MainWindow.h" #include "..\Header\MainWindow.h"
#include "..\Header\FreeCamera.h"
#include "..\Header\OrbitCamera.h"
#include "..\Header\MoveCamera.h"
#include <QMouseEvent> #include <QMouseEvent>
#include <QDropEvent> #include <QDropEvent>
#include <QMimeData> #include <QMimeData>
...@@ -14,7 +17,8 @@ ...@@ -14,7 +17,8 @@
OglViewerWidget::OglViewerWidget(QWidget *parent) OglViewerWidget::OglViewerWidget(QWidget *parent)
: QOpenGLWidget(parent) : QOpenGLWidget(parent)
, m_dataEngine(0) , m_dataEngine(Q_NULLPTR)
, m_camera(new FreeCamera)
{ {
setFocus(); setFocus();
setAcceptDrops(true); setAcceptDrops(true);
...@@ -29,7 +33,7 @@ OglViewerWidget::OglViewerWidget(QWidget *parent) ...@@ -29,7 +33,7 @@ OglViewerWidget::OglViewerWidget(QWidget *parent)
connect(m_settings, &SettingsWindow::updateAmbCoef, this, &OglViewerWidget::setAmbCoef); connect(m_settings, &SettingsWindow::updateAmbCoef, this, &OglViewerWidget::setAmbCoef);
connect(m_settings, &SettingsWindow::sendHeadlight, this, &OglViewerWidget::setHeadlight); connect(m_settings, &SettingsWindow::sendHeadlight, this, &OglViewerWidget::setHeadlight);
connect(m_settings, &SettingsWindow::sendBackfaceCulling, this, &OglViewerWidget::setBackfaceCulling); connect(m_settings, &SettingsWindow::sendBackfaceCulling, this, &OglViewerWidget::setBackfaceCulling);
connect(m_settings, &SettingsWindow::sendZommSpeed, this, &OglViewerWidget::setZoomSpeed); connect(m_settings, &SettingsWindow::sendZommSpeed, [this](int value) {m_camera->setZoomSpeed(value); });
} }
OglViewerWidget::~OglViewerWidget() OglViewerWidget::~OglViewerWidget()
...@@ -40,6 +44,7 @@ OglViewerWidget::~OglViewerWidget() ...@@ -40,6 +44,7 @@ OglViewerWidget::~OglViewerWidget()
delete m_dataEngine; delete m_dataEngine;
doneCurrent(); doneCurrent();
delete m_camera;
delete m_settings; delete m_settings;
} }
...@@ -68,9 +73,7 @@ void OglViewerWidget::initShaders() ...@@ -68,9 +73,7 @@ void OglViewerWidget::initShaders()
void OglViewerWidget::resetView() void OglViewerWidget::resetView()
{ {
m_rotation = QQuaternion(); m_camera->resetView();
m_translation = { 0.0, 0.0, DEFAULT_Z_DISTANCE };
m_zSpeed = 1;
if (m_light.headlight) if (m_light.headlight)
updateLightPosition(); updateLightPosition();
...@@ -79,13 +82,13 @@ void OglViewerWidget::resetView() ...@@ -79,13 +82,13 @@ void OglViewerWidget::resetView()
void OglViewerWidget::updateLightPosition() void OglViewerWidget::updateLightPosition()
{ {
QMatrix4x4 rotateBack; QVector4D lightPosition = { 0,0,0,1 };
rotateBack.rotate(m_rotation.inverted());
QVector3D cameraPosition = rotateBack * (-m_translation);
m_light.position.setX(cameraPosition.x()); lightPosition = m_camera->getMatrix().inverted() * lightPosition;
m_light.position.setY(cameraPosition.y());
m_light.position.setZ(cameraPosition.z()); m_light.position.setX(lightPosition.x());
m_light.position.setY(lightPosition.y());
m_light.position.setZ(lightPosition.z());
} }
// OpenGL /////////////////////////////////////////////////////////////// // OpenGL ///////////////////////////////////////////////////////////////
...@@ -139,13 +142,8 @@ void OglViewerWidget::paintGL() ...@@ -139,13 +142,8 @@ void OglViewerWidget::paintGL()
// Clear color and depth buffer // Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Calculate view transformation
QMatrix4x4 view;
view.translate(m_translation);
view.rotate(m_rotation);
// Set view-projection matrix // Set view-projection matrix
m_program.setUniformValue("vp_matrix", m_projection * view); m_program.setUniformValue("vp_matrix", m_projection * m_camera->getMatrix());
// Set Light values // Set Light values
m_program.setUniformValue("b_light", m_lightOn); m_program.setUniformValue("b_light", m_lightOn);
...@@ -155,9 +153,7 @@ void OglViewerWidget::paintGL() ...@@ -155,9 +153,7 @@ void OglViewerWidget::paintGL()
m_program.setUniformValue("light.ambientCoefficient", m_light.ambientCoefficient); m_program.setUniformValue("light.ambientCoefficient", m_light.ambientCoefficient);
// Set camera position // Set camera position
QMatrix4x4 rotateBack; m_program.setUniformValue("cameraPosition", (m_camera->getMatrix().inverted() * QVector4D(0,0,0,1)).toVector3D());
rotateBack.rotate(m_rotation.inverted());
m_program.setUniformValue("cameraPosition", rotateBack * (-m_translation));
// Draw cube geometry // Draw cube geometry
if (m_backfaceCulling) if (m_backfaceCulling)
...@@ -199,76 +195,11 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e) ...@@ -199,76 +195,11 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
if (m_mouse.left) if (m_mouse.left)
{ {
// get the difference between last press and now // get the difference between last press and now
QVector2D diff = QVector2D(e->localPos()) - m_mouse.position; m_camera->rotateAction(QVector2D(e->localPos()) - m_mouse.position);
// update the new position // update the new position
m_mouse.position = QVector2D(e->localPos()); m_mouse.position = QVector2D(e->localPos());
// calculate the rotations depending on the active axis
// XYZ
if (m_rotDirections.x && m_rotDirections.y && m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(diff.y(), diff.x(), 0.0).normalized(), diff.length() * 0.5) * m_rotation;
}
// XY
else if (m_rotDirections.x && m_rotDirections.y && !m_rotDirections.z)
{
float pitch, yaw, roll;
m_rotation.getEulerAngles(&pitch, &yaw, &roll);
pitch += diff.y() * 0.5;
yaw += diff.x() * 0.5;
if (pitch > 89)
pitch = 89;
else if (pitch < -89)
pitch = -89;
m_rotation = QQuaternion::fromEulerAngles(pitch, yaw, roll);
}
// X
else if (m_rotDirections.x && !m_rotDirections.y && !m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(0.0, 1.0, 0.0).normalized(), diff.x() * 0.5) * m_rotation;
}
// Y
else if (!m_rotDirections.x && m_rotDirections.y && !m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0).normalized(), diff.y() * 0.5) * m_rotation;
}
// Z
else if (!m_rotDirections.x && !m_rotDirections.y && m_rotDirections.z)
{
m_rotation = QQuaternion::fromAxisAndAngle(QVector3D(0.0, 0.0, 1.0).normalized(), diff.x() * 0.5) * m_rotation;
}
// XZ
else if (m_rotDirections.x && !m_rotDirections.y && m_rotDirections.z)
{
float pitch, yaw, roll;
m_rotation.getEulerAngles(&pitch, &yaw, &roll);
roll -= diff.y() * 0.5;
yaw += diff.x() * 0.5;
m_rotation = QQuaternion::fromEulerAngles(pitch, yaw, roll);
}
// YZ
else if (!m_rotDirections.x && m_rotDirections.y && m_rotDirections.z)
{
float pitch, yaw, roll;
m_rotation.getEulerAngles(&pitch, &yaw, &roll);
pitch += diff.y() * 0.5;
roll += diff.x() * 0.5;
if (pitch > 89)
pitch = 89;
else if (pitch < -89)
pitch = -89;
m_rotation = QQuaternion::fromEulerAngles(pitch, yaw, roll);