From 2406510c8c7e48919e8ebedcfd016eecdfafe384 Mon Sep 17 00:00:00 2001 From: James Goppert Date: Mon, 22 Nov 2010 02:54:56 -0500 Subject: [PATCH] Added a more generic osgqtwidget for map3d. Still need to add uas connections. New osgwidget inherits from qgraphicsview to expose more functionality to qt. Map3d.ui contains the graphics view and some buttons. Currently runs yahoo_heightfield by default. Make sure you run qgroundcontrol fromt the top dir or it will seg fault, :-). I'll add some error handling soon. --- data/yahoo_aerial.earth | 23 +++ data/yahoo_heightfield.earth | 33 ++++ data/yahoo_maps.earth | 19 ++ map.earth => data/zurich.earth | 0 qgroundcontrol.pri | 12 +- qgroundcontrol.pro | 58 +++--- src/uas/UAS.cc | 5 + src/ui/CommConfigurationWindow.cc | 4 + src/ui/CommConfigurationWindow.h | 6 + src/ui/MainWindow.cc | 13 +- src/ui/MainWindow.h | 7 +- src/ui/QMap3D.ui | 45 +++++ src/ui/map3D/PixhawkCheetahGeode.cc | 0 src/ui/map3D/QMap3D.cc | 50 +++++ src/ui/map3D/QMap3D.h | 51 +++++ src/ui/map3D/QOSGWidget.cc | 277 ++++++++++++++++++++++++++++ src/ui/map3D/QOSGWidget.h | 208 +++++++++++++++++++++ 17 files changed, 769 insertions(+), 42 deletions(-) create mode 100644 data/yahoo_aerial.earth create mode 100644 data/yahoo_heightfield.earth create mode 100644 data/yahoo_maps.earth rename map.earth => data/zurich.earth (100%) create mode 100644 src/ui/QMap3D.ui mode change 100755 => 100644 src/ui/map3D/PixhawkCheetahGeode.cc create mode 100644 src/ui/map3D/QMap3D.cc create mode 100644 src/ui/map3D/QMap3D.h create mode 100644 src/ui/map3D/QOSGWidget.cc create mode 100644 src/ui/map3D/QOSGWidget.h diff --git a/data/yahoo_aerial.earth b/data/yahoo_aerial.earth new file mode 100644 index 000000000..679c01f5b --- /dev/null +++ b/data/yahoo_aerial.earth @@ -0,0 +1,23 @@ + + + + + + /tmp/OsgEarthCache + + + + satellite + + + + true + + diff --git a/data/yahoo_heightfield.earth b/data/yahoo_heightfield.earth new file mode 100644 index 000000000..4fe6133ad --- /dev/null +++ b/data/yahoo_heightfield.earth @@ -0,0 +1,33 @@ + + + + + + satellite + + + + false + + + http://onearth.jpl.nasa.gov/wms.cgi + worldwind_dem + + tiff + ft + + + true + + 50 + + 0.01 + + diff --git a/data/yahoo_maps.earth b/data/yahoo_maps.earth new file mode 100644 index 000000000..871a114b0 --- /dev/null +++ b/data/yahoo_maps.earth @@ -0,0 +1,19 @@ + + + + + + roads + + + + true + + diff --git a/map.earth b/data/zurich.earth similarity index 100% rename from map.earth rename to data/zurich.earth diff --git a/qgroundcontrol.pri b/qgroundcontrol.pri index 46c19979f..4de1bea4a 100644 --- a/qgroundcontrol.pri +++ b/qgroundcontrol.pri @@ -82,13 +82,14 @@ macx { # Include OpenSceneGraph and osgEarth libraries LIBS += -losg \ -losgViewer \ - -losgEarth + -losgEarth \ + -losgEarthUtil DEFINES += QGC_OSG_ENABLED } } # GNU/Linux -linux-g++-32 { +linux-g++ { CONFIG += debug @@ -127,17 +128,18 @@ linux-g++-32 { -lSDL \ -lSDLmain -exists(/usr/lib/osg):exists(/usr/lib/osgEarth) { +exists(/usr/include/osgEarth) | exists(/usr/local/include/osgEarth) { message("Building support for OSGEARTH") DEPENDENCIES_PRESENT += osgearth # Include OpenSceneGraph and osgEarth libraries LIBS += -losg \ -losgViewer \ - -losgEarth + -losgEarth \ + -losgEarthUtil DEFINES += QGC_OSG_ENABLED } -QMAKE_CXXFLAGS += -Wl,-E +QMAKE_CXXFLAGS += -Wl,-E, -DUSE_QT4 #-lflite_cmu_us_rms \ #-lflite_cmu_us_slt \ diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 235381749..ac6812121 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -47,7 +47,6 @@ MAVLINK_CONF = "" # if the variable MAVLINK_CONF contains the name of an # additional project, QGroundControl includes the support # of custom MAVLink messages of this project - exists(user_config.pri) { include(user_config.pri) message("----- USING CUSTOM USER QGROUNDCONTROL CONFIG FROM user_config.pri -----") @@ -79,10 +78,10 @@ contains(MAVLINK_CONF, ualberta) { INCLUDEPATH += $$BASEDIR/../mavlink/include/ualberta DEFINES += QGC_USE_UALBERTA_MESSAGES } -contains(MAVLINK_CONF, ardupilotmega) { +contains(MAVLINK_CONF, ardupilotmega) { # Remove the default set - it is included anyway INCLUDEPATH -= $$BASEDIR/../mavlink/include/common - + # UALBERTA SPECIAL MESSAGES INCLUDEPATH += $$BASEDIR/../mavlink/include/ardupilotmega DEFINES += QGC_USE_ARDUPILOTMEGA_MESSAGES @@ -138,8 +137,10 @@ FORMS += src/ui/MainWindow.ui \ src/ui/QGCFirmwareUpdate.ui \ src/ui/QGCPxImuFirmwareUpdate.ui \ src/ui/QGCDataPlot2D.ui \ - src/ui/QGCRemoteControlView.ui - #src/ui/WaypointGlobalView.ui + src/ui/QGCRemoteControlView.ui \ + src/ui/QMap3D.ui + +# src/ui/WaypointGlobalView.ui INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -221,8 +222,7 @@ HEADERS += src/MG.h \ src/ui/linechart/IncrementalPlot.h \ src/ui/map/Waypoint2DIcon.h \ src/ui/map/MAV2DIcon.h \ - src/ui/QGCRemoteControlView.h \ - #src/ui/WaypointGlobalView.h \ + src/ui/QGCRemoteControlView.h \ # src/ui/WaypointGlobalView.h \ src/ui/RadioCalibration/RadioCalibrationData.h \ src/ui/RadioCalibration/RadioCalibrationWindow.h \ src/ui/RadioCalibration/AirfoilServoCalibrator.h \ @@ -230,17 +230,18 @@ HEADERS += src/MG.h \ src/ui/RadioCalibration/CurveCalibrator.h \ src/ui/RadioCalibration/AbstractCalibrator.h \ src/comm/QGCMAVLink.h - -contains(DEPENDENCIES_PRESENT, osgearth) { -message("Including headers for OSGEARTH") -# Enable only if OpenSceneGraph is available -HEADERS += src/ui/map3D/Q3DWidget.h \ - src/ui/map3D/PixhawkCheetahGeode.h \ - src/ui/map3D/Pixhawk3DWidget.h \ - src/ui/map3D/Q3DWidgetFactory.h \ - src/ui/map3D/GCManipulator.h +contains(DEPENDENCIES_PRESENT, osgearth) { + message("Including headers for OSGEARTH") + + # Enable only if OpenSceneGraph is available + HEADERS += src/ui/map3D/Q3DWidget.h \ + src/ui/map3D/QOSGWidget.h \ + src/ui/map3D/QMap3D.h \ + src/ui/map3D/PixhawkCheetahGeode.h \ + src/ui/map3D/Pixhawk3DWidget.h \ + src/ui/map3D/Q3DWidgetFactory.h \ + src/ui/map3D/GCManipulator.h } - SOURCES += src/main.cc \ src/Core.cc \ src/uas/UASManager.cc \ @@ -309,17 +310,18 @@ SOURCES += src/main.cc \ src/ui/RadioCalibration/SwitchCalibrator.cc \ src/ui/RadioCalibration/CurveCalibrator.cc \ src/ui/RadioCalibration/AbstractCalibrator.cc \ - src/ui/RadioCalibration/RadioCalibrationData.cc \ - #src/ui/WaypointGlobalView.cc \ - -contains(DEPENDENCIES_PRESENT, osgearth) { -message("Including sources for OSGEARTH") -# Enable only if OpenSceneGraph is available -SOURCES += src/ui/map3D/Q3DWidget.cc \ - src/ui/map3D/PixhawkCheetahGeode.cc \ - src/ui/map3D/Pixhawk3DWidget.cc \ - src/ui/map3D/Q3DWidgetFactory.cc \ - src/ui/map3D/GCManipulator.cc + src/ui/RadioCalibration/RadioCalibrationData.cc # src/ui/WaypointGlobalView.cc \ +contains(DEPENDENCIES_PRESENT, osgearth) { + message("Including sources for OSGEARTH") + + # Enable only if OpenSceneGraph is available + SOURCES += src/ui/map3D/Q3DWidget.cc \ + src/ui/map3D/QOSGWidget.cc \ + src/ui/map3D/QMap3D.cc \ + src/ui/map3D/PixhawkCheetahGeode.cc \ + src/ui/map3D/Pixhawk3DWidget.cc \ + src/ui/map3D/Q3DWidgetFactory.cc \ + src/ui/map3D/GCManipulator.cc } RESOURCES += mavground.qrc diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index 1c2b5666e..3b4f13618 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -357,6 +357,11 @@ void UAS::receiveMessage(LinkInterface* link, mavlink_message_t message) GAudioOutput::instance()->notifyPositive(); } positionLock = true; + + // Send to patch antenna + mavlink_message_t msg; + mavlink_msg_global_position_pack(MG::SYSTEM::ID, MG::SYSTEM::COMPID, &msg, pos.usec, pos.lat, pos.lon, pos.alt, pos.vx, pos.vy, pos.vz); + sendMessage(msg); } break; case MAVLINK_MSG_ID_GPS_RAW: diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 5aba706ef..0708aeef9 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -55,6 +55,10 @@ CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolIn // Setup the user interface according to link type ui.setupUi(this); + // add link types + ui.linkType->addItem("Serial",QGC_LINK_SERIAL); + ui.linkType->addItem("UDP",QGC_LINK_UDP); + // Create action to open this menu // Create configuration action for this link // Connect the current UAS diff --git a/src/ui/CommConfigurationWindow.h b/src/ui/CommConfigurationWindow.h index f190aa956..fce37dbbe 100644 --- a/src/ui/CommConfigurationWindow.h +++ b/src/ui/CommConfigurationWindow.h @@ -39,6 +39,12 @@ This file is part of the QGROUNDCONTROL project #include "ProtocolInterface.h" #include "ui_CommSettings.h" +enum qgc_link_t +{ + QGC_LINK_SERIAL, + QGC_LINK_UDP +}; + #ifdef OPAL_RT #include "OpalLink.h" #endif diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index b6939fa2a..9b82d7f03 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -46,8 +46,8 @@ This file is part of the QGROUNDCONTROL project #include "JoystickWidget.h" #include "GAudioOutput.h" - #ifdef QGC_OSG_ENABLED -#include "Q3DWidgetFactory.h" +#ifdef QGC_OSG_ENABLED +#include "QMap3D.h" #endif // FIXME Move @@ -136,8 +136,9 @@ void MainWindow::buildWidgets() protocolWidget = new XMLCommProtocolWidget(this); dataplotWidget = new QGCDataPlot2D(this); #ifdef QGC_OSG_ENABLED - _3DWidget = Q3DWidgetFactory::get("PIXHAWK"); -#endif + //_3DWidget = Q3DWidgetFactory::get(QGC_MAP3D_OSGEARTH); + _3DWidget = new QMap3D(this); + #endif // Dock widgets controlDockWidget = new QDockWidget(tr("Control"), this); @@ -229,9 +230,9 @@ void MainWindow::arrangeCenterStack() if (linechartWidget) centerStack->addWidget(linechartWidget); if (protocolWidget) centerStack->addWidget(protocolWidget); if (mapWidget) centerStack->addWidget(mapWidget); - #ifdef QGC_OSG_ENABLED + #ifdef QGC_OSG_ENABLED if (_3DWidget) centerStack->addWidget(_3DWidget); -#endif + #endif if (hudWidget) centerStack->addWidget(hudWidget); if (dataplotWidget) centerStack->addWidget(dataplotWidget); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 7da4f9d36..ed0b59c5b 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -64,7 +64,8 @@ This file is part of the QGROUNDCONTROL project #include "QGCDataPlot2D.h" #include "QGCRemoteControlView.h" #ifdef QGC_OSG_ENABLED -#include "Q3DWidget.h" +//#include "Q3DWidget.h" +#include "QMap3D.h" #endif #include "LogCompressor.h" @@ -166,8 +167,8 @@ protected: QPointer protocolWidget; QPointer dataplotWidget; #ifdef QGC_OSG_ENABLED - QPointer _3DWidget; -#endif + QPointer _3DWidget; + #endif // Dock widgets QPointer controlDockWidget; QPointer infoDockWidget; diff --git a/src/ui/QMap3D.ui b/src/ui/QMap3D.ui new file mode 100644 index 000000000..ea573001e --- /dev/null +++ b/src/ui/QMap3D.ui @@ -0,0 +1,45 @@ + + + QMap3D + + + + 0 + 0 + 548 + 211 + + + + Form + + + + + + Map + + + + + + + + + + Vehicle + + + + + + + + ViewerQOSG + QGraphicsView +
QOSGWidget.h
+
+
+ + +
diff --git a/src/ui/map3D/PixhawkCheetahGeode.cc b/src/ui/map3D/PixhawkCheetahGeode.cc old mode 100755 new mode 100644 diff --git a/src/ui/map3D/QMap3D.cc b/src/ui/map3D/QMap3D.cc new file mode 100644 index 000000000..00f9b0b54 --- /dev/null +++ b/src/ui/map3D/QMap3D.cc @@ -0,0 +1,50 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2010 QGROUNDCONTROL PROJECT + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL 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 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Definition of the class QMap3D. + * + * @author James Goppert + * + */ + +#include "QMap3D.h" +#include +#include + +QMap3D::QMap3D(QWidget * parent, const char * name, WindowFlags f) : + QWidget(parent,f) +{ + setupUi(this); + osg::ref_ptr map = osgDB::readNodeFile("data/yahoo_heightfield.earth"); + if (!map) throw std::runtime_error("unable to load file"); + graphicsView->updateCamera(); + graphicsView->setCameraManipulator(new osgEarthUtil::EarthManipulator); + graphicsView->setSceneData(map); + show(); +} + +QMap3D::~QMap3D() +{ +} diff --git a/src/ui/map3D/QMap3D.h b/src/ui/map3D/QMap3D.h new file mode 100644 index 000000000..43fae8d22 --- /dev/null +++ b/src/ui/map3D/QMap3D.h @@ -0,0 +1,51 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2010 QGROUNDCONTROL PROJECT + +This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL 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 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Definition of the class QMap3D.h + * + * @author James Goppert + * + */ + +#ifndef QMAP3D_H +#define QMAP3D_H + +#include "QOSGWidget.h" +#include "ui_QMap3D.h" + +namespace Ui { + class QMap3D; +} + +class QMap3D : public QWidget, private Ui::QMap3D +{ + Q_OBJECT +public: + QMap3D(QWidget * parent = 0, const char * name = 0, WindowFlags f = 0); + ~QMap3D(); +}; + +#endif // QMAP3D_H + diff --git a/src/ui/map3D/QOSGWidget.cc b/src/ui/map3D/QOSGWidget.cc new file mode 100644 index 000000000..0021a40a8 --- /dev/null +++ b/src/ui/map3D/QOSGWidget.cc @@ -0,0 +1,277 @@ +/* OpenSceneGraph example, osganimate. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include "QOSGWidget.h" + +QOSGWidget::QOSGWidget( QWidget * parent, const char * name, WindowFlags f, bool overrideTraits): +#if USE_QT4 + QWidget(parent, f), _overrideTraits (overrideTraits) +#else + QWidget(parent, name, f), _overrideTraits (overrideTraits) +#endif +{ + createContext(); + + +#if USE_QT4 + setAttribute(Qt::WA_PaintOnScreen); + setAttribute(Qt::WA_NoSystemBackground); + setFocusPolicy(Qt::ClickFocus); +#else + setBackgroundMode(Qt::NoBackground); +#endif +} + +void QOSGWidget::createContext() +{ + osg::DisplaySettings* ds = osg::DisplaySettings::instance(); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + + traits->readDISPLAY(); + if (traits->displayNum<0) traits->displayNum = 0; + + traits->windowName = "osgViewerQt"; + traits->screenNum = 0; + traits->x = x(); + traits->y = y(); + traits->width = width(); + traits->height = height(); + traits->alpha = ds->getMinimumNumAlphaBits(); + traits->stencil = ds->getMinimumNumStencilBits(); + traits->windowDecoration = false; + traits->doubleBuffer = true; + traits->sharedContext = 0; + traits->sampleBuffers = ds->getMultiSamples(); + traits->samples = ds->getNumMultiSamples(); + +#if defined(__APPLE__) + // Extract a WindowPtr from the HIViewRef that QWidget::winId() returns. + // Without this change, the peer tries to call GetWindowPort on the HIViewRef + // which returns 0 and we only render white. + traits->inheritedWindowData = new WindowData(HIViewGetWindow((HIViewRef)winId())); + +#else // all others + traits->inheritedWindowData = new WindowData(winId()); +#endif + + + if (ds->getStereo()) + { + switch(ds->getStereoMode()) + { + case(osg::DisplaySettings::QUAD_BUFFER): traits->quadBufferStereo = true; break; + case(osg::DisplaySettings::VERTICAL_INTERLACE): + case(osg::DisplaySettings::CHECKERBOARD): + case(osg::DisplaySettings::HORIZONTAL_INTERLACE): traits->stencil = 8; break; + default: break; + } + } + + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits.get()); + _gw = dynamic_cast(gc.get()); + + // get around dearanged traits on X11 (MTCompositeViewer only) + if (_overrideTraits) + { + traits->x = x(); + traits->y = y(); + traits->width = width(); + traits->height = height(); + } + +} + +#ifndef WIN32 +void QOSGWidget::destroyEvent(bool destroyWindow, bool destroySubWindows) +{ + _gw->getEventQueue()->closeWindow(); +} + + +void QOSGWidget::closeEvent( QCloseEvent * event ) +{ +#ifndef USE_QT4 + event->accept(); +#endif + + _gw->getEventQueue()->closeWindow(); +} + + +void QOSGWidget::resizeEvent( QResizeEvent * event ) +{ + const QSize & size = event->size(); + _gw->getEventQueue()->windowResize(0, 0, size.width(), size.height() ); + _gw->resized(0, 0, size.width(), size.height()); +} + +void QOSGWidget::keyPressEvent( QKeyEvent* event ) +{ +#if USE_QT4 + _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data() ) ); +#else + _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) event->ascii() ); +#endif +} + +void QOSGWidget::keyReleaseEvent( QKeyEvent* event ) +{ +#if USE_QT4 + int c = *event->text().toAscii().data(); +#else + int c = event->ascii(); +#endif + + _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) (c) ); +} + +void QOSGWidget::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; + } + _gw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button); +} +void QOSGWidget::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; + } + _gw->getEventQueue()->mouseDoubleButtonPress(event->x(), event->y(), button); +} +void QOSGWidget::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; + } + _gw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button); +} + +void QOSGWidget::mouseMoveEvent( QMouseEvent* event ) +{ + _gw->getEventQueue()->mouseMotion(event->x(), event->y()); +} +#endif + + + + +void CompositeViewerQOSG::Tile() +{ + int n = getNumViews() - 1; // -1 to account for dummy view + + for ( int i = 0; i < n; ++i ) + { + osgViewer::View * view = getView(i+1); // +1 to account for dummy view + view->getCamera()->setViewport( new osg::Viewport( 0, i*height()/n , width(), height()/n ) ); + view->getCamera()->setProjectionMatrixAsPerspective( 30.0f, double( width() ) / double( height()/n ), 1.0f, 10000.0f ); + } +} + + +void CompositeViewerQOSG::AddView( osg::Node * scene ) +{ + osgViewer::View* view = new osgViewer::View; + addView(view); + + view->setSceneData( scene ); + view->setCameraManipulator(new osgGA::TrackballManipulator); + + // add the state manipulator + osg::ref_ptr statesetManipulator = new osgGA::StateSetManipulator; + statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet()); + + view->getCamera()->setGraphicsContext( getGraphicsWindow() ); + view->getCamera()->setClearColor( osg::Vec4( 0.08, 0.08, 0.5, 1.0 ) ); + Tile(); +} + +void CompositeViewerQOSG::RemoveView() +{ + if ( getNumViews() > 1 ) + { + removeView( getView( getNumViews() - 1 ) ); + } + Tile(); +} + + +#if USE_QT4 +// we use this wrapper for CompositeViewer ONLY because of the timer +// NOTE: this is a workaround because we're not using QT's moc precompiler here. +// +class QViewerTimer : public QWidget +{ + + public: + + QViewerTimer (int fps = 20, QWidget * parent = 0, WindowFlags f = 0): + QWidget (parent, f) + { + _viewer = new osgViewer::CompositeViewer (); + _viewer->setThreadingModel(osgViewer::CompositeViewer::DrawThreadPerContext); + connect(&_timer, SIGNAL(timeout()), this, SLOT(repaint())); + _timer.start(1000.0f/fps); + } + + ~QViewerTimer () + { + _timer.stop (); + } + + virtual void paintEvent (QPaintEvent * event) { _viewer->frame(); } + + osg::ref_ptr _viewer; + QTimer _timer; + +}; +#endif + +void setupHandlers(osgViewer::View * viewer) +{ + // add the state manipulator + viewer->addEventHandler( new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()) ); + + // add the thread model handler + viewer->addEventHandler(new osgViewer::ThreadingHandler); + + // add the window size toggle handler + viewer->addEventHandler(new osgViewer::WindowSizeHandler); + + // add the stats handler + viewer->addEventHandler(new osgViewer::StatsHandler); +} diff --git a/src/ui/map3D/QOSGWidget.h b/src/ui/map3D/QOSGWidget.h new file mode 100644 index 000000000..32b597374 --- /dev/null +++ b/src/ui/map3D/QOSGWidget.h @@ -0,0 +1,208 @@ +/* OpenSceneGraph example, osganimate. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include + +#if defined(_MSC_VER) && defined(OSG_DISABLE_MSVC_WARNINGS) + // disable warning "'QtConcurrent::BlockSizeManager' : assignment operator could not be generated" + #pragma warning( disable : 4512 ) +#endif + +#if USE_QT4 + + #include + #include + #include + #include + #include + #include + using Qt::WindowFlags; + +#else + + class QWidget; + #include + #include + #include + + #define WindowFlags WFlags + +#endif + + +#include +#include +#include +#include + +#include + +#if defined(WIN32) && !defined(__CYGWIN__) +#include +typedef HWND WindowHandle; +typedef osgViewer::GraphicsWindowWin32::WindowData WindowData; +#elif defined(__APPLE__) // Assume using Carbon on Mac. +#include +typedef WindowRef WindowHandle; +typedef osgViewer::GraphicsWindowCarbon::WindowData WindowData; +#else // all other unix +#include +typedef Window WindowHandle; +typedef osgViewer::GraphicsWindowX11::WindowData WindowData; +#endif + + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#ifndef QOSGWIDGET_H +#define QOSGWIDGET_H + +class QOSGWidget : public QWidget +{ + public: + + QOSGWidget( QWidget * parent = 0, const char * name = 0, WindowFlags f = 0, bool overrideTraits = false); + + virtual ~QOSGWidget() {} + + osgViewer::GraphicsWindow* getGraphicsWindow() { return _gw.get(); } + const osgViewer::GraphicsWindow* getGraphicsWindow() const { return _gw.get(); } + + protected: + + void init(); + void createContext(); + + // The GraphincsWindowWin32 implementation already takes care of message handling. + // We don't want to relay these on Windows, it will just cause duplicate messages + // with further problems downstream (i.e. not being able to throw the trackball +#ifndef WIN32 + virtual void mouseDoubleClickEvent ( QMouseEvent * event ); + virtual void closeEvent( QCloseEvent * event ); + virtual void destroyEvent( bool destroyWindow = true, bool destroySubWindows = true); + virtual void resizeEvent( QResizeEvent * 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 ); +#endif + osg::ref_ptr _gw; + bool _overrideTraits; +}; + +class ViewerQOSG : public osgViewer::Viewer, public QOSGWidget +{ + public: + + ViewerQOSG(QWidget * parent = 0, const char * name = 0, WindowFlags f = 0, int fps = 20): + QOSGWidget( parent, name, f ) + { + setThreadingModel(osgViewer::Viewer::SingleThreaded); + + connect(&_timer, SIGNAL(timeout()), this, SLOT(update())); + _timer.start(1000.0f/fps); + } + + void updateCamera() + { + getCamera()->setViewport(new osg::Viewport(0,0,width(),height())); + // we want an aspect ratio of 1.0, not: static_cast(width())/static_cast(height()) + getCamera()->setProjectionMatrixAsPerspective(30.0f, 1.0f , 1.0f, 10000.0f); + getCamera()->setGraphicsContext(getGraphicsWindow()); + } + + virtual void paintEvent( QPaintEvent * event ) { frame(); } + + protected: + + QTimer _timer; +}; + + +class CompositeViewerQOSG : public osgViewer::CompositeViewer, public QOSGWidget +{ + public: + CompositeViewerQOSG(QWidget * parent = 0, const char * name = 0, WindowFlags f = 0, int fps = 20) + : QOSGWidget( parent, name, f ) + { + setThreadingModel(osgViewer::CompositeViewer::SingleThreaded); + + connect(&_timer, SIGNAL(timeout()), this, SLOT(repaint())); + + // The composite viewer needs at least one view to work + // Create a dummy view with a zero sized viewport and no + // scene to keep the viewer alive. + osgViewer::View * pView = new osgViewer::View; + pView->getCamera()->setGraphicsContext( getGraphicsWindow() ); + pView->getCamera()->setViewport( 0, 0, 0, 0 ); + addView( pView ); + + // Clear the viewer of removed views + getGraphicsWindow()->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + getGraphicsWindow()->setClearColor( osg::Vec4( 0.08, 0.08, 0.5, 1.0 ) ); + + // The app would hang on exit when using start(1). Behaves better with 10 + // like the non-composite viewer. Was this just a typo? + _timer.start(1000.0f/fps); + } + + virtual void paintEvent( QPaintEvent * event ) { frame(); } + + void keyPressEvent( QKeyEvent* event ) + { + if ( event->text() == "a" ) + { + AddView( _scene.get() ); + } + + if ( event->text() == "r" ) + { + RemoveView(); + } + + QOSGWidget::keyPressEvent( event ); + } + + + void AddView( osg::Node * scene ); + void RemoveView(); + void Tile(); + + osg::ref_ptr< osg::Node > _scene; + + protected: + QTimer _timer; +}; + +void setupHandlers(osgViewer::View * viewer); + + +#endif // QOSGWIDGET_H + -- 2.22.0