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

Revision 10520, 37.3 kB (checked in by robert, 4 years ago)

Moved the updating and expiry of the Registry object cache from DatabasePager? into osgViewer::Viewer/CompositeViewer.

  • 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 <osgUtil/GLObjectsVisitor>
16#include <osgGA/TrackballManipulator>
17#include <osgViewer/CompositeViewer>
18#include <osgViewer/Renderer>
19#include <osgDB/Registry>
20#include <osgDB/ReadFile>
21
22#include <osg/io_utils>
23
24using namespace osgViewer;
25
26CompositeViewer::CompositeViewer()
27{
28    constructorInit();
29}
30
31CompositeViewer::CompositeViewer(const CompositeViewer& cv,const osg::CopyOp& copyop):
32    ViewerBase()
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::notify(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::notify(osg::INFO)<<"finished CompositeViewer::~CompositeViewer()"<<std::endl;
130}
131
132bool CompositeViewer::readConfiguration(const std::string& filename)
133{
134    osg::notify(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    }
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
271int CompositeViewer::run()
272{
273    for(RefViews::iterator itr = _views.begin();
274        itr != _views.end();
275        ++itr)
276    {
277        osgViewer::View* view = itr->get();
278        if ((view->getCameraManipulator()==0) && view->getCamera()->getAllowEventFocus())
279        {
280            view->setCameraManipulator(new osgGA::TrackballManipulator());
281        }
282    }
283       
284    setReleaseContextAtEndOfFrameHint(false);
285
286    return ViewerBase::run();
287}
288
289void CompositeViewer::setStartTick(osg::Timer_t tick)
290{
291    _startTick = tick;
292   
293    for(RefViews::iterator vitr = _views.begin();
294        vitr != _views.end();
295        ++vitr)
296    {
297        (*vitr)->setStartTick(tick);
298    }
299   
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
330void CompositeViewer::viewerInit()
331{
332    osg::notify(osg::INFO)<<"CompositeViewer::init()"<<std::endl;
333
334    for(RefViews::iterator itr = _views.begin();
335        itr != _views.end();
336        ++itr)
337    {
338        (*itr)->init();
339    }
340}
341
342void CompositeViewer::getContexts(Contexts& contexts, bool onlyValid)
343{
344    typedef std::set<osg::GraphicsContext*> ContextSet;
345    ContextSet contextSet;
346
347    contexts.clear();
348
349    for(RefViews::iterator vitr = _views.begin();
350        vitr != _views.end();
351        ++vitr)
352    {
353        osgViewer::View* view = vitr->get();
354        osg::GraphicsContext* gc = view->getCamera() ? view->getCamera()->getGraphicsContext() : 0;
355        if (gc && (gc->valid() || !onlyValid))
356        {
357            if (contextSet.count(gc)==0)
358            {
359                contextSet.insert(gc);
360                contexts.push_back(gc);
361            }
362        }
363
364        for(unsigned int i=0; i<view->getNumSlaves(); ++i)
365        {
366            View::Slave& slave = view->getSlave(i);
367            osg::GraphicsContext* sgc = slave._camera.valid() ? slave._camera->getGraphicsContext() : 0;
368            if (sgc && (sgc->valid() || !onlyValid))
369            {
370                if (contextSet.count(sgc)==0)
371                {
372                    contextSet.insert(sgc);
373                    contexts.push_back(sgc);
374                }
375            }
376        }
377    }
378}
379
380void CompositeViewer::getCameras(Cameras& cameras, bool onlyActive)
381{
382    cameras.clear();
383   
384    for(RefViews::iterator vitr = _views.begin();
385        vitr != _views.end();
386        ++vitr)
387    {
388        View* view = vitr->get();
389
390        if (view->getCamera() &&
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}
402 
403void CompositeViewer::getScenes(Scenes& scenes, bool onlyValid)
404{
405    scenes.clear();
406
407    typedef std::set<osgViewer::Scene*> SceneSet;
408    SceneSet sceneSet;
409
410    for(RefViews::iterator vitr = _views.begin();
411        vitr != _views.end();
412        ++vitr)
413    {
414        osgViewer::View* view = vitr->get();
415        if (view->getScene() && (!onlyValid || view->getScene()->getSceneData()))
416        {
417            if (sceneSet.count(view->getScene())==0)
418            {
419                sceneSet.insert(view->getScene());
420                scenes.push_back(view->getScene());
421            }
422        }
423    }
424}
425
426void CompositeViewer::getViews(Views& views, bool onlyValid)
427{
428    views.clear();
429
430    for(RefViews::iterator vitr = _views.begin();
431        vitr != _views.end();
432        ++vitr)
433    {
434        views.push_back(vitr->get());
435    }
436}
437
438void CompositeViewer::getAllThreads(Threads& threads, bool onlyActive)
439{
440    threads.clear();
441
442    OperationThreads operationThreads;
443    getOperationThreads(operationThreads);
444   
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);
454   
455    for(Scenes::iterator sitr = scenes.begin();
456        sitr != scenes.end();
457        ++sitr)
458    {
459        Scene* scene = *sitr;
460        osgDB::DatabasePager* dp = scene->getDatabasePager();
461        if (dp)
462        {
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            }
471        }
472    }
473}
474
475
476void CompositeViewer::getOperationThreads(OperationThreads& threads, bool onlyActive)
477{
478    threads.clear();
479   
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;
487        if (gc->getGraphicsThread() &&
488            (!onlyActive || gc->getGraphicsThread()->isRunning()) )
489        {
490            threads.push_back(gc->getGraphicsThread());
491        }
492    }
493   
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;
501        if (camera->getCameraThread() &&
502            (!onlyActive || camera->getCameraThread()->isRunning()) )
503        {
504            threads.push_back(camera->getCameraThread());
505        }
506    }
507   
508}
509
510void CompositeViewer::realize()
511{
512    //osg::notify(osg::INFO)<<"CompositeViewer::realize()"<<std::endl;
513   
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);
525   
526    if (contexts.empty())
527    {
528        osg::notify(osg::INFO)<<"CompositeViewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl;
529   
530        // no windows are already set up so set up a default view       
531        _views[0]->setUpViewAcrossAllScreens();
532       
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    }
542   
543    for(Contexts::iterator citr = contexts.begin();
544        citr != contexts.end();
545        ++citr)
546    {
547        osg::GraphicsContext* gc = *citr;
548        gc->realize();
549       
550        if (_realizeOperation.valid() && gc->valid())
551        {
552            gc->makeCurrent();
553           
554            (*_realizeOperation)(gc);
555           
556            gc->releaseContext();
557        }
558    }
559   
560    // attach contexts to _incrementalCompileOperation if attached.
561    if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
562
563
564    bool grabFocus = true;
565    if (grabFocus)
566    {
567        for(Contexts::iterator citr = contexts.begin();
568            citr != contexts.end();
569            ++citr)
570        {
571            osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
572            if (gw)
573            {
574                gw->grabFocusIfPointerInWindow();   
575            }
576        }
577    }
578   
579   
580    startThreading();
581
582    // initialize the global timer to be relative to the current time.
583    osg::Timer::instance()->setStartTick();
584
585    // pass on the start tick to all the associated eventqueues
586    setStartTick(osg::Timer::instance()->getStartTick());
587
588    if (osg::DisplaySettings::instance()->getCompileContextsHint())
589    {
590        int numProcessors = OpenThreads::GetNumberOfProcessors();
591        int processNum = 0;
592
593        for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i)
594        {
595            osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i);
596
597            if (gc)
598            {
599                gc->createGraphicsThread();
600                gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
601                gc->getGraphicsThread()->startThread();
602               
603                ++processNum;
604            }
605        }
606    }
607
608}
609
610void CompositeViewer::advance(double simulationTime)
611{
612    if (_done) return;
613   
614    double prevousReferenceTime = _frameStamp->getReferenceTime();
615    int previousFrameNumber = _frameStamp->getFrameNumber();
616
617
618    _frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1);
619
620    _frameStamp->setReferenceTime( osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()) );
621
622    if (simulationTime==USE_REFERENCE_TIME)
623    {
624        _frameStamp->setSimulationTime(_frameStamp->getReferenceTime());
625    }
626    else
627    {
628        _frameStamp->setSimulationTime(simulationTime);
629    }
630   
631    if (getViewerStats() && getViewerStats()->collectStats("frame_rate"))
632    {
633        // update previous frame stats
634        double deltaFrameTime = _frameStamp->getReferenceTime() - prevousReferenceTime;
635        getViewerStats()->setAttribute(previousFrameNumber, "Frame duration", deltaFrameTime);
636        getViewerStats()->setAttribute(previousFrameNumber, "Frame rate", 1.0/deltaFrameTime);
637
638        // update current frames stats
639        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Reference time", _frameStamp->getReferenceTime());
640    }
641
642}
643
644void CompositeViewer::setCameraWithFocus(osg::Camera* camera)
645{
646    _cameraWithFocus = camera;
647
648    if (camera)
649    {
650        for(RefViews::iterator vitr = _views.begin();
651            vitr != _views.end();
652            ++vitr)
653        {
654            View* view = vitr->get();
655            if (view->containsCamera(camera))
656            {
657                _viewWithFocus = view;
658                return;
659            }
660        }
661    }
662
663    _viewWithFocus = 0;
664}
665
666void CompositeViewer::eventTraversal()
667{
668    if (_done) return;
669   
670    if (_views.empty()) return;
671   
672    double beginEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
673
674    // osg::notify(osg::NOTICE)<<"CompositeViewer::frameEventTraversal()."<<std::endl;
675   
676    // need to copy events from the GraphicsWindow's into local EventQueue;
677   
678    typedef std::map<osgViewer::View*, osgGA::EventQueue::Events> ViewEventsMap;
679    ViewEventsMap viewEventsMap;
680   
681    Contexts contexts;
682    getContexts(contexts);
683
684    Scenes scenes;
685    getScenes(scenes);
686
687    osgViewer::View* masterView = getViewWithFocus() ? getViewWithFocus() : _views[0].get();
688   
689    osg::Camera* masterCamera = masterView->getCamera();
690    osgGA::GUIEventAdapter* eventState = masterView->getEventQueue()->getCurrentEventState();
691    osg::Matrix masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
692    if (masterCamera->getViewport())
693    {
694        osg::Viewport* viewport = masterCamera->getViewport();
695        masterCameraVPW *= viewport->computeWindowMatrix();
696    }
697
698    for(Contexts::iterator citr = contexts.begin();
699        citr != contexts.end();
700        ++citr)
701    {
702        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
703        if (gw)
704        {
705            gw->checkEvents();
706           
707            osgGA::EventQueue::Events gw_events;
708            gw->getEventQueue()->takeEvents(gw_events);
709           
710            osgGA::EventQueue::Events::iterator itr;
711            for(itr = gw_events.begin();
712                itr != gw_events.end();
713                ++itr)
714            {
715                osgGA::GUIEventAdapter* event = itr->get();
716               
717                //osg::notify(osg::NOTICE)<<"event->getGraphicsContext()="<<event->getGraphicsContext()<<std::endl;
718               
719                bool pointerEvent = false;
720
721                float x = event->getX();
722                float y = event->getY();
723               
724                bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
725                if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
726               
727                switch(event->getEventType())
728                {
729                    case(osgGA::GUIEventAdapter::RESIZE):
730                        setCameraWithFocus(0);
731                        break;
732                    case(osgGA::GUIEventAdapter::PUSH):
733                    case(osgGA::GUIEventAdapter::RELEASE):
734                    case(osgGA::GUIEventAdapter::DRAG):
735                    case(osgGA::GUIEventAdapter::MOVE):
736                    {
737                        pointerEvent = true;
738                       
739                        if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
740                        {
741                            osg::GraphicsContext::Cameras& cameras = gw->getCameras();
742                            for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
743                                citr != cameras.end();
744                                ++citr)
745                            {
746                                osg::Camera* camera = *citr;
747                                if (camera->getView() &&
748                                    camera->getAllowEventFocus() &&
749                                    camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
750                                {
751                                    osg::Viewport* viewport = camera ? camera->getViewport() : 0;
752                                    if (viewport &&
753                                        x >= viewport->x() && y >= viewport->y() &&
754                                        x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
755                                    {
756                                        setCameraWithFocus(camera);
757
758                                        // If this camera is not a slave camera
759                                        if (camera->getView()->getCamera() == camera)
760                                        {
761                                            eventState->setGraphicsContext(gw);
762                                            eventState->setInputRange( viewport->x(), viewport->y(),
763                                                                       viewport->x()+viewport->width(),
764                                                                       viewport->y()+viewport->height());
765
766                                        }
767                                        else
768                                        {
769                                            eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
770                                        }
771
772                                        if (getViewWithFocus()!=masterView)
773                                        {
774                                            // need to reset the masterView
775                                            masterView = getViewWithFocus();
776                                            masterCamera = masterView->getCamera();
777                                            eventState = masterView->getEventQueue()->getCurrentEventState();
778                                            masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
779
780                                            if (masterCamera->getViewport())
781                                            {
782                                                osg::Viewport* viewport = masterCamera->getViewport();
783                                                masterCameraVPW *= viewport->computeWindowMatrix();
784                                            }
785                                        }
786
787                                        // If this camera is not a slave camera
788                                        if (camera->getView()->getCamera() == camera)
789                                        {
790                                            eventState->setGraphicsContext(gw);
791                                            eventState->setInputRange( viewport->x(), viewport->y(),
792                                                                       viewport->x()+viewport->width(),
793                                                                       viewport->y()+viewport->height());
794
795                                        }
796                                        else
797                                        {
798                                            eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
799                                        }
800                                    }
801                                }
802                            }
803                        }
804                       
805                        break;
806                    }
807                    default:
808                        break;
809                }
810               
811                if (pointerEvent)
812                {
813                    if (getCameraWithFocus())
814                    {
815                        osg::Viewport* viewport = getCameraWithFocus()->getViewport();
816                        osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
817                        if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
818
819                        osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
820
821                        osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
822
823                        x = new_coord.x();
824                        y = new_coord.y();                               
825
826                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
827                        event->setX(x);
828                        event->setY(y);
829                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
830
831                    }
832                    // pass along the new pointer events details to the eventState of the viewer
833                    eventState->setX(x);
834                    eventState->setY(y);
835                    eventState->setButtonMask(event->getButtonMask());
836                    eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
837
838                }
839                else
840                {
841                    event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
842                    event->setX(eventState->getX());
843                    event->setY(eventState->getY());
844                    event->setButtonMask(eventState->getButtonMask());
845                    event->setMouseYOrientation(eventState->getMouseYOrientation());
846                }
847            }
848
849            for(itr = gw_events.begin();
850                itr != gw_events.end();
851                ++itr)
852            {
853                osgGA::GUIEventAdapter* event = itr->get();
854                switch(event->getEventType())
855                {
856                    case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
857                    {
858                        bool wasThreading = areThreadsRunning();
859                        if (wasThreading) stopThreading();
860                       
861                        gw->close();
862
863                        if (wasThreading) startThreading();
864
865                        break;
866                    }
867                    default:
868                        break;
869                }
870            }
871
872            viewEventsMap[masterView].insert( viewEventsMap[masterView].end(), gw_events.begin(), gw_events.end() );
873
874        }
875    }
876   
877
878    // osg::notify(osg::NOTICE)<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
879
880
881    for(RefViews::iterator vitr = _views.begin();
882        vitr != _views.end();
883        ++vitr)
884    {
885        View* view = vitr->get();
886        view->getEventQueue()->frame( getFrameStamp()->getReferenceTime() );
887        view->getEventQueue()->takeEvents(viewEventsMap[view]);
888    }
889   
890
891    // osg::notify(osg::NOTICE)<<"Events "<<events.size()<<std::endl;
892   
893    if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
894    {
895        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
896            veitr != viewEventsMap.end();
897            ++veitr)
898        {
899            for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
900                itr != veitr->second.end();
901                ++itr)
902            {
903                osgGA::GUIEventAdapter* event = itr->get();
904                switch(event->getEventType())
905                {
906                    case(osgGA::GUIEventAdapter::KEYUP):
907                        if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
908                        break;
909
910                    case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
911                        if (_quitEventSetsDone) _done = true;
912                        break;
913
914                    default:
915                        break;
916                }
917            }
918        }
919    }
920       
921    if (_done) return;
922
923    if (_eventVisitor.valid())
924    {
925        _eventVisitor->setFrameStamp(getFrameStamp());
926        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
927
928        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
929            veitr != viewEventsMap.end();
930            ++veitr)
931        {
932            View* view = veitr->first;
933            _eventVisitor->setActionAdapter(view);
934           
935            if (view->getSceneData())
936            {           
937                for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
938                    itr != veitr->second.end();
939                    ++itr)
940                {
941                    osgGA::GUIEventAdapter* event = itr->get();
942
943                    _eventVisitor->reset();
944                    _eventVisitor->addEvent( event );
945
946                    view->getSceneData()->accept(*_eventVisitor);
947
948                    // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
949                    // leave that to the scene update traversal.
950                    osg::NodeVisitor::TraversalMode tm = _eventVisitor->getTraversalMode();
951                    _eventVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
952
953                    if (view->getCamera() && view->getCamera()->getEventCallback()) view->getCamera()->accept(*_eventVisitor);
954
955                    for(unsigned int i=0; i<view->getNumSlaves(); ++i)
956                    {
957                        osg::Camera* camera = view->getSlave(i)._camera.get();
958                        if (camera && camera->getEventCallback()) camera->accept(*_eventVisitor);
959                    }
960
961                    _eventVisitor->setTraversalMode(tm);
962
963                }
964            }
965        }
966       
967    }
968
969    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
970        veitr != viewEventsMap.end();
971        ++veitr)
972    {
973        View* view = veitr->first;
974       
975        for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
976            itr != veitr->second.end();
977            ++itr)
978        {
979            osgGA::GUIEventAdapter* event = itr->get();
980
981            for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
982                hitr != view->getEventHandlers().end();
983                ++hitr)
984            {
985                (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, 0);
986            }
987        }
988    }
989
990    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
991        veitr != viewEventsMap.end();
992        ++veitr)
993    {
994        View* view = veitr->first;
995       
996        for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
997            itr != veitr->second.end();
998            ++itr)
999        {
1000            osgGA::GUIEventAdapter* event = itr->get();
1001
1002            if (view->getCameraManipulator())
1003            {
1004                view->getCameraManipulator()->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view);
1005            }
1006        }
1007    }
1008
1009   
1010
1011    if (getViewerStats() && getViewerStats()->collectStats("event"))
1012    {
1013        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1014
1015        // update current frames stats
1016        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal begin time", beginEventTraversal);
1017        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal end time", endEventTraversal);
1018        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal time taken", endEventTraversal-beginEventTraversal);
1019    }
1020}
1021
1022
1023void CompositeViewer::updateTraversal()
1024{
1025    if (_done) return;
1026   
1027    double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1028
1029    _updateVisitor->reset();
1030    _updateVisitor->setFrameStamp(getFrameStamp());
1031    _updateVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
1032
1033    Scenes scenes;
1034    getScenes(scenes);
1035    for(Scenes::iterator sitr = scenes.begin();
1036        sitr != scenes.end();
1037        ++sitr)
1038    {
1039        Scene* scene = *sitr;
1040        scene->updateSceneGraph(*_updateVisitor);
1041    }
1042
1043    // if we have a shared state manager prune any unused entries
1044    if (osgDB::Registry::instance()->getSharedStateManager())
1045        osgDB::Registry::instance()->getSharedStateManager()->prune();
1046
1047    // update the Registry object cache.
1048    osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(*getFrameStamp());
1049    osgDB::Registry::instance()->removeExpiredObjectsInCache(*getFrameStamp());
1050
1051
1052    if (_incrementalCompileOperation.valid())
1053    {
1054        // merge subgraphs that have been compiled by the incremental compiler operation.
1055        _incrementalCompileOperation->mergeCompiledSubgraphs();
1056    }
1057
1058    if (_updateOperations.valid())
1059    {
1060        _updateOperations->runOperations(this);
1061    }
1062
1063    for(RefViews::iterator vitr = _views.begin();
1064        vitr != _views.end();
1065        ++vitr)
1066    {
1067        View* view = vitr->get();
1068
1069        {
1070            // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
1071            // leave that to the scene update traversal.
1072            osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode();
1073            _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
1074
1075            if (view->getCamera() && view->getCamera()->getUpdateCallback()) view->getCamera()->accept(*_updateVisitor);
1076
1077            for(unsigned int i=0; i<view->getNumSlaves(); ++i)
1078            {
1079                osg::Camera* camera = view->getSlave(i)._camera.get();
1080                if (camera && camera->getUpdateCallback()) camera->accept(*_updateVisitor);
1081            }
1082
1083            _updateVisitor->setTraversalMode(tm);
1084        }
1085
1086
1087        if (view->getCameraManipulator())
1088        {
1089            view->setFusionDistance( view->getCameraManipulator()->getFusionDistanceMode(),
1090                                     view->getCameraManipulator()->getFusionDistanceValue() );
1091                                     
1092            view->getCamera()->setViewMatrix( view->getCameraManipulator()->getInverseMatrix());
1093        }
1094        view->updateSlaves();
1095
1096    }
1097   
1098    if (getViewerStats() && getViewerStats()->collectStats("update"))
1099    {
1100        double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1101
1102        // update current frames stats
1103        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal);
1104        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal);
1105        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal);
1106    }
1107
1108}
1109
1110double CompositeViewer::elapsedTime()
1111{
1112    return osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1113}
1114
1115void CompositeViewer::getUsage(osg::ApplicationUsage& usage) const
1116{
1117    for(RefViews::const_iterator vitr = _views.begin();
1118        vitr != _views.end();
1119        ++vitr)
1120    {
1121        const View* view = vitr->get();
1122        if (view->getCameraManipulator())
1123        {
1124            view->getCameraManipulator()->getUsage(usage);
1125        }
1126
1127        for(View::EventHandlers::const_iterator hitr = view->_eventHandlers.begin();
1128            hitr != view->_eventHandlers.end();
1129            ++hitr)
1130        {
1131            (*hitr)->getUsage(usage);
1132        }
1133    }
1134}
Note: See TracBrowser for help on using the browser.