// Copyright (C) 2017 Mike Krus // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "viewer/OSGRenderer.h" //#include //#include #include #include #include #include #include #include #include #include #include #include namespace { 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_Insert ] = osgGA::GUIEventAdapter::KEY_KP_Insert; } ~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; } // namespace OSGRenderer::OSGRenderer(QObject *parent) : QObject(parent) , m_osgInitialized(false) , m_windowScale(1.f) , m_continuousUpdate(true) { } void OSGRenderer::render() { if (m_osgViewer.getSceneData()) m_osgViewer.frame(); if (m_continuousUpdate) update(); } void OSGRenderer::resize(int windowWidth, int windowHeight, float windowScale) { if (!m_osgInitialized) return; m_windowScale = windowScale; m_osgViewer.getCamera()->setViewport(new osg::Viewport(0, 0, windowWidth * windowScale, windowHeight * windowScale)); m_osgWinEmb->resized(0, 0, windowWidth * windowScale, windowHeight * windowScale); m_osgWinEmb->getEventQueue()->windowResize( 0, 0, windowWidth * windowScale, windowHeight * windowScale ); } void OSGRenderer::setupOSG(int windowWidth, int windowHeight, float windowScale) { m_osgInitialized = true; m_windowScale = windowScale; m_osgWinEmb = new osgViewer::GraphicsWindowEmbedded(0, 0, windowWidth * windowScale, windowHeight * windowScale); // make sure the event queue has the correct window rectangle size and input range m_osgWinEmb->getEventQueue()->syncWindowRectangleWithGraphicsContext(); m_osgViewer.getCamera()->setViewport(new osg::Viewport(0, 0, windowWidth * windowScale, windowHeight * windowScale)); m_osgViewer.getCamera()->setGraphicsContext(m_osgWinEmb.get()); m_osgViewer.getCamera()->setClearColor(osg::Vec4(1., 1., 1., 1.)); m_osgViewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); osgViewer::Viewer::Windows windows; m_osgViewer.getWindows(windows); for(osgViewer::Viewer::Windows::iterator itr = windows.begin(); itr != windows.end(); ++itr) { (*itr)->getState()->setUseModelViewAndProjectionUniforms(true); (*itr)->getState()->setUseVertexAttributeAliasing(true); } } void OSGRenderer::setKeyboardModifiers( QInputEvent* event ) const { 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; m_osgWinEmb->getEventQueue()->getCurrentEventState()->setModKeyMask( mask ); } void OSGRenderer::keyPressEvent( QKeyEvent* event ) { setKeyboardModifiers( event ); int value = s_QtKeyboardMap.remapKey( event ); m_osgWinEmb->getEventQueue()->keyPress( value ); } void OSGRenderer::keyReleaseEvent( QKeyEvent* event ) { if( event->isAutoRepeat() ) { event->ignore(); } else { setKeyboardModifiers( event ); int value = s_QtKeyboardMap.remapKey( event ); m_osgWinEmb->getEventQueue()->keyRelease( value ); } } void OSGRenderer::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 ); m_osgWinEmb->getEventQueue()->mouseButtonPress( event->x() * m_windowScale, event->y() * m_windowScale, button ); } void OSGRenderer::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 ); m_osgWinEmb->getEventQueue()->mouseButtonRelease( event->x() * m_windowScale, event->y() * m_windowScale, button ); } void OSGRenderer::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 ); m_osgWinEmb->getEventQueue()->mouseDoubleButtonPress( event->x() * m_windowScale, event->y() * m_windowScale, button ); } void OSGRenderer::mouseMoveEvent( QMouseEvent* event ) { setKeyboardModifiers( event ); m_osgWinEmb->getEventQueue()->mouseMotion( event->x() * m_windowScale, event->y() * m_windowScale ); } void OSGRenderer::wheelEvent( QWheelEvent* event ) { setKeyboardModifiers( event ); m_osgWinEmb->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) ); }