diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 1ba24039bd..bb4a9d3298 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -68,7 +68,7 @@ opencs_units (view/render ) opencs_units_noqt (view/render - navigation + navigation navigation1st ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/render/navigation1st.cpp b/apps/opencs/view/render/navigation1st.cpp new file mode 100644 index 0000000000..5a3bc7b652 --- /dev/null +++ b/apps/opencs/view/render/navigation1st.cpp @@ -0,0 +1,60 @@ + +#include "navigation1st.hpp" + +#include + +#include + +CSVRender::Navigation1st::Navigation1st() : mCamera (0) {} + +bool CSVRender::Navigation1st::activate (Ogre::Camera *camera) +{ + mCamera = camera; + mCamera->setFixedYawAxis (true); + return false; +} + +bool CSVRender::Navigation1st::wheelMoved (int delta) +{ + mCamera->move (getFactor (true) * mCamera->getDirection() * delta); + return true; +} + +bool CSVRender::Navigation1st::mouseMoved (const QPoint& delta, int mode) +{ + if (mode==0) + { + // turn camera + if (delta.x()) + mCamera->yaw (Ogre::Degree (getFactor (true) * delta.x())); + + if (delta.y()) + mCamera->pitch (Ogre::Degree (getFactor (true) * delta.y())); + + return true; + } + else if (mode==1) + { + // pan camera + if (delta.x()) + mCamera->move (getFactor (true) * mCamera->getDerivedRight() * delta.x()); + + if (delta.y()) + mCamera->move (getFactor (true) * -mCamera->getDerivedUp() * delta.y()); + + return true; + } + + return false; +} + +bool CSVRender::Navigation1st::handleMovementKeys (int vertical, int horizontal) +{ + if (vertical) + mCamera->move (getFactor (false) * mCamera->getDirection() * vertical); + + if (horizontal) + mCamera->move (getFactor (true) * mCamera->getDerivedRight() * horizontal); + + return true; +} diff --git a/apps/opencs/view/render/navigation1st.hpp b/apps/opencs/view/render/navigation1st.hpp new file mode 100644 index 0000000000..815e0b1174 --- /dev/null +++ b/apps/opencs/view/render/navigation1st.hpp @@ -0,0 +1,32 @@ +#ifndef OPENCS_VIEW_NAVIGATION1ST_H +#define OPENCS_VIEW_NAVIGATION1ST_H + +#include "navigation.hpp" + +namespace CSVRender +{ + /// \brief First person-like camera controls + class Navigation1st : public Navigation + { + Ogre::Camera *mCamera; + + public: + + Navigation1st(); + + virtual bool activate (Ogre::Camera *camera); + ///< \return Update required? + + virtual bool wheelMoved (int delta); + ///< \return Update required? + + virtual bool mouseMoved (const QPoint& delta, int mode); + ///< \param mode: 0: default mouse key, 1: default mouse key and modifier key 1 + /// \return Update required? + + virtual bool handleMovementKeys (int vertical, int horizontal); + ///< \return Update required? + }; +} + +#endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 07fe56f8fa..41868dfb5b 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -9,16 +9,18 @@ #include #include +#include "navigation.hpp" + namespace CSVRender { SceneWidget::SceneWidget(QWidget *parent) : QWidget(parent) , mWindow(NULL) , mCamera(NULL) - , mSceneMgr(NULL), mNavigationMode (NavigationMode_1stPerson), mUpdate (false) + , mSceneMgr(NULL), mNavigation (0), mUpdate (false) , mKeyForward (false), mKeyBackward (false), mKeyLeft (false), mKeyRight (false) , mFast (false), mDragging (false), mMod1 (false) - , mMouseSensitivity (2), mFastFactor (4) /// \todo make these configurable + , mFastFactor (4) /// \todo make this configurable { setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); @@ -94,12 +96,12 @@ namespace CSVRender Ogre::Root::getSingleton().destroyRenderTarget(mWindow); } - void SceneWidget::setNavigationMode (NavigationMode mode) + void SceneWidget::setNavigation (Navigation *navigation) { - if (mode!=mNavigationMode) + if ((mNavigation = navigation)) { - mNavigationMode = mode; - + mNavigation->setFastModeFactor (mFast ? mFastFactor : 1); + mNavigation->activate (mCamera); } } @@ -156,8 +158,17 @@ namespace CSVRender case Qt::Key_S: mKeyBackward = true; break; case Qt::Key_A: mKeyLeft = true; break; case Qt::Key_D: mKeyRight = true; break; - case Qt::Key_Shift: mFast = true; break; case Qt::Key_Control: mMod1 = true; break; + + case Qt::Key_Shift: + + mFast = true; + + if (mNavigation) + mNavigation->setFastModeFactor (mFastFactor); + + break; + default: QWidget::keyPressEvent (event); } } @@ -170,19 +181,27 @@ namespace CSVRender case Qt::Key_S: mKeyBackward = false; break; case Qt::Key_A: mKeyLeft = false; break; case Qt::Key_D: mKeyRight = false; break; - case Qt::Key_Shift: mFast = false; break; case Qt::Key_Control: mMod1 = false; break; + + case Qt::Key_Shift: + + mFast = false; + + if (mNavigation) + mNavigation->setFastModeFactor (1); + + break; + default: QWidget::keyReleaseEvent (event); } } void SceneWidget::wheelEvent (QWheelEvent *event) { - if (int delta = event->delta()) - { - mCamera->move ((getFastFactor() * mCamera->getDirection() * delta)/mMouseSensitivity); - mUpdate = true; - } + if (mNavigation) + if (event->delta()) + if (mNavigation->wheelMoved (event->delta())) + mUpdate = true; } void SceneWidget::leaveEvent (QEvent *event) @@ -199,40 +218,9 @@ namespace CSVRender QPoint diff = mOldPos-event->pos(); mOldPos = event->pos(); - if (!mMod1) - { - // turn camera - if (diff.x()) - { - mCamera->yaw ( - Ogre::Degree ((getFastFactor() * diff.x())/mMouseSensitivity)); + if (mNavigation) + if (mNavigation->mouseMoved (diff, mMod1 ? 1 : 0)) mUpdate = true; - } - - if (diff.y()) - { - mCamera->pitch ( - Ogre::Degree ((getFastFactor() * diff.y())/mMouseSensitivity)); - mUpdate = true; - } - } - else - { - // pan camera - if (diff.x()) - { - Ogre::Vector3 direction = mCamera->getDerivedRight(); - mCamera->move ((getFastFactor() * direction * diff.x())/mMouseSensitivity); - mUpdate = true; - } - - if (diff.y()) - { - Ogre::Vector3 direction = mCamera->getDerivedUp(); - mCamera->move ((getFastFactor() * -direction * diff.y())/mMouseSensitivity); - mUpdate = true; - } - } } else { @@ -262,30 +250,24 @@ namespace CSVRender void SceneWidget::update() { - if (mKeyForward && !mKeyBackward) + if (mNavigation) { - mCamera->move (getFastFactor() * mCamera->getDirection()); - mUpdate = true; - } + int horizontal = 0; + int vertical = 0; - if (!mKeyForward && mKeyBackward) - { - mCamera->move (getFastFactor() * -mCamera->getDirection()); - mUpdate = true; - } + if (mKeyForward && !mKeyBackward) + vertical = 1; + else if (!mKeyForward && mKeyBackward) + vertical = -1; - if (mKeyLeft && !mKeyRight) - { - Ogre::Vector3 direction = mCamera->getDerivedRight(); - mCamera->move (getFastFactor() * -direction); - mUpdate = true; - } + if (mKeyLeft && !mKeyRight) + horizontal = -1; + else if (!mKeyLeft && mKeyRight) + horizontal = 1; - if (!mKeyLeft && mKeyRight) - { - Ogre::Vector3 direction = mCamera->getDerivedRight(); - mCamera->move (getFastFactor() * direction); - mUpdate = true; + if (horizontal || vertical) + if (mNavigation->handleMovementKeys (vertical, horizontal)) + mUpdate = true; } if (mUpdate) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 55f62d6619..247dbbb1a1 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -12,25 +12,21 @@ namespace Ogre namespace CSVRender { + class Navigation; + class SceneWidget : public QWidget { Q_OBJECT public: - enum NavigationMode - { - NavigationMode_1stPerson, - NavigationMode_Free, - NavigationMode_Orbit - }; - SceneWidget(QWidget *parent); virtual ~SceneWidget(); QPaintEngine* paintEngine() const; - void setNavigationMode (NavigationMode mode); + void setNavigation (Navigation *navigation); + ///< \attention The ownership of \a navigation is not transferred to *this. private: void paintEvent(QPaintEvent* e); @@ -59,7 +55,7 @@ namespace CSVRender Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; - NavigationMode mNavigationMode; + Navigation *mNavigation; bool mUpdate; int mKeyForward; int mKeyBackward; @@ -69,7 +65,6 @@ namespace CSVRender bool mDragging; bool mMod1; QPoint mOldPos; - int mMouseSensitivity; int mFastFactor; private slots: diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 339a885191..5b7b6a587b 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -59,6 +59,8 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D widget->setLayout (layout); setWidget (widget); + + mScene->setNavigation (&m1st); } void CSVWorld::SceneSubView::setEditLock (bool locked) @@ -81,9 +83,13 @@ void CSVWorld::SceneSubView::setStatusBar (bool show) void CSVWorld::SceneSubView::selectNavigationMode (const std::string& mode) { if (mode=="1st") - mScene->setNavigationMode (CSVRender::SceneWidget::NavigationMode_1stPerson); + mScene->setNavigation (&m1st); else if (mode=="free") - mScene->setNavigationMode (CSVRender::SceneWidget::NavigationMode_Free); + { + + } else if (mode=="orbit") - mScene->setNavigationMode (CSVRender::SceneWidget::NavigationMode_Orbit); + { + + } } diff --git a/apps/opencs/view/world/scenesubview.hpp b/apps/opencs/view/world/scenesubview.hpp index 65e1614c11..f948ecefbe 100644 --- a/apps/opencs/view/world/scenesubview.hpp +++ b/apps/opencs/view/world/scenesubview.hpp @@ -3,6 +3,8 @@ #include "../doc/subview.hpp" +#include "../render/navigation1st.hpp" + class QModelIndex; namespace CSMDoc @@ -27,6 +29,7 @@ namespace CSVWorld TableBottomBox *mBottom; CSVRender::SceneWidget *mScene; + CSVRender::Navigation1st m1st; public: