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

Revision 13172, 40.1 kB (checked in by robert, 2 days ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • 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.