OpenWalnut  1.4.0
WGEViewer.cpp
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