From 48047beb9abc3f40aaf09811697702dadcd58972 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Wed, 9 Mar 2016 15:29:12 -0500 Subject: [PATCH 01/41] Stripped OSG mouse and keyboard handling. --- extern/osgQt/GraphicsWindowQt | 29 +-- extern/osgQt/GraphicsWindowQt.cpp | 322 +----------------------------- 2 files changed, 10 insertions(+), 341 deletions(-) diff --git a/extern/osgQt/GraphicsWindowQt b/extern/osgQt/GraphicsWindowQt index 54d069176..ad456ef44 100644 --- a/extern/osgQt/GraphicsWindowQt +++ b/extern/osgQt/GraphicsWindowQt @@ -56,32 +56,15 @@ class GLWidget : public QGLWidget public: - GLWidget( QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false ); - GLWidget( QGLContext* context, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false ); - GLWidget( const QGLFormat& format, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false ); + GLWidget( QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0); + GLWidget( QGLContext* context, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0); + GLWidget( const QGLFormat& format, QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0); virtual ~GLWidget(); inline void setGraphicsWindow( GraphicsWindowQt* gw ) { _gw = gw; } inline GraphicsWindowQt* getGraphicsWindow() { return _gw; } inline const GraphicsWindowQt* getGraphicsWindow() const { return _gw; } - inline bool getForwardKeyEvents() const { return _forwardKeyEvents; } - virtual void setForwardKeyEvents( bool f ) { _forwardKeyEvents = f; } - - inline bool getTouchEventsEnabled() const { return _touchEventsEnabled; } - void setTouchEventsEnabled( bool e ); - - void setKeyboardModifiers( QInputEvent* event ); - - virtual void keyPressEvent( QKeyEvent* event ); - virtual void keyReleaseEvent( QKeyEvent* event ); - virtual void mousePressEvent( QMouseEvent* event ); - virtual void mouseReleaseEvent( QMouseEvent* event ); - virtual void mouseDoubleClickEvent( QMouseEvent* event ); - virtual void mouseMoveEvent( QMouseEvent* event ); - virtual void wheelEvent( QWheelEvent* event ); - virtual bool gestureEvent( QGestureEvent* event ); - protected: int getNumDeferredEvents() @@ -114,9 +97,6 @@ protected: QQueue _deferredEventQueue; QSet _eventCompressor; - bool _touchEventsEnabled; - - bool _forwardKeyEvents; qreal _devicePixelRatio; virtual void resizeEvent( QResizeEvent* event ); @@ -164,9 +144,6 @@ public: virtual std::string getWindowName(); virtual void useCursor( bool cursorOn ); virtual void setCursor( MouseCursor cursor ); - inline bool getTouchEventsEnabled() const { return _widget->getTouchEventsEnabled(); } - virtual void setTouchEventsEnabled( bool e ) { _widget->setTouchEventsEnabled(e); } - virtual bool valid() const; virtual bool realizeImplementation(); diff --git a/extern/osgQt/GraphicsWindowQt.cpp b/extern/osgQt/GraphicsWindowQt.cpp index 2001c8b31..770ac9ada 100644 --- a/extern/osgQt/GraphicsWindowQt.cpp +++ b/extern/osgQt/GraphicsWindowQt.cpp @@ -26,98 +26,6 @@ using namespace osgQt; - -class QtKeyboardMap -{ - -public: - QtKeyboardMap() - { - mKeyMap[Qt::Key_Escape ] = osgGA::GUIEventAdapter::KEY_Escape; - mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; - mKeyMap[Qt::Key_Home ] = osgGA::GUIEventAdapter::KEY_Home; - mKeyMap[Qt::Key_Enter ] = osgGA::GUIEventAdapter::KEY_KP_Enter; - mKeyMap[Qt::Key_End ] = osgGA::GUIEventAdapter::KEY_End; - mKeyMap[Qt::Key_Return ] = osgGA::GUIEventAdapter::KEY_Return; - mKeyMap[Qt::Key_PageUp ] = osgGA::GUIEventAdapter::KEY_Page_Up; - mKeyMap[Qt::Key_PageDown ] = osgGA::GUIEventAdapter::KEY_Page_Down; - mKeyMap[Qt::Key_Left ] = osgGA::GUIEventAdapter::KEY_Left; - mKeyMap[Qt::Key_Right ] = osgGA::GUIEventAdapter::KEY_Right; - mKeyMap[Qt::Key_Up ] = osgGA::GUIEventAdapter::KEY_Up; - mKeyMap[Qt::Key_Down ] = osgGA::GUIEventAdapter::KEY_Down; - mKeyMap[Qt::Key_Backspace ] = osgGA::GUIEventAdapter::KEY_BackSpace; - mKeyMap[Qt::Key_Tab ] = osgGA::GUIEventAdapter::KEY_Tab; - mKeyMap[Qt::Key_Space ] = osgGA::GUIEventAdapter::KEY_Space; - mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_Delete; - mKeyMap[Qt::Key_Alt ] = osgGA::GUIEventAdapter::KEY_Alt_L; - mKeyMap[Qt::Key_Shift ] = osgGA::GUIEventAdapter::KEY_Shift_L; - mKeyMap[Qt::Key_Control ] = osgGA::GUIEventAdapter::KEY_Control_L; - mKeyMap[Qt::Key_Meta ] = osgGA::GUIEventAdapter::KEY_Meta_L; - - mKeyMap[Qt::Key_F1 ] = osgGA::GUIEventAdapter::KEY_F1; - mKeyMap[Qt::Key_F2 ] = osgGA::GUIEventAdapter::KEY_F2; - mKeyMap[Qt::Key_F3 ] = osgGA::GUIEventAdapter::KEY_F3; - mKeyMap[Qt::Key_F4 ] = osgGA::GUIEventAdapter::KEY_F4; - mKeyMap[Qt::Key_F5 ] = osgGA::GUIEventAdapter::KEY_F5; - mKeyMap[Qt::Key_F6 ] = osgGA::GUIEventAdapter::KEY_F6; - mKeyMap[Qt::Key_F7 ] = osgGA::GUIEventAdapter::KEY_F7; - mKeyMap[Qt::Key_F8 ] = osgGA::GUIEventAdapter::KEY_F8; - mKeyMap[Qt::Key_F9 ] = osgGA::GUIEventAdapter::KEY_F9; - mKeyMap[Qt::Key_F10 ] = osgGA::GUIEventAdapter::KEY_F10; - mKeyMap[Qt::Key_F11 ] = osgGA::GUIEventAdapter::KEY_F11; - mKeyMap[Qt::Key_F12 ] = osgGA::GUIEventAdapter::KEY_F12; - mKeyMap[Qt::Key_F13 ] = osgGA::GUIEventAdapter::KEY_F13; - mKeyMap[Qt::Key_F14 ] = osgGA::GUIEventAdapter::KEY_F14; - mKeyMap[Qt::Key_F15 ] = osgGA::GUIEventAdapter::KEY_F15; - mKeyMap[Qt::Key_F16 ] = osgGA::GUIEventAdapter::KEY_F16; - mKeyMap[Qt::Key_F17 ] = osgGA::GUIEventAdapter::KEY_F17; - mKeyMap[Qt::Key_F18 ] = osgGA::GUIEventAdapter::KEY_F18; - mKeyMap[Qt::Key_F19 ] = osgGA::GUIEventAdapter::KEY_F19; - mKeyMap[Qt::Key_F20 ] = osgGA::GUIEventAdapter::KEY_F20; - - mKeyMap[Qt::Key_hyphen ] = '-'; - mKeyMap[Qt::Key_Equal ] = '='; - - mKeyMap[Qt::Key_division ] = osgGA::GUIEventAdapter::KEY_KP_Divide; - mKeyMap[Qt::Key_multiply ] = osgGA::GUIEventAdapter::KEY_KP_Multiply; - mKeyMap[Qt::Key_Minus ] = '-'; - mKeyMap[Qt::Key_Plus ] = '+'; - //mKeyMap[Qt::Key_H ] = osgGA::GUIEventAdapter::KEY_KP_Home; - //mKeyMap[Qt::Key_ ] = osgGA::GUIEventAdapter::KEY_KP_Up; - //mKeyMap[92 ] = osgGA::GUIEventAdapter::KEY_KP_Page_Up; - //mKeyMap[86 ] = osgGA::GUIEventAdapter::KEY_KP_Left; - //mKeyMap[87 ] = osgGA::GUIEventAdapter::KEY_KP_Begin; - //mKeyMap[88 ] = osgGA::GUIEventAdapter::KEY_KP_Right; - //mKeyMap[83 ] = osgGA::GUIEventAdapter::KEY_KP_End; - //mKeyMap[84 ] = osgGA::GUIEventAdapter::KEY_KP_Down; - //mKeyMap[85 ] = osgGA::GUIEventAdapter::KEY_KP_Page_Down; - mKeyMap[Qt::Key_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert; - //mKeyMap[Qt::Key_Delete ] = osgGA::GUIEventAdapter::KEY_KP_Delete; - } - - ~QtKeyboardMap() - { - } - - int remapKey(QKeyEvent* event) - { - KeyMap::iterator itr = mKeyMap.find(event->key()); - if (itr == mKeyMap.end()) - { - return int(*(event->text().toLatin1().data())); - } - else - return itr->second; - } - - private: - typedef std::map KeyMap; - KeyMap mKeyMap; -}; - -static QtKeyboardMap s_QtKeyboardMap; - - /// The object responsible for the scene re-rendering. class HeartBeat : public QObject { public: @@ -126,7 +34,7 @@ public: osg::observer_ptr< osgViewer::ViewerBase > _viewer; virtual ~HeartBeat(); - + void init( osgViewer::ViewerBase *viewer ); void stopTimer(); void timerEvent( QTimerEvent *event ); @@ -146,31 +54,20 @@ QPointer HeartBeat::heartBeat; #define GETDEVICEPIXELRATIO() devicePixelRatio() #endif -GLWidget::GLWidget( QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f, bool forwardKeyEvents ) -: QGLWidget(parent, shareWidget, f), -_gw( NULL ), -_touchEventsEnabled( false ), -_forwardKeyEvents( forwardKeyEvents ) +GLWidget::GLWidget( QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) +: QGLWidget(parent, shareWidget, f), _gw( NULL ) { _devicePixelRatio = GETDEVICEPIXELRATIO(); } -GLWidget::GLWidget( QGLContext* context, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f, - bool forwardKeyEvents ) -: QGLWidget(context, parent, shareWidget, f), -_gw( NULL ), -_touchEventsEnabled( false ), -_forwardKeyEvents( forwardKeyEvents ) +GLWidget::GLWidget( QGLContext* context, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) +: QGLWidget(context, parent, shareWidget, f), _gw( NULL ) { _devicePixelRatio = GETDEVICEPIXELRATIO(); } -GLWidget::GLWidget( const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f, - bool forwardKeyEvents ) -: QGLWidget(format, parent, shareWidget, f), -_gw( NULL ), -_touchEventsEnabled( false ), -_forwardKeyEvents( forwardKeyEvents ) +GLWidget::GLWidget( const QGLFormat& format, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f) +: QGLWidget(format, parent, shareWidget, f), _gw( NULL ) { _devicePixelRatio = GETDEVICEPIXELRATIO(); } @@ -186,25 +83,6 @@ GLWidget::~GLWidget() } } -void GLWidget::setTouchEventsEnabled(bool e) -{ -#ifdef USE_GESTURES - if (e==_touchEventsEnabled) - return; - - _touchEventsEnabled = e; - - if (_touchEventsEnabled) - { - grabGesture(Qt::PinchGesture); - } - else - { - ungrabGesture(Qt::PinchGesture); - } -#endif -} - void GLWidget::processDeferredEvents() { QQueue deferredEventQueueCopy; @@ -224,10 +102,6 @@ void GLWidget::processDeferredEvents() bool GLWidget::event( QEvent* event ) { -#ifdef USE_GESTURES - if ( event->type()==QEvent::Gesture ) - return gestureEvent(static_cast(event)); -#endif // QEvent::Hide // @@ -274,16 +148,6 @@ bool GLWidget::event( QEvent* event ) return QGLWidget::event( event ); } -void GLWidget::setKeyboardModifiers( QInputEvent* event ) -{ - int modkey = event->modifiers() & (Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier); - unsigned int mask = 0; - if ( modkey & Qt::ShiftModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_SHIFT; - if ( modkey & Qt::ControlModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_CTRL; - if ( modkey & Qt::AltModifier ) mask |= osgGA::GUIEventAdapter::MODKEY_ALT; - _gw->getEventQueue()->getCurrentEventState()->setModKeyMask( mask ); -} - void GLWidget::resizeEvent( QResizeEvent* event ) { const QSize& size = event->size(); @@ -309,178 +173,6 @@ void GLWidget::glDraw() _gw->requestRedraw(); } -void GLWidget::keyPressEvent( QKeyEvent* event ) -{ - setKeyboardModifiers( event ); - int value = s_QtKeyboardMap.remapKey( event ); - _gw->getEventQueue()->keyPress( value ); - - // this passes the event to the regular Qt key event processing, - // among others, it closes popup windows on ESC and forwards the event to the parent widgets - if( _forwardKeyEvents ) - inherited::keyPressEvent( event ); -} - -void GLWidget::keyReleaseEvent( QKeyEvent* event ) -{ - if( event->isAutoRepeat() ) - { - event->ignore(); - } - else - { - setKeyboardModifiers( event ); - int value = s_QtKeyboardMap.remapKey( event ); - _gw->getEventQueue()->keyRelease( value ); - } - - // this passes the event to the regular Qt key event processing, - // among others, it closes popup windows on ESC and forwards the event to the parent widgets - if( _forwardKeyEvents ) - inherited::keyReleaseEvent( event ); -} - -void GLWidget::mousePressEvent( QMouseEvent* event ) -{ - int button = 0; - switch ( event->button() ) - { - case Qt::LeftButton: button = 1; break; - case Qt::MidButton: button = 2; break; - case Qt::RightButton: button = 3; break; - case Qt::NoButton: button = 0; break; - default: button = 0; break; - } - setKeyboardModifiers( event ); - _gw->getEventQueue()->mouseButtonPress( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button ); -} - -void GLWidget::mouseReleaseEvent( QMouseEvent* event ) -{ - int button = 0; - switch ( event->button() ) - { - case Qt::LeftButton: button = 1; break; - case Qt::MidButton: button = 2; break; - case Qt::RightButton: button = 3; break; - case Qt::NoButton: button = 0; break; - default: button = 0; break; - } - setKeyboardModifiers( event ); - _gw->getEventQueue()->mouseButtonRelease( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button ); -} - -void GLWidget::mouseDoubleClickEvent( QMouseEvent* event ) -{ - int button = 0; - switch ( event->button() ) - { - case Qt::LeftButton: button = 1; break; - case Qt::MidButton: button = 2; break; - case Qt::RightButton: button = 3; break; - case Qt::NoButton: button = 0; break; - default: button = 0; break; - } - setKeyboardModifiers( event ); - _gw->getEventQueue()->mouseDoubleButtonPress( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio, button ); -} - -void GLWidget::mouseMoveEvent( QMouseEvent* event ) -{ - setKeyboardModifiers( event ); - _gw->getEventQueue()->mouseMotion( event->x()*_devicePixelRatio, event->y()*_devicePixelRatio ); -} - -void GLWidget::wheelEvent( QWheelEvent* event ) -{ - setKeyboardModifiers( event ); - _gw->getEventQueue()->mouseScroll( - event->orientation() == Qt::Vertical ? - (event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN) : - (event->delta()>0 ? osgGA::GUIEventAdapter::SCROLL_LEFT : osgGA::GUIEventAdapter::SCROLL_RIGHT) ); -} - -#ifdef USE_GESTURES -static osgGA::GUIEventAdapter::TouchPhase translateQtGestureState( Qt::GestureState state ) -{ - osgGA::GUIEventAdapter::TouchPhase touchPhase; - switch ( state ) - { - case Qt::GestureStarted: - touchPhase = osgGA::GUIEventAdapter::TOUCH_BEGAN; - break; - case Qt::GestureUpdated: - touchPhase = osgGA::GUIEventAdapter::TOUCH_MOVED; - break; - case Qt::GestureFinished: - case Qt::GestureCanceled: - touchPhase = osgGA::GUIEventAdapter::TOUCH_ENDED; - break; - default: - touchPhase = osgGA::GUIEventAdapter::TOUCH_UNKNOWN; - }; - - return touchPhase; -} -#endif - - -bool GLWidget::gestureEvent( QGestureEvent* qevent ) -{ -#ifndef USE_GESTURES - return false; -#else - - bool accept = false; - - if ( QPinchGesture* pinch = static_cast(qevent->gesture(Qt::PinchGesture) ) ) - { - const QPointF qcenterf = pinch->centerPoint(); - const float angle = pinch->totalRotationAngle(); - const float scale = pinch->totalScaleFactor(); - - const QPoint pinchCenterQt = mapFromGlobal(qcenterf.toPoint()); - const osg::Vec2 pinchCenter( pinchCenterQt.x(), pinchCenterQt.y() ); - - //We don't have absolute positions of the two touches, only a scale and rotation - //Hence we create pseudo-coordinates which are reasonable, and centered around the - //real position - const float radius = (width()+height())/4; - const osg::Vec2 vector( scale*cos(angle)*radius, scale*sin(angle)*radius); - const osg::Vec2 p0 = pinchCenter+vector; - const osg::Vec2 p1 = pinchCenter-vector; - - osg::ref_ptr event = 0; - const osgGA::GUIEventAdapter::TouchPhase touchPhase = translateQtGestureState( pinch->state() ); - if ( touchPhase==osgGA::GUIEventAdapter::TOUCH_BEGAN ) - { - event = _gw->getEventQueue()->touchBegan(0 , touchPhase, p0[0], p0[1] ); - } - else if ( touchPhase==osgGA::GUIEventAdapter::TOUCH_MOVED ) - { - event = _gw->getEventQueue()->touchMoved( 0, touchPhase, p0[0], p0[1] ); - } - else - { - event = _gw->getEventQueue()->touchEnded( 0, touchPhase, p0[0], p0[1], 1 ); - } - - if ( event ) - { - event->addTouchPoint( 1, touchPhase, p1[0], p1[1] ); - accept = true; - } - } - - if ( accept ) - qevent->accept(); - - return accept; -#endif -} - - - GraphicsWindowQt::GraphicsWindowQt( osg::GraphicsContext::Traits* traits, QWidget* parent, const QGLWidget* shareWidget, Qt::WindowFlags f ) : _realized(false) { From 38059593a754faac2a12a9fc12e7468a8555225d Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Wed, 9 Mar 2016 15:31:38 -0500 Subject: [PATCH 02/41] Removed workaround for OSG input handling in RenderWidget. --- apps/opencs/view/render/scenewidget.cpp | 20 -------------------- apps/opencs/view/render/scenewidget.hpp | 2 -- 2 files changed, 22 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 55d9c8195..21a4c56a4 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -100,26 +100,6 @@ void RenderWidget::setVisibilityMask(int mask) mView->getCamera()->setCullMask(mask | Mask_ParticleSystem | Mask_Lighting); } -bool RenderWidget::eventFilter(QObject* obj, QEvent* event) -{ - // handle event in this widget, is there a better way to do this? - if (event->type() == QEvent::MouseButtonPress) - mousePressEvent(static_cast(event)); - if (event->type() == QEvent::MouseButtonRelease) - mouseReleaseEvent(static_cast(event)); - if (event->type() == QEvent::MouseMove) - mouseMoveEvent(static_cast(event)); - if (event->type() == QEvent::KeyPress) - keyPressEvent(static_cast(event)); - if (event->type() == QEvent::KeyRelease) - keyReleaseEvent(static_cast(event)); - if (event->type() == QEvent::Wheel) - wheelEvent(static_cast(event)); - - // Always pass the event on to GLWidget, i.e. to OSG event queue - return QObject::eventFilter(obj, event); -} - osg::Camera *RenderWidget::getCamera() { return mView->getCamera(); diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 07a7d7600..e759e78c4 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -46,8 +46,6 @@ namespace CSVRender void setVisibilityMask(int mask); - bool eventFilter(QObject *, QEvent *); - osg::Camera *getCamera(); protected: From f4f7afb53b6354591992ed479b4530c8f6b283cd Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Thu, 10 Mar 2016 03:20:15 -0500 Subject: [PATCH 03/41] Removed now unnecessary installation of event filter. --- apps/opencs/view/render/scenewidget.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 21a4c56a4..504f5cc25 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -57,9 +57,6 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) layout->addWidget(window->getGLWidget()); setLayout(layout); - // Pass events through this widget first - window->getGLWidget()->installEventFilter(this); - mView->getCamera()->setGraphicsContext(window); mView->getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) ); mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); From 9afb0e0f9001c17ce0386a5c9dd35d1cd673f294 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Thu, 10 Mar 2016 04:29:24 -0500 Subject: [PATCH 04/41] Input restructuring. --- apps/opencs/view/render/scenewidget.cpp | 96 ++++++++- apps/opencs/view/render/scenewidget.hpp | 24 ++- apps/opencs/view/render/worldspacewidget.cpp | 198 ++++++++----------- apps/opencs/view/render/worldspacewidget.hpp | 16 +- 4 files changed, 206 insertions(+), 128 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 504f5cc25..ff6ae2551 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -18,6 +18,8 @@ #include "../widget/scenetoolmode.hpp" +#include "../../model/prefs/state.hpp" + #include "lighting.hpp" #include "mask.hpp" @@ -143,7 +145,8 @@ void CompositeViewer::update() // --------------------------------------------------- -SceneWidget::SceneWidget(boost::shared_ptr resourceSystem, QWidget *parent, Qt::WindowFlags f) +SceneWidget::SceneWidget(boost::shared_ptr resourceSystem, QWidget *parent, Qt::WindowFlags f, + bool retrieveInput) : RenderWidget(parent, f) , mResourceSystem(resourceSystem) , mLighting(NULL) @@ -159,6 +162,16 @@ SceneWidget::SceneWidget(boost::shared_ptr resourceSys /// \todo make shortcut configurable QShortcut *focusToolbar = new QShortcut (Qt::Key_T, this, 0, 0, Qt::WidgetWithChildrenShortcut); connect (focusToolbar, SIGNAL (activated()), this, SIGNAL (focusToolbarRequest())); + + connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)), + this, SLOT (settingChanged (const CSMPrefs::Setting *))); + + // TODO update this outside of the constructor where virtual methods can be used + if (retrieveInput) + { + CSMPrefs::get()["3D Scene Input"].update(); + CSMPrefs::get()["Tooltips"].update(); + } } SceneWidget::~SceneWidget() @@ -238,4 +251,85 @@ void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour) setAmbient(mLighting->getAmbientColour(&mDefaultAmbient)); } +void SceneWidget::mousePressEvent (QMouseEvent *event) +{ + std::string button = mapButton(event); + + // TODO placeholders + if (button == "p-navi") + { + } + else if (button == "s-navi") + { + } +} + +void SceneWidget::mouseReleaseEvent (QMouseEvent *event) +{ + std::string button = mapButton(event); + + // TODO placeholders + if (button == "p-navi") + { + } + else if (button == "s-navi") + { + } +} + +void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) +{ + storeMappingSetting(setting); +} + +bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting) +{ + if (setting->getParent()->getKey()!="3D Scene Input") + return false; + + static const char * const sMappingSettings[] = + { + "p-navi", "s-navi", + 0 + }; + + for (int i=0; sMappingSettings[i]; ++i) + if (setting->getKey()==sMappingSettings[i]) + { + QString value = QString::fromUtf8 (setting->toString().c_str()); + + Qt::MouseButton button = Qt::NoButton; + + if (value.endsWith ("Left Mouse-Button")) + button = Qt::LeftButton; + else if (value.endsWith ("Right Mouse-Button")) + button = Qt::RightButton; + else if (value.endsWith ("Middle Mouse-Button")) + button = Qt::MiddleButton; + else + return false; + + bool ctrl = value.startsWith ("Ctrl-"); + + mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i]; + return true; + } + + return false; +} + +std::string SceneWidget::mapButton (QMouseEvent *event) +{ + std::pair phyiscal ( + event->button(), event->modifiers() & Qt::ControlModifier); + + std::map, std::string>::const_iterator iter = + mButtonMapping.find (phyiscal); + + if (iter!=mButtonMapping.end()) + return iter->second; + + return ""; +} + } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index e759e78c4..8d17fb8a5 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -1,6 +1,8 @@ #ifndef OPENCS_VIEW_SCENEWIDGET_H #define OPENCS_VIEW_SCENEWIDGET_H +#include + #include #include @@ -30,6 +32,11 @@ namespace CSVWidget class SceneToolbar; } +namespace CSMPrefs +{ + class Setting; +} + namespace CSVRender { class Lighting; @@ -62,7 +69,8 @@ namespace CSVRender { Q_OBJECT public: - SceneWidget(boost::shared_ptr resourceSystem, QWidget* parent = 0, Qt::WindowFlags f = 0); + SceneWidget(boost::shared_ptr resourceSystem, QWidget* parent = 0, + Qt::WindowFlags f = 0, bool retrieveInput = true); virtual ~SceneWidget(); CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent); @@ -78,6 +86,14 @@ namespace CSVRender void setAmbient(const osg::Vec4f& ambient); + virtual void mousePressEvent (QMouseEvent *event); + virtual void mouseReleaseEvent (QMouseEvent *event); + + /// \return Is \a key a button mapping setting? (ignored otherwise) + virtual bool storeMappingSetting (const CSMPrefs::Setting *setting); + + std::string mapButton (QMouseEvent *event); + boost::shared_ptr mResourceSystem; Lighting* mLighting; @@ -88,6 +104,12 @@ namespace CSVRender LightingNight mLightingNight; LightingBright mLightingBright; + std::map, std::string> mButtonMapping; + + protected slots: + + virtual void settingChanged (const CSMPrefs::Setting *setting); + private slots: void selectLightingMode (const std::string& mode); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index df5790473..70aaf7e85 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -32,7 +32,7 @@ #include "instancemode.hpp" CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) -: SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document), +: SceneWidget (document.getData().getResourceSystem(), parent, 0, false), mSceneElements(0), mRun(0), mDocument(document), mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mDragX(0), mDragY(0), mDragFactor(0), mDragWheelFactor(0), mDragShiftFactor(0), mToolTipPos (-1, -1), mShowToolTips(false), mToolTipDelay(0) @@ -67,13 +67,11 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int))); - connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)), - this, SLOT (settingChanged (const CSMPrefs::Setting *))); - CSMPrefs::get()["3D Scene Input"].update(); - CSMPrefs::get()["Tooltips"].update(); - mToolTipDelayTimer.setSingleShot (true); connect (&mToolTipDelayTimer, SIGNAL (timeout()), this, SLOT (showToolTip())); + + CSMPrefs::get()["3D Scene Input"].update(); + CSMPrefs::get()["Tooltips"].update(); } CSVRender::WorldspaceWidget::~WorldspaceWidget () @@ -82,9 +80,6 @@ CSVRender::WorldspaceWidget::~WorldspaceWidget () void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setting) { - if (storeMappingSetting (setting)) - return; - if (*setting=="3D Scene Input/drag-factor") mDragFactor = setting->toDouble(); else if (*setting=="3D Scene Input/drag-wheel-factor") @@ -95,6 +90,8 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti mToolTipDelay = setting->toInt(); else if (*setting=="Tooltips/scene") mShowToolTips = setting->isTrue(); + else + SceneWidget::settingChanged(setting); } void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) @@ -418,40 +415,41 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event) bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *setting) { - if (setting->getParent()->getKey()!="3D Scene Input") - return false; - static const char * const sMappingSettings[] = { - "p-navi", "s-navi", "p-edit", "s-edit", "p-select", "s-select", 0 }; - for (int i=0; sMappingSettings[i]; ++i) - if (setting->getKey()==sMappingSettings[i]) + if (setting->getParent()->getKey()=="3D Scene Input") + { + for (int i=0; sMappingSettings[i]; ++i) { - QString value = QString::fromUtf8 (setting->toString().c_str()); + if (setting->getKey()==sMappingSettings[i]) + { + QString value = QString::fromUtf8 (setting->toString().c_str()); - Qt::MouseButton button = Qt::NoButton; + Qt::MouseButton button = Qt::NoButton; - if (value.endsWith ("Left Mouse-Button")) - button = Qt::LeftButton; - else if (value.endsWith ("Right Mouse-Button")) - button = Qt::RightButton; - else if (value.endsWith ("Middle Mouse-Button")) - button = Qt::MiddleButton; - else - return false; + if (value.endsWith ("Left Mouse-Button")) + button = Qt::LeftButton; + else if (value.endsWith ("Right Mouse-Button")) + button = Qt::RightButton; + else if (value.endsWith ("Middle Mouse-Button")) + button = Qt::MiddleButton; + else + return false; - bool ctrl = value.startsWith ("Ctrl-"); + bool ctrl = value.startsWith ("Ctrl-"); - mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i]; - return true; + mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i]; + return true; + } } + } - return false; + return SceneWidget::storeMappingSetting(setting); } osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos) @@ -496,20 +494,6 @@ osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (const Q return osg::ref_ptr(); } -std::string CSVRender::WorldspaceWidget::mapButton (QMouseEvent *event) -{ - std::pair phyiscal ( - event->button(), event->modifiers() & Qt::ControlModifier); - - std::map, std::string>::const_iterator iter = - mButtonMapping.find (phyiscal); - - if (iter!=mButtonMapping.end()) - return iter->second; - - return ""; -} - void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) { const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); @@ -615,50 +599,7 @@ void CSVRender::WorldspaceWidget::updateOverlay() void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) { - if (!mDragging) - { - if (mDragMode.empty()) - { - if (event->globalPos()!=mToolTipPos) - { - mToolTipPos = event->globalPos(); - - if (mShowToolTips) - mToolTipDelayTimer.start (mToolTipDelay); - } - } - else if (mDragMode=="p-navi" || mDragMode=="s-navi") - { - - } - else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select") - { - osg::ref_ptr tag = mousePick (event->pos()); - - EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); - - if (mDragMode=="p-edit") - mDragging = editMode.primaryEditStartDrag (tag); - else if (mDragMode=="s-edit") - mDragging = editMode.secondaryEditStartDrag (tag); - else if (mDragMode=="p-select") - mDragging = editMode.primarySelectStartDrag (tag); - else if (mDragMode=="s-select") - mDragging = editMode.secondarySelectStartDrag (tag); - - if (mDragging) - { -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) - mDragX = event->localPos().x(); - mDragY = height() - event->localPos().y(); -#else - mDragX = event->posF().x(); - mDragY = height() - event->posF().y(); -#endif - } - } - } - else + if (mDragging) { int diffX = event->x() - mDragX; int diffY = (height() - event->y()) - mDragY; @@ -675,59 +616,84 @@ void CSVRender::WorldspaceWidget::mouseMoveEvent (QMouseEvent *event) editMode.drag (diffX, diffY, factor); } + else if (mDragMode=="p-edit" || mDragMode=="s-edit" || mDragMode=="p-select" || mDragMode=="s-select") + { + osg::ref_ptr tag = mousePick (event->pos()); + + EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); + + if (mDragMode=="p-edit") + mDragging = editMode.primaryEditStartDrag (tag); + else if (mDragMode=="s-edit") + mDragging = editMode.secondaryEditStartDrag (tag); + else if (mDragMode=="p-select") + mDragging = editMode.primarySelectStartDrag (tag); + else if (mDragMode=="s-select") + mDragging = editMode.secondarySelectStartDrag (tag); + + if (mDragging) + { +#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) + mDragX = event->localPos().x(); + mDragY = height() - event->localPos().y(); +#else + mDragX = event->posF().x(); + mDragY = height() - event->posF().y(); +#endif + } + } + else + { + if (event->globalPos()!=mToolTipPos) + { + mToolTipPos = event->globalPos(); + + if (mShowToolTips) + mToolTipDelayTimer.start (mToolTipDelay); + } + + SceneWidget::mouseMoveEvent(event); + } } void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) { std::string button = mapButton (event); - if (!mDragging) - mDragMode = button; + if (button=="p-edit" || button=="s-edit" || + button=="p-select" || button=="s-select") + { + if (!mDragging) + mDragMode = button; + } + else + SceneWidget::mousePressEvent(event); } void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) { std::string button = mapButton (event); + mDragMode.clear(); - if (mDragging) + if (button=="p-edit" || button=="s-edit" || + button=="p-select" || button=="s-select") { - if (mDragMode=="p-navi" || mDragMode=="s-navi") - { - - } - else if (mDragMode=="p-edit" || mDragMode=="s-edit" || - mDragMode=="p-select" || mDragMode=="s-select") + if (mDragging) { EditMode& editMode = dynamic_cast (*mEditMode->getCurrent()); editMode.dragCompleted(); mDragging = false; } - } - else - { - if (button=="p-navi" || button=="s-navi") - { - - } - else if (button=="p-edit" || button=="s-edit" || - button=="p-select" || button=="s-select") + else { osg::ref_ptr tag = mousePick (event->pos()); handleMouseClick (tag, button, event->modifiers() & Qt::ShiftModifier); } } - - mDragMode.clear(); -} - -void CSVRender::WorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event) -{ - if(event->button() == Qt::RightButton) - { - //mMouse->mouseDoubleClickEvent(event); - } + else + SceneWidget::mouseReleaseEvent(event); } void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) @@ -743,6 +709,8 @@ void CSVRender::WorldspaceWidget::wheelEvent (QWheelEvent *event) editMode.dragWheel (event->delta(), factor); } + else + SceneWidget::wheelEvent(event); } void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 4c9c0c31e..87f22581c 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -1,8 +1,6 @@ #ifndef OPENCS_VIEW_WORLDSPACEWIDGET_H #define OPENCS_VIEW_WORLDSPACEWIDGET_H -#include - #include #include @@ -45,7 +43,6 @@ namespace CSVRender CSVWidget::SceneToolRun *mRun; CSMDoc::Document& mDocument; unsigned int mInteractionMask; - std::map, std::string> mButtonMapping; CSVWidget::SceneToolMode *mEditMode; bool mLocked; std::string mDragMode; @@ -189,13 +186,17 @@ namespace CSVRender virtual void mouseMoveEvent (QMouseEvent *event); virtual void mousePressEvent (QMouseEvent *event); virtual void mouseReleaseEvent (QMouseEvent *event); - virtual void mouseDoubleClickEvent (QMouseEvent *event); virtual void wheelEvent (QWheelEvent *event); virtual void keyPressEvent (QKeyEvent *event); virtual void handleMouseClick (osg::ref_ptr tag, const std::string& button, bool shift); + /// \return Is \a key a button mapping setting? (ignored otherwise) + virtual bool storeMappingSetting (const CSMPrefs::Setting *setting); + + virtual void settingChanged (const CSMPrefs::Setting *setting); + EditMode *getEditMode(); private: @@ -206,19 +207,12 @@ namespace CSVRender void dragMoveEvent(QDragMoveEvent *event); - /// \return Is \a key a button mapping setting? (ignored otherwise) - bool storeMappingSetting (const CSMPrefs::Setting *setting); - osg::ref_ptr mousePick (const QPoint& localPos); - std::string mapButton (QMouseEvent *event); - virtual std::string getStartupInstruction() = 0; private slots: - void settingChanged (const CSMPrefs::Setting *setting); - void selectNavigationMode (const std::string& mode); virtual void referenceableDataChanged (const QModelIndex& topLeft, From ebdc21288648b8a2176e4328f0b9e1a8856bd136 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Thu, 10 Mar 2016 16:56:14 -0500 Subject: [PATCH 05/41] Moved selectNavigationMode to SceneWidget class, centralized camera selection. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 4 +--- apps/opencs/view/render/previewwidget.cpp | 4 +--- apps/opencs/view/render/scenewidget.cpp | 15 +++++++++++++++ apps/opencs/view/render/scenewidget.hpp | 2 ++ .../view/render/unpagedworldspacewidget.cpp | 2 +- apps/opencs/view/render/worldspacewidget.cpp | 14 +------------- apps/opencs/view/render/worldspacewidget.hpp | 2 -- 7 files changed, 21 insertions(+), 22 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index d96f36692..c0861d351 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -6,8 +6,6 @@ #include #include -#include - #include #include "../../model/world/tablemimedata.hpp" @@ -117,7 +115,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() /// \todo do not overwrite manipulator object /// \todo move code to useViewHint function if (modified && wasEmpty) - mView->setCameraManipulator(new osgGA::TrackballManipulator); + selectNavigationMode("trackball"); return modified; } diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index a03b277d3..7b3645135 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -1,7 +1,5 @@ #include "previewwidget.hpp" -#include - #include "../../model/world/data.hpp" #include "../../model/world/idtable.hpp" @@ -9,7 +7,7 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget *parent) : SceneWidget (data.getResourceSystem(), parent), mData (data), mObject(data, mRootNode, id, referenceable) { - mView->setCameraManipulator(new osgGA::TrackballManipulator); + selectNavigationMode("trackball"); QAbstractItemModel *referenceables = mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index ff6ae2551..6115a9bc3 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -12,6 +12,9 @@ #include #include +#include +#include + #include #include #include @@ -282,6 +285,18 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) storeMappingSetting(setting); } +void SceneWidget::selectNavigationMode (const std::string& mode) +{ + if (mode=="1st") + mView->setCameraManipulator(new osgGA::FirstPersonManipulator); + else if (mode=="free") + mView->setCameraManipulator(new osgGA::FirstPersonManipulator); + else if (mode=="orbit") + mView->setCameraManipulator(new osgGA::OrbitManipulator); + else if (mode=="trackball") + mView->setCameraManipulator(new osgGA::TrackballManipulator); +} + bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting) { if (setting->getParent()->getKey()!="3D Scene Input") diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 8d17fb8a5..6870c06ab 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -110,6 +110,8 @@ namespace CSVRender virtual void settingChanged (const CSMPrefs::Setting *setting); + void selectNavigationMode (const std::string& mode); + private slots: void selectLightingMode (const std::string& mode); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 16c28cf93..9c2557438 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -51,7 +51,7 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& mCell.reset (new Cell (document.getData(), mRootNode, mCellId)); - mView->setCameraManipulator(new osgGA::TrackballManipulator); + selectNavigationMode("trackball"); } void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 70aaf7e85..14253537d 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -12,9 +12,6 @@ #include #include -#include -#include - #include #include "../../model/world/universalid.hpp" @@ -94,21 +91,12 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti SceneWidget::settingChanged(setting); } -void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) -{ - if (mode=="1st") - mView->setCameraManipulator(new osgGA::FirstPersonManipulator); - else if (mode=="free") - mView->setCameraManipulator(new osgGA::FirstPersonManipulator); - else if (mode=="orbit") - mView->setCameraManipulator(new osgGA::OrbitManipulator); -} void CSVRender::WorldspaceWidget::useViewHint (const std::string& hint) {} void CSVRender::WorldspaceWidget::selectDefaultNavigationMode() { - mView->setCameraManipulator(new osgGA::FirstPersonManipulator); + selectNavigationMode("1st"); } CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 87f22581c..36aae0329 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -213,8 +213,6 @@ namespace CSVRender private slots: - void selectNavigationMode (const std::string& mode); - virtual void referenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) = 0; From 9ed2cf6581f157279d73d19594879675d13b5223 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sun, 13 Mar 2016 23:51:44 -0400 Subject: [PATCH 06/41] Fix callback being skipped --- apps/opencs/view/render/worldspacewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 14253537d..3cd2c4093 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -708,7 +708,7 @@ void CSVRender::WorldspaceWidget::keyPressEvent (QKeyEvent *event) abortDrag(); } else - RenderWidget::keyPressEvent(event); + SceneWidget::keyPressEvent(event); } void CSVRender::WorldspaceWidget::handleMouseClick (osg::ref_ptr tag, const std::string& button, bool shift) From 2cff2cd643b7bb15c5a05a369b5608bc5f573324 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sun, 13 Mar 2016 23:55:10 -0400 Subject: [PATCH 07/41] Remove unnecessary override. --- apps/opencs/view/render/pagedworldspacewidget.cpp | 5 ----- apps/opencs/view/render/unpagedworldspacewidget.cpp | 2 -- 2 files changed, 7 deletions(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index c0861d351..63437cb2c 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -112,11 +112,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() } } - /// \todo do not overwrite manipulator object - /// \todo move code to useViewHint function - if (modified && wasEmpty) - selectNavigationMode("trackball"); - return modified; } diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 9c2557438..4ed71ac96 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -50,8 +50,6 @@ CSVRender::UnpagedWorldspaceWidget::UnpagedWorldspaceWidget (const std::string& update(); mCell.reset (new Cell (document.getData(), mRootNode, mCellId)); - - selectNavigationMode("trackball"); } void CSVRender::UnpagedWorldspaceWidget::cellDataChanged (const QModelIndex& topLeft, From 08fe914ba10d455d160270442e25d87ac0df82da Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 14 Mar 2016 00:04:11 -0400 Subject: [PATCH 08/41] Preliminary editor camera --- apps/opencs/CMakeLists.txt | 4 +- apps/opencs/view/render/cameracontroller.cpp | 458 +++++++++++++++++++ apps/opencs/view/render/cameracontroller.hpp | 121 +++++ apps/opencs/view/render/scenewidget.cpp | 89 +++- apps/opencs/view/render/scenewidget.hpp | 20 + 5 files changed, 669 insertions(+), 23 deletions(-) create mode 100644 apps/opencs/view/render/cameracontroller.cpp create mode 100644 apps/opencs/view/render/cameracontroller.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index ec4737d16..79876224d 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -89,8 +89,8 @@ opencs_units (view/render ) opencs_units_noqt (view/render - lighting lightingday lightingnight - lightingbright object cell terrainstorage tagbase cellarrow cellmarker cellborder + lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase + cellarrow cellmarker cellborder cameracontroller ) opencs_hdrs_noqt (view/render diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp new file mode 100644 index 000000000..fa2ad8560 --- /dev/null +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -0,0 +1,458 @@ +#include "cameracontroller.hpp" + +#include + +#include +#include +#include + +namespace CSVRender +{ + + /* + Camera Controller + */ + + const osg::Vec3d CameraController::LocalUp = osg::Vec3d(0, 1, 0); + const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0); + const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1); + + const double CameraController::LinearSpeed = 1000; + const double CameraController::RotationalSpeed = osg::PI / 2.f; + const double CameraController::SpeedMultiplier = 8; + + CameraController::CameraController() + : mActive(false) + , mModified(false) + , mMouseScalar(-1/350.f) + , mCamera(NULL) + { + } + + CameraController::~CameraController() + { + } + + bool CameraController::isActive() const + { + return mActive; + } + + bool CameraController::isModified() const + { + return mModified; + } + + osg::Camera* CameraController::getCamera() const + { + return mCamera; + } + + double CameraController::getMouseScalar() const + { + return mMouseScalar; + } + + void CameraController::setCamera(osg::Camera* camera) + { + mCamera = camera; + mActive = (mCamera != NULL); + + if (mActive) + onActivate(); + } + + void CameraController::setMouseScalar(double value) + { + mMouseScalar = value; + } + + void CameraController::setModified() + { + mModified = true; + } + + void CameraController::resetModified() + { + mModified = false; + } + + /* + Free Camera Controller + */ + + FreeCameraController::FreeCameraController() + : mLockUpright(false) + , mFast(false) + , mLeft(false) + , mRight(false) + , mForward(false) + , mBackward(false) + , mRollLeft(false) + , mRollRight(false) + , mUp(LocalUp) + { + } + + void FreeCameraController::fixUpAxis(const osg::Vec3d& up) + { + mLockUpright = true; + mUp = up; + } + + void FreeCameraController::unfixUpAxis() + { + mLockUpright = false; + } + + bool FreeCameraController::handleKeyEvent(QKeyEvent* event, bool pressed) + { + if (!isActive()) + return false; + + if (event->key() == Qt::Key_Q) + { + mRollLeft = pressed; + setModified(); + } + else if (event->key() == Qt::Key_E) + { + mRollRight = pressed; + setModified(); + } + else if (event->key() == Qt::Key_A) + { + mLeft = pressed; + setModified(); + } + else if (event->key() == Qt::Key_D) + { + mRight = pressed; + setModified(); + } + else if (event->key() == Qt::Key_W) + { + mForward = pressed; + setModified(); + } + else if (event->key() == Qt::Key_S) + { + mBackward = pressed; + setModified(); + } + else if (event->key() == Qt::Key_Shift) + { + mFast = pressed; + setModified(); + } + else + { + return false; + } + + return true; + } + + bool FreeCameraController::handleMouseMoveEvent(std::string mode, int x, int y) + { + if (!isActive()) + return false; + + if (mode == "p-navi") + { + yaw(x * getMouseScalar()); + pitch(y * getMouseScalar()); + setModified(); + } + else if (mode == "s-navi") + { + translate(LocalLeft * x + LocalUp * -y); + setModified(); + } + else if (mode == "t-navi") + { + translate(LocalForward * x * (mFast ? SpeedMultiplier : 1)); + } + else + { + return false; + } + + return true; + } + + void FreeCameraController::update(double dt) + { + if (!isActive()) + return; + + double linDist = LinearSpeed * dt; + double rotDist = RotationalSpeed * dt; + + if (mFast) + linDist *= SpeedMultiplier; + + if (mLeft) + translate(LocalLeft * linDist); + if (mRight) + translate(LocalLeft * -linDist); + if (mForward) + translate(LocalForward * linDist); + if (mBackward) + translate(LocalForward * -linDist); + + if (!mLockUpright) + { + if (mRollLeft) + roll(-rotDist); + if (mRollRight) + roll(rotDist); + } + else if(isModified()) + { + stabilize(); + } + + // Normalize the matrix to counter drift + getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix()); + + resetModified(); + } + + void FreeCameraController::yaw(double value) + { + getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalUp); + } + + void FreeCameraController::pitch(double value) + { + getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalLeft); + } + + void FreeCameraController::roll(double value) + { + getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalForward); + } + + void FreeCameraController::translate(const osg::Vec3d& offset) + { + getCamera()->getViewMatrix() *= osg::Matrixd::translate(offset); + } + + void FreeCameraController::stabilize() + { + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); + getCamera()->setViewMatrixAsLookAt(eye, center, mUp); + } + + /* + Orbit Camera Controller + */ + + OrbitCameraController::OrbitCameraController() + : mInitialized(false) + , mFast(false) + , mLeft(false) + , mRight(false) + , mUp(false) + , mDown(false) + , mRollLeft(false) + , mRollRight(false) + , mCenter(0,0,0) + { + } + + bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed) + { + if (!isActive()) + return false; + + if (!mInitialized) + initialize(); + + if (event->key() == Qt::Key_Q) + { + mRollLeft = pressed; + setModified(); + } + else if (event->key() == Qt::Key_E) + { + mRollRight = pressed; + setModified(); + } + else if (event->key() == Qt::Key_A) + { + mLeft = pressed; + setModified(); + } + else if (event->key() == Qt::Key_D) + { + mRight = pressed; + setModified(); + } + else if (event->key() == Qt::Key_W) + { + mUp = pressed; + setModified(); + } + else if (event->key() == Qt::Key_S) + { + mDown = pressed; + setModified(); + } + else if (event->key() == Qt::Key_Shift) + { + mFast = pressed; + setModified(); + } + else + { + return false; + } + + return true; + } + + bool OrbitCameraController::handleMouseMoveEvent(std::string mode, int x, int y) + { + if (!isActive()) + return false; + + if (!mInitialized) + initialize(); + + if (mode == "p-navi") + { + rotateHorizontal(x * getMouseScalar()); + rotateVertical(y * getMouseScalar()); + setModified(); + } + else if (mode == "s-navi") + { + translate(LocalLeft * x + LocalUp * -y); + setModified(); + } + else if (mode == "t-navi") + { + zoom(x * (mFast ? SpeedMultiplier : 1)); + } + else + { + return false; + } + + return true; + } + + void OrbitCameraController::update(double dt) + { + if (!isActive()) + return; + + if (!mInitialized) + initialize(); + + double rotDist = RotationalSpeed * dt; + + if (mFast) + rotDist *= SpeedMultiplier; + + if (mLeft) + rotateHorizontal(-rotDist); + if (mRight) + rotateHorizontal(rotDist); + if (mUp) + rotateVertical(rotDist); + if (mDown) + rotateVertical(-rotDist); + + if (mRollLeft) + roll(-rotDist); + if (mRollRight) + roll(rotDist); + + lookAtCenter(); + + // Normalize the matrix to counter drift + getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix()); + + resetModified(); + } + + void OrbitCameraController::onActivate() + { + mInitialized = false; + } + + void OrbitCameraController::initialize() + { + static const int DefaultStartDistance = 10000.f; + + osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); + osg::Vec3d offset = rotation * (LocalForward * DefaultStartDistance); + + mCenter = position + offset; + + mInitialized = true; + } + + void OrbitCameraController::rotateHorizontal(double value) + { + osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); + osg::Vec3d offset = position - mCenter; + osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + + osg::Quat offsetRotation = osg::Quat(value, LocalUp); + osg::Vec3d newOffset = (rotation * offsetRotation) * (rotation.inverse() * offset); + + getCamera()->getViewMatrix().setTrans(mCenter + newOffset); + } + + void OrbitCameraController::rotateVertical(double value) + { + osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); + osg::Vec3d offset = position - mCenter; + osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + + osg::Quat offsetRotation = osg::Quat(value, LocalLeft); + osg::Vec3d newOffset = (rotation * offsetRotation) * (rotation.inverse() * offset); + + getCamera()->getViewMatrix().setTrans(mCenter + newOffset); + } + + void OrbitCameraController::roll(double value) + { + getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalForward); + } + + void OrbitCameraController::translate(const osg::Vec3d& offset) + { + mCenter += offset; + getCamera()->getViewMatrix() *= osg::Matrixd::translate(offset); + } + + void OrbitCameraController::zoom(double value) + { + osg::Vec3d dir = mCenter - getCamera()->getViewMatrix().getTrans(); + double distance = dir.normalize(); + + if (distance > 1 || value < 0) + { + getCamera()->getViewMatrix() *= osg::Matrixd::translate(dir * value); + } + } + + void OrbitCameraController::lookAtCenter() + { + osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); + osg::Vec3d offset = mCenter - position; + osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + + osg::Quat newRotation; + newRotation.makeRotate(LocalForward, offset); + + getCamera()->getViewMatrix().setRotate(newRotation); + } +} diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp new file mode 100644 index 000000000..e45e7bead --- /dev/null +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -0,0 +1,121 @@ +#ifndef OPENCS_VIEW_CAMERACONTROLLER_H +#define OPENCS_VIEW_CAMERACONTROLLER_H + +#include + +#include +#include + +class QKeyEvent; + +namespace osg +{ + class Camera; +} + +namespace CSVRender +{ + class CameraController + { + public: + + static const osg::Vec3d LocalUp; + static const osg::Vec3d LocalLeft; + static const osg::Vec3d LocalForward; + + static const double LinearSpeed; + static const double RotationalSpeed; + static const double SpeedMultiplier; + + CameraController(); + virtual ~CameraController(); + + bool isActive() const; + bool isModified() const; + + osg::Camera* getCamera() const; + double getMouseScalar() const; + + void setCamera(osg::Camera*); + void setMouseScalar(double value); + + virtual bool handleKeyEvent(QKeyEvent* event, bool pressed) = 0; + virtual bool handleMouseMoveEvent(std::string mode, int x, int y) = 0; + + virtual void update(double dt) = 0; + + protected: + + void setModified(); + void resetModified(); + + virtual void onActivate(){} + + private: + + bool mActive, mModified; + double mMouseScalar; + + osg::Camera* mCamera; + }; + + class FreeCameraController : public CameraController + { + public: + + FreeCameraController(); + + void fixUpAxis(const osg::Vec3d& up); + void unfixUpAxis(); + + bool handleKeyEvent(QKeyEvent* event, bool pressed); + bool handleMouseMoveEvent(std::string mode, int x, int y); + + void update(double dt); + + private: + + void yaw(double value); + void pitch(double value); + void roll(double value); + void translate(const osg::Vec3d& offset); + + void stabilize(); + + bool mLockUpright; + bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight; + osg::Vec3d mUp; + }; + + class OrbitCameraController : public CameraController + { + public: + + OrbitCameraController(); + + bool handleKeyEvent(QKeyEvent* event, bool pressed); + bool handleMouseMoveEvent(std::string mode, int x, int y); + + void update(double dt); + + private: + + void onActivate(); + + void initialize(); + + void rotateHorizontal(double value); + void rotateVertical(double value); + void roll(double value); + void translate(const osg::Vec3d& offset); + void zoom(double value); + + void lookAtCenter(); + + bool mInitialized; + bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; + osg::Vec3d mCenter; + }; +} + +#endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 6115a9bc3..c3b4b9a19 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -25,6 +25,7 @@ #include "lighting.hpp" #include "mask.hpp" +#include "cameracontroller.hpp" namespace CSVRender { @@ -141,8 +142,12 @@ CompositeViewer &CompositeViewer::get() void CompositeViewer::update() { - mSimulationTime += mFrameTimer.time_s(); + double dt = mFrameTimer.time_s(); mFrameTimer.setStartTick(); + + emit simulationUpdated(dt); + + mSimulationTime += dt; frame(mSimulationTime); } @@ -154,7 +159,14 @@ SceneWidget::SceneWidget(boost::shared_ptr resourceSys , mResourceSystem(resourceSystem) , mLighting(NULL) , mHasDefaultAmbient(false) + , mPrevMouseX(0) + , mPrevMouseY(0) + , mFreeCamControl(new FreeCameraController()) + , mOrbitCamControl(new OrbitCameraController()) + , mCurrentCamControl(mFreeCamControl.get()) { + selectNavigationMode("free"); + // we handle lighting manually mView->setLightingMode(osgViewer::View::NO_LIGHT); @@ -175,6 +187,8 @@ SceneWidget::SceneWidget(boost::shared_ptr resourceSys CSMPrefs::get()["3D Scene Input"].update(); CSMPrefs::get()["Tooltips"].update(); } + + connect (&CompositeViewer::get(), SIGNAL (simulationUpdated(double)), this, SLOT (update(double))); } SceneWidget::~SceneWidget() @@ -256,28 +270,43 @@ void SceneWidget::setDefaultAmbient (const osg::Vec4f& colour) void SceneWidget::mousePressEvent (QMouseEvent *event) { - std::string button = mapButton(event); + mMouseMode = mapButton(event); - // TODO placeholders - if (button == "p-navi") - { - } - else if (button == "s-navi") - { - } + mPrevMouseX = event->x(); + mPrevMouseY = event->y(); } void SceneWidget::mouseReleaseEvent (QMouseEvent *event) { - std::string button = mapButton(event); + mMouseMode = ""; +} + +void SceneWidget::mouseMoveEvent (QMouseEvent *event) +{ + mCurrentCamControl->handleMouseMoveEvent(mMouseMode, event->x() - mPrevMouseX, event->y() - mPrevMouseY); - // TODO placeholders - if (button == "p-navi") - { - } - else if (button == "s-navi") - { - } + mPrevMouseX = event->x(); + mPrevMouseY = event->y(); +} + +void SceneWidget::wheelEvent(QWheelEvent *event) +{ + mCurrentCamControl->handleMouseMoveEvent("t-navi", event->delta(), 0); +} + +void SceneWidget::keyPressEvent (QKeyEvent *event) +{ + mCurrentCamControl->handleKeyEvent(event, true); +} + +void SceneWidget::keyReleaseEvent (QKeyEvent *event) +{ + mCurrentCamControl->handleKeyEvent(event, false); +} + +void SceneWidget::update(double dt) +{ + mCurrentCamControl->update(dt); } void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) @@ -288,13 +317,31 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) void SceneWidget::selectNavigationMode (const std::string& mode) { if (mode=="1st") - mView->setCameraManipulator(new osgGA::FirstPersonManipulator); + { + mCurrentCamControl->setCamera(NULL); + mCurrentCamControl = mFreeCamControl.get(); + mCurrentCamControl->setCamera(getCamera()); + mFreeCamControl->fixUpAxis(osg::Vec3d(0,0,1)); + } else if (mode=="free") - mView->setCameraManipulator(new osgGA::FirstPersonManipulator); + { + mCurrentCamControl->setCamera(NULL); + mCurrentCamControl = mFreeCamControl.get(); + mCurrentCamControl->setCamera(getCamera()); + mFreeCamControl->unfixUpAxis(); + } else if (mode=="orbit") - mView->setCameraManipulator(new osgGA::OrbitManipulator); + { + mCurrentCamControl->setCamera(NULL); + mCurrentCamControl = mOrbitCamControl.get(); + mCurrentCamControl->setCamera(getCamera()); + } else if (mode=="trackball") - mView->setCameraManipulator(new osgGA::TrackballManipulator); + { + mCurrentCamControl->setCamera(NULL); + mCurrentCamControl = mOrbitCamControl.get(); + mCurrentCamControl->setCamera(getCamera()); + } } bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 6870c06ab..43f969aca 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -2,6 +2,7 @@ #define OPENCS_VIEW_SCENEWIDGET_H #include +#include #include #include @@ -39,6 +40,9 @@ namespace CSMPrefs namespace CSVRender { + class CameraController; + class FreeCameraController; + class OrbitCameraController; class Lighting; class RenderWidget : public QWidget @@ -88,6 +92,10 @@ namespace CSVRender virtual void mousePressEvent (QMouseEvent *event); virtual void mouseReleaseEvent (QMouseEvent *event); + virtual void mouseMoveEvent (QMouseEvent *event); + virtual void wheelEvent (QWheelEvent *event); + virtual void keyPressEvent (QKeyEvent *event); + virtual void keyReleaseEvent (QKeyEvent *event); /// \return Is \a key a button mapping setting? (ignored otherwise) virtual bool storeMappingSetting (const CSMPrefs::Setting *setting); @@ -104,8 +112,17 @@ namespace CSVRender LightingNight mLightingNight; LightingBright mLightingBright; + int mPrevMouseX, mPrevMouseY; + std::string mMouseMode; + std::auto_ptr mFreeCamControl; + std::auto_ptr mOrbitCamControl; + CameraController* mCurrentCamControl; + std::map, std::string> mButtonMapping; + public slots: + void update(double dt); + protected slots: virtual void settingChanged (const CSMPrefs::Setting *setting); @@ -139,6 +156,9 @@ namespace CSVRender public slots: void update(); + + signals: + void simulationUpdated(double dt); }; } From 59f59a33855c5ebd5767e98d24a02737cfdf3a44 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 14 Mar 2016 00:14:28 -0400 Subject: [PATCH 09/41] Fix indentation --- apps/opencs/view/render/scenewidget.hpp | 134 ++++++++++++------------ 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 43f969aca..7dcc74047 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -47,118 +47,118 @@ namespace CSVRender class RenderWidget : public QWidget { - Q_OBJECT + Q_OBJECT - public: - RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); - virtual ~RenderWidget(); + public: + RenderWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); + virtual ~RenderWidget(); - void flagAsModified(); + void flagAsModified(); - void setVisibilityMask(int mask); + void setVisibilityMask(int mask); - osg::Camera *getCamera(); + osg::Camera *getCamera(); - protected: + protected: - osg::ref_ptr mView; + osg::ref_ptr mView; - osg::Group* mRootNode; + osg::Group* mRootNode; - QTimer mTimer; + QTimer mTimer; }; // Extension of RenderWidget to support lighting mode selection & toolbar class SceneWidget : public RenderWidget { - Q_OBJECT - public: - SceneWidget(boost::shared_ptr resourceSystem, QWidget* parent = 0, - Qt::WindowFlags f = 0, bool retrieveInput = true); - virtual ~SceneWidget(); + Q_OBJECT + public: + SceneWidget(boost::shared_ptr resourceSystem, QWidget* parent = 0, + Qt::WindowFlags f = 0, bool retrieveInput = true); + virtual ~SceneWidget(); - CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent); - ///< \attention The created tool is not added to the toolbar (via addTool). Doing that - /// is the responsibility of the calling function. + CSVWidget::SceneToolMode *makeLightingSelector (CSVWidget::SceneToolbar *parent); + ///< \attention The created tool is not added to the toolbar (via addTool). Doing that + /// is the responsibility of the calling function. - void setDefaultAmbient (const osg::Vec4f& colour); - ///< \note The actual ambient colour may differ based on lighting settings. + void setDefaultAmbient (const osg::Vec4f& colour); + ///< \note The actual ambient colour may differ based on lighting settings. - protected: - void setLighting (Lighting *lighting); - ///< \attention The ownership of \a lighting is not transferred to *this. + protected: + void setLighting (Lighting *lighting); + ///< \attention The ownership of \a lighting is not transferred to *this. - void setAmbient(const osg::Vec4f& ambient); + void setAmbient(const osg::Vec4f& ambient); - virtual void mousePressEvent (QMouseEvent *event); - virtual void mouseReleaseEvent (QMouseEvent *event); - virtual void mouseMoveEvent (QMouseEvent *event); - virtual void wheelEvent (QWheelEvent *event); - virtual void keyPressEvent (QKeyEvent *event); - virtual void keyReleaseEvent (QKeyEvent *event); + virtual void mousePressEvent (QMouseEvent *event); + virtual void mouseReleaseEvent (QMouseEvent *event); + virtual void mouseMoveEvent (QMouseEvent *event); + virtual void wheelEvent (QWheelEvent *event); + virtual void keyPressEvent (QKeyEvent *event); + virtual void keyReleaseEvent (QKeyEvent *event); - /// \return Is \a key a button mapping setting? (ignored otherwise) - virtual bool storeMappingSetting (const CSMPrefs::Setting *setting); + /// \return Is \a key a button mapping setting? (ignored otherwise) + virtual bool storeMappingSetting (const CSMPrefs::Setting *setting); - std::string mapButton (QMouseEvent *event); + std::string mapButton (QMouseEvent *event); - boost::shared_ptr mResourceSystem; + boost::shared_ptr mResourceSystem; - Lighting* mLighting; + Lighting* mLighting; - osg::Vec4f mDefaultAmbient; - bool mHasDefaultAmbient; - LightingDay mLightingDay; - LightingNight mLightingNight; - LightingBright mLightingBright; + osg::Vec4f mDefaultAmbient; + bool mHasDefaultAmbient; + LightingDay mLightingDay; + LightingNight mLightingNight; + LightingBright mLightingBright; - int mPrevMouseX, mPrevMouseY; - std::string mMouseMode; - std::auto_ptr mFreeCamControl; - std::auto_ptr mOrbitCamControl; - CameraController* mCurrentCamControl; + int mPrevMouseX, mPrevMouseY; + std::string mMouseMode; + std::auto_ptr mFreeCamControl; + std::auto_ptr mOrbitCamControl; + CameraController* mCurrentCamControl; - std::map, std::string> mButtonMapping; + std::map, std::string> mButtonMapping; - public slots: - void update(double dt); + public slots: + void update(double dt); - protected slots: + protected slots: - virtual void settingChanged (const CSMPrefs::Setting *setting); + virtual void settingChanged (const CSMPrefs::Setting *setting); - void selectNavigationMode (const std::string& mode); + void selectNavigationMode (const std::string& mode); - private slots: + private slots: - void selectLightingMode (const std::string& mode); + void selectLightingMode (const std::string& mode); signals: - void focusToolbarRequest(); + void focusToolbarRequest(); }; // There are rendering glitches when using multiple Viewer instances, work around using CompositeViewer with multiple views class CompositeViewer : public QObject, public osgViewer::CompositeViewer { - Q_OBJECT - public: - CompositeViewer(); + Q_OBJECT + public: + CompositeViewer(); - static CompositeViewer& get(); + static CompositeViewer& get(); - QTimer mTimer; + QTimer mTimer; - private: - osg::Timer mFrameTimer; - double mSimulationTime; + private: + osg::Timer mFrameTimer; + double mSimulationTime; - public slots: - void update(); + public slots: + void update(); - signals: - void simulationUpdated(double dt); + signals: + void simulationUpdated(double dt); }; } From fcccacc0faace18b5a66239e22f066133c996776 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 13:57:48 -0400 Subject: [PATCH 10/41] Define a constant for the World Up vector --- apps/opencs/view/render/cameracontroller.cpp | 2 ++ apps/opencs/view/render/cameracontroller.hpp | 2 ++ apps/opencs/view/render/scenewidget.cpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index fa2ad8560..8fc9c4801 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -13,6 +13,8 @@ namespace CSVRender Camera Controller */ + const osg::Vec3d CameraController::WorldUp = osg::Vec3d(0, 0, 1); + const osg::Vec3d CameraController::LocalUp = osg::Vec3d(0, 1, 0); const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0); const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1); diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index e45e7bead..44e35069b 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -19,6 +19,8 @@ namespace CSVRender { public: + static const osg::Vec3d WorldUp; + static const osg::Vec3d LocalUp; static const osg::Vec3d LocalLeft; static const osg::Vec3d LocalForward; diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index c3b4b9a19..d7049c1b5 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -321,7 +321,7 @@ void SceneWidget::selectNavigationMode (const std::string& mode) mCurrentCamControl->setCamera(NULL); mCurrentCamControl = mFreeCamControl.get(); mCurrentCamControl->setCamera(getCamera()); - mFreeCamControl->fixUpAxis(osg::Vec3d(0,0,1)); + mFreeCamControl->fixUpAxis(CameraController::WorldUp); } else if (mode=="free") { From 999869da24b2937939850dcd575db9a894c0af35 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 14:02:24 -0400 Subject: [PATCH 11/41] Position camera above, near, and looking at the scene. --- apps/opencs/view/render/cameracontroller.cpp | 8 ++++++++ apps/opencs/view/render/cameracontroller.hpp | 4 ++++ apps/opencs/view/render/scenewidget.cpp | 19 ++++++++++++++++++- apps/opencs/view/render/scenewidget.hpp | 3 +++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 8fc9c4801..7f8f9013c 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -69,6 +69,14 @@ namespace CSVRender mMouseScalar = value; } + void CameraController::setSceneBounds(const osg::BoundingBox& bounds, const osg::Vec3d& up) + { + osg::Vec3d eye = osg::Vec3d(bounds.xMax(), bounds.yMax(), bounds.zMax()); + osg::Vec3d center = bounds.center(); + + getCamera()->setViewMatrixAsLookAt(eye, center, up); + } + void CameraController::setModified() { mModified = true; diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 44e35069b..156b1cb56 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -3,6 +3,7 @@ #include +#include #include #include @@ -41,6 +42,9 @@ namespace CSVRender void setCamera(osg::Camera*); void setMouseScalar(double value); + // moves the camera to an intelligent position + void setSceneBounds(const osg::BoundingBox& bounds, const osg::Vec3d& up); + virtual bool handleKeyEvent(QKeyEvent* event, bool pressed) = 0; virtual bool handleMouseMoveEvent(std::string mode, int x, int y) = 0; diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index d7049c1b5..ea282ffcd 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -164,6 +166,7 @@ SceneWidget::SceneWidget(boost::shared_ptr resourceSys , mFreeCamControl(new FreeCameraController()) , mOrbitCamControl(new OrbitCameraController()) , mCurrentCamControl(mFreeCamControl.get()) + , mCamPositionSet(false) { selectNavigationMode("free"); @@ -306,7 +309,21 @@ void SceneWidget::keyReleaseEvent (QKeyEvent *event) void SceneWidget::update(double dt) { - mCurrentCamControl->update(dt); + if (mCamPositionSet) + { + mCurrentCamControl->update(dt); + } + else + { + osg::ComputeBoundsVisitor boundsVisitor; + osg::BoundingBox &boundingBox(boundsVisitor.getBoundingBox()); + + mRootNode->accept(boundsVisitor); + + mCurrentCamControl->setSceneBounds(boundingBox, CameraController::WorldUp); + + mCamPositionSet = true; + } } void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 7dcc74047..dfda1f96c 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -120,6 +120,9 @@ namespace CSVRender std::map, std::string> mButtonMapping; + private: + bool mCamPositionSet; + public slots: void update(double dt); From 2b72a04e7a4171af65b4e33a340901b69dd91aa5 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 14:02:55 -0400 Subject: [PATCH 12/41] Update 1st person up axis ASAP. --- apps/opencs/view/render/cameracontroller.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 7f8f9013c..85301bb62 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -108,6 +108,7 @@ namespace CSVRender { mLockUpright = true; mUp = up; + setModified(); } void FreeCameraController::unfixUpAxis() From 4374f69a601d1168b8f7dfe9b1c254782388d56f Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 14:43:13 -0400 Subject: [PATCH 13/41] Reduce mouse sensitivity --- apps/opencs/view/render/cameracontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 85301bb62..f1ed5635b 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -26,7 +26,7 @@ namespace CSVRender CameraController::CameraController() : mActive(false) , mModified(false) - , mMouseScalar(-1/350.f) + , mMouseScalar(-1/700.f) , mCamera(NULL) { } From 7009355bafdd045f7a763341ada105f8096b7038 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 14:46:53 -0400 Subject: [PATCH 14/41] Remove unused variable --- apps/opencs/view/render/pagedworldspacewidget.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index 63437cb2c..8b20d22ba 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -21,7 +21,6 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() { bool modified = false; - bool wasEmpty = mCells.empty(); const CSMWorld::IdCollection& cells = mDocument.getData().getCells(); From 0e75b4a23488a32490d44f08abcbbed935f8f945 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 14:49:00 -0400 Subject: [PATCH 15/41] Remove warning about */ outside of comment --- extern/osgQt/GraphicsWindowQt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/osgQt/GraphicsWindowQt.cpp b/extern/osgQt/GraphicsWindowQt.cpp index 770ac9ada..46df7216c 100644 --- a/extern/osgQt/GraphicsWindowQt.cpp +++ b/extern/osgQt/GraphicsWindowQt.cpp @@ -708,7 +708,7 @@ void HeartBeat::init( osgViewer::ViewerBase *viewer ) } -void HeartBeat::timerEvent( QTimerEvent */*event*/ ) +void HeartBeat::timerEvent( QTimerEvent * /*event*/ ) { osg::ref_ptr< osgViewer::ViewerBase > viewer; if( !_viewer.lock( viewer ) ) From c8bae38a8e42bff2bfc522205ed1ba9bea6dc4ba Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 14:53:10 -0400 Subject: [PATCH 16/41] Remove trackball mode --- apps/opencs/view/render/previewwidget.cpp | 2 +- apps/opencs/view/render/scenewidget.cpp | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 7b3645135..2f3510317 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -7,7 +7,7 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& id, bool referenceable, QWidget *parent) : SceneWidget (data.getResourceSystem(), parent), mData (data), mObject(data, mRootNode, id, referenceable) { - selectNavigationMode("trackball"); + selectNavigationMode("orbit"); QAbstractItemModel *referenceables = mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index ea282ffcd..27c828ec4 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -353,12 +353,6 @@ void SceneWidget::selectNavigationMode (const std::string& mode) mCurrentCamControl = mOrbitCamControl.get(); mCurrentCamControl->setCamera(getCamera()); } - else if (mode=="trackball") - { - mCurrentCamControl->setCamera(NULL); - mCurrentCamControl = mOrbitCamControl.get(); - mCurrentCamControl->setCamera(getCamera()); - } } bool SceneWidget::storeMappingSetting (const CSMPrefs::Setting *setting) From 2c894acd98ed593c8433e29443f84035a2c74297 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 16:06:35 -0400 Subject: [PATCH 17/41] Create a visual representation of the center of the orbit camera. For debugging purposes. --- apps/opencs/view/render/cameracontroller.cpp | 24 +++++++++++++++++++- apps/opencs/view/render/cameracontroller.hpp | 7 +++++- apps/opencs/view/render/scenewidget.cpp | 2 +- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index f1ed5635b..74f72938f 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -3,8 +3,12 @@ #include #include +#include +#include #include #include +#include +#include namespace CSVRender { @@ -261,7 +265,7 @@ namespace CSVRender Orbit Camera Controller */ - OrbitCameraController::OrbitCameraController() + OrbitCameraController::OrbitCameraController(osg::Group* group) : mInitialized(false) , mFast(false) , mLeft(false) @@ -271,7 +275,10 @@ namespace CSVRender , mRollLeft(false) , mRollRight(false) , mCenter(0,0,0) + , mCenterNode(new osg::PositionAttitudeTransform()) { + group->addChild(mCenterNode); + createShape(); } bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed) @@ -383,6 +390,8 @@ namespace CSVRender if (mRollRight) roll(rotDist); + mCenterNode->setPosition(mCenter); + lookAtCenter(); // Normalize the matrix to counter drift @@ -409,6 +418,19 @@ namespace CSVRender mInitialized = true; } + void OrbitCameraController::createShape() + { + const float boxWidth = 100; + + osg::ref_ptr box = new osg::Box(osg::Vec3f(0, 0, 0), boxWidth); + osg::ref_ptr drawable = new osg::ShapeDrawable(box); + drawable->setColor(osg::Vec4f(0.f, 0.9f, 0.f, 1.f)); + + osg::ref_ptr geode = new osg::Geode(); + geode->addChild(drawable); + mCenterNode->addChild(geode); + } + void OrbitCameraController::rotateHorizontal(double value) { osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 156b1cb56..6c89d20f7 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -12,6 +13,7 @@ class QKeyEvent; namespace osg { class Camera; + class Group; } namespace CSVRender @@ -97,7 +99,7 @@ namespace CSVRender { public: - OrbitCameraController(); + OrbitCameraController(osg::Group* group); bool handleKeyEvent(QKeyEvent* event, bool pressed); bool handleMouseMoveEvent(std::string mode, int x, int y); @@ -109,6 +111,7 @@ namespace CSVRender void onActivate(); void initialize(); + void createShape(); void rotateHorizontal(double value); void rotateVertical(double value); @@ -121,6 +124,8 @@ namespace CSVRender bool mInitialized; bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; osg::Vec3d mCenter; + + osg::ref_ptr mCenterNode; }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 27c828ec4..dc0041c0f 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -164,7 +164,7 @@ SceneWidget::SceneWidget(boost::shared_ptr resourceSys , mPrevMouseX(0) , mPrevMouseY(0) , mFreeCamControl(new FreeCameraController()) - , mOrbitCamControl(new OrbitCameraController()) + , mOrbitCamControl(new OrbitCameraController(mRootNode)) , mCurrentCamControl(mFreeCamControl.get()) , mCamPositionSet(false) { From 2903271331b00051c153ad8bd8956dbe89e08b53 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 16:07:15 -0400 Subject: [PATCH 18/41] Correct the center position for the orbit camera controller --- apps/opencs/view/render/cameracontroller.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 74f72938f..c70f87565 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -409,11 +409,8 @@ namespace CSVRender { static const int DefaultStartDistance = 10000.f; - osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); - osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); - osg::Vec3d offset = rotation * (LocalForward * DefaultStartDistance); - - mCenter = position + offset; + osg::Vec3d eye, up; + getCamera()->getViewMatrixAsLookAt(eye, mCenter, up, DefaultStartDistance); mInitialized = true; } From 342d31de76eff1d9c2b0587df7df8a8aeb4cf1a1 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 16:56:40 -0400 Subject: [PATCH 19/41] More fixes to the orbit manipulator --- apps/opencs/view/render/cameracontroller.cpp | 55 ++++++++------------ apps/opencs/view/render/cameracontroller.hpp | 3 +- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index c70f87565..49e14bfa0 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -275,6 +275,7 @@ namespace CSVRender , mRollLeft(false) , mRollRight(false) , mCenter(0,0,0) + , mDistance(0) , mCenterNode(new osg::PositionAttitudeTransform()) { group->addChild(mCenterNode); @@ -343,7 +344,7 @@ namespace CSVRender if (mode == "p-navi") { rotateHorizontal(x * getMouseScalar()); - rotateVertical(y * getMouseScalar()); + rotateVertical(-y * getMouseScalar()); setModified(); } else if (mode == "s-navi") @@ -353,7 +354,7 @@ namespace CSVRender } else if (mode == "t-navi") { - zoom(x * (mFast ? SpeedMultiplier : 1)); + zoom(-x * (mFast ? SpeedMultiplier : 1)); } else { @@ -392,8 +393,6 @@ namespace CSVRender mCenterNode->setPosition(mCenter); - lookAtCenter(); - // Normalize the matrix to counter drift getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix()); @@ -412,6 +411,8 @@ namespace CSVRender osg::Vec3d eye, up; getCamera()->getViewMatrixAsLookAt(eye, mCenter, up, DefaultStartDistance); + mDistance = DefaultStartDistance; + mInitialized = true; } @@ -430,26 +431,27 @@ namespace CSVRender void OrbitCameraController::rotateHorizontal(double value) { - osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); - osg::Vec3d offset = position - mCenter; - osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Quat offsetRotation = osg::Quat(value, LocalUp); - osg::Vec3d newOffset = (rotation * offsetRotation) * (rotation.inverse() * offset); + osg::Quat rotation = osg::Quat(value, up); + osg::Vec3d oldOffset = eye - mCenter; + osg::Vec3d newOffset = rotation * oldOffset; - getCamera()->getViewMatrix().setTrans(mCenter + newOffset); + getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } void OrbitCameraController::rotateVertical(double value) { - osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); - osg::Vec3d offset = position - mCenter; - osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Quat offsetRotation = osg::Quat(value, LocalLeft); - osg::Vec3d newOffset = (rotation * offsetRotation) * (rotation.inverse() * offset); + osg::Vec3d forward = center - eye; + osg::Quat rotation = osg::Quat(value, up ^ forward); + osg::Vec3d oldOffset = eye - mCenter; + osg::Vec3d newOffset = rotation * oldOffset; - getCamera()->getViewMatrix().setTrans(mCenter + newOffset); + getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } void OrbitCameraController::roll(double value) @@ -465,24 +467,13 @@ namespace CSVRender void OrbitCameraController::zoom(double value) { - osg::Vec3d dir = mCenter - getCamera()->getViewMatrix().getTrans(); - double distance = dir.normalize(); + mDistance = std::max(10., mDistance + value); - if (distance > 1 || value < 0) - { - getCamera()->getViewMatrix() *= osg::Matrixd::translate(dir * value); - } - } - - void OrbitCameraController::lookAtCenter() - { - osg::Vec3d position = getCamera()->getViewMatrix().getTrans(); - osg::Vec3d offset = mCenter - position; - osg::Quat rotation = getCamera()->getViewMatrix().getRotate(); + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up, 1.f); - osg::Quat newRotation; - newRotation.makeRotate(LocalForward, offset); + osg::Vec3d offset = (eye - center) * mDistance; - getCamera()->getViewMatrix().setRotate(newRotation); + getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up); } } diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 6c89d20f7..78afe2320 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -119,11 +119,10 @@ namespace CSVRender void translate(const osg::Vec3d& offset); void zoom(double value); - void lookAtCenter(); - bool mInitialized; bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; osg::Vec3d mCenter; + double mDistance; osg::ref_ptr mCenterNode; }; From 3a676fc45648798ef4148c883c1524cdf221ffe4 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 18 Mar 2016 16:06:35 -0400 Subject: [PATCH 20/41] Revert "Create a visual representation of the center of the orbit camera." This reverts commit 2c894acd98ed593c8433e29443f84035a2c74297. # Conflicts: # apps/opencs/view/render/cameracontroller.cpp # apps/opencs/view/render/cameracontroller.hpp --- apps/opencs/view/render/cameracontroller.cpp | 24 +------------------- apps/opencs/view/render/cameracontroller.hpp | 7 +----- apps/opencs/view/render/scenewidget.cpp | 2 +- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 49e14bfa0..7e677b2db 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -3,12 +3,8 @@ #include #include -#include -#include #include #include -#include -#include namespace CSVRender { @@ -265,7 +261,7 @@ namespace CSVRender Orbit Camera Controller */ - OrbitCameraController::OrbitCameraController(osg::Group* group) + OrbitCameraController::OrbitCameraController() : mInitialized(false) , mFast(false) , mLeft(false) @@ -276,10 +272,7 @@ namespace CSVRender , mRollRight(false) , mCenter(0,0,0) , mDistance(0) - , mCenterNode(new osg::PositionAttitudeTransform()) { - group->addChild(mCenterNode); - createShape(); } bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed) @@ -391,8 +384,6 @@ namespace CSVRender if (mRollRight) roll(rotDist); - mCenterNode->setPosition(mCenter); - // Normalize the matrix to counter drift getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix()); @@ -416,19 +407,6 @@ namespace CSVRender mInitialized = true; } - void OrbitCameraController::createShape() - { - const float boxWidth = 100; - - osg::ref_ptr box = new osg::Box(osg::Vec3f(0, 0, 0), boxWidth); - osg::ref_ptr drawable = new osg::ShapeDrawable(box); - drawable->setColor(osg::Vec4f(0.f, 0.9f, 0.f, 1.f)); - - osg::ref_ptr geode = new osg::Geode(); - geode->addChild(drawable); - mCenterNode->addChild(geode); - } - void OrbitCameraController::rotateHorizontal(double value) { osg::Vec3d eye, center, up; diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 78afe2320..cced8a4c3 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -13,7 +12,6 @@ class QKeyEvent; namespace osg { class Camera; - class Group; } namespace CSVRender @@ -99,7 +97,7 @@ namespace CSVRender { public: - OrbitCameraController(osg::Group* group); + OrbitCameraController(); bool handleKeyEvent(QKeyEvent* event, bool pressed); bool handleMouseMoveEvent(std::string mode, int x, int y); @@ -111,7 +109,6 @@ namespace CSVRender void onActivate(); void initialize(); - void createShape(); void rotateHorizontal(double value); void rotateVertical(double value); @@ -123,8 +120,6 @@ namespace CSVRender bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; osg::Vec3d mCenter; double mDistance; - - osg::ref_ptr mCenterNode; }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index dc0041c0f..27c828ec4 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -164,7 +164,7 @@ SceneWidget::SceneWidget(boost::shared_ptr resourceSys , mPrevMouseX(0) , mPrevMouseY(0) , mFreeCamControl(new FreeCameraController()) - , mOrbitCamControl(new OrbitCameraController(mRootNode)) + , mOrbitCamControl(new OrbitCameraController()) , mCurrentCamControl(mFreeCamControl.get()) , mCamPositionSet(false) { From 3c83128abc5a211a2856fa9eb9b3dc2627d929ec Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 25 Mar 2016 20:47:18 -0400 Subject: [PATCH 21/41] Add more customization. --- apps/opencs/view/render/cameracontroller.cpp | 125 +++++++++++++++---- apps/opencs/view/render/cameracontroller.hpp | 37 ++++-- 2 files changed, 133 insertions(+), 29 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 7e677b2db..5941cfb1e 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -19,14 +19,12 @@ namespace CSVRender const osg::Vec3d CameraController::LocalLeft = osg::Vec3d(1, 0, 0); const osg::Vec3d CameraController::LocalForward = osg::Vec3d(0, 0, 1); - const double CameraController::LinearSpeed = 1000; - const double CameraController::RotationalSpeed = osg::PI / 2.f; - const double CameraController::SpeedMultiplier = 8; - CameraController::CameraController() : mActive(false) , mModified(false) - , mMouseScalar(-1/700.f) + , mCameraSensitivity(-1/700.f) + , mSecondaryMoveMult(50) + , mWheelMoveMult(8) , mCamera(NULL) { } @@ -50,9 +48,19 @@ namespace CSVRender return mCamera; } - double CameraController::getMouseScalar() const + double CameraController::getCameraSensitivity() const + { + return mCameraSensitivity; + } + + double CameraController::getSecondaryMovementMultiplier() const + { + return mSecondaryMoveMult; + } + + double CameraController::getWheelMovementMultiplier() const { - return mMouseScalar; + return mWheelMoveMult; } void CameraController::setCamera(osg::Camera* camera) @@ -64,9 +72,19 @@ namespace CSVRender onActivate(); } - void CameraController::setMouseScalar(double value) + void CameraController::setCameraSensitivity(double value) + { + mCameraSensitivity = value; + } + + void CameraController::setSecondaryMovementMultiplier(double value) { - mMouseScalar = value; + mSecondaryMoveMult = value; + } + + void CameraController::setWheelMovementMultiplier(double value) + { + mWheelMoveMult = value; } void CameraController::setSceneBounds(const osg::BoundingBox& bounds, const osg::Vec3d& up) @@ -101,7 +119,40 @@ namespace CSVRender , mRollLeft(false) , mRollRight(false) , mUp(LocalUp) + , mLinSpeed(1000) + , mRotSpeed(osg::PI / 2) + , mSpeedMult(8) + { + } + + double FreeCameraController::getLinearSpeed() const { + return mLinSpeed; + } + + double FreeCameraController::getRotationalSpeed() const + { + return mRotSpeed; + } + + double FreeCameraController::getSpeedMultiplier() const + { + return mSpeedMult; + } + + void FreeCameraController::setLinearSpeed(double value) + { + mLinSpeed = value; + } + + void FreeCameraController::setRotationalSpeed(double value) + { + mRotSpeed = value; + } + + void FreeCameraController::setSpeedMultiplier(double value) + { + mSpeedMult = value; } void FreeCameraController::fixUpAxis(const osg::Vec3d& up) @@ -171,18 +222,22 @@ namespace CSVRender if (mode == "p-navi") { - yaw(x * getMouseScalar()); - pitch(y * getMouseScalar()); + yaw(x * getCameraSensitivity()); + pitch(y * getCameraSensitivity()); setModified(); } else if (mode == "s-navi") { - translate(LocalLeft * x + LocalUp * -y); + osg::Vec3d movement; + movement += LocalLeft * -x * getSecondaryMovementMultiplier(); + movement += LocalUp * y * getSecondaryMovementMultiplier(); + + translate(movement); setModified(); } else if (mode == "t-navi") { - translate(LocalForward * x * (mFast ? SpeedMultiplier : 1)); + translate(LocalForward * x * (mFast ? getWheelMovementMultiplier() : 1)); } else { @@ -197,11 +252,11 @@ namespace CSVRender if (!isActive()) return; - double linDist = LinearSpeed * dt; - double rotDist = RotationalSpeed * dt; + double linDist = mLinSpeed * dt; + double rotDist = mRotSpeed * dt; if (mFast) - linDist *= SpeedMultiplier; + linDist *= mSpeedMult; if (mLeft) translate(LocalLeft * linDist); @@ -272,7 +327,29 @@ namespace CSVRender , mRollRight(false) , mCenter(0,0,0) , mDistance(0) + , mOrbitSpeed(osg::PI / 4) + , mOrbitSpeedMult(4) + { + } + + double OrbitCameraController::getOrbitSpeed() const + { + return mOrbitSpeed; + } + + double OrbitCameraController::getOrbitSpeedMultiplier() const { + return mOrbitSpeedMult; + } + + void OrbitCameraController::setOrbitSpeed(double value) + { + mOrbitSpeed = value; + } + + void OrbitCameraController::setOrbitSpeedMultiplier(double value) + { + mOrbitSpeedMult = value; } bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed) @@ -336,18 +413,22 @@ namespace CSVRender if (mode == "p-navi") { - rotateHorizontal(x * getMouseScalar()); - rotateVertical(-y * getMouseScalar()); + rotateHorizontal(x * getCameraSensitivity()); + rotateVertical(-y * getCameraSensitivity()); setModified(); } else if (mode == "s-navi") { - translate(LocalLeft * x + LocalUp * -y); + osg::Vec3d movement; + movement += LocalLeft * x * getSecondaryMovementMultiplier(); + movement += LocalUp * -y * getSecondaryMovementMultiplier(); + + translate(movement); setModified(); } else if (mode == "t-navi") { - zoom(-x * (mFast ? SpeedMultiplier : 1)); + zoom(-x * (mFast ? getWheelMovementMultiplier() : 1)); } else { @@ -365,10 +446,10 @@ namespace CSVRender if (!mInitialized) initialize(); - double rotDist = RotationalSpeed * dt; + double rotDist = mOrbitSpeed * dt; if (mFast) - rotDist *= SpeedMultiplier; + rotDist *= mOrbitSpeedMult; if (mLeft) rotateHorizontal(-rotDist); diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index cced8a4c3..97a5ef2b2 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -26,10 +26,6 @@ namespace CSVRender static const osg::Vec3d LocalLeft; static const osg::Vec3d LocalForward; - static const double LinearSpeed; - static const double RotationalSpeed; - static const double SpeedMultiplier; - CameraController(); virtual ~CameraController(); @@ -37,10 +33,14 @@ namespace CSVRender bool isModified() const; osg::Camera* getCamera() const; - double getMouseScalar() const; + double getCameraSensitivity() const; + double getSecondaryMovementMultiplier() const; + double getWheelMovementMultiplier() const; void setCamera(osg::Camera*); - void setMouseScalar(double value); + void setCameraSensitivity(double value); + void setSecondaryMovementMultiplier(double value); + void setWheelMovementMultiplier(double value); // moves the camera to an intelligent position void setSceneBounds(const osg::BoundingBox& bounds, const osg::Vec3d& up); @@ -60,7 +60,9 @@ namespace CSVRender private: bool mActive, mModified; - double mMouseScalar; + double mCameraSensitivity; + double mSecondaryMoveMult; + double mWheelMoveMult; osg::Camera* mCamera; }; @@ -71,6 +73,14 @@ namespace CSVRender FreeCameraController(); + double getLinearSpeed() const; + double getRotationalSpeed() const; + double getSpeedMultiplier() const; + + void setLinearSpeed(double value); + void setRotationalSpeed(double value); + void setSpeedMultiplier(double value); + void fixUpAxis(const osg::Vec3d& up); void unfixUpAxis(); @@ -91,6 +101,10 @@ namespace CSVRender bool mLockUpright; bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight; osg::Vec3d mUp; + + double mLinSpeed; + double mRotSpeed; + double mSpeedMult; }; class OrbitCameraController : public CameraController @@ -99,6 +113,12 @@ namespace CSVRender OrbitCameraController(); + double getOrbitSpeed() const; + double getOrbitSpeedMultiplier() const; + + void setOrbitSpeed(double value); + void setOrbitSpeedMultiplier(double value); + bool handleKeyEvent(QKeyEvent* event, bool pressed); bool handleMouseMoveEvent(std::string mode, int x, int y); @@ -120,6 +140,9 @@ namespace CSVRender bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; osg::Vec3d mCenter; double mDistance; + + double mOrbitSpeed; + double mOrbitSpeedMult; }; } From dede1718868be15c94fad52672c892000bcec9bb Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 25 Mar 2016 21:35:34 -0400 Subject: [PATCH 22/41] Fix the secondary navigation method for OrbitCameraController. --- apps/opencs/view/render/cameracontroller.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 5941cfb1e..518db2076 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -520,8 +520,14 @@ namespace CSVRender void OrbitCameraController::translate(const osg::Vec3d& offset) { - mCenter += offset; - getCamera()->getViewMatrix() *= osg::Matrixd::translate(offset); + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); + + osg::Vec3d newOffset = getCamera()->getViewMatrix().getRotate().inverse() * offset; + mCenter += newOffset; + eye += newOffset; + + getCamera()->setViewMatrixAsLookAt(eye, mCenter, up); } void OrbitCameraController::zoom(double value) From bee8977e45f23a135a44df0fc5ce7515562477cd Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 25 Mar 2016 22:19:44 -0400 Subject: [PATCH 23/41] Add camera control customization options. --- apps/opencs/model/prefs/state.cpp | 8 +++++ apps/opencs/view/render/scenewidget.cpp | 40 ++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 772047961..40c6d4781 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -172,6 +172,14 @@ void CSMPrefs::State::declare() inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle); declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons); declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons); + declareDouble ("p-navi-sensitivity", "Camera Sensitivity", -1/750.).setRange(-2.0, 2.0); + declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(1.0, 1000.0); + declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); + declareDouble ("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0); + declareDouble ("navi-free-rot-speed", "Free Camera Rotational Speed", 3.14 / 2).setRange(0.001, 6.28); + declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0); + declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28); + declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0); declareEnum ("p-edit", "Primary Editing Button", right).addValues (inputButtons); declareEnum ("s-edit", "Secondary Editing Button", cRight).addValues (inputButtons); declareEnum ("p-select", "Primary Selection Button", middle).addValues (inputButtons); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 27c828ec4..5c565cd2f 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -328,7 +328,45 @@ void SceneWidget::update(double dt) void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) { - storeMappingSetting(setting); + if (*setting=="3D Scene Input/p-navi-sensitivity") + { + mFreeCamControl->setCameraSensitivity(setting->toDouble()); + mOrbitCamControl->setCameraSensitivity(setting->toDouble()); + } + else if (*setting=="3D Scene Input/s-navi-sensitivity") + { + mFreeCamControl->setSecondaryMovementMultiplier(setting->toDouble()); + mOrbitCamControl->setSecondaryMovementMultiplier(setting->toDouble()); + } + else if (*setting=="3D Scene Input/navi-wheel-factor") + { + mFreeCamControl->setWheelMovementMultiplier(setting->toDouble()); + mOrbitCamControl->setWheelMovementMultiplier(setting->toDouble()); + } + else if (*setting=="3D Scene Input/navi-free-lin-speed") + { + mFreeCamControl->setLinearSpeed(setting->toDouble()); + } + else if (*setting=="3D Scene Input/navi-free-rot-speed") + { + mFreeCamControl->setRotationalSpeed(setting->toDouble()); + } + else if (*setting=="3D Scene Input/navi-free-speed-mult") + { + mFreeCamControl->setSpeedMultiplier(setting->toDouble()); + } + else if (*setting=="3D Scene Input/navi-orbit-rot-speed") + { + mOrbitCamControl->setOrbitSpeed(setting->toDouble()); + } + else if (*setting=="3D Scene Input/navi-orbit-speed-mult") + { + mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble()); + } + else + { + storeMappingSetting(setting); + } } void SceneWidget::selectNavigationMode (const std::string& mode) From a0fb242bf859ed7e5d1ca6893a62442a5143343f Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Fri, 25 Mar 2016 23:47:05 -0400 Subject: [PATCH 24/41] Slight improvement to camera placement. --- apps/opencs/view/render/cameracontroller.cpp | 28 ++++++++++++++++++++ apps/opencs/view/render/cameracontroller.hpp | 16 +++++++++++ apps/opencs/view/render/scenewidget.cpp | 3 +-- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 518db2076..bfdb00089 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -541,4 +542,31 @@ namespace CSVRender getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up); } + + CameraComputeBoundsVisitor::CameraComputeBoundsVisitor(unsigned int mask) + : mMask(mask) + { + } + + unsigned int CameraComputeBoundsVisitor::getMask() const + { + return mMask; + } + + void CameraComputeBoundsVisitor::setMask(unsigned int value) + { + mMask = value; + } + + void CameraComputeBoundsVisitor::apply(osg::Drawable& drawable) + { + if (drawable.getNodeMask() & mMask) + ComputeBoundsVisitor::apply(drawable); + } + + void CameraComputeBoundsVisitor::apply(osg::Transform& transform) + { + if (transform.getNodeMask() & mMask) + ComputeBoundsVisitor::apply(transform); + } } diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 97a5ef2b2..fefa3a422 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -144,6 +145,21 @@ namespace CSVRender double mOrbitSpeed; double mOrbitSpeedMult; }; + + class CameraComputeBoundsVisitor : public osg::ComputeBoundsVisitor + { + public: + CameraComputeBoundsVisitor(unsigned int mask); + + unsigned int getMask() const; + void setMask(unsigned int mask); + + void apply(osg::Drawable& drawable); + void apply(osg::Transform& transform); + + private: + unsigned int mMask; + }; } #endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5c565cd2f..fe8de40e7 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -315,7 +314,7 @@ void SceneWidget::update(double dt) } else { - osg::ComputeBoundsVisitor boundsVisitor; + CameraComputeBoundsVisitor boundsVisitor(Mask_Reference | Mask_Terrain); osg::BoundingBox &boundingBox(boundsVisitor.getBoundingBox()); mRootNode->accept(boundsVisitor); From fbe9177f5d86893a82ee1919fc653f1724b148ab Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 26 Mar 2016 00:51:19 -0400 Subject: [PATCH 25/41] Better center picking for the Orbit Camera. --- apps/opencs/view/render/cameracontroller.cpp | 30 ++++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index bfdb00089..8e990482c 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -7,6 +7,10 @@ #include #include +#include + +#include "mask.hpp" + namespace CSVRender { @@ -481,10 +485,30 @@ namespace CSVRender { static const int DefaultStartDistance = 10000.f; - osg::Vec3d eye, up; - getCamera()->getViewMatrixAsLookAt(eye, mCenter, up, DefaultStartDistance); + // Try to intelligently pick focus object + osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector( + osgUtil::Intersector::PROJECTION, osg::Vec3d(0, 0, 0), LocalForward)); + + intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); + osgUtil::IntersectionVisitor visitor(intersector); + + visitor.setTraversalMask(Mask_Reference | Mask_Terrain); + + getCamera()->accept(visitor); + + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up, DefaultStartDistance); - mDistance = DefaultStartDistance; + if (intersector->getIntersections().begin() != intersector->getIntersections().end()) + { + mCenter = intersector->getIntersections().begin()->getWorldIntersectPoint(); + mDistance = (eye - center).length(); + } + else + { + mCenter = center; + mDistance = DefaultStartDistance; + } mInitialized = true; } From 35ff4ec4b174fd049d2ecbdc59de3f58bb1aff93 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 26 Mar 2016 14:15:07 -0400 Subject: [PATCH 26/41] Normalize default camera controls so that is appears as if the camera is the object being moved. Also, allow mouse inversion for secondary movement. --- apps/opencs/model/prefs/state.cpp | 4 ++-- apps/opencs/view/render/cameracontroller.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 40c6d4781..2a4d9e8a0 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -172,8 +172,8 @@ void CSMPrefs::State::declare() inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle); declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons); declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons); - declareDouble ("p-navi-sensitivity", "Camera Sensitivity", -1/750.).setRange(-2.0, 2.0); - declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(1.0, 1000.0); + declareDouble ("p-navi-sensitivity", "Camera Sensitivity", 1/650.).setRange(-2.0, 2.0); + declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0); declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); declareDouble ("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0); declareDouble ("navi-free-rot-speed", "Free Camera Rotational Speed", 3.14 / 2).setRange(0.001, 6.28); diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 8e990482c..a07061a18 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -27,7 +27,7 @@ namespace CSVRender CameraController::CameraController() : mActive(false) , mModified(false) - , mCameraSensitivity(-1/700.f) + , mCameraSensitivity(1/650.f) , mSecondaryMoveMult(50) , mWheelMoveMult(8) , mCamera(NULL) From 08d055ca2309d0230ce3659682c7e98735a2497f Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 26 Mar 2016 14:35:03 -0400 Subject: [PATCH 27/41] Allow setting precision of double preferences. Also increase precision of camera sensitivity. --- apps/opencs/model/prefs/doublesetting.cpp | 9 ++++++++- apps/opencs/model/prefs/doublesetting.hpp | 3 +++ apps/opencs/model/prefs/state.cpp | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/prefs/doublesetting.cpp b/apps/opencs/model/prefs/doublesetting.cpp index 7c247777d..531196174 100644 --- a/apps/opencs/model/prefs/doublesetting.cpp +++ b/apps/opencs/model/prefs/doublesetting.cpp @@ -15,10 +15,16 @@ CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label, double default_) : Setting (parent, values, mutex, key, label), - mMin (0), mMax (std::numeric_limits::max()), + mPrecision(2), mMin (0), mMax (std::numeric_limits::max()), mDefault (default_) {} +CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setPrecision(int precision) +{ + mPrecision = precision; + return *this; +} + CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setRange (double min, double max) { mMin = min; @@ -49,6 +55,7 @@ std::pair CSMPrefs::DoubleSetting::makeWidgets (QWidget *p QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent); QDoubleSpinBox *widget = new QDoubleSpinBox (parent); + widget->setDecimals(mPrecision); widget->setRange (mMin, mMax); widget->setValue (mDefault); diff --git a/apps/opencs/model/prefs/doublesetting.hpp b/apps/opencs/model/prefs/doublesetting.hpp index 3868f014e..6fe6b772a 100644 --- a/apps/opencs/model/prefs/doublesetting.hpp +++ b/apps/opencs/model/prefs/doublesetting.hpp @@ -9,6 +9,7 @@ namespace CSMPrefs { Q_OBJECT + int mPrecision; double mMin; double mMax; std::string mTooltip; @@ -21,6 +22,8 @@ namespace CSMPrefs double default_); // defaults to [0, std::numeric_limits::max()] + DoubleSetting& setPrecision (int precision); + DoubleSetting& setRange (double min, double max); DoubleSetting& setMin (double min); diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 2a4d9e8a0..fd6c7b6ed 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -172,7 +172,7 @@ void CSMPrefs::State::declare() inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle); declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons); declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons); - declareDouble ("p-navi-sensitivity", "Camera Sensitivity", 1/650.).setRange(-2.0, 2.0); + declareDouble ("p-navi-sensitivity", "Camera Sensitivity", 1/650.).setPrecision(4).setRange(-2.0, 2.0); declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0); declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); declareDouble ("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0); From 09bce73c33c0c7da6235a4d7594b95cfe67489df Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 26 Mar 2016 14:42:33 -0400 Subject: [PATCH 28/41] Fix starting distance not being correctly set. --- apps/opencs/view/render/cameracontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index a07061a18..bfff16154 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -502,7 +502,7 @@ namespace CSVRender if (intersector->getIntersections().begin() != intersector->getIntersections().end()) { mCenter = intersector->getIntersections().begin()->getWorldIntersectPoint(); - mDistance = (eye - center).length(); + mDistance = (eye - mCenter).length(); } else { From 7d9dddfa38112bfb6c4ec35bec45e1a70af209a2 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Thu, 31 Mar 2016 23:34:47 -0400 Subject: [PATCH 29/41] Place camera farther away, improves preview camera placement. --- apps/opencs/view/render/cameracontroller.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index bfff16154..d3e1fa53b 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -94,7 +94,13 @@ namespace CSVRender void CameraController::setSceneBounds(const osg::BoundingBox& bounds, const osg::Vec3d& up) { - osg::Vec3d eye = osg::Vec3d(bounds.xMax(), bounds.yMax(), bounds.zMax()); + osg::Vec3d minBounds = bounds.corner(0) - bounds.center(); + osg::Vec3d maxBounds = bounds.corner(7) - bounds.center(); + + osg::Vec3d camOffset = up * maxBounds > 0 ? maxBounds : minBounds; + camOffset *= 2; + + osg::Vec3d eye = camOffset + bounds.center(); osg::Vec3d center = bounds.center(); getCamera()->setViewMatrixAsLookAt(eye, center, up); From 1e308918911fe28bd032578e2dc765a90953d5f9 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Thu, 31 Mar 2016 23:54:20 -0400 Subject: [PATCH 30/41] Broaden selection mask for getting scene bounds if nothing is found. --- apps/opencs/view/render/scenewidget.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index fe8de40e7..051559922 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -319,6 +319,20 @@ void SceneWidget::update(double dt) mRootNode->accept(boundsVisitor); + // Remove mask if nothing is found + if (!boundingBox.valid()) + { + boundsVisitor.reset(); + boundsVisitor.setMask(~0); + mRootNode->accept(boundsVisitor); + } + + // Set a default if there is still nothing found + if (!boundingBox.valid()) + { + boundingBox.set(-1, -1, -1, 1, 1, 1); + } + mCurrentCamControl->setSceneBounds(boundingBox, CameraController::WorldUp); mCamPositionSet = true; From efa2ec21ff8cf2bdcb7017613a3b21e8c4d3e737 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 2 Apr 2016 13:14:46 -0400 Subject: [PATCH 31/41] Cleanup, no need to inherit and override osg::ComputeBoundsVisitor --- apps/opencs/view/render/cameracontroller.cpp | 27 -------------------- apps/opencs/view/render/cameracontroller.hpp | 16 ------------ apps/opencs/view/render/scenewidget.cpp | 6 +++-- 3 files changed, 4 insertions(+), 45 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index d3e1fa53b..eb0515c28 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -572,31 +572,4 @@ namespace CSVRender getCamera()->setViewMatrixAsLookAt(mCenter + offset, mCenter, up); } - - CameraComputeBoundsVisitor::CameraComputeBoundsVisitor(unsigned int mask) - : mMask(mask) - { - } - - unsigned int CameraComputeBoundsVisitor::getMask() const - { - return mMask; - } - - void CameraComputeBoundsVisitor::setMask(unsigned int value) - { - mMask = value; - } - - void CameraComputeBoundsVisitor::apply(osg::Drawable& drawable) - { - if (drawable.getNodeMask() & mMask) - ComputeBoundsVisitor::apply(drawable); - } - - void CameraComputeBoundsVisitor::apply(osg::Transform& transform) - { - if (transform.getNodeMask() & mMask) - ComputeBoundsVisitor::apply(transform); - } } diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index fefa3a422..97a5ef2b2 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -145,21 +144,6 @@ namespace CSVRender double mOrbitSpeed; double mOrbitSpeedMult; }; - - class CameraComputeBoundsVisitor : public osg::ComputeBoundsVisitor - { - public: - CameraComputeBoundsVisitor(unsigned int mask); - - unsigned int getMask() const; - void setMask(unsigned int mask); - - void apply(osg::Drawable& drawable); - void apply(osg::Transform& transform); - - private: - unsigned int mMask; - }; } #endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 051559922..0ca495031 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -314,8 +315,9 @@ void SceneWidget::update(double dt) } else { - CameraComputeBoundsVisitor boundsVisitor(Mask_Reference | Mask_Terrain); + osg::ComputeBoundsVisitor boundsVisitor; osg::BoundingBox &boundingBox(boundsVisitor.getBoundingBox()); + boundsVisitor.setNodeMaskOverride(Mask_Reference | Mask_Terrain); mRootNode->accept(boundsVisitor); @@ -323,7 +325,7 @@ void SceneWidget::update(double dt) if (!boundingBox.valid()) { boundsVisitor.reset(); - boundsVisitor.setMask(~0); + boundsVisitor.setNodeMaskOverride(~0); mRootNode->accept(boundsVisitor); } From a4cc891383221c9eff156926680417c8c1771c00 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 2 Apr 2016 13:36:12 -0400 Subject: [PATCH 32/41] Cleanup, move setup to CameraController class --- apps/opencs/view/render/cameracontroller.cpp | 35 +++++++++++++++++--- apps/opencs/view/render/cameracontroller.hpp | 4 +-- apps/opencs/view/render/scenewidget.cpp | 24 +------------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index eb0515c28..57c87ecb3 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -2,8 +2,11 @@ #include +#include #include +#include #include +#include #include #include @@ -92,16 +95,38 @@ namespace CSVRender mWheelMoveMult = value; } - void CameraController::setSceneBounds(const osg::BoundingBox& bounds, const osg::Vec3d& up) + void CameraController::setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up) { - osg::Vec3d minBounds = bounds.corner(0) - bounds.center(); - osg::Vec3d maxBounds = bounds.corner(7) - bounds.center(); + // Find World bounds + osg::ComputeBoundsVisitor boundsVisitor; + osg::BoundingBox& boundingBox = boundsVisitor.getBoundingBox(); + + boundsVisitor.setNodeMaskOverride(mask); + root->accept(boundsVisitor); + + if (!boundingBox.valid()) + { + // Try again without any mask + boundsVisitor.reset(); + boundsVisitor.setNodeMaskOverride(~0); + root->accept(boundsVisitor); + + // Last resort, set a default + if (!boundingBox.valid()) + { + boundingBox.set(-1, -1, -1, 1, 1, 1); + } + } + + // Calculate a good starting position + osg::Vec3d minBounds = boundingBox.corner(0) - boundingBox.center(); + osg::Vec3d maxBounds = boundingBox.corner(7) - boundingBox.center(); osg::Vec3d camOffset = up * maxBounds > 0 ? maxBounds : minBounds; camOffset *= 2; - osg::Vec3d eye = camOffset + bounds.center(); - osg::Vec3d center = bounds.center(); + osg::Vec3d eye = camOffset + boundingBox.center(); + osg::Vec3d center = boundingBox.center(); getCamera()->setViewMatrixAsLookAt(eye, center, up); } diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 97a5ef2b2..bec76dd43 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -3,7 +3,6 @@ #include -#include #include #include @@ -12,6 +11,7 @@ class QKeyEvent; namespace osg { class Camera; + class Group; } namespace CSVRender @@ -43,7 +43,7 @@ namespace CSVRender void setWheelMovementMultiplier(double value); // moves the camera to an intelligent position - void setSceneBounds(const osg::BoundingBox& bounds, const osg::Vec3d& up); + void setup(osg::Group* root, unsigned int mask, const osg::Vec3d& up); virtual bool handleKeyEvent(QKeyEvent* event, bool pressed) = 0; virtual bool handleMouseMoveEvent(std::string mode, int x, int y) = 0; diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 0ca495031..9923d6ef0 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -315,28 +314,7 @@ void SceneWidget::update(double dt) } else { - osg::ComputeBoundsVisitor boundsVisitor; - osg::BoundingBox &boundingBox(boundsVisitor.getBoundingBox()); - boundsVisitor.setNodeMaskOverride(Mask_Reference | Mask_Terrain); - - mRootNode->accept(boundsVisitor); - - // Remove mask if nothing is found - if (!boundingBox.valid()) - { - boundsVisitor.reset(); - boundsVisitor.setNodeMaskOverride(~0); - mRootNode->accept(boundsVisitor); - } - - // Set a default if there is still nothing found - if (!boundingBox.valid()) - { - boundingBox.set(-1, -1, -1, 1, 1, 1); - } - - mCurrentCamControl->setSceneBounds(boundingBox, CameraController::WorldUp); - + mCurrentCamControl->setup(mRootNode, Mask_Reference | Mask_Terrain, CameraController::WorldUp); mCamPositionSet = true; } } From 99e9017242370f7b61f40df1cc5a31498d13f754 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 2 Apr 2016 13:59:57 -0400 Subject: [PATCH 33/41] Cleanup, externalize mask used to pick center --- apps/opencs/view/render/cameracontroller.cpp | 15 ++++++++++++--- apps/opencs/view/render/cameracontroller.hpp | 3 +++ apps/opencs/view/render/scenewidget.cpp | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 57c87ecb3..3967c983d 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -12,8 +12,6 @@ #include -#include "mask.hpp" - namespace CSVRender { @@ -361,6 +359,7 @@ namespace CSVRender , mDown(false) , mRollLeft(false) , mRollRight(false) + , mPickingMask(~0) , mCenter(0,0,0) , mDistance(0) , mOrbitSpeed(osg::PI / 4) @@ -378,6 +377,11 @@ namespace CSVRender return mOrbitSpeedMult; } + unsigned int OrbitCameraController::getPickingMask() const + { + return mPickingMask; + } + void OrbitCameraController::setOrbitSpeed(double value) { mOrbitSpeed = value; @@ -388,6 +392,11 @@ namespace CSVRender mOrbitSpeedMult = value; } + void OrbitCameraController::setPickingMask(unsigned int value) + { + mPickingMask = value; + } + bool OrbitCameraController::handleKeyEvent(QKeyEvent* event, bool pressed) { if (!isActive()) @@ -523,7 +532,7 @@ namespace CSVRender intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); osgUtil::IntersectionVisitor visitor(intersector); - visitor.setTraversalMask(Mask_Reference | Mask_Terrain); + visitor.setTraversalMask(mPickingMask); getCamera()->accept(visitor); diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index bec76dd43..7c1f96e15 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -115,9 +115,11 @@ namespace CSVRender double getOrbitSpeed() const; double getOrbitSpeedMultiplier() const; + unsigned int getPickingMask() const; void setOrbitSpeed(double value); void setOrbitSpeedMultiplier(double value); + void setPickingMask(unsigned int value); bool handleKeyEvent(QKeyEvent* event, bool pressed); bool handleMouseMoveEvent(std::string mode, int x, int y); @@ -138,6 +140,7 @@ namespace CSVRender bool mInitialized; bool mFast, mLeft, mRight, mUp, mDown, mRollLeft, mRollRight; + unsigned int mPickingMask; osg::Vec3d mCenter; double mDistance; diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 9923d6ef0..fea29effd 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -167,6 +167,7 @@ SceneWidget::SceneWidget(boost::shared_ptr resourceSys , mCurrentCamControl(mFreeCamControl.get()) , mCamPositionSet(false) { + mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain); selectNavigationMode("free"); // we handle lighting manually From 02f991c63ea1077150bdcea612016b047ee6a17b Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sat, 2 Apr 2016 14:02:56 -0400 Subject: [PATCH 34/41] Cleanup, fix comment --- apps/opencs/model/prefs/doublesetting.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/model/prefs/doublesetting.hpp b/apps/opencs/model/prefs/doublesetting.hpp index 6fe6b772a..8fd345f4d 100644 --- a/apps/opencs/model/prefs/doublesetting.hpp +++ b/apps/opencs/model/prefs/doublesetting.hpp @@ -21,9 +21,9 @@ namespace CSMPrefs QMutex *mutex, const std::string& key, const std::string& label, double default_); - // defaults to [0, std::numeric_limits::max()] DoubleSetting& setPrecision (int precision); + // defaults to [0, std::numeric_limits::max()] DoubleSetting& setRange (double min, double max); DoubleSetting& setMin (double min); From 4ef9981544b48677f28cc88de3d9b92c676030f3 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sun, 3 Apr 2016 16:30:50 -0400 Subject: [PATCH 35/41] Add ability to set orbit camera center outside of class. --- apps/opencs/view/render/cameracontroller.cpp | 18 ++++++++++++++++++ apps/opencs/view/render/cameracontroller.hpp | 2 ++ 2 files changed, 20 insertions(+) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 3967c983d..ab066033b 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -367,6 +367,11 @@ namespace CSVRender { } + osg::Vec3d OrbitCameraController::getCenter() const + { + return mCenter; + } + double OrbitCameraController::getOrbitSpeed() const { return mOrbitSpeed; @@ -382,6 +387,19 @@ namespace CSVRender return mPickingMask; } + void OrbitCameraController::setCenter(const osg::Vec3d& value) + { + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); + + mCenter = value; + mDistance = (eye - mCenter).length(); + + getCamera()->setViewMatrixAsLookAt(eye, mCenter, up); + + mInitialized = true; + } + void OrbitCameraController::setOrbitSpeed(double value) { mOrbitSpeed = value; diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index 7c1f96e15..b1dcc320a 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -113,10 +113,12 @@ namespace CSVRender OrbitCameraController(); + osg::Vec3d getCenter() const; double getOrbitSpeed() const; double getOrbitSpeedMultiplier() const; unsigned int getPickingMask() const; + void setCenter(const osg::Vec3d& center); void setOrbitSpeed(double value); void setOrbitSpeedMultiplier(double value); void setPickingMask(unsigned int value); From 6c471349f0f36eed48993de43ace2f9cdc1f394d Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sun, 3 Apr 2016 16:32:07 -0400 Subject: [PATCH 36/41] Add context menu for orbit camera. --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/view/render/orbitcameramode.cpp | 37 ++++++++++++++++++++ apps/opencs/view/render/orbitcameramode.hpp | 33 +++++++++++++++++ apps/opencs/view/render/worldspacewidget.cpp | 36 ++++++++++++++----- apps/opencs/view/render/worldspacewidget.hpp | 2 ++ 5 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 apps/opencs/view/render/orbitcameramode.cpp create mode 100644 apps/opencs/view/render/orbitcameramode.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 79876224d..816b8d732 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -86,6 +86,7 @@ opencs_units (view/widget opencs_units (view/render scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget previewwidget editmode instancemode instanceselectionmode instancemovemode + orbitcameramode ) opencs_units_noqt (view/render diff --git a/apps/opencs/view/render/orbitcameramode.cpp b/apps/opencs/view/render/orbitcameramode.cpp new file mode 100644 index 000000000..e6f3612c6 --- /dev/null +++ b/apps/opencs/view/render/orbitcameramode.cpp @@ -0,0 +1,37 @@ +#include "orbitcameramode.hpp" + +#include + +#include "worldspacewidget.hpp" + +namespace CSVRender +{ + OrbitCameraMode::OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip, + QWidget* parent) + : ModeButton(icon, tooltip, parent) + , mWorldspaceWidget(worldspaceWidget) + , mCenterOnSelection(0) + { + } + + void OrbitCameraMode::activate(CSVWidget::SceneToolbar* toolbar) + { + mCenterOnSelection = new QAction("Center on selected object", this); + connect(mCenterOnSelection, SIGNAL(triggered()), this, SLOT(centerSelection())); + } + + bool OrbitCameraMode::createContextMenu(QMenu* menu) + { + if (menu) + { + menu->addAction(mCenterOnSelection); + } + + return true; + } + + void OrbitCameraMode::centerSelection() + { + mWorldspaceWidget->centerOrbitCameraOnSelection(); + } +} diff --git a/apps/opencs/view/render/orbitcameramode.hpp b/apps/opencs/view/render/orbitcameramode.hpp new file mode 100644 index 000000000..cd8387084 --- /dev/null +++ b/apps/opencs/view/render/orbitcameramode.hpp @@ -0,0 +1,33 @@ +#ifndef CSV_RENDER_ORBITCAMERAPICKMODE_H +#define CSV_RENDER_ORBITCAMERAPICKMODE_H + +#include "../widget/modebutton.hpp" + +namespace CSVRender +{ + class WorldspaceWidget; + + class OrbitCameraMode : public CSVWidget::ModeButton + { + Q_OBJECT + + public: + + OrbitCameraMode(WorldspaceWidget* worldspaceWidget, const QIcon& icon, const QString& tooltip = "", + QWidget* parent = 0); + + virtual void activate(CSVWidget::SceneToolbar* toolbar); + virtual bool createContextMenu(QMenu* menu); + + private: + + WorldspaceWidget* mWorldspaceWidget; + QAction* mCenterOnSelection; + + private slots: + + void centerSelection(); + }; +} + +#endif diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 3cd2c4093..927ce545f 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -19,6 +19,8 @@ #include "../../model/prefs/state.hpp" +#include "../render/orbitcameramode.hpp" + #include "../widget/scenetoolmode.hpp" #include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetoolrun.hpp" @@ -27,6 +29,7 @@ #include "mask.hpp" #include "editmode.hpp" #include "instancemode.hpp" +#include "cameracontroller.hpp" CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) : SceneWidget (document.getData().getResourceSystem(), parent, 0, false), mSceneElements(0), mRun(0), mDocument(document), @@ -99,6 +102,19 @@ void CSVRender::WorldspaceWidget::selectDefaultNavigationMode() selectNavigationMode("1st"); } +void CSVRender::WorldspaceWidget::centerOrbitCameraOnSelection() +{ + std::vector > selection = getSelection(~0); + + for (std::vector >::iterator it = selection.begin(); it!=selection.end(); ++it) + { + if (CSVRender::ObjectTag *objectTag = dynamic_cast (it->get())) + { + mOrbitCamControl->setCenter(objectTag->mObject->getPosition().asVec3()); + } + } +} + CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( CSVWidget::SceneToolbar *parent) { @@ -123,15 +139,17 @@ CSVWidget::SceneToolMode *CSVRender::WorldspaceWidget::makeNavigationSelector ( "
  • Roll camera with Q and E keys
  • " "
  • Hold shift to speed up movement
  • " ""); - tool->addButton (":scenetoolbar/orbiting-camera", "orbit", - "Orbiting Camera" - "
    • Always facing the centre point
    • " - "
    • Rotate around the centre point via WASD or by moving the mouse while holding the left button
    • " - "
    • Mouse wheel moves camera away or towards centre point but can not pass through it
    • " - "
    • Roll camera with Q and E keys
    • " - "
    • Strafing (also vertically) by holding the left mouse button and control (includes relocation of the centre point)
    • " - "
    • Hold shift to speed up movement
    • " - "
    "); + tool->addButton( + new CSVRender::OrbitCameraMode(this, QIcon(":scenetoolbar/orbiting-camera"), + "Orbiting Camera" + "
    • Always facing the centre point
    • " + "
    • Rotate around the centre point via WASD or by moving the mouse while holding the left button
    • " + "
    • Mouse wheel moves camera away or towards centre point but can not pass through it
    • " + "
    • Roll camera with Q and E keys
    • " + "
    • Strafing (also vertically) by holding the left mouse button and control (includes relocation of the centre point)
    • " + "
    • Hold shift to speed up movement
    • " + "
    ", tool), + "orbit"); connect (tool, SIGNAL (modeChanged (const std::string&)), this, SLOT (selectNavigationMode (const std::string&))); diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 36aae0329..b18123944 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -97,6 +97,8 @@ namespace CSVRender void selectDefaultNavigationMode(); + void centerOrbitCameraOnSelection(); + static DropType getDropType(const std::vector& data); virtual dropRequirments getDropRequirements(DropType type) const; From 0ef7c778e0e939567d11a9250afc7ddcaed9bc14 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sun, 3 Apr 2016 17:26:34 -0400 Subject: [PATCH 37/41] Cleanup, isModified was a remnant of an old design and is only used in the first person camera mode. --- apps/opencs/view/render/cameracontroller.cpp | 48 ++++---------------- apps/opencs/view/render/cameracontroller.hpp | 8 +--- 2 files changed, 10 insertions(+), 46 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index ab066033b..cf10cb346 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -27,7 +27,6 @@ namespace CSVRender CameraController::CameraController() : mActive(false) - , mModified(false) , mCameraSensitivity(1/650.f) , mSecondaryMoveMult(50) , mWheelMoveMult(8) @@ -44,11 +43,6 @@ namespace CSVRender return mActive; } - bool CameraController::isModified() const - { - return mModified; - } - osg::Camera* CameraController::getCamera() const { return mCamera; @@ -129,22 +123,13 @@ namespace CSVRender getCamera()->setViewMatrixAsLookAt(eye, center, up); } - void CameraController::setModified() - { - mModified = true; - } - - void CameraController::resetModified() - { - mModified = false; - } - /* Free Camera Controller */ FreeCameraController::FreeCameraController() : mLockUpright(false) + , mModified(false) , mFast(false) , mLeft(false) , mRight(false) @@ -193,7 +178,7 @@ namespace CSVRender { mLockUpright = true; mUp = up; - setModified(); + mModified = true; } void FreeCameraController::unfixUpAxis() @@ -209,37 +194,30 @@ namespace CSVRender if (event->key() == Qt::Key_Q) { mRollLeft = pressed; - setModified(); } else if (event->key() == Qt::Key_E) { mRollRight = pressed; - setModified(); } else if (event->key() == Qt::Key_A) { mLeft = pressed; - setModified(); } else if (event->key() == Qt::Key_D) { mRight = pressed; - setModified(); } else if (event->key() == Qt::Key_W) { mForward = pressed; - setModified(); } else if (event->key() == Qt::Key_S) { mBackward = pressed; - setModified(); } else if (event->key() == Qt::Key_Shift) { mFast = pressed; - setModified(); } else { @@ -258,7 +236,6 @@ namespace CSVRender { yaw(x * getCameraSensitivity()); pitch(y * getCameraSensitivity()); - setModified(); } else if (mode == "s-navi") { @@ -267,7 +244,6 @@ namespace CSVRender movement += LocalUp * y * getSecondaryMovementMultiplier(); translate(movement); - setModified(); } else if (mode == "t-navi") { @@ -308,35 +284,38 @@ namespace CSVRender if (mRollRight) roll(rotDist); } - else if(isModified()) + else if(mModified) { stabilize(); + mModified = false; } // Normalize the matrix to counter drift getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix()); - - resetModified(); } void FreeCameraController::yaw(double value) { getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalUp); + mModified = true; } void FreeCameraController::pitch(double value) { getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalLeft); + mModified = true; } void FreeCameraController::roll(double value) { getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalForward); + mModified = true; } void FreeCameraController::translate(const osg::Vec3d& offset) { getCamera()->getViewMatrix() *= osg::Matrixd::translate(offset); + mModified = true; } void FreeCameraController::stabilize() @@ -426,37 +405,30 @@ namespace CSVRender if (event->key() == Qt::Key_Q) { mRollLeft = pressed; - setModified(); } else if (event->key() == Qt::Key_E) { mRollRight = pressed; - setModified(); } else if (event->key() == Qt::Key_A) { mLeft = pressed; - setModified(); } else if (event->key() == Qt::Key_D) { mRight = pressed; - setModified(); } else if (event->key() == Qt::Key_W) { mUp = pressed; - setModified(); } else if (event->key() == Qt::Key_S) { mDown = pressed; - setModified(); } else if (event->key() == Qt::Key_Shift) { mFast = pressed; - setModified(); } else { @@ -478,7 +450,6 @@ namespace CSVRender { rotateHorizontal(x * getCameraSensitivity()); rotateVertical(-y * getCameraSensitivity()); - setModified(); } else if (mode == "s-navi") { @@ -487,7 +458,6 @@ namespace CSVRender movement += LocalUp * -y * getSecondaryMovementMultiplier(); translate(movement); - setModified(); } else if (mode == "t-navi") { @@ -530,8 +500,6 @@ namespace CSVRender // Normalize the matrix to counter drift getCamera()->getViewMatrix().orthoNormal(getCamera()->getViewMatrix()); - - resetModified(); } void OrbitCameraController::onActivate() diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index b1dcc320a..be83181ed 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -30,7 +30,6 @@ namespace CSVRender virtual ~CameraController(); bool isActive() const; - bool isModified() const; osg::Camera* getCamera() const; double getCameraSensitivity() const; @@ -52,14 +51,11 @@ namespace CSVRender protected: - void setModified(); - void resetModified(); - virtual void onActivate(){} private: - bool mActive, mModified; + bool mActive; double mCameraSensitivity; double mSecondaryMoveMult; double mWheelMoveMult; @@ -98,7 +94,7 @@ namespace CSVRender void stabilize(); - bool mLockUpright; + bool mLockUpright, mModified; bool mFast, mLeft, mRight, mForward, mBackward, mRollLeft, mRollRight; osg::Vec3d mUp; From ec25998b12b2d5b32ef6e442bc79cfbd5ae360cd Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sun, 3 Apr 2016 18:19:20 -0400 Subject: [PATCH 38/41] Cleanup, use setTraversalMask instead of setNodeMaskOverride --- apps/opencs/view/render/cameracontroller.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index cf10cb346..0ca8aabf1 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -93,14 +93,14 @@ namespace CSVRender osg::ComputeBoundsVisitor boundsVisitor; osg::BoundingBox& boundingBox = boundsVisitor.getBoundingBox(); - boundsVisitor.setNodeMaskOverride(mask); + boundsVisitor.setTraversalMask(mask); root->accept(boundsVisitor); if (!boundingBox.valid()) { // Try again without any mask boundsVisitor.reset(); - boundsVisitor.setNodeMaskOverride(~0); + boundsVisitor.setTraversalMask(~0); root->accept(boundsVisitor); // Last resort, set a default From e127c691e22b94f813e2e9618e4cfaf7234352f4 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Sun, 3 Apr 2016 18:23:06 -0400 Subject: [PATCH 39/41] Cleanup, remove some unused includes --- apps/opencs/view/render/scenewidget.cpp | 4 ---- apps/opencs/view/render/unpagedworldspacewidget.cpp | 2 -- 2 files changed, 6 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index fea29effd..6379f8eca 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,10 +11,6 @@ #include #include #include -#include - -#include -#include #include #include diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index 4ed71ac96..79ffd4fb0 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -2,8 +2,6 @@ #include -#include - #include #include From e07687ee01c0b91165312f55349c6baa92f9cf92 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 4 Apr 2016 18:42:57 -0400 Subject: [PATCH 40/41] Add button for camera mouse inversion in user preferences, and separate the sensitivity settings for orbit and free cameras. --- apps/opencs/model/prefs/state.cpp | 5 ++++- apps/opencs/view/render/cameracontroller.cpp | 21 ++++++++++++++++---- apps/opencs/view/render/cameracontroller.hpp | 4 +++- apps/opencs/view/render/scenewidget.cpp | 13 +++++++++++- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index fd6c7b6ed..70456ee1d 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -172,7 +172,10 @@ void CSMPrefs::State::declare() inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle); declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons); declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons); - declareDouble ("p-navi-sensitivity", "Camera Sensitivity", 1/650.).setPrecision(4).setRange(-2.0, 2.0); + declareDouble ("p-navi-free-sensitivity", "Free Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0); + declareBool ("p-navi-free-invert", "Invert Free Camera Mouse Input", false); + declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0); + declareBool ("p-navi-orbit-invert", "Invert Orbit Camera Mouse Input", false); declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0); declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); declareDouble ("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0); diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 0ca8aabf1..cefd81003 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -27,6 +27,7 @@ namespace CSVRender CameraController::CameraController() : mActive(false) + , mInverted(false) , mCameraSensitivity(1/650.f) , mSecondaryMoveMult(50) , mWheelMoveMult(8) @@ -53,6 +54,11 @@ namespace CSVRender return mCameraSensitivity; } + bool CameraController::getInverted() const + { + return mInverted; + } + double CameraController::getSecondaryMovementMultiplier() const { return mSecondaryMoveMult; @@ -77,6 +83,11 @@ namespace CSVRender mCameraSensitivity = value; } + void CameraController::setInverted(bool value) + { + mInverted = value; + } + void CameraController::setSecondaryMovementMultiplier(double value) { mSecondaryMoveMult = value; @@ -234,8 +245,9 @@ namespace CSVRender if (mode == "p-navi") { - yaw(x * getCameraSensitivity()); - pitch(y * getCameraSensitivity()); + double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0); + yaw(x * scalar); + pitch(y * scalar); } else if (mode == "s-navi") { @@ -448,8 +460,9 @@ namespace CSVRender if (mode == "p-navi") { - rotateHorizontal(x * getCameraSensitivity()); - rotateVertical(-y * getCameraSensitivity()); + double scalar = getCameraSensitivity() * (getInverted() ? -1.0 : 1.0); + rotateHorizontal(x * scalar); + rotateVertical(-y * scalar); } else if (mode == "s-navi") { diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index be83181ed..575bbb4ea 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -33,11 +33,13 @@ namespace CSVRender osg::Camera* getCamera() const; double getCameraSensitivity() const; + bool getInverted() const; double getSecondaryMovementMultiplier() const; double getWheelMovementMultiplier() const; void setCamera(osg::Camera*); void setCameraSensitivity(double value); + void setInverted(bool value); void setSecondaryMovementMultiplier(double value); void setWheelMovementMultiplier(double value); @@ -55,7 +57,7 @@ namespace CSVRender private: - bool mActive; + bool mActive, mInverted; double mCameraSensitivity; double mSecondaryMoveMult; double mWheelMoveMult; diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 6379f8eca..2ba396563 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -318,11 +318,22 @@ void SceneWidget::update(double dt) void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) { - if (*setting=="3D Scene Input/p-navi-sensitivity") + if (*setting=="3D Scene Input/p-navi-free-sensitivity") { mFreeCamControl->setCameraSensitivity(setting->toDouble()); + } + else if (*setting=="3D Scene Input/p-navi-orbit-sensitivity") + { mOrbitCamControl->setCameraSensitivity(setting->toDouble()); } + else if (*setting=="3D Scene Input/p-navi-free-invert") + { + mFreeCamControl->setInverted(setting->isTrue()); + } + else if (*setting=="3D Scene Input/p-navi-orbit-invert") + { + mOrbitCamControl->setInverted(setting->isTrue()); + } else if (*setting=="3D Scene Input/s-navi-sensitivity") { mFreeCamControl->setSecondaryMovementMultiplier(setting->toDouble()); From b111febfc9d8d25dbe2d19af75d6c810a30c69fc Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 4 Apr 2016 20:56:13 -0400 Subject: [PATCH 41/41] Add pitch constraint for first person camera. --- apps/opencs/view/render/cameracontroller.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index cefd81003..68f0c76ef 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -1,5 +1,7 @@ #include "cameracontroller.hpp" +#include + #include #include @@ -314,6 +316,24 @@ namespace CSVRender void FreeCameraController::pitch(double value) { + const double Constraint = osg::PI / 2 - 0.1; + + if (mLockUpright) + { + osg::Vec3d eye, center, up; + getCamera()->getViewMatrixAsLookAt(eye, center, up); + + osg::Vec3d forward = center - eye; + osg::Vec3d left = up ^ forward; + + double pitchAngle = std::acos(up * mUp); + if ((mUp ^ up) * left < 0) + pitchAngle *= -1; + + if (std::abs(pitchAngle + value) > Constraint) + value = (pitchAngle > 0 ? 1 : -1) * Constraint - pitchAngle; + } + getCamera()->getViewMatrix() *= osg::Matrixd::rotate(value, LocalLeft); mModified = true; }