From f59ab5c34f2e464ac247b5185f705959a6e20d42 Mon Sep 17 00:00:00 2001 From: smalcom Date: Thu, 24 May 2018 17:11:21 +0300 Subject: [PATCH] [F] More correct control by a mouse --- tools/assimp_qt_viewer/glview.cpp | 21 +++++++++--- tools/assimp_qt_viewer/glview.hpp | 23 ++++++++++--- tools/assimp_qt_viewer/mainwindow.cpp | 47 ++++++++++++++++++--------- tools/assimp_qt_viewer/mainwindow.hpp | 19 +++++++++-- 4 files changed, 82 insertions(+), 28 deletions(-) diff --git a/tools/assimp_qt_viewer/glview.cpp b/tools/assimp_qt_viewer/glview.cpp index c52ac34e3..833400c46 100644 --- a/tools/assimp_qt_viewer/glview.cpp +++ b/tools/assimp_qt_viewer/glview.cpp @@ -1073,24 +1073,30 @@ void CGLView::Camera_Set(const size_t pCameraNumber) gluLookAt(hcam.Position.x, hcam.Position.y, hcam.Position.z, hcam.Target.x, hcam.Target.y, hcam.Target.z, up.x, up.y, up.z); } -void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z) +void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) { auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; }; aiMatrix4x4 mat_rot; mat_rot.FromEulerAnglesXYZ(deg2rad(pAngle_X), deg2rad(pAngle_Y), deg2rad(pAngle_Z)); - mHelper_Camera.Rotation_Scene *= mat_rot; + if(pMatrix_Rotation_Initial != nullptr) + mHelper_Camera.Rotation_Scene = *pMatrix_Rotation_Initial * mat_rot; + else + mHelper_Camera.Rotation_Scene *= mat_rot; } -void CGLView::Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z) +void CGLView::Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) { auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; }; aiMatrix4x4 mat_rot; mat_rot.FromEulerAnglesXYZ(deg2rad(pAngle_X), deg2rad(pAngle_Y), deg2rad(pAngle_Z)); - mHelper_Camera.Rotation_AroundCamera *= mat_rot; + if(pMatrix_Rotation_Initial != nullptr) + mHelper_Camera.Rotation_AroundCamera = *pMatrix_Rotation_Initial * mat_rot; + else + mHelper_Camera.Rotation_AroundCamera *= mat_rot; } void CGLView::Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z) @@ -1100,3 +1106,10 @@ aiVector3D vect_tr(pTranslate_X, pTranslate_Y, pTranslate_Z); vect_tr *= mHelper_Camera.Rotation_AroundCamera; mHelper_Camera.Translation_ToScene += vect_tr; } + +void CGLView::Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera) +{ + pRotation_Camera = mHelper_Camera.Rotation_AroundCamera; + pRotation_Scene = mHelper_Camera.Rotation_Scene; + pTranslation_Camera = mHelper_Camera.Translation_ToScene; +} diff --git a/tools/assimp_qt_viewer/glview.hpp b/tools/assimp_qt_viewer/glview.hpp index 3bfb8fa08..2d8614e21 100644 --- a/tools/assimp_qt_viewer/glview.hpp +++ b/tools/assimp_qt_viewer/glview.hpp @@ -310,7 +310,9 @@ public: /// \param [in] pEnable - if true then enable textures, false - disable textures. void Enable_Textures(const bool pEnable); - ///TODO: doc + /// \fn void Enable_Axes(const bool pEnable) + /// Control axes drawing. + /// \param [in] pEnable - if true then enable axes, false - disable axes. void Enable_Axes(const bool pEnable) { this->mScene_AxesEnabled = pEnable; } /********************************************************************/ @@ -350,19 +352,23 @@ public: /// \param [in] pCamera_Index - index of the camera (\ref aiScene::mCameras). void Camera_Set(const size_t pCameraNumber); - /// \fn void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z) + /// \fn void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) /// Rotate scene around axisees. /// \param [in] pAngle_X - specifies the angle of rotation around axis oX, in degrees. /// \param [in] pAngle_Y - specifies the angle of rotation around axis oY, in degrees. /// \param [in] pAngle_Z - specifies the angle of rotation around axis oZ, in degrees. - void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z); + /// \param [in] pMatrix_Rotation_Initial - matrix from which calculates new transformation matrix. If not set (equal to nullptr) then current transformation matrix + /// will be used. + void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr); - /// \fn void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z) + /// \fn void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr) /// Rotate camera around axisees. /// \param [in] pAngle_X - specifies the angle of rotation around axis oX, in degrees. /// \param [in] pAngle_Y - specifies the angle of rotation around axis oY, in degrees. /// \param [in] pAngle_Z - specifies the angle of rotation around axis oZ, in degrees. - void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z); + /// \param [in] pMatrix_Rotation_Initial - matrix from which calculates new transformation matrix. If not set (equal to nullptr) then current transformation matrix + /// will be used. + void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr); /// \fn void Camera_Translate(const size_t pTranslate_X, const size_t pTranslate_Y, const size_t pTranslate_Z) /// Translate camera along axises. In local coordinates. @@ -371,6 +377,13 @@ public: /// \param [in] pTranslate_Z - specifies the Z coordinate of translation vector. void Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z); + /// \fn void Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera) + /// Return data about camera position in world. + /// \param [out] pRotation_Camera - rotation matrix which set rotation angles of the scene around camera. + /// \param [out] pRotation_Scene - rotation matrix which set rotation angles of the scene around own center. + /// \param [out] pTranslation_Camera - translation vector from camera to the scene. + void Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera); + signals: /// \fn void Paint_Finished(const size_t pPaintTime, const GLfloat pDistance) diff --git a/tools/assimp_qt_viewer/mainwindow.cpp b/tools/assimp_qt_viewer/mainwindow.cpp index 2d87005a0..c17188472 100644 --- a/tools/assimp_qt_viewer/mainwindow.cpp +++ b/tools/assimp_qt_viewer/mainwindow.cpp @@ -130,51 +130,63 @@ void MainWindow::mousePressEvent(QMouseEvent* pEvent) { const QPoint ms_pt = pEvent->pos(); +__unused aiVector3D temp_v3; + // Check if GLView is pointed. if(childAt(ms_pt) == mGLView) { - mPosition_Pressed_Valid = true; + if(!mMouse_Transformation.Position_Pressed_Valid) + { + mMouse_Transformation.Position_Pressed_Valid = true;// set flag + // Store current transformation matrices. + mGLView->Camera_Matrix(mMouse_Transformation.Rotation_AroundCamera, mMouse_Transformation.Rotation_Scene, temp_v3); + } + if(pEvent->button() & Qt::LeftButton) - mPosition_Pressed_LMB = ms_pt; + mMouse_Transformation.Position_Pressed_LMB = ms_pt; else if(pEvent->button() & Qt::RightButton) - mPosition_Pressed_RMB = ms_pt; + mMouse_Transformation.Position_Pressed_RMB = ms_pt; } else { - mPosition_Pressed_Valid = false; + mMouse_Transformation.Position_Pressed_Valid = false; } } +void MainWindow::mouseReleaseEvent(QMouseEvent *pEvent) +{ + if(pEvent->buttons() == 0) mMouse_Transformation.Position_Pressed_Valid = false; + +} + void MainWindow::mouseMoveEvent(QMouseEvent* pEvent) { - if(mPosition_Pressed_Valid) + if(mMouse_Transformation.Position_Pressed_Valid) { if(pEvent->buttons() & Qt::LeftButton) { - GLfloat dx = 180 * GLfloat(pEvent->x() - mPosition_Pressed_LMB.x()) / mGLView->width(); - GLfloat dy = 180 * GLfloat(pEvent->y() - mPosition_Pressed_LMB.y()) / mGLView->height(); + GLfloat dx = 180 * GLfloat(pEvent->x() - mMouse_Transformation.Position_Pressed_LMB.x()) / mGLView->width(); + GLfloat dy = 180 * GLfloat(pEvent->y() - mMouse_Transformation.Position_Pressed_LMB.y()) / mGLView->height(); if(pEvent->modifiers() & Qt::ShiftModifier) - mGLView->Camera_RotateScene(dy, 0, dx);// Rotate around oX and oZ axises. + mGLView->Camera_RotateScene(dy, 0, dx, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oZ axises. else - mGLView->Camera_RotateScene(dy, dx, 0);// Rotate around oX and oY axises. + mGLView->Camera_RotateScene(dy, dx, 0, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oY axises. mGLView->updateGL(); - mPosition_Pressed_LMB = pEvent->pos(); } if(pEvent->buttons() & Qt::RightButton) { - GLfloat dx = 180 * GLfloat(pEvent->x() - mPosition_Pressed_RMB.x()) / mGLView->width(); - GLfloat dy = 180 * GLfloat(pEvent->y() - mPosition_Pressed_RMB.y()) / mGLView->height(); + GLfloat dx = 180 * GLfloat(pEvent->x() - mMouse_Transformation.Position_Pressed_RMB.x()) / mGLView->width(); + GLfloat dy = 180 * GLfloat(pEvent->y() - mMouse_Transformation.Position_Pressed_RMB.y()) / mGLView->height(); if(pEvent->modifiers() & Qt::ShiftModifier) - mGLView->Camera_Rotate(dy, 0, dx);// Rotate around oX and oZ axises. + mGLView->Camera_Rotate(dy, 0, dx, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oZ axises. else - mGLView->Camera_Rotate(dy, dx, 0);// Rotate around oX and oY axises. + mGLView->Camera_Rotate(dy, dx, 0, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oY axises. mGLView->updateGL(); - mPosition_Pressed_RMB = pEvent->pos(); } } } @@ -212,10 +224,13 @@ GLfloat step; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), - mScene(nullptr), mPosition_Pressed_Valid(false) + mScene(nullptr) { using namespace Assimp; + // other variables + mMouse_Transformation.Position_Pressed_Valid = false; + ui->setupUi(this); // Create OpenGL widget mGLView = new CGLView(this); diff --git a/tools/assimp_qt_viewer/mainwindow.hpp b/tools/assimp_qt_viewer/mainwindow.hpp index fc31599b7..2eedf18f2 100644 --- a/tools/assimp_qt_viewer/mainwindow.hpp +++ b/tools/assimp_qt_viewer/mainwindow.hpp @@ -36,9 +36,17 @@ private: CLoggerView* mLoggerView;///< Pointer to logging object. Assimp::Importer mImporter;///< Assimp importer. const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene). - bool mPosition_Pressed_Valid;///< Mouse button pressed on GLView. - QPoint mPosition_Pressed_LMB;///< Position where was pressed left mouse button. - QPoint mPosition_Pressed_RMB;///< Position where was pressed right mouse button. + + /// \struct SMouse_Transformation + /// Holds data about transformation of the scene/camera when mouse us used. + struct SMouse_Transformation + { + bool Position_Pressed_Valid;///< Mouse button pressed on GLView. + QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button. + QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button. + aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera. + aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center. + } mMouse_Transformation; /**********************************/ /************ Functions ***********/ @@ -81,6 +89,11 @@ protected: /// \param [in] pEvent - pointer to event data. void mousePressEvent(QMouseEvent* pEvent) override; + /// \fn void mouseReleaseEvent(QMouseEvent *pEvent) override + /// Override function which handles mouse event "button released". + /// \param [in] pEvent - pointer to event data. + void mouseReleaseEvent(QMouseEvent *pEvent) override; + /// \fn void mouseMoveEvent(QMouseEvent* pEvent) override /// Override function which handles mouse event "move". /// \param [in] pEvent - pointer to event data.