WGEViewer.cpp 11.6 KB
Newer Older
ebaum's avatar
ebaum committed
1 2
//---------------------------------------------------------------------------
//
3
// Project: OpenWalnut ( http://www.openwalnut.org )
ebaum's avatar
ebaum committed
4
//
5 6
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
ebaum's avatar
ebaum committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

25 26 27 28 29
#include <string>
#include <iostream>

#include <osg/ShapeDrawable>
#include <osg/Geode>
30
#include <osg/Camera>
31 32 33 34 35 36 37 38 39 40 41 42 43

#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/UFOManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/View>

#include <osgDB/ReadFile>

44 45
#include "core/common/WLogger.h"

46
#include "WGE2DManipulator.h"
47
#include "WGEGroupNode.h"
48
#include "WGENoOpManipulator.h"
49
#include "WGEZoomTrackballManipulator.h"
50
#include "WGraphicsEngine.h"
51
#include "WPickHandler.h"
52
#include "WMouseLocationHandler.h"
53
#include "exceptions/WGEInitFailed.h"
54

55 56
#include "core/common/WConditionOneShot.h"
#include "core/common/WThreadedRunner.h"
57

ebaum's avatar
ebaum committed
58
#include "WGEViewer.h"
59

60 61 62 63 64 65 66 67 68 69 70
WGEViewer::WGEViewer( std::string name, osg::ref_ptr<osg::Referenced> wdata, int x, int y, int width, int height,
                      WGECamera::ProjectionMode projectionMode ):
    WGEGraphicsWindow( wdata, x, y, width, height ),
    boost::enable_shared_from_this< WGEViewer >(),
    m_name( name ),
    m_scene( new WGEGroupNode ),
    m_rendered( WBoolFlag::SPtr( new WBoolFlag( new WConditionOneShot(), false ) ) ),
    m_screenCapture( new WGEScreenCapture() ),
    m_inAnimationMode( false ),
    m_effectHorizon( new WGEViewerEffectHorizon() ),
    m_effectVignette( new WGEViewerEffectVignette() ),
71 72
    m_effectImageOverlay( new WGEViewerEffectImageOverlay() ),
    m_paused( false )
73 74 75 76 77
{
    try
    {
        m_View = osg::ref_ptr<osgViewer::Viewer>( new osgViewer::Viewer );

78 79 80
        osg::ref_ptr< WGECamera > cam( new WGECamera( width, height, projectionMode ) );
        m_View->setCamera( cam );
        m_queryCallback = new QueryCallback( cam, m_rendered );
81
        m_View->getCamera()->setInitialDrawCallback( m_queryCallback );
82
        m_View->getCamera()->setFinalDrawCallback( m_screenCapture );
83

84 85
        m_View->getCamera()->setGraphicsContext( m_GraphicsWindow.get() );

86 87 88
        m_mouseLocationHandler = new WMouseLocationHandler( name );
        m_View->addEventHandler( m_mouseLocationHandler );

89 90 91 92 93
        switch( projectionMode )
        {
            case( WGECamera::ORTHOGRAPHIC ):
                m_pickHandler = new WPickHandler( name );
                m_View->addEventHandler( m_pickHandler );
94
                if( name != std::string( "Main View" ) )
95
                    break;
96
                /* FALLTHRU */
97 98 99 100 101 102 103 104 105 106
            case( WGECamera::PERSPECTIVE ):
                // camera manipulator
                m_View->setCameraManipulator( new WGEZoomTrackballManipulator() );

                m_View->setLightingMode( osg::View::HEADLIGHT ); // this is the default anyway

                break;
            case( WGECamera::TWO_D ):
                // no manipulators nor gui handlers
                break;
107 108 109 110
            case( WGECamera::TWO_D_UNIT ):
                // use no-op handler by default
                m_View->setCameraManipulator( new WGENoOpManipulator() );
                break;
111 112 113 114 115 116
            default:
                throw WGEInitFailed( std::string( "Unknown projection mode" ) );
        }

        // add the stats handler
        m_View->addEventHandler( new osgViewer::StatsHandler );
117 118

        // Properties of the view. Collects props of the effects and similar
119
        m_properties = boost::shared_ptr< WProperties >( new WProperties( "Viewer Properties", "The view's properties" ) );
120 121 122 123 124 125 126 127 128 129 130 131
        m_bgColor = m_properties->addProperty( "Background Color", "Default background color if not overwritten by a camera effect.",
                                               defaultColor::WHITE,
                                               boost::bind( &WGEViewer::updateBgColor, this ) );
        m_throwing = m_properties->addProperty( "Throwing", "If checked, you can grab the scene and throw it. It will keep the rotation impulse.",
                                                false,
                                                boost::bind( &WGEViewer::updateThrowing, this ) );

        WPropGroup effects = m_properties->addPropertyGroup( "Camera Effects", "Several effects that to not depend on any scene content." );
        effects->addProperty( m_effectHorizon->getProperties() );
        effects->addProperty( m_effectVignette->getProperties() );
        effects->addProperty( m_effectImageOverlay->getProperties() );

132 133 134 135 136 137 138
        // scene node
        m_View->setSceneData( m_scene );
        // add effects to it:
        m_scene->insert( m_effectVignette );
        m_scene->insert( m_effectImageOverlay );
        m_scene->insert( m_effectHorizon );

139 140 141
        // apply the above default
        updateThrowing();
        updateBgColor();
142 143 144 145 146 147 148 149 150 151 152 153 154
    }
    catch( ... )
    {
        throw WGEInitFailed( std::string( "Initialization of WGEViewer failed" ) );
    }
}

WGEViewer::~WGEViewer()
{
    // cleanup
    close();
}

155
osg::ref_ptr<osgViewer::Viewer> WGEViewer::getView()
156 157 158 159 160 161
{
    return m_View;
}

void WGEViewer::setCameraManipulator( osg::ref_ptr<osgGA::MatrixManipulator> manipulator )
{
162
    if( !m_inAnimationMode )
163 164 165
    {
        m_View->setCameraManipulator( manipulator );
    }
166 167 168 169 170 171 172
}

osg::ref_ptr<osgGA::MatrixManipulator> WGEViewer::getCameraManipulator()
{
    return m_View->getCameraManipulator();
}

173
void WGEViewer::setCamera( osg::ref_ptr<WGECamera> camera )
174 175 176 177 178
{
    m_View->setCamera( camera );
    // redraw request?? No since it redraws permanently and uses the new settings
}

179
osg::ref_ptr<WGECamera> WGEViewer::getCamera()
180
{
181
    return dynamic_cast< WGECamera* >( m_View->getCamera() );
182 183 184 185
}

void WGEViewer::setScene( osg::ref_ptr< WGEGroupNode > node )
{
186
    m_sceneMainNode = node;
187

188
    m_effectImageOverlay->setReferenceViewer( shared_from_this() );
189

190 191 192 193 194 195
    m_scene->clear();
    m_scene->insert( m_sceneMainNode );
    // add effects to scene node. We cleared it earlier.
    m_scene->insert( m_effectVignette );
    m_scene->insert( m_effectImageOverlay );
    m_scene->insert( m_effectHorizon );
196 197 198 199
}

osg::ref_ptr< WGEGroupNode > WGEViewer::getScene()
{
200
    return m_sceneMainNode;
201 202
}

203 204 205 206 207 208 209 210 211 212 213 214 215 216
void WGEViewer::updateThrowing()
{
    WGEZoomTrackballManipulator* manipulator = dynamic_cast< WGEZoomTrackballManipulator* >( getCameraManipulator().get() );
    if( manipulator )
    {
        manipulator->setThrow( m_throwing->get() );
    }
}

void WGEViewer::updateBgColor()
{
    m_View->getCamera()->setClearColor( m_bgColor->get() );
}

217 218
void WGEViewer::setBgColor( const WColor& bgColor )
{
219 220 221 222 223 224
    m_bgColor->set( bgColor );
}

WColor WGEViewer::getBgColor() const
{
    return m_bgColor->get();
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
}

void WGEViewer::paint()
{
    m_View->frame();
}

void WGEViewer::resize( int width, int height )
{
    m_View->getEventQueue()->windowResize( 0, 0, width, height );

    WGEGraphicsWindow::resize( width, height );

    // also update the camera
    m_View->getCamera()->setViewport( 0, 0, width, height );
    WGECamera* camera = dynamic_cast< WGECamera* >( m_View->getCamera() );
    if( camera )
    {
        camera->resize();
    }
}

void WGEViewer::close()
{
249 250 251
    // delete/unset all the objects we sponsored a "shared_from_this" pointer to ensure the viewer gets deleted after close
    m_effectImageOverlay->setReferenceViewer( WGEViewer::SPtr() );

252 253 254 255 256 257 258 259 260 261 262 263 264 265
    // forward close event
    WGEGraphicsWindow::close();
}

std::string WGEViewer::getName() const
{
    return m_name;
}

osg::ref_ptr< WPickHandler > WGEViewer::getPickHandler()
{
    return m_pickHandler;
}

266 267 268 269 270
osg::ref_ptr< WMouseLocationHandler > WGEViewer::getMouseLocationHandler()
{
    return m_mouseLocationHandler;
}

271 272 273 274 275
void WGEViewer::reset()
{
    m_View->home();
}

276 277 278 279 280
WGEScreenCapture::RefPtr WGEViewer::getScreenCapture() const
{
    return m_screenCapture;
}

281 282 283 284 285 286 287 288 289 290
std::string WGEViewer::getOpenGLVendor() const
{
    return m_queryCallback->getVendor();
}

WBoolFlag::SPtr WGEViewer::isFrameRendered() const
{
    return m_rendered;
}

291
WGEViewer::QueryCallback::QueryCallback( osg::ref_ptr<WGECamera> camera, WBoolFlag::SPtr run ):
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
    m_vendor( "" ),
    m_run( run ),
    m_camera( camera )
{
    // init
}

WGEViewer::QueryCallback::~QueryCallback()
{
    // cleanup
}

void WGEViewer::QueryCallback::operator()( osg::RenderInfo& /* renderInfo */ ) const
{
    const GLubyte* vendor = glGetString( GL_VENDOR );
    m_vendor = reinterpret_cast< const char* >( vendor );

    // job done. De-register.
    m_camera->setInitialDrawCallback( NULL );
    m_run->set( true );
}

std::string WGEViewer::QueryCallback::getVendor() const
{
    return m_vendor;
}

319 320
WGEAnimationManipulator::RefPtr WGEViewer::animationMode( bool on )
{
321
    if( m_inAnimationMode && !on ) // turn off mode
322 323 324 325 326 327 328
    {
        m_inAnimationMode = false;

        // restore old manipulator
        m_View->setCameraManipulator( m_animationModeManipulatorBackup );
        return NULL;
    }
329
    else if( !m_inAnimationMode && on ) // turn on
330 331 332 333 334 335 336 337 338 339 340
    {
        m_inAnimationMode = true;

        // backup
        m_animationModeManipulatorBackup = getCameraManipulator();

        // create animation manipulator
        WGEAnimationManipulator::RefPtr anim = new WGEAnimationManipulator();
        m_View->setCameraManipulator( anim );
        return anim;
    }
341
    else if( m_inAnimationMode ) // already on
342 343 344 345 346 347 348 349 350 351 352 353 354
    {
        return dynamic_cast< WGEAnimationManipulator* >( getCameraManipulator().get() );
    }

    // else: do nothing
    return NULL;
}

bool WGEViewer::isAnimationMode() const
{
    return m_inAnimationMode;
}

355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
WGEViewerEffectHorizon::SPtr WGEViewer::getBackground()
{
    return m_effectHorizon;
}

WGEViewerEffectImageOverlay::SPtr WGEViewer::getImageOverlay()
{
    return m_effectImageOverlay;
}

WGEViewerEffectVignette::SPtr WGEViewer::getVignette()
{
    return m_effectVignette;
}

WGEViewerEffectHorizon::ConstSPtr WGEViewer::getBackground() const
{
    return m_effectHorizon;
}

WGEViewerEffectImageOverlay::ConstSPtr WGEViewer::getImageOverlay() const
{
    return m_effectImageOverlay;
}

WGEViewerEffectVignette::ConstSPtr WGEViewer::getVignette() const
{
    return m_effectVignette;
}
384 385 386 387 388

WProperties::SPtr WGEViewer::getProperties() const
{
    return m_properties;
}
389 390 391 392 393 394 395 396

void WGEViewer::setEffectsActiveDefault( bool activeByDefault )
{
    getBackground()->setEnabledByDefault( activeByDefault );
    getImageOverlay()->setEnabledByDefault( activeByDefault );
    getVignette()->setEnabledByDefault( activeByDefault );
}

397 398 399 400 401 402 403 404 405
void WGEViewer::setPaused( bool pause )
{
    m_paused = pause;
}

bool WGEViewer::getPaused() const
{
    return m_paused;
}
406 407 408 409 410 411 412 413 414 415

void WGEViewer::handleVisibilityChange( bool visible )
{
    getView()->getScene()->getSceneData()->setNodeMask( visible * 0xFFFFFFFF );
}

void WGEViewer::requestContinuousUpdate( bool continuous )
{
    getView()->requestContinuousUpdate( continuous );
}