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

Revision 13172, 40.1 kB (checked in by robert, 19 minutes ago)

From Mattias Helsing, "Seems I was only half right given what you asked for. CMP0017 only
says that modules that are found and ran from cmake modules dir should
prefer cmake-provided modules. find_package() and include() still look
in CMAKE_MODULE_PATH first.

After some investigating I've come up with a proposal examplified in
the attached FindGDAL.cmake script. It simply calls the cmake provided
FindGDAL.cmake if it exists and returns if it succeeds in finding GDAL
using that, otherwise continue with our local cmake code.
Pro: Wont clutter our root CMakeLists.txt
Con: If we begin to write more advanced Findxxx modules (using
COMPONENTS, REQUIRED etc.) we may have to revise this scheme.
"

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