OpenWalnut 1.3.1
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #include <string> 00026 #include <iostream> 00027 00028 #include <osg/ShapeDrawable> 00029 #include <osg/Geode> 00030 #include <osg/Camera> 00031 00032 #include <osgGA/FlightManipulator> 00033 #include <osgGA/DriveManipulator> 00034 #include <osgGA/UFOManipulator> 00035 #include <osgGA/KeySwitchMatrixManipulator> 00036 #include <osgGA/StateSetManipulator> 00037 #include <osgGA/AnimationPathManipulator> 00038 #include <osgGA/TerrainManipulator> 00039 #include <osgViewer/ViewerEventHandlers> 00040 #include <osgViewer/View> 00041 00042 #include <osgDB/ReadFile> 00043 00044 #include "exceptions/WGEInitFailed.h" 00045 #include "WGE2DManipulator.h" 00046 #include "WGEGroupNode.h" 00047 #include "WGENoOpManipulator.h" 00048 #include "WGEZoomTrackballManipulator.h" 00049 #include "WPickHandler.h" 00050 #include "../common/WConditionOneShot.h" 00051 00052 #include "../common/WThreadedRunner.h" 00053 00054 #include "WGEViewer.h" 00055 00056 WGEViewer::WGEViewer( std::string name, osg::ref_ptr<osg::Referenced> wdata, int x, int y, 00057 int width, int height, WGECamera::ProjectionMode projectionMode ) 00058 : WGEGraphicsWindow( wdata, x, y, width, height ), 00059 boost::enable_shared_from_this< WGEViewer >(), 00060 m_name( name ), 00061 m_rendered( WBoolFlag::SPtr( new WBoolFlag( new WConditionOneShot(), false ) ) ), 00062 m_screenCapture( new WGEScreenCapture() ), 00063 m_inAnimationMode( false ) 00064 { 00065 try 00066 { 00067 #ifdef WGEMODE_MULTITHREADED 00068 m_View = osg::ref_ptr<osgViewer::View>( new osgViewer::View ); 00069 #else 00070 // on mac, this is a viewer! 00071 m_View = osg::ref_ptr<osgViewer::Viewer>( new osgViewer::Viewer ); 00072 #endif 00073 00074 m_View->setCamera( new WGECamera( width, height, projectionMode ) ); 00075 m_queryCallback = new QueryCallback( m_View->getCamera(), m_rendered ); 00076 m_View->getCamera()->setInitialDrawCallback( m_queryCallback ); 00077 m_View->getCamera()->setFinalDrawCallback( m_screenCapture ); 00078 00079 #ifdef WGEMODE_MULTITHREADED 00080 m_View->getCamera()->setGraphicsContext( m_GraphicsContext.get() ); 00081 #else 00082 m_View->getCamera()->setGraphicsContext( m_GraphicsWindow.get() ); 00083 #endif 00084 00085 switch( projectionMode ) 00086 { 00087 case( WGECamera::ORTHOGRAPHIC ): 00088 m_pickHandler = new WPickHandler( name ); 00089 m_View->addEventHandler( m_pickHandler ); 00090 if( name != std::string( "Main View" ) ) 00091 break; 00092 case( WGECamera::PERSPECTIVE ): 00093 // camera manipulator 00094 m_View->setCameraManipulator( new WGEZoomTrackballManipulator() ); 00095 00096 m_View->setLightingMode( osg::View::HEADLIGHT ); // this is the default anyway 00097 00098 break; 00099 case( WGECamera::TWO_D ): 00100 // no manipulators nor gui handlers 00101 break; 00102 case( WGECamera::TWO_D_UNIT ): 00103 // use no-op handler by default 00104 m_View->setCameraManipulator( new WGENoOpManipulator() ); 00105 break; 00106 default: 00107 throw WGEInitFailed( std::string( "Unknown projection mode" ) ); 00108 } 00109 00110 // add the stats handler 00111 m_View->addEventHandler( new osgViewer::StatsHandler ); 00112 } 00113 catch( ... ) 00114 { 00115 throw WGEInitFailed( std::string( "Initialization of WGEViewer failed" ) ); 00116 } 00117 } 00118 00119 WGEViewer::~WGEViewer() 00120 { 00121 // cleanup 00122 close(); 00123 } 00124 00125 #ifdef WGEMODE_SINGLETHREADED 00126 osg::ref_ptr<osgViewer::Viewer> 00127 #else 00128 osg::ref_ptr<osgViewer::View> 00129 #endif 00130 WGEViewer::getView() 00131 { 00132 return m_View; 00133 } 00134 00135 void WGEViewer::setCameraManipulator( osg::ref_ptr<osgGA::MatrixManipulator> manipulator ) 00136 { 00137 if( !m_inAnimationMode ) 00138 { 00139 m_View->setCameraManipulator( manipulator ); 00140 } 00141 } 00142 00143 osg::ref_ptr<osgGA::MatrixManipulator> WGEViewer::getCameraManipulator() 00144 { 00145 return m_View->getCameraManipulator(); 00146 } 00147 00148 void WGEViewer::setCamera( osg::ref_ptr<osg::Camera> camera ) 00149 { 00150 m_View->setCamera( camera ); 00151 // redraw request?? No since it redraws permanently and uses the new settings 00152 } 00153 00154 osg::ref_ptr<osg::Camera> WGEViewer::getCamera() 00155 { 00156 return m_View->getCamera(); 00157 } 00158 00159 void WGEViewer::setScene( osg::ref_ptr< WGEGroupNode > node ) 00160 { 00161 m_View->setSceneData( node ); 00162 m_scene = node; 00163 } 00164 00165 osg::ref_ptr< WGEGroupNode > WGEViewer::getScene() 00166 { 00167 return m_scene; 00168 } 00169 00170 void WGEViewer::setBgColor( const WColor& bgColor ) 00171 { 00172 m_View->getCamera()->setClearColor( bgColor ); 00173 } 00174 00175 void WGEViewer::paint() 00176 { 00177 #ifdef WGEMODE_SINGLETHREADED 00178 m_View->frame(); 00179 #endif 00180 } 00181 00182 void WGEViewer::resize( int width, int height ) 00183 { 00184 m_View->getEventQueue()->windowResize( 0, 0, width, height ); 00185 00186 WGEGraphicsWindow::resize( width, height ); 00187 00188 // also update the camera 00189 m_View->getCamera()->setViewport( 0, 0, width, height ); 00190 WGECamera* camera = dynamic_cast< WGECamera* >( m_View->getCamera() ); 00191 if( camera ) 00192 { 00193 camera->resize(); 00194 } 00195 } 00196 00197 void WGEViewer::close() 00198 { 00199 // forward close event 00200 WGEGraphicsWindow::close(); 00201 } 00202 00203 std::string WGEViewer::getName() const 00204 { 00205 return m_name; 00206 } 00207 00208 osg::ref_ptr< WPickHandler > WGEViewer::getPickHandler() 00209 { 00210 return m_pickHandler; 00211 } 00212 00213 void WGEViewer::reset() 00214 { 00215 m_View->home(); 00216 } 00217 00218 WGEScreenCapture::RefPtr WGEViewer::getScreenCapture() const 00219 { 00220 return m_screenCapture; 00221 } 00222 00223 std::string WGEViewer::getOpenGLVendor() const 00224 { 00225 return m_queryCallback->getVendor(); 00226 } 00227 00228 WBoolFlag::SPtr WGEViewer::isFrameRendered() const 00229 { 00230 return m_rendered; 00231 } 00232 00233 WGEViewer::QueryCallback::QueryCallback( osg::ref_ptr<osg::Camera> camera, WBoolFlag::SPtr run ): 00234 m_vendor( "" ), 00235 m_run( run ), 00236 m_camera( camera ) 00237 { 00238 // init 00239 } 00240 00241 WGEViewer::QueryCallback::~QueryCallback() 00242 { 00243 // cleanup 00244 } 00245 00246 void WGEViewer::QueryCallback::operator()( osg::RenderInfo& /* renderInfo */ ) const 00247 { 00248 const GLubyte* vendor = glGetString( GL_VENDOR ); 00249 m_vendor = reinterpret_cast< const char* >( vendor ); 00250 00251 // job done. De-register. 00252 m_camera->setInitialDrawCallback( NULL ); 00253 m_run->set( true ); 00254 } 00255 00256 std::string WGEViewer::QueryCallback::getVendor() const 00257 { 00258 return m_vendor; 00259 } 00260 00261 WGEAnimationManipulator::RefPtr WGEViewer::animationMode( bool on ) 00262 { 00263 if( m_inAnimationMode && !on ) // turn off mode 00264 { 00265 m_inAnimationMode = false; 00266 00267 // restore old manipulator 00268 m_View->setCameraManipulator( m_animationModeManipulatorBackup ); 00269 return NULL; 00270 } 00271 else if( !m_inAnimationMode && on ) // turn on 00272 { 00273 m_inAnimationMode = true; 00274 00275 // backup 00276 m_animationModeManipulatorBackup = getCameraManipulator(); 00277 00278 // create animation manipulator 00279 WGEAnimationManipulator::RefPtr anim = new WGEAnimationManipulator(); 00280 m_View->setCameraManipulator( anim ); 00281 return anim; 00282 } 00283 else if( m_inAnimationMode ) // already on 00284 { 00285 return dynamic_cast< WGEAnimationManipulator* >( getCameraManipulator().get() ); 00286 } 00287 00288 // else: do nothing 00289 return NULL; 00290 } 00291 00292 bool WGEViewer::isAnimationMode() const 00293 { 00294 return m_inAnimationMode; 00295 } 00296