OpenWalnut 1.3.1
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 #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