use class for camera handling,

orbit does not work. Need to figure out why
This commit is contained in:
Anakin
2017-02-02 18:01:08 +01:00
parent b17ab3f8e9
commit 333eca25eb
12 changed files with 329 additions and 185 deletions

View File

@@ -0,0 +1,53 @@
#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();
}

View File

@@ -90,41 +90,26 @@ void MainWindow::setupWidgets()
//////////////////////////////////////////////////
ui->mainToolBar->addSeparator();
QSignalMapper* signalMapper = new QSignalMapper(this);
// Free Camera
QToolButton *freeCamera = new QToolButton(this);
freeCamera->setObjectName("freeCamera");
freeCamera->setToolTip("free camera");
connect(freeCamera, &QToolButton::pressed, viewer, &OglViewerWidget::useFreeCamera);
ui->mainToolBar->addWidget(freeCamera);
// X
QToolButton *x = new QToolButton(this);
x->setObjectName("x");
x->setToolTip("x-direction");
x->setCheckable(true);
x->setChecked(true);
ui->mainToolBar->addWidget(x);
// Orbital Camera
QToolButton *orbitCamera = new QToolButton(this);
orbitCamera->setObjectName("orbitalCamera");
orbitCamera->setToolTip("orbital camera");
connect(orbitCamera, &QToolButton::pressed, viewer, &OglViewerWidget::useOrbitCamera);
ui->mainToolBar->addWidget(orbitCamera);
// Y
QToolButton *y = new QToolButton(this);
y->setObjectName("y");
y->setToolTip("y-direction");
y->setCheckable(true);
y->setChecked(true);
ui->mainToolBar->addWidget(y);
// Z
QToolButton *z = new QToolButton(this);
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)));
// Move Camera
QToolButton *moveCamera = new QToolButton(this);
moveCamera->setObjectName("moveCamera");
moveCamera->setToolTip("move camera");
connect(moveCamera, &QToolButton::pressed, viewer, &OglViewerWidget::useMoveCamera);
ui->mainToolBar->addWidget(moveCamera);
//////////////////////////////////////////////////
ui->mainToolBar->addSeparator();

View File

@@ -0,0 +1,46 @@
#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();
}

View File

@@ -1,5 +1,8 @@
#include "..\Header\OglViewerWidget.h"
#include "..\Header\MainWindow.h"
#include "..\Header\FreeCamera.h"
#include "..\Header\OrbitCamera.h"
#include "..\Header\MoveCamera.h"
#include <QMouseEvent>
#include <QDropEvent>
#include <QMimeData>
@@ -14,7 +17,8 @@
OglViewerWidget::OglViewerWidget(QWidget *parent)
: QOpenGLWidget(parent)
, m_dataEngine(0)
, m_dataEngine(Q_NULLPTR)
, m_camera(new FreeCamera)
{
setFocus();
setAcceptDrops(true);
@@ -29,7 +33,7 @@ OglViewerWidget::OglViewerWidget(QWidget *parent)
connect(m_settings, &SettingsWindow::updateAmbCoef, this, &OglViewerWidget::setAmbCoef);
connect(m_settings, &SettingsWindow::sendHeadlight, this, &OglViewerWidget::setHeadlight);
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()
@@ -40,6 +44,7 @@ OglViewerWidget::~OglViewerWidget()
delete m_dataEngine;
doneCurrent();
delete m_camera;
delete m_settings;
}
@@ -68,9 +73,7 @@ void OglViewerWidget::initShaders()
void OglViewerWidget::resetView()
{
m_rotation = QQuaternion();
m_translation = { 0.0, 0.0, DEFAULT_Z_DISTANCE };
m_zSpeed = 1;
m_camera->resetView();
if (m_light.headlight)
updateLightPosition();
@@ -79,13 +82,13 @@ void OglViewerWidget::resetView()
void OglViewerWidget::updateLightPosition()
{
QMatrix4x4 rotateBack;
rotateBack.rotate(m_rotation.inverted());
QVector3D cameraPosition = rotateBack * (-m_translation);
QVector4D lightPosition = { 0,0,0,1 };
m_light.position.setX(cameraPosition.x());
m_light.position.setY(cameraPosition.y());
m_light.position.setZ(cameraPosition.z());
lightPosition = m_camera->getMatrix().inverted() * lightPosition;
m_light.position.setX(lightPosition.x());
m_light.position.setY(lightPosition.y());
m_light.position.setZ(lightPosition.z());
}
// OpenGL ///////////////////////////////////////////////////////////////
@@ -139,13 +142,8 @@ void OglViewerWidget::paintGL()
// Clear color and depth buffer
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
m_program.setUniformValue("vp_matrix", m_projection * view);
m_program.setUniformValue("vp_matrix", m_projection * m_camera->getMatrix());
// Set Light values
m_program.setUniformValue("b_light", m_lightOn);
@@ -155,9 +153,7 @@ void OglViewerWidget::paintGL()
m_program.setUniformValue("light.ambientCoefficient", m_light.ambientCoefficient);
// Set camera position
QMatrix4x4 rotateBack;
rotateBack.rotate(m_rotation.inverted());
m_program.setUniformValue("cameraPosition", rotateBack * (-m_translation));
m_program.setUniformValue("cameraPosition", (m_camera->getMatrix().inverted() * QVector4D(0,0,0,1)).toVector3D());
// Draw cube geometry
if (m_backfaceCulling)
@@ -199,76 +195,11 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
if (m_mouse.left)
{
// 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
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);
}
// request an update
if (m_light.headlight)
updateLightPosition();
@@ -277,14 +208,11 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
else if (m_mouse.right)
{
// get the difference between last press and now
QVector2D diff = QVector2D(e->localPos()) - m_mouse.position;
m_camera->moveAction(QVector2D(e->localPos()) - m_mouse.position);
// update the new position
m_mouse.position = QVector2D(e->localPos());
// calculate the translation
m_translation += {(float)(diff.x() * 0.01), (float)(diff.y() * -0.01), 0.0};
// request an update
if (m_light.headlight)
updateLightPosition();
@@ -294,7 +222,7 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
void OglViewerWidget::wheelEvent(QWheelEvent *e)
{
m_translation += {0.0, 0.0, (float)m_zSpeed * e->angleDelta().y() / 240};
m_camera->wheelAction(e->angleDelta().y());
if (m_light.headlight)
updateLightPosition();
@@ -341,20 +269,34 @@ void OglViewerWidget::loadFile(QString name)
m_dataEngine->loadFile(name);
}
void OglViewerWidget::toggleAxis(int axis)
void OglViewerWidget::useFreeCamera()
{
switch (axis)
{
case 1:
m_rotDirections.x = !m_rotDirections.x;
break;
case 2:
m_rotDirections.y = !m_rotDirections.y;
break;
case 3:
m_rotDirections.z = !m_rotDirections.z;
break;
}
delete m_camera;
m_camera = new FreeCamera;
if (m_lightOn)
updateLightPosition();
update();
}
void OglViewerWidget::useOrbitCamera()
{
delete m_camera;
m_camera = new OrbitCamera;
if (m_lightOn)
updateLightPosition();
update();
}
void OglViewerWidget::useMoveCamera()
{
delete m_camera;
m_camera = new MoveCamera;
if (m_lightOn)
updateLightPosition();
update();
}
void OglViewerWidget::toggleWireframe()
@@ -441,8 +383,3 @@ void OglViewerWidget::setBackfaceCulling(bool value)
m_backfaceCulling = value;
update();
}
void OglViewerWidget::setZoomSpeed(int percent)
{
m_zSpeed = (double) percent / 100;
}

View File

@@ -0,0 +1,64 @@
#include "..\Header\OrbitCamera.h"
#include <QVector2D>
#include <qmath.h>
#include <iostream>
/////////////////////////////////////////////////////////////////////////
// constructor/destructor
OrbitCamera::OrbitCamera()
{
resetView();
}
OrbitCamera::~OrbitCamera()
{
}
/////////////////////////////////////////////////////////////////////////
// functions
void OrbitCamera::rotateAction(QVector2D diff)
{
//m_phi += diff.x() * 0.01;
m_theta -= diff.y() * 0.01;
m_theta = qMax(qMin(M_PI_2, m_theta), -M_PI_2);
}
void OrbitCamera::moveAction(QVector2D diff)
{
}
void OrbitCamera::wheelAction(double value)
{
m_roh -= m_zSpeed * value / 240;
m_roh = qMax(m_roh, 0.0);
}
void OrbitCamera::recalculateMatrix()
{
m_matrix = QMatrix4x4();
QVector3D tmpPosition;
tmpPosition.setX(qSin(m_theta) * qCos(m_phi));
tmpPosition.setY(qSin(m_theta) * qSin(m_phi));
tmpPosition.setZ(qCos(m_theta));
std::cout << m_theta << ":" << tmpPosition.x() << "-" << tmpPosition.y() << "-" << tmpPosition.z() << std::endl;
m_matrix.lookAt(m_roh * tmpPosition, QVector3D(0, 0, 0), QVector3D(0, 1, 0));
}
void OrbitCamera::resetView()
{
m_roh = 4;
m_phi = - M_PI_2;
m_theta = 0;
CameraInterface::resetView();
}