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

Revision 13111, 39.4 kB (checked in by robert, 3 days ago)

Fixed comment

  • 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    for(Contexts::iterator citr = contexts.begin();
739        citr != contexts.end();
740        ++citr)
741    {
742        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
743        if (gw)
744        {
745            gw->checkEvents();
746
747            osgGA::EventQueue::Events gw_events;
748            gw->getEventQueue()->takeEvents(gw_events, cutOffTime);
749
750            osgGA::EventQueue::Events::iterator itr;
751            for(itr = gw_events.begin();
752                itr != gw_events.end();
753                ++itr)
754            {
755                osgGA::GUIEventAdapter* event = itr->get();
756
757                //OSG_NOTICE<<"event->getGraphicsContext()="<<event->getGraphicsContext()<<std::endl;
758
759                bool pointerEvent = false;
760
761                float x = event->getX();
762                float y = event->getY();
763
764                bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
765                if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
766
767                switch(event->getEventType())
768                {
769                    case(osgGA::GUIEventAdapter::RESIZE):
770                        setCameraWithFocus(0);
771                        break;
772                    case(osgGA::GUIEventAdapter::PUSH):
773                    case(osgGA::GUIEventAdapter::RELEASE):
774                    case(osgGA::GUIEventAdapter::DOUBLECLICK):
775                    case(osgGA::GUIEventAdapter::DRAG):
776                    case(osgGA::GUIEventAdapter::MOVE):
777                    {
778                        pointerEvent = true;
779
780                        if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
781                        {
782                            osg::GraphicsContext::Cameras& cameras = gw->getCameras();
783                            for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
784                                citr != cameras.end();
785                                ++citr)
786                            {
787                                osg::Camera* camera = *citr;
788                                if ((camera->getNodeMask()!=0) &&
789                                    camera->getView() &&
790                                    camera->getAllowEventFocus() &&
791                                    camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
792                                {
793                                    osg::Viewport* viewport = camera ? camera->getViewport() : 0;
794                                    if (viewport &&
795                                        x >= viewport->x() && y >= viewport->y() &&
796                                        x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
797                                    {
798                                        setCameraWithFocus(camera);
799
800                                        // If this camera is not a slave camera
801                                        if (camera->getView()->getCamera() == camera)
802                                        {
803                                            eventState->setGraphicsContext(gw);
804                                            eventState->setInputRange( viewport->x(), viewport->y(),
805                                                                    viewport->x()+viewport->width(),
806                                                                    viewport->y()+viewport->height());
807
808                                        }
809                                        else
810                                        {
811                                            eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
812                                        }
813
814                                        if (getViewWithFocus()!=masterView)
815                                        {
816                                            // need to reset the masterView
817                                            masterView = getViewWithFocus();
818                                            masterCamera = masterView->getCamera();
819                                            eventState = masterView->getEventQueue()->getCurrentEventState();
820                                            masterCameraVPW = masterCamera->getViewMatrix() * masterCamera->getProjectionMatrix();
821
822                                            if (masterCamera->getViewport())
823                                            {
824                                                osg::Viewport* viewport = masterCamera->getViewport();
825                                                masterCameraVPW *= viewport->computeWindowMatrix();
826                                            }
827                                        }
828
829                                        // If this camera is not a slave camera
830                                        if (camera->getView()->getCamera() == camera)
831                                        {
832                                            eventState->setGraphicsContext(gw);
833                                            eventState->setInputRange( viewport->x(), viewport->y(),
834                                                                    viewport->x()+viewport->width(),
835                                                                    viewport->y()+viewport->height());
836
837                                        }
838                                        else
839                                        {
840                                            eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
841                                        }
842                                    }
843                                }
844                            }
845                        }
846
847                        break;
848                    }
849                    default:
850                        break;
851                }
852
853                if (pointerEvent)
854                {
855                    if (getCameraWithFocus())
856                    {
857                        osg::Viewport* viewport = getCameraWithFocus()->getViewport();
858                        osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
859                        if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
860
861                        osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
862
863                        osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
864
865                        x = new_coord.x();
866                        y = new_coord.y();
867
868                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
869                        event->setX(x);
870                        event->setY(y);
871                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
872
873                    }
874                    // pass along the new pointer events details to the eventState of the viewer
875                    eventState->setX(x);
876                    eventState->setY(y);
877                    eventState->setButtonMask(event->getButtonMask());
878                    eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
879
880                }
881                else
882                {
883                    event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
884                    event->setX(eventState->getX());
885                    event->setY(eventState->getY());
886                    event->setButtonMask(eventState->getButtonMask());
887                    event->setMouseYOrientation(eventState->getMouseYOrientation());
888                }
889            }
890
891            for(itr = gw_events.begin();
892                itr != gw_events.end();
893                ++itr)
894            {
895                osgGA::GUIEventAdapter* event = itr->get();
896                switch(event->getEventType())
897                {
898                    case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
899                    {
900                        bool wasThreading = areThreadsRunning();
901                        if (wasThreading) stopThreading();
902
903                        gw->close();
904
905                        if (wasThreading) startThreading();
906
907                        break;
908                    }
909                    default:
910                        break;
911                }
912            }
913
914            viewEventsMap[masterView].insert( viewEventsMap[masterView].end(), gw_events.begin(), gw_events.end() );
915
916        }
917    }
918
919
920    // OSG_NOTICE<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
921
922
923    for(RefViews::iterator vitr = _views.begin();
924        vitr != _views.end();
925        ++vitr)
926    {
927        View* view = vitr->get();
928        view->getEventQueue()->takeEvents(viewEventsMap[view], cutOffTime);
929    }
930
931
932    // OSG_NOTICE<<"Events "<<events.size()<<std::endl;
933
934    if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
935    {
936        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
937            veitr != viewEventsMap.end();
938            ++veitr)
939        {
940            for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
941                itr != veitr->second.end();
942                ++itr)
943            {
944                osgGA::GUIEventAdapter* event = itr->get();
945                switch(event->getEventType())
946                {
947                    case(osgGA::GUIEventAdapter::KEYUP):
948                        if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
949                        break;
950
951                    case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
952                        if (_quitEventSetsDone) _done = true;
953                        break;
954
955                    default:
956                        break;
957                }
958            }
959        }
960    }
961
962    if (_done) return;
963
964    if (_eventVisitor.valid())
965    {
966        _eventVisitor->setFrameStamp(getFrameStamp());
967        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
968
969        for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
970            veitr != viewEventsMap.end();
971            ++veitr)
972        {
973            View* view = veitr->first;
974            _eventVisitor->setActionAdapter(view);
975
976            if (view->getSceneData())
977            {
978                for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
979                    itr != veitr->second.end();
980                    ++itr)
981                {
982                    osgGA::GUIEventAdapter* event = itr->get();
983
984                    _eventVisitor->reset();
985                    _eventVisitor->addEvent( event );
986
987                    view->getSceneData()->accept(*_eventVisitor);
988
989                    // Do EventTraversal for slaves with their own subgraph
990                    for(unsigned int i=0; i<view->getNumSlaves(); ++i)
991                    {
992                        osg::View::Slave& slave = view->getSlave(i);
993                        osg::Camera* camera = slave._camera.get();
994                        if(camera && !slave._useMastersSceneData)
995                        {
996                            camera->accept(*_eventVisitor);
997                        }
998                    }
999
1000                    // call any camera event callbacks, but only traverse that callback, don't traverse its subgraph
1001                    // leave that to the scene update traversal.
1002                    osg::NodeVisitor::TraversalMode tm = _eventVisitor->getTraversalMode();
1003                    _eventVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
1004
1005                    if (view->getCamera() && view->getCamera()->getEventCallback()) view->getCamera()->accept(*_eventVisitor);
1006
1007                    for(unsigned int i=0; i<view->getNumSlaves(); ++i)
1008                    {
1009                        osg::View::Slave& slave = view->getSlave(i);
1010                        osg::Camera* camera = view->getSlave(i)._camera.get();
1011                        if (camera && slave._useMastersSceneData && camera->getEventCallback())
1012                        {
1013                            camera->accept(*_eventVisitor);
1014                        }
1015                    }
1016
1017                    _eventVisitor->setTraversalMode(tm);
1018
1019                }
1020            }
1021        }
1022
1023    }
1024
1025    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
1026        veitr != viewEventsMap.end();
1027        ++veitr)
1028    {
1029        View* view = veitr->first;
1030
1031        for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
1032            itr != veitr->second.end();
1033            ++itr)
1034        {
1035            osgGA::GUIEventAdapter* event = itr->get();
1036
1037            for(View::EventHandlers::iterator hitr = view->getEventHandlers().begin();
1038                hitr != view->getEventHandlers().end();
1039                ++hitr)
1040            {
1041                (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view, 0, _eventVisitor.get());
1042            }
1043        }
1044    }
1045
1046    for(ViewEventsMap::iterator veitr = viewEventsMap.begin();
1047        veitr != viewEventsMap.end();
1048        ++veitr)
1049    {
1050        View* view = veitr->first;
1051
1052        for(osgGA::EventQueue::Events::iterator itr = veitr->second.begin();
1053            itr != veitr->second.end();
1054            ++itr)
1055        {
1056            osgGA::GUIEventAdapter* event = itr->get();
1057
1058            if (view->getCameraManipulator())
1059            {
1060                view->getCameraManipulator()->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *view);
1061            }
1062        }
1063    }
1064
1065
1066
1067    if (getViewerStats() && getViewerStats()->collectStats("event"))
1068    {
1069        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1070
1071        // update current frames stats
1072        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal begin time", beginEventTraversal);
1073        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal end time", endEventTraversal);
1074        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal time taken", endEventTraversal-beginEventTraversal);
1075    }
1076}
1077
1078
1079void CompositeViewer::updateTraversal()
1080{
1081    if (_done) return;
1082
1083    double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1084
1085    _updateVisitor->reset();
1086    _updateVisitor->setFrameStamp(getFrameStamp());
1087    _updateVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
1088
1089    Scenes scenes;
1090    getScenes(scenes);
1091    for(Scenes::iterator sitr = scenes.begin();
1092        sitr != scenes.end();
1093        ++sitr)
1094    {
1095        Scene* scene = *sitr;
1096        scene->updateSceneGraph(*_updateVisitor);
1097    }
1098
1099    // if we have a shared state manager prune any unused entries
1100    if (osgDB::Registry::instance()->getSharedStateManager())
1101        osgDB::Registry::instance()->getSharedStateManager()->prune();
1102
1103    // update the Registry object cache.
1104    osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(*getFrameStamp());
1105    osgDB::Registry::instance()->removeExpiredObjectsInCache(*getFrameStamp());
1106
1107
1108    if (_incrementalCompileOperation.valid())
1109    {
1110        // merge subgraphs that have been compiled by the incremental compiler operation.
1111        _incrementalCompileOperation->mergeCompiledSubgraphs(getFrameStamp());
1112    }
1113
1114    if (_updateOperations.valid())
1115    {
1116        _updateOperations->runOperations(this);
1117    }
1118
1119    for(RefViews::iterator vitr = _views.begin();
1120        vitr != _views.end();
1121        ++vitr)
1122    {
1123        View* view = vitr->get();
1124
1125        {
1126            // Do UpdateTraversal for slaves with their own subgraph
1127            for(unsigned int i=0; i<view->getNumSlaves(); ++i)
1128            {
1129                osg::View::Slave& slave = view->getSlave(i);
1130                osg::Camera* camera = slave._camera.get();
1131                if(camera && !slave._useMastersSceneData)
1132                {
1133                    camera->accept(*_updateVisitor);
1134                }
1135            }
1136
1137            // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
1138            // leave that to the scene update traversal.
1139            osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode();
1140            _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
1141
1142            if (view->getCamera() && view->getCamera()->getUpdateCallback()) view->getCamera()->accept(*_updateVisitor);
1143
1144            for(unsigned int i=0; i<view->getNumSlaves(); ++i)
1145            {
1146                osg::View::Slave& slave = view->getSlave(i);
1147                osg::Camera* camera = slave._camera.get();
1148                if (camera && slave._useMastersSceneData && camera->getUpdateCallback())
1149                {
1150                    camera->accept(*_updateVisitor);
1151                }
1152            }
1153
1154            _updateVisitor->setTraversalMode(tm);
1155        }
1156
1157
1158        if (view->getCameraManipulator())
1159        {
1160            view->setFusionDistance( view->getCameraManipulator()->getFusionDistanceMode(),
1161                                    view->getCameraManipulator()->getFusionDistanceValue() );
1162           
1163            view->getCameraManipulator()->updateCamera(*(view->getCamera()));
1164           
1165        }
1166        view->updateSlaves();
1167
1168    }
1169
1170    if (getViewerStats() && getViewerStats()->collectStats("update"))
1171    {
1172        double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1173
1174        // update current frames stats
1175        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal);
1176        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal);
1177        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal);
1178    }
1179
1180}
1181
1182double CompositeViewer::elapsedTime()
1183{
1184    return osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1185}
1186
1187void CompositeViewer::getUsage(osg::ApplicationUsage& usage) const
1188{
1189    for(RefViews::const_iterator vitr = _views.begin();
1190        vitr != _views.end();
1191        ++vitr)
1192    {
1193        const View* view = vitr->get();
1194        if (view->getCameraManipulator())
1195        {
1196            view->getCameraManipulator()->getUsage(usage);
1197        }
1198
1199        for(View::EventHandlers::const_iterator hitr = view->_eventHandlers.begin();
1200            hitr != view->_eventHandlers.end();
1201            ++hitr)
1202        {
1203            (*hitr)->getUsage(usage);
1204        }
1205    }
1206}
Note: See TracBrowser for help on using the browser.