root/OpenSceneGraph/trunk/src/osgViewer/CompositeViewer.cpp @ 10588

Revision 10588, 37.3 kB (checked in by robert, 5 years ago)

Preliminary work on support for a texture object pool that is designed to help manage resources down the GPU more tightly.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[10588]1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
[5757]2 *
[10588]3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
[5757]5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
[10588]7 *
[5757]8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
[10588]10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
[5757]11 * OpenSceneGraph Public License for more details.
12*/
13
[5991]14#include <osg/GLExtensions>
15#include <osgUtil/GLObjectsVisitor>
16#include <osgGA/TrackballManipulator>
[5757]17#include <osgViewer/CompositeViewer>
[7178]18#include <osgViewer/Renderer>
[6855]19#include <osgDB/Registry>
[9997]20#include <osgDB/ReadFile>
[5757]21
[5991]22#include <osg/io_utils>
23
[5757]24using namespace osgViewer;
25
[6855]26CompositeViewer::CompositeViewer()
[5757]27{
[6855]28    constructorInit();
29}
30
[7213]31CompositeViewer::CompositeViewer(const CompositeViewer& cv,const osg::CopyOp& copyop):
[7506]32    ViewerBase()
[7213]33{
34    constructorInit();
35}
36
[6855]37CompositeViewer::CompositeViewer(osg::ArgumentParser& arguments)
38{
39    constructorInit();
[10098]40
41    arguments.getApplicationUsage()->addCommandLineOption("--SingleThreaded","Select SingleThreaded threading model for viewer.");
42    arguments.getApplicationUsage()->addCommandLineOption("--CullDrawThreadPerContext","Select CullDrawThreadPerContext threading model for viewer.");
43    arguments.getApplicationUsage()->addCommandLineOption("--DrawThreadPerContext","Select DrawThreadPerContext threading model for viewer.");
44    arguments.getApplicationUsage()->addCommandLineOption("--CullThreadPerCameraDrawThreadPerContext","Select CullThreadPerCameraDrawThreadPerContext threading model for viewer.");
45
46    arguments.getApplicationUsage()->addCommandLineOption("--run-on-demand","Set the run methods frame rate management to only rendering frames when required.");
47    arguments.getApplicationUsage()->addCommandLineOption("--run-continuous","Set the run methods frame rate management to rendering frames continuously.");
48    arguments.getApplicationUsage()->addCommandLineOption("--run-max-frame-rate","Set the run methods maximum permissable frame rate, 0.0 is default and switching off frame rate capping.");
49
50
[7447]51    std::string filename;
52    bool readConfig = false;
53    while (arguments.read("-c",filename))
54    {
55        readConfig = readConfiguration(filename) || readConfig;
56    }
57
[6855]58    while (arguments.read("--SingleThreaded")) setThreadingModel(SingleThreaded);
[7535]59    while (arguments.read("--CullDrawThreadPerContext")) setThreadingModel(CullDrawThreadPerContext);
60    while (arguments.read("--DrawThreadPerContext")) setThreadingModel(DrawThreadPerContext);
61    while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) setThreadingModel(CullThreadPerCameraDrawThreadPerContext);
[6855]62
[10098]63
64    while(arguments.read("--run-on-demand")) { setRunFrameScheme(ON_DEMAND); }
65    while(arguments.read("--run-continuous")) { setRunFrameScheme(CONTINUOUS); }
66
67    double runMaxFrameRate;
68    while(arguments.read("--run-max-frame-rate", runMaxFrameRate)) { setRunMaxFrameRate(runMaxFrameRate); }
69
70
[6855]71    osg::DisplaySettings::instance()->readCommandLine(arguments);
72    osgDB::readCommandLine(arguments);
73}
74
75void CompositeViewer::constructorInit()
76{
77    _endBarrierPosition = AfterSwapBuffers;
78    _startTick = 0;
79
[5991]80    // make sure View is safe to reference multi-threaded.
81    setThreadSafeRefUnref(true);
82
83    _frameStamp = new osg::FrameStamp;
84    _frameStamp->setFrameNumber(0);
85    _frameStamp->setReferenceTime(0);
[6051]86    _frameStamp->setSimulationTime(0);
[10588]87
[5991]88    _eventVisitor = new osgGA::EventVisitor;
[7209]89    _eventVisitor->setFrameStamp(_frameStamp.get());
[10588]90
[7209]91    _updateVisitor = new osgUtil::UpdateVisitor;
92    _updateVisitor->setFrameStamp(_frameStamp.get());
93
[9554]94    setViewerStats(new osg::Stats("CompsiteViewer"));
[5757]95}
96
97CompositeViewer::~CompositeViewer()
98{
[5995]99    osg::notify(osg::INFO)<<"CompositeViewer::~CompositeViewer()"<<std::endl;
[5991]100
101    stopThreading();
[10588]102
[5991]103    Scenes scenes;
104    getScenes(scenes);
[10588]105
[5991]106    for(Scenes::iterator sitr = scenes.begin();
107        sitr != scenes.end();
108        ++sitr)
109    {
110        Scene* scene = *sitr;
111        if (scene->getDatabasePager())
112        {
113            scene->getDatabasePager()->cancel();
114            scene->setDatabasePager(0);
115        }
116    }
117
118    Contexts contexts;
119    getContexts(contexts);
120
121    // clear out all the previously assigned operations
122    for(Contexts::iterator citr = contexts.begin();
123        citr != contexts.end();
124        ++citr)
125    {
126        (*citr)->close();
127    }
128
[9997]129    osg::notify(osg::INFO)<<"finished CompositeViewer::~CompositeViewer()"<<std::endl;
[5757]130}
[5773]131
[7447]132bool CompositeViewer::readConfiguration(const std::string& filename)
133{
134    osg::notify(osg::NOTICE)<<"CompositeViewer::readConfiguration("<<filename<<")"<<std::endl;
[9997]135    osg::ref_ptr<osg::Object> obj = osgDB::readObjectFile(filename);
136    osgViewer::View * view = dynamic_cast<osgViewer::View *>(obj.get());
137    if (view)
138    {
139        addView(view);
140        return true;
141    }
[7449]142    return false;
[7447]143}
[5991]144
[7447]145
[5991]146void CompositeViewer::addView(osgViewer::View* view)
147{
[9462]148    if (!view) return;
149
[8512]150    bool alreadyRealized = isRealized();
[10588]151
[9992]152    bool threadsWereRunning = _threadsRunning;
153    if (threadsWereRunning) stopThreading();
[6652]154
[5991]155    _views.push_back(view);
[10588]156
[7506]157    view->_viewerBase = this;
[10588]158
[9462]159    if (view->getSceneData())
[10588]160    {
[9462]161        // make sure that existing scene graph objects are allocated with thread safe ref/unref
[10588]162        if (getThreadingModel()!=ViewerBase::SingleThreaded)
[9462]163        {
164            view->getSceneData()->setThreadSafeRefUnref(true);
165        }
[10588]166
[9462]167        // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it.
168        view->getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts());
169    }
170
[7209]171    view->setFrameStamp(_frameStamp.get());
[10588]172
[8512]173    if (alreadyRealized)
174    {
175        Contexts contexts;
176        if (view->getCamera()->getGraphicsContext())
177        {
178            contexts.push_back(view->getCamera()->getGraphicsContext());
179        }
180        for(unsigned int i=0; i<view->getNumSlaves(); ++i)
181        {
182            if (view->getSlave(i)._camera->getGraphicsContext())
183            {
184                contexts.push_back(view->getSlave(i)._camera->getGraphicsContext());
185            }
186        }
187
188        for(Contexts::iterator itr = contexts.begin();
189            itr != contexts.end();
190            ++itr)
191        {
192            if (!((*itr)->isRealized()))
193            {
194                (*itr)->realize();
195            }
196        }
197
198    }
[10588]199
[9992]200    if (threadsWereRunning) startThreading();
[5991]201}
202
[6652]203void CompositeViewer::removeView(osgViewer::View* view)
204{
[7507]205    for(RefViews::iterator itr = _views.begin();
[6652]206        itr != _views.end();
207        ++itr)
208    {
209        if (*itr == view)
210        {
[9992]211            bool threadsWereRunning = _threadsRunning;
212            if (threadsWereRunning) stopThreading();
[6652]213
[7506]214            view->_viewerBase = 0;
215
[6652]216            _views.erase(itr);
217
[9992]218            if (threadsWereRunning) startThreading();
[6652]219
220            return;
221        }
222    }
223}
224
[5991]225bool CompositeViewer::isRealized() const
226{
227    Contexts contexts;
228    const_cast<CompositeViewer*>(this)->getContexts(contexts);
229
230    unsigned int numRealizedWindows = 0;
231
232    // clear out all the previously assigned operations
233    for(Contexts::iterator citr = contexts.begin();
234        citr != contexts.end();
235        ++citr)
236    {
237        if ((*citr)->isRealized()) ++numRealizedWindows;
238    }
[10588]239
[5991]240    return numRealizedWindows > 0;
241}
242
[10098]243bool CompositeViewer::checkNeedToDoFrame()
244{
245    if (_requestRedraw) return true;
246    if (_requestContinousUpdate) return true;
247
248    for(RefViews::iterator itr = _views.begin();
249        itr != _views.end();
250        ++itr)
251    {
252        osgViewer::View* view = itr->get();
253        if (view)
254        {
255            // If the database pager is going to update the scene the render flag is
256            // set so that the updates show up
257            if (view->getDatabasePager()->requiresUpdateSceneGraph() ||
258                view->getDatabasePager()->getRequestsInProgress()) return true;
259        }
260    }
261
262    // now do a eventTraversal to see if any events might require a new frame.
263    eventTraversal();
264
265    if (_requestRedraw) return true;
266    if (_requestContinousUpdate) return true;
267
268    return false;
269}
270
[5991]271int CompositeViewer::run()
272{
[7507]273    for(RefViews::iterator itr = _views.begin();
[5991]274        itr != _views.end();
275        ++itr)
276    {
277        osgViewer::View* view = itr->get();
[6760]278        if ((view->getCameraManipulator()==0) && view->getCamera()->getAllowEventFocus())
[5991]279        {
280            view->setCameraManipulator(new osgGA::TrackballManipulator());
281        }
282    }
[10588]283
[8406]284    setReleaseContextAtEndOfFrameHint(false);
285
[7535]286    return ViewerBase::run();
[5991]287}
288
289void CompositeViewer::setStartTick(osg::Timer_t tick)
290{
291    _startTick = tick;
[10588]292
[7507]293    for(RefViews::iterator vitr = _views.begin();
[7209]294        vitr != _views.end();
295        ++vitr)
296    {
297        (*vitr)->setStartTick(tick);
298    }
[10588]299
[5991]300    Contexts contexts;
301    getContexts(contexts,false);
302
303    for(Contexts::iterator citr = contexts.begin();
304        citr != contexts.end();
305        ++citr)
306    {
307        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
308        if (gw)
309        {
310            gw->getEventQueue()->setStartTick(_startTick);
311        }
312    }
313}
314
315
316void CompositeViewer::setReferenceTime(double time)
317{
318    osg::Timer_t tick = osg::Timer::instance()->tick();
319    double currentTime = osg::Timer::instance()->delta_s(_startTick, tick);
320    double delta_ticks = (time-currentTime)*(osg::Timer::instance()->getSecondsPerTick());
321    if (delta_ticks>=0) tick += osg::Timer_t(delta_ticks);
322    else tick -= osg::Timer_t(-delta_ticks);
323
324    // assign the new start tick
325    setStartTick(tick);
326}
327
328
329
[7535]330void CompositeViewer::viewerInit()
[5991]331{
332    osg::notify(osg::INFO)<<"CompositeViewer::init()"<<std::endl;
333
[7507]334    for(RefViews::iterator itr = _views.begin();
[5991]335        itr != _views.end();
336        ++itr)
337    {
[5995]338        (*itr)->init();
[5991]339    }
[5866]340}
341
[5991]342void CompositeViewer::getContexts(Contexts& contexts, bool onlyValid)
[5945]343{
[5991]344    typedef std::set<osg::GraphicsContext*> ContextSet;
345    ContextSet contextSet;
346
[8893]347    contexts.clear();
348
[7507]349    for(RefViews::iterator vitr = _views.begin();
[5991]350        vitr != _views.end();
351        ++vitr)
352    {
353        osgViewer::View* view = vitr->get();
[8893]354        osg::GraphicsContext* gc = view->getCamera() ? view->getCamera()->getGraphicsContext() : 0;
355        if (gc && (gc->valid() || !onlyValid))
[5991]356        {
[8893]357            if (contextSet.count(gc)==0)
358            {
359                contextSet.insert(gc);
360                contexts.push_back(gc);
361            }
[5991]362        }
363
364        for(unsigned int i=0; i<view->getNumSlaves(); ++i)
365        {
366            View::Slave& slave = view->getSlave(i);
[8893]367            osg::GraphicsContext* sgc = slave._camera.valid() ? slave._camera->getGraphicsContext() : 0;
368            if (sgc && (sgc->valid() || !onlyValid))
[5991]369            {
[8893]370                if (contextSet.count(sgc)==0)
371                {
372                    contextSet.insert(sgc);
373                    contexts.push_back(sgc);
374                }
[5991]375            }
376        }
377    }
[5945]378}
379
[7506]380void CompositeViewer::getCameras(Cameras& cameras, bool onlyActive)
381{
382    cameras.clear();
[10588]383
[7507]384    for(RefViews::iterator vitr = _views.begin();
[7506]385        vitr != _views.end();
386        ++vitr)
387    {
388        View* view = vitr->get();
389
[10588]390        if (view->getCamera() &&
[7506]391            (!onlyActive || (view->getCamera()->getGraphicsContext() && view->getCamera()->getGraphicsContext()->valid())) ) cameras.push_back(view->getCamera());
392
393        for(View::Slaves::iterator itr = view->_slaves.begin();
394            itr != view->_slaves.end();
395            ++itr)
396        {
397            if (itr->_camera.valid() &&
398                (!onlyActive || (itr->_camera->getGraphicsContext() && itr->_camera->getGraphicsContext()->valid())) ) cameras.push_back(itr->_camera.get());
399        }
400    }
401}
[10588]402
[5991]403void CompositeViewer::getScenes(Scenes& scenes, bool onlyValid)
404{
[10365]405    scenes.clear();
406
[5991]407    typedef std::set<osgViewer::Scene*> SceneSet;
408    SceneSet sceneSet;
409
[7507]410    for(RefViews::iterator vitr = _views.begin();
[5991]411        vitr != _views.end();
412        ++vitr)
413    {
414        osgViewer::View* view = vitr->get();
415        if (view->getScene() && (!onlyValid || view->getScene()->getSceneData()))
416        {
[8893]417            if (sceneSet.count(view->getScene())==0)
418            {
419                sceneSet.insert(view->getScene());
420                scenes.push_back(view->getScene());
421            }
[5991]422        }
423    }
424}
425
[7507]426void CompositeViewer::getViews(Views& views, bool onlyValid)
427{
[10365]428    views.clear();
429
[7507]430    for(RefViews::iterator vitr = _views.begin();
431        vitr != _views.end();
432        ++vitr)
433    {
434        views.push_back(vitr->get());
435    }
436}
437
[7506]438void CompositeViewer::getAllThreads(Threads& threads, bool onlyActive)
439{
[10365]440    threads.clear();
441
[7506]442    OperationThreads operationThreads;
443    getOperationThreads(operationThreads);
[10588]444
[7506]445    for(OperationThreads::iterator itr = operationThreads.begin();
446        itr != operationThreads.end();
447        ++itr)
448    {
449        threads.push_back(*itr);
450    }
451
452    Scenes scenes;
453    getScenes(scenes);
[10588]454
[7506]455    for(Scenes::iterator sitr = scenes.begin();
456        sitr != scenes.end();
457        ++sitr)
458    {
459        Scene* scene = *sitr;
[8325]460        osgDB::DatabasePager* dp = scene->getDatabasePager();
461        if (dp)
[7506]462        {
[8325]463            for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
464            {
465                osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
466                if (!onlyActive || dt->isRunning())
467                {
468                    threads.push_back(dt);
469                }
470            }
[7506]471        }
472    }
473}
474
475
476void CompositeViewer::getOperationThreads(OperationThreads& threads, bool onlyActive)
477{
478    threads.clear();
[10588]479
[7506]480    Contexts contexts;
481    getContexts(contexts);
482    for(Contexts::iterator gcitr = contexts.begin();
483        gcitr != contexts.end();
484        ++gcitr)
485    {
486        osg::GraphicsContext* gc = *gcitr;
[10588]487        if (gc->getGraphicsThread() &&
[7506]488            (!onlyActive || gc->getGraphicsThread()->isRunning()) )
489        {
490            threads.push_back(gc->getGraphicsThread());
491        }
492    }
[10588]493
[7506]494    Cameras cameras;
495    getCameras(cameras);
496    for(Cameras::iterator citr = cameras.begin();
497        citr != cameras.end();
498        ++citr)
499    {
500        osg::Camera* camera = *citr;
[10588]501        if (camera->getCameraThread() &&
[7506]502            (!onlyActive || camera->getCameraThread()->isRunning()) )
503        {
504            threads.push_back(camera->getCameraThread());
505        }
506    }
[10588]507
[7506]508}
509
[5991]510void CompositeViewer::realize()
511{
512    //osg::notify(osg::INFO)<<"CompositeViewer::realize()"<<std::endl;
[10588]513
[5991]514    setCameraWithFocus(0);
515
516    if (_views.empty())
517    {
518        osg::notify(osg::NOTICE)<<"CompositeViewer::realize() - not views to realize."<<std::endl;
519        _done = true;
520        return;
521    }
522
523    Contexts contexts;
524    getContexts(contexts);
[10588]525
[5991]526    if (contexts.empty())
527    {
528        osg::notify(osg::INFO)<<"CompositeViewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl;
[10588]529
530        // no windows are already set up so set up a default view
[5991]531        _views[0]->setUpViewAcrossAllScreens();
[10588]532
[5991]533        getContexts(contexts);
534    }
535
536    if (contexts.empty())
537    {
538        osg::notify(osg::NOTICE)<<"CompositeViewer::realize() - failed to set up any windows"<<std::endl;
539        _done = true;
540        return;
541    }
[10588]542
543    unsigned int maxTexturePoolSize = osg::DisplaySettings::instance()->getMaxTexturePoolSize();
544    unsigned int maxVBOPoolSize = osg::DisplaySettings::instance()->getMaxVBOPoolSize();
545    unsigned int maxFBOPoolSize = osg::DisplaySettings::instance()->getMaxFBOPoolSize();
546
[5991]547    for(Contexts::iterator citr = contexts.begin();
548        citr != contexts.end();
549        ++citr)
550    {
[6066]551        osg::GraphicsContext* gc = *citr;
[10588]552
553        // set the pool sizes, 0 the default will result in no GL object pools.
554        gc->getState()->setMaxTexturePoolSize(maxTexturePoolSize);
555        gc->getState()->setMaxVBOPoolSize(maxVBOPoolSize);
556        gc->getState()->setMaxFBOPoolSize(maxFBOPoolSize);
557
[6066]558        gc->realize();
[10588]559
560        if (_realizeOperation.valid() && gc->valid())
[6066]561        {
562            gc->makeCurrent();
[10588]563
[6066]564            (*_realizeOperation)(gc);
[10588]565
[6066]566            gc->releaseContext();
567        }
[5991]568    }
[10588]569
[9868]570    // attach contexts to _incrementalCompileOperation if attached.
571    if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
572
573
[5991]574    bool grabFocus = true;
575    if (grabFocus)
576    {
577        for(Contexts::iterator citr = contexts.begin();
578            citr != contexts.end();
579            ++citr)
580        {
581            osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
582            if (gw)
583            {
[10588]584                gw->grabFocusIfPointerInWindow();
[5991]585            }
586        }
587    }
[10588]588
589
[5991]590    startThreading();
591
592    // initialize the global timer to be relative to the current time.
593    osg::Timer::instance()->setStartTick();
594
595    // pass on the start tick to all the associated eventqueues
596    setStartTick(osg::Timer::instance()->getStartTick());
[7215]597
598    if (osg::DisplaySettings::instance()->getCompileContextsHint())
599    {
600        int numProcessors = OpenThreads::GetNumberOfProcessors();
601        int processNum = 0;
602
603        for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i)
604        {
605            osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i);
606
607            if (gc)
608            {
609                gc->createGraphicsThread();
610                gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
611                gc->getGraphicsThread()->startThread();
[10588]612
[7215]613                ++processNum;
614            }
615        }
616    }
617
[5991]618}
619
[6051]620void CompositeViewer::advance(double simulationTime)
[5773]621{
[5991]622    if (_done) return;
[10588]623
[7505]624    double prevousReferenceTime = _frameStamp->getReferenceTime();
625    int previousFrameNumber = _frameStamp->getFrameNumber();
[5991]626
[7505]627
[6051]628    _frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1);
629
[5991]630    _frameStamp->setReferenceTime( osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()) );
[6051]631
632    if (simulationTime==USE_REFERENCE_TIME)
633    {
634        _frameStamp->setSimulationTime(_frameStamp->getReferenceTime());
635    }
636    else
637    {
638        _frameStamp->setSimulationTime(simulationTime);
639    }
[10588]640
[9554]641    if (getViewerStats() && getViewerStats()->collectStats("frame_rate"))
[7505]642    {
[7507]643        // update previous frame stats
644        double deltaFrameTime = _frameStamp->getReferenceTime() - prevousReferenceTime;
[9554]645        getViewerStats()->setAttribute(previousFrameNumber, "Frame duration", deltaFrameTime);
646        getViewerStats()->setAttribute(previousFrameNumber, "Frame rate", 1.0/deltaFrameTime);
[7505]647
[7507]648        // update current frames stats
[9554]649        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Reference time", _frameStamp->getReferenceTime());
[7505]650    }
[7507]651
[5773]652}
653
[5991]654void CompositeViewer::setCameraWithFocus(osg::Camera* camera)
[5773]655{
[5991]656    _cameraWithFocus = camera;
657
658    if (camera)
659    {
[7507]660        for(RefViews::iterator vitr = _views.begin();
[5991]661            vitr != _views.end();
662            ++vitr)
663        {
664            View* view = vitr->get();
[10588]665            if (view->containsCamera(camera))
[5991]666            {
667                _viewWithFocus = view;
668                return;
669            }
670        }
671    }
672
673    _viewWithFocus = 0;
[5773]674}
675
[5991]676void CompositeViewer::eventTraversal()
[5773]677{
[5991]678    if (_done) return;
[10588]679
[5991]680    if (_views.empty()) return;
[10588]681
[7505]682    double beginEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
[5991]683
684    // osg::notify(osg::NOTICE)<<"CompositeViewer::frameEventTraversal()."<<std::endl;
[10588]685
[5991]686    // need to copy events from the GraphicsWindow's into local EventQueue;
[10588]687
[5993]688    typedef std::map<osgViewer::View*, osgGA::EventQueue::Events> ViewEventsMap;
689    ViewEventsMap viewEventsMap;
[10588]690
[5991]691    Contexts contexts;
692    getContexts(contexts);
693
694    Scenes scenes;
695    getScenes(scenes);
696
697    osgViewer::View* masterView = getViewWithFocus() ? getViewWithFocus() : _views[0].get();
[10588]698
[5991]699    osg::Camera* masterCamera = masterView->getCamera();
[10588]700    osgGA::GUIEventAdapter* eventState = masterView->getEventQueue()->getCurrentEventState();
[5991]701    osg::Matrix masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
[10588]702    if (masterCamera->getViewport())
[5991]703    {
704        osg::Viewport* viewport = masterCamera->getViewport();
705        masterCameraVPW *= viewport->computeWindowMatrix();
706    }
707
708    for(Contexts::iterator citr = contexts.begin();
709        citr != contexts.end();
710        ++citr)
711    {
712        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
713        if (gw)
714        {
715            gw->checkEvents();
[10588]716
[5991]717            osgGA::EventQueue::Events gw_events;
718            gw->getEventQueue()->takeEvents(gw_events);
[10588]719
[5991]720            osgGA::EventQueue::Events::iterator itr;
721            for(itr = gw_events.begin();
722                itr != gw_events.end();
723                ++itr)
724            {
725                osgGA::GUIEventAdapter* event = itr->get();
[10588]726
[8398]727                //osg::notify(osg::NOTICE)<<"event->getGraphicsContext()="<<event->getGraphicsContext()<<std::endl;
[10588]728
[5991]729                bool pointerEvent = false;
730
731                float x = event->getX();
732                float y = event->getY();
[10588]733
[5991]734                bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
735                if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
[10588]736
[5991]737                switch(event->getEventType())
738                {
[6730]739                    case(osgGA::GUIEventAdapter::RESIZE):
740                        setCameraWithFocus(0);
741                        break;
[5991]742                    case(osgGA::GUIEventAdapter::PUSH):
743                    case(osgGA::GUIEventAdapter::RELEASE):
744                    case(osgGA::GUIEventAdapter::DRAG):
745                    case(osgGA::GUIEventAdapter::MOVE):
746                    {
747                        pointerEvent = true;
[10588]748
[5991]749                        if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
750                        {
751                            osg::GraphicsContext::Cameras& cameras = gw->getCameras();
752                            for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
753                                citr != cameras.end();
754                                ++citr)
755                            {
756                                osg::Camera* camera = *citr;
[10588]757                                if (camera->getView() &&
[6262]758                                    camera->getAllowEventFocus() &&
759                                    camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
[5991]760                                {
[6262]761                                    osg::Viewport* viewport = camera ? camera->getViewport() : 0;
[10588]762                                    if (viewport &&
[6262]763                                        x >= viewport->x() && y >= viewport->y() &&
764                                        x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
[5991]765                                    {
[6262]766                                        setCameraWithFocus(camera);
767
[7915]768                                        // If this camera is not a slave camera
769                                        if (camera->getView()->getCamera() == camera)
[6730]770                                        {
[8398]771                                            eventState->setGraphicsContext(gw);
[10588]772                                            eventState->setInputRange( viewport->x(), viewport->y(),
773                                                                    viewport->x()+viewport->width(),
774                                                                    viewport->y()+viewport->height());
[8398]775
[6730]776                                        }
777                                        else
778                                        {
779                                            eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
780                                        }
781
[6262]782                                        if (getViewWithFocus()!=masterView)
[5991]783                                        {
[6262]784                                            // need to reset the masterView
785                                            masterView = getViewWithFocus();
786                                            masterCamera = masterView->getCamera();
[10588]787                                            eventState = masterView->getEventQueue()->getCurrentEventState();
[6262]788                                            masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
[6730]789
[10588]790                                            if (masterCamera->getViewport())
[6262]791                                            {
792                                                osg::Viewport* viewport = masterCamera->getViewport();
793                                                masterCameraVPW *= viewport->computeWindowMatrix();
794                                            }
[5991]795                                        }
[9209]796
797                                        // If this camera is not a slave camera
798                                        if (camera->getView()->getCamera() == camera)
799                                        {
800                                            eventState->setGraphicsContext(gw);
[10588]801                                            eventState->setInputRange( viewport->x(), viewport->y(),
802                                                                    viewport->x()+viewport->width(),
803                                                                    viewport->y()+viewport->height());
[9209]804
805                                        }
806                                        else
807                                        {
808                                            eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
809                                        }
[5991]810                                    }
811                                }
812                            }
813                        }
[10588]814
[5991]815                        break;
816                    }
817                    default:
818                        break;
819                }
[10588]820
[5991]821                if (pointerEvent)
822                {
823                    if (getCameraWithFocus())
824                    {
825                        osg::Viewport* viewport = getCameraWithFocus()->getViewport();
826                        osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
827                        if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
828
829                        osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
830
831                        osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
832
833                        x = new_coord.x();
[10588]834                        y = new_coord.y();
[5991]835
836                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
837                        event->setX(x);
838                        event->setY(y);
839                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
840
841                    }
[10588]842                    // pass along the new pointer events details to the eventState of the viewer
[5991]843                    eventState->setX(x);
844                    eventState->setY(y);
845                    eventState->setButtonMask(event->getButtonMask());
846                    eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
847
848                }
849                else
850                {
851                    event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
852                    event->setX(eventState->getX());
853                    event->setY(eventState->getY());
854                    event->setButtonMask(eventState->getButtonMask());
855                    event->setMouseYOrientation(eventState->getMouseYOrientation());
856                }
857            }
858
859            for(itr = gw_events.begin();
860                itr != gw_events.end();
861                ++itr)
862            {
863                osgGA::GUIEventAdapter* event = itr->get();
864                switch(event->getEventType())
865                {
866                    case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
867                    {
[6728]868                        bool wasThreading = areThreadsRunning();
869                        if (wasThreading) stopThreading();
[10588]870
[5991]871                        gw->close();
[6728]872
873                        if (wasThreading) startThreading();
874
[5991]875                        break;
876                    }
877                    default:
878                        break;
879                }
880            }
881
[5993]882            viewEventsMap[masterView].insert( viewEventsMap[masterView].end(), gw_events.begin(), gw_events.end() );
[5991]883
884        }
885    }
886
[10588]887
[5991]888    // osg::notify(osg::NOTICE)<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
889
890
[7507]891    for(RefViews::iterator vitr = _views.begin();
[5993]892        vitr != _views.end();
893        ++vitr)
894    {
895        View* view = vitr->get();
896        view->getEventQueue()->frame( getFrameStamp()->getReferenceTime() );
897        view->getEventQueue()->takeEvents(viewEventsMap[view]);
898    }
[5991]899
[10588]900
[5991]901    // osg::notify(osg::NOTICE)<<"Events "<<events.size()<<std::endl;
[10588]902
[5991]903    if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
904    {
[5993]905        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
906            veitr != viewEventsMap.end();
907            ++veitr)
[5991]908        {
[5993]909            for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
910                itr != veitr->second.end();
911                ++itr)
[5991]912            {
[5993]913                osgGA::GUIEventAdapter* event = itr->get();
914                switch(event->getEventType())
915                {
916                    case(osgGA::GUIEventAdapter::KEYUP):
917                        if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
918                        break;
919
920                    case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
921                        if (_quitEventSetsDone) _done = true;
922                        break;
923
924                    default:
925                        break;
926                }
[5991]927            }
928        }
929    }
[10588]930
[5991]931    if (_done) return;
932
[5999]933    if (_eventVisitor.valid())
[5991]934    {
935        _eventVisitor->setFrameStamp(getFrameStamp());
936        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
937
[5999]938        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
939            veitr != viewEventsMap.end();
940            ++veitr)
[5991]941        {
[5999]942            View* view = veitr->first;
[9112]943            _eventVisitor->setActionAdapter(view);
[10588]944
[6262]945            if (view->getSceneData())
[10588]946            {
[6262]947                for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
948                    itr != veitr->second.end();
949                    ++itr)
950                {
951                    osgGA::GUIEventAdapter* event = itr->get();
[5991]952
[6262]953                    _eventVisitor->reset();
954                    _eventVisitor->addEvent( event );
[5991]955
[6262]956                    view->getSceneData()->accept(*_eventVisitor);
[6767]957
958                    // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
959                    // leave that to the scene update traversal.
960                    osg::NodeVisitor::TraversalMode tm = _eventVisitor->getTraversalMode();
961                    _eventVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
962
963                    if (view->getCamera() && view->getCamera()->getEventCallback()) view->getCamera()->accept(*_eventVisitor);
964
965                    for(unsigned int i=0; i<view->getNumSlaves(); ++i)
966                    {
967                        osg::Camera* camera = view->getSlave(i)._camera.get();
968                        if (camera && camera->getEventCallback()) camera->accept(*_eventVisitor);
969                    }
970
971                    _eventVisitor->setTraversalMode(tm);
972
[6262]973                }
[5999]974            }
[5991]975        }
[10588]976
[5991]977    }
[9088]978
979    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
980        veitr != viewEventsMap.end();
981        ++veitr)
982    {
983        View* view = veitr->first;
[10588]984
[9088]985        for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
986            itr != veitr->second.end();
987            ++itr)
988        {
989            osgGA::GUIEventAdapter* event = itr->get();
990
991            for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
992                hitr != view->getEventHandlers().end();
993                ++hitr)
994            {
995                (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, 0);
996            }
997        }
998    }
999
1000    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
1001        veitr != viewEventsMap.end();
1002        ++veitr)
1003    {
1004        View* view = veitr->first;
[10588]1005
[9088]1006        for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
1007            itr != veitr->second.end();
1008            ++itr)
1009        {
1010            osgGA::GUIEventAdapter* event = itr->get();
1011
1012            if (view->getCameraManipulator())
1013            {
1014                view->getCameraManipulator()->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view);
1015            }
1016        }
1017    }
1018
[7507]1019
[10588]1020
[9554]1021    if (getViewerStats() && getViewerStats()->collectStats("event"))
[7505]1022    {
[7507]1023        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
[7505]1024
[7507]1025        // update current frames stats
[9554]1026        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal begin time", beginEventTraversal);
1027        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal end time", endEventTraversal);
1028        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal time taken", endEventTraversal-beginEventTraversal);
[7505]1029    }
[5773]1030}
1031
[7213]1032
[5991]1033void CompositeViewer::updateTraversal()
[5773]1034{
[5991]1035    if (_done) return;
[10588]1036
[7505]1037    double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
[5991]1038
[7785]1039    _updateVisitor->reset();
1040    _updateVisitor->setFrameStamp(getFrameStamp());
1041    _updateVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
1042
[5991]1043    Scenes scenes;
1044    getScenes(scenes);
1045    for(Scenes::iterator sitr = scenes.begin();
1046        sitr != scenes.end();
1047        ++sitr)
1048    {
[7209]1049        Scene* scene = *sitr;
[10520]1050        scene->updateSceneGraph(*_updateVisitor);
1051    }
[5991]1052
[10520]1053    // if we have a shared state manager prune any unused entries
1054    if (osgDB::Registry::instance()->getSharedStateManager())
1055        osgDB::Registry::instance()->getSharedStateManager()->prune();
[5991]1056
[10520]1057    // update the Registry object cache.
1058    osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(*getFrameStamp());
1059    osgDB::Registry::instance()->removeExpiredObjectsInCache(*getFrameStamp());
[8633]1060
[7213]1061
[9868]1062    if (_incrementalCompileOperation.valid())
1063    {
1064        // merge subgraphs that have been compiled by the incremental compiler operation.
1065        _incrementalCompileOperation->mergeCompiledSubgraphs();
1066    }
1067
[7213]1068    if (_updateOperations.valid())
1069    {
1070        _updateOperations->runOperations(this);
1071    }
1072
[7507]1073    for(RefViews::iterator vitr = _views.begin();
[5991]1074        vitr != _views.end();
1075        ++vitr)
1076    {
1077        View* view = vitr->get();
[6767]1078
1079        {
1080            // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
1081            // leave that to the scene update traversal.
[7209]1082            osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode();
1083            _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
[6767]1084
[7209]1085            if (view->getCamera() && view->getCamera()->getUpdateCallback()) view->getCamera()->accept(*_updateVisitor);
[6767]1086
1087            for(unsigned int i=0; i<view->getNumSlaves(); ++i)
1088            {
1089                osg::Camera* camera = view->getSlave(i)._camera.get();
[7209]1090                if (camera && camera->getUpdateCallback()) camera->accept(*_updateVisitor);
[6767]1091            }
1092
[7209]1093            _updateVisitor->setTraversalMode(tm);
[6767]1094        }
1095
1096
[10588]1097        if (view->getCameraManipulator())
[6690]1098        {
1099            view->setFusionDistance( view->getCameraManipulator()->getFusionDistanceMode(),
[10588]1100                                    view->getCameraManipulator()->getFusionDistanceValue() );
1101
[6690]1102            view->getCamera()->setViewMatrix( view->getCameraManipulator()->getInverseMatrix());
1103        }
[5991]1104        view->updateSlaves();
[7505]1105
[5991]1106    }
[10588]1107
[9554]1108    if (getViewerStats() && getViewerStats()->collectStats("update"))
[7507]1109    {
1110        double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
[5991]1111
[7507]1112        // update current frames stats
[9554]1113        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal);
1114        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal);
1115        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal);
[7507]1116    }
1117
[5773]1118}
1119
[7535]1120double CompositeViewer::elapsedTime()
[5773]1121{
[7535]1122    return osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
[5773]1123}
[7506]1124
1125void CompositeViewer::getUsage(osg::ApplicationUsage& usage) const
1126{
[7507]1127    for(RefViews::const_iterator vitr = _views.begin();
[7506]1128        vitr != _views.end();
1129        ++vitr)
1130    {
1131        const View* view = vitr->get();
1132        if (view->getCameraManipulator())
1133        {
1134            view->getCameraManipulator()->getUsage(usage);
1135        }
1136
1137        for(View::EventHandlers::const_iterator hitr = view->_eventHandlers.begin();
1138            hitr != view->_eventHandlers.end();
1139            ++hitr)
1140        {
1141            (*hitr)->getUsage(usage);
1142        }
1143    }
1144}
Note: See TracBrowser for help on using the browser.