OpenWalnut
1.4.0
|
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 00051 #include "../common/WConditionOneShot.h" 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, int width, int height, 00057 WGECamera::ProjectionMode projectionMode ): 00058 WGEGraphicsWindow( wdata, x, y, width, height ), 00059 boost::enable_shared_from_this< WGEViewer >(), 00060 m_name( name ), 00061 m_scene( new WGEGroupNode ), 00062 m_rendered( WBoolFlag::SPtr( new WBoolFlag( new WConditionOneShot(), false ) ) ), 00063 m_screenCapture( new WGEScreenCapture() ), 00064 m_inAnimationMode( false ), 00065 m_effectHorizon( new WGEViewerEffectHorizon() ), 00066 m_effectVignette( new WGEViewerEffectVignette() ), 00067 m_effectImageOverlay( new WGEViewerEffectImageOverlay() ) 00068 { 00069 try 00070 { 00071 #ifdef WGEMODE_MULTITHREADED 00072 m_View = osg::ref_ptr<osgViewer::View>( new osgViewer::View ); 00073 #else 00074 // on mac, this is a viewer! 00075 m_View = osg::ref_ptr<osgViewer::Viewer>( new osgViewer::Viewer ); 00076 #endif 00077 00078 osg::ref_ptr< WGECamera > cam( new WGECamera( width, height, projectionMode ) ); 00079 m_View->setCamera( cam ); 00080 m_queryCallback = new QueryCallback( cam, m_rendered ); 00081 m_View->getCamera()->setInitialDrawCallback( m_queryCallback ); 00082 m_View->getCamera()->setFinalDrawCallback( m_screenCapture ); 00083 00084 #ifdef WGEMODE_MULTITHREADED 00085 m_View->getCamera()->setGraphicsContext( m_GraphicsContext.get() ); 00086 #else 00087 m_View->getCamera()->setGraphicsContext( m_GraphicsWindow.get() ); 00088 #endif 00089 00090 switch( projectionMode ) 00091 { 00092 case( WGECamera::ORTHOGRAPHIC ): 00093 m_pickHandler = new WPickHandler( name ); 00094 m_View->addEventHandler( m_pickHandler ); 00095 if( name != std::string( "Main View" ) ) 00096 break; 00097 case( WGECamera::PERSPECTIVE ): 00098 // camera manipulator 00099 m_View->setCameraManipulator( new WGEZoomTrackballManipulator() ); 00100 00101 m_View->setLightingMode( osg::View::HEADLIGHT ); // this is the default anyway 00102 00103 break; 00104 case( WGECamera::TWO_D ): 00105 // no manipulators nor gui handlers 00106 break; 00107 case( WGECamera::TWO_D_UNIT ): 00108 // use no-op handler by default 00109 m_View->setCameraManipulator( new WGENoOpManipulator() ); 00110 break; 00111 default: 00112 throw WGEInitFailed( std::string( "Unknown projection mode" ) ); 00113 } 00114 00115 // add the stats handler 00116 m_View->addEventHandler( new osgViewer::StatsHandler ); 00117 00118 // Properties of the view. Collects props of the effects and similar 00119 m_properties = boost::shared_ptr< WProperties >( new WProperties( "Properties", "The view's properties" ) ); 00120 m_bgColor = m_properties->addProperty( "Background Color", "Default background color if not overwritten by a camera effect.", 00121 defaultColor::WHITE, 00122 boost::bind( &WGEViewer::updateBgColor, this ) ); 00123 m_throwing = m_properties->addProperty( "Throwing", "If checked, you can grab the scene and throw it. It will keep the rotation impulse.", 00124 false, 00125 boost::bind( &WGEViewer::updateThrowing, this ) ); 00126 00127 WPropGroup effects = m_properties->addPropertyGroup( "Camera Effects", "Several effects that to not depend on any scene content." ); 00128 effects->addProperty( m_effectHorizon->getProperties() ); 00129 effects->addProperty( m_effectVignette->getProperties() ); 00130 effects->addProperty( m_effectImageOverlay->getProperties() ); 00131 00132 // scene node 00133 m_View->setSceneData( m_scene ); 00134 // add effects to it: 00135 m_scene->insert( m_effectVignette ); 00136 m_scene->insert( m_effectImageOverlay ); 00137 m_scene->insert( m_effectHorizon ); 00138 00139 // apply the above default 00140 updateThrowing(); 00141 updateBgColor(); 00142 } 00143 catch( ... ) 00144 { 00145 throw WGEInitFailed( std::string( "Initialization of WGEViewer failed" ) ); 00146 } 00147 } 00148 00149 WGEViewer::~WGEViewer() 00150 { 00151 // cleanup 00152 close(); 00153 } 00154 00155 #ifdef WGEMODE_SINGLETHREADED 00156 osg::ref_ptr<osgViewer::Viewer> 00157 #else 00158 osg::ref_ptr<osgViewer::View> 00159 #endif 00160 WGEViewer::getView() 00161 { 00162 return m_View; 00163 } 00164 00165 void WGEViewer::setCameraManipulator( osg::ref_ptr<osgGA::MatrixManipulator> manipulator ) 00166 { 00167 if( !m_inAnimationMode ) 00168 { 00169 m_View->setCameraManipulator( manipulator ); 00170 } 00171 } 00172 00173 osg::ref_ptr<osgGA::MatrixManipulator> WGEViewer::getCameraManipulator() 00174 { 00175 return m_View->getCameraManipulator(); 00176 } 00177 00178 void WGEViewer::setCamera( osg::ref_ptr<WGECamera> camera ) 00179 { 00180 m_View->setCamera( camera ); 00181 // redraw request?? No since it redraws permanently and uses the new settings 00182 } 00183 00184 osg::ref_ptr<WGECamera> WGEViewer::getCamera() 00185 { 00186 return dynamic_cast< WGECamera* >( m_View->getCamera() ); 00187 } 00188 00189 void WGEViewer::setScene( osg::ref_ptr< WGEGroupNode > node ) 00190 { 00191 m_sceneMainNode = node; 00192 00193 m_effectImageOverlay->setReferenceViewer( shared_from_this() ); 00194 00195 m_scene->clear(); 00196 m_scene->insert( m_sceneMainNode ); 00197 // add effects to scene node. We cleared it earlier. 00198 m_scene->insert( m_effectVignette ); 00199 m_scene->insert( m_effectImageOverlay ); 00200 m_scene->insert( m_effectHorizon ); 00201 } 00202 00203 osg::ref_ptr< WGEGroupNode > WGEViewer::getScene() 00204 { 00205 return m_sceneMainNode; 00206 } 00207 00208 void WGEViewer::updateThrowing() 00209 { 00210 WGEZoomTrackballManipulator* manipulator = dynamic_cast< WGEZoomTrackballManipulator* >( getCameraManipulator().get() ); 00211 if( manipulator ) 00212 { 00213 manipulator->setThrow( m_throwing->get() ); 00214 } 00215 } 00216 00217 void WGEViewer::updateBgColor() 00218 { 00219 m_View->getCamera()->setClearColor( m_bgColor->get() ); 00220 } 00221 00222 void WGEViewer::setBgColor( const WColor& bgColor ) 00223 { 00224 m_bgColor->set( bgColor ); 00225 } 00226 00227 WColor WGEViewer::getBgColor() const 00228 { 00229 return m_bgColor->get(); 00230 } 00231 00232 void WGEViewer::paint() 00233 { 00234 #ifdef WGEMODE_SINGLETHREADED 00235 m_View->frame(); 00236 #endif 00237 } 00238 00239 void WGEViewer::resize( int width, int height ) 00240 { 00241 m_View->getEventQueue()->windowResize( 0, 0, width, height ); 00242 00243 WGEGraphicsWindow::resize( width, height ); 00244 00245 // also update the camera 00246 m_View->getCamera()->setViewport( 0, 0, width, height ); 00247 WGECamera* camera = dynamic_cast< WGECamera* >( m_View->getCamera() ); 00248 if( camera ) 00249 { 00250 camera->resize(); 00251 } 00252 } 00253 00254 void WGEViewer::close() 00255 { 00256 // forward close event 00257 WGEGraphicsWindow::close(); 00258 } 00259 00260 std::string WGEViewer::getName() const 00261 { 00262 return m_name; 00263 } 00264 00265 osg::ref_ptr< WPickHandler > WGEViewer::getPickHandler() 00266 { 00267 return m_pickHandler; 00268 } 00269 00270 void WGEViewer::reset() 00271 { 00272 m_View->home(); 00273 } 00274 00275 WGEScreenCapture::RefPtr WGEViewer::getScreenCapture() const 00276 { 00277 return m_screenCapture; 00278 } 00279 00280 std::string WGEViewer::getOpenGLVendor() const 00281 { 00282 return m_queryCallback->getVendor(); 00283 } 00284 00285 WBoolFlag::SPtr WGEViewer::isFrameRendered() const 00286 { 00287 return m_rendered; 00288 } 00289 00290 WGEViewer::QueryCallback::QueryCallback( osg::ref_ptr<WGECamera> camera, WBoolFlag::SPtr run ): 00291 m_vendor( "" ), 00292 m_run( run ), 00293 m_camera( camera ) 00294 { 00295 // init 00296 } 00297 00298 WGEViewer::QueryCallback::~QueryCallback() 00299 { 00300 // cleanup 00301 } 00302 00303 void WGEViewer::QueryCallback::operator()( osg::RenderInfo& /* renderInfo */ ) const 00304 { 00305 const GLubyte* vendor = glGetString( GL_VENDOR ); 00306 m_vendor = reinterpret_cast< const char* >( vendor ); 00307 00308 // job done. De-register. 00309 m_camera->setInitialDrawCallback( NULL ); 00310 m_run->set( true ); 00311 } 00312 00313 std::string WGEViewer::QueryCallback::getVendor() const 00314 { 00315 return m_vendor; 00316 } 00317 00318 WGEAnimationManipulator::RefPtr WGEViewer::animationMode( bool on ) 00319 { 00320 if( m_inAnimationMode && !on ) // turn off mode 00321 { 00322 m_inAnimationMode = false; 00323 00324 // restore old manipulator 00325 m_View->setCameraManipulator( m_animationModeManipulatorBackup ); 00326 return NULL; 00327 } 00328 else if( !m_inAnimationMode && on ) // turn on 00329 { 00330 m_inAnimationMode = true; 00331 00332 // backup 00333 m_animationModeManipulatorBackup = getCameraManipulator(); 00334 00335 // create animation manipulator 00336 WGEAnimationManipulator::RefPtr anim = new WGEAnimationManipulator(); 00337 m_View->setCameraManipulator( anim ); 00338 return anim; 00339 } 00340 else if( m_inAnimationMode ) // already on 00341 { 00342 return dynamic_cast< WGEAnimationManipulator* >( getCameraManipulator().get() ); 00343 } 00344 00345 // else: do nothing 00346 return NULL; 00347 } 00348 00349 bool WGEViewer::isAnimationMode() const 00350 { 00351 return m_inAnimationMode; 00352 } 00353 00354 WGEViewerEffectHorizon::SPtr WGEViewer::getBackground() 00355 { 00356 return m_effectHorizon; 00357 } 00358 00359 WGEViewerEffectImageOverlay::SPtr WGEViewer::getImageOverlay() 00360 { 00361 return m_effectImageOverlay; 00362 } 00363 00364 WGEViewerEffectVignette::SPtr WGEViewer::getVignette() 00365 { 00366 return m_effectVignette; 00367 } 00368 00369 WGEViewerEffectHorizon::ConstSPtr WGEViewer::getBackground() const 00370 { 00371 return m_effectHorizon; 00372 } 00373 00374 WGEViewerEffectImageOverlay::ConstSPtr WGEViewer::getImageOverlay() const 00375 { 00376 return m_effectImageOverlay; 00377 } 00378 00379 WGEViewerEffectVignette::ConstSPtr WGEViewer::getVignette() const 00380 { 00381 return m_effectVignette; 00382 } 00383 00384 WProperties::SPtr WGEViewer::getProperties() const 00385 { 00386 return m_properties; 00387 } 00388 00389 void WGEViewer::setEffectsActiveDefault( bool activeByDefault ) 00390 { 00391 getBackground()->setEnabledByDefault( activeByDefault ); 00392 getImageOverlay()->setEnabledByDefault( activeByDefault ); 00393 getVignette()->setEnabledByDefault( activeByDefault ); 00394 } 00395