root/OpenSceneGraph/trunk/src/osgViewer/Viewer.cpp @ 13277

Revision 13277, 42.2 kB (checked in by robert, 12 minutes ago)

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

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

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#include <stdio.h>
15#include <stdlib.h>
16
17#include <osg/DeleteHandler>
18#include <osg/io_utils>
19
20#include <osgDB/Registry>
21#include <osgDB/ReadFile>
22#include <osgGA/TrackballManipulator>
23
24#include <osgViewer/Viewer>
25#include <osgViewer/Renderer>
26#include <osgViewer/CompositeViewer>
27
28#include <sstream>
29#include <string.h>
30
31using namespace osgViewer;
32
33
34Viewer::Viewer()
35{
36    _viewerBase = this;
37
38    constructorInit();
39}
40
41Viewer::Viewer(osg::ArgumentParser& arguments)
42{
43    _viewerBase = this;
44
45    constructorInit();
46
47    // Add help for command-line options read here
48    arguments.getApplicationUsage()->addCommandLineOption("--SingleThreaded","Select SingleThreaded threading model for viewer.");
49    arguments.getApplicationUsage()->addCommandLineOption("--CullDrawThreadPerContext","Select CullDrawThreadPerContext threading model for viewer.");
50    arguments.getApplicationUsage()->addCommandLineOption("--DrawThreadPerContext","Select DrawThreadPerContext threading model for viewer.");
51    arguments.getApplicationUsage()->addCommandLineOption("--CullThreadPerCameraDrawThreadPerContext","Select CullThreadPerCameraDrawThreadPerContext threading model for viewer.");
52    arguments.getApplicationUsage()->addCommandLineOption("--clear-color <color>","Set the background color of the viewer in the form \"r,g,b[,a]\".");
53    arguments.getApplicationUsage()->addCommandLineOption("--screen <num>","Set the screen to use when multiple screens are present.");
54    arguments.getApplicationUsage()->addCommandLineOption("--window <x y w h>","Set the position (x,y) and size (w,h) of the viewer window.");
55
56    arguments.getApplicationUsage()->addCommandLineOption("--run-on-demand","Set the run methods frame rate management to only rendering frames when required.");
57    arguments.getApplicationUsage()->addCommandLineOption("--run-continuous","Set the run methods frame rate management to rendering frames continuously.");
58    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.");
59    arguments.getApplicationUsage()->addCommandLineOption("--enable-object-cache","Enable caching of objects, images, etc.");
60
61    // FIXME: Uncomment these lines when the options have been documented properly
62    //arguments.getApplicationUsage()->addCommandLineOption("--3d-sd","");
63    //arguments.getApplicationUsage()->addCommandLineOption("--panoramic-sd","");
64    //arguments.getApplicationUsage()->addCommandLineOption("--radius","");
65    //arguments.getApplicationUsage()->addCommandLineOption("--collar","");
66    //arguments.getApplicationUsage()->addCommandLineOption("--im","");
67
68    if (arguments.read("--ico"))
69    {
70        setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation());
71    }
72
73    std::string filename;
74    bool readConfig = false;
75    while (arguments.read("-c",filename))
76    {
77        readConfig = readConfiguration(filename) || readConfig;
78    }
79
80    // Enable caching?
81    while (arguments.read("--enable-object-cache"))
82    {
83        if (osgDB::Registry::instance()->getOptions()==0) osgDB::Registry::instance()->setOptions(new osgDB::Options());
84        osgDB::Registry::instance()->getOptions()->setObjectCacheHint(osgDB::Options::CACHE_ALL);
85    }
86
87    while (arguments.read("--SingleThreaded")) setThreadingModel(SingleThreaded);
88    while (arguments.read("--CullDrawThreadPerContext")) setThreadingModel(CullDrawThreadPerContext);
89    while (arguments.read("--DrawThreadPerContext")) setThreadingModel(DrawThreadPerContext);
90    while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) setThreadingModel(CullThreadPerCameraDrawThreadPerContext);
91
92    osg::DisplaySettings::instance()->readCommandLine(arguments);
93    osgDB::readCommandLine(arguments);
94
95    std::string colorStr;
96    while (arguments.read("--clear-color",colorStr))
97    {
98        float r, g, b;
99        float a = 1.0f;
100        int cnt = sscanf( colorStr.c_str(), "%f,%f,%f,%f", &r, &g, &b, &a );
101        if( cnt==3 || cnt==4 )
102        {
103            getCamera()->setClearColor( osg::Vec4(r,g,b,a) );
104        }
105        else
106        {
107            OSG_WARN<<"Invalid clear color \""<<colorStr<<"\""<<std::endl;
108        }
109    }
110
111
112    while(arguments.read("--run-on-demand")) { setRunFrameScheme(ON_DEMAND); }
113    while(arguments.read("--run-continuous")) { setRunFrameScheme(CONTINUOUS); }
114
115    double runMaxFrameRate;
116    while(arguments.read("--run-max-frame-rate", runMaxFrameRate)) { setRunMaxFrameRate(runMaxFrameRate); }
117
118
119    int screenNum = -1;
120    while (arguments.read("--screen",screenNum)) {}
121
122    int x = -1, y = -1, width = -1, height = -1;
123    while (arguments.read("--window",x,y,width,height)) {}
124
125    bool ss3d = false;
126    bool wowvx20 = false;
127    bool wowvx42 = false;
128    if ((wowvx20=arguments.read("--wowvx-20")) || (wowvx42=arguments.read("--wowvx-42")) || arguments.read("--wowvx"))
129    {
130        int wow_content=0x02, wow_factor=0x40, wow_offset=0x80;
131        float wow_Zd, wow_vz, wow_M, wow_C;
132        if (wowvx20){
133            wow_Zd = 0.459813f;
134            wow_vz = 6.180772f;
135            wow_M = -1586.34f;
136            wow_C = 127.5f;
137        }
138        else if (wowvx42){
139            wow_Zd = 0.467481f;
140            wow_vz = 7.655192f;
141            wow_M = -1960.37f;
142            wow_C = 127.5f;
143        }
144
145        while (arguments.read("--wow-content",wow_content)) {}
146        while (arguments.read("--wow-factor",wow_factor)) {}
147        while (arguments.read("--wow-offset",wow_offset)) {}
148        while (arguments.read("--wow-zd",wow_Zd)) {}
149        while (arguments.read("--wow-vz",wow_vz)) {}
150        while (arguments.read("--wow-M",wow_M)) {}
151        while (arguments.read("--wow-C",wow_C)) {}
152
153        if (screenNum<0) screenNum = 0;
154
155        setUpViewForWoWVxDisplay( screenNum, wow_content, wow_factor, wow_offset, wow_Zd, wow_vz, wow_M, wow_C );
156    }
157    else if ((ss3d=arguments.read("--3d-sd")) || arguments.read("--panoramic-sd"))
158    {
159        double radius = 1.0;
160        while (arguments.read("--radius",radius)) {}
161
162        double collar = 0.45;
163        while (arguments.read("--collar",collar)) {}
164
165        std::string intensityMapFilename;
166        while (arguments.read("--im",intensityMapFilename)) {}
167
168        osg::ref_ptr<osg::Image> intensityMap = intensityMapFilename.empty() ? 0 : osgDB::readImageFile(intensityMapFilename);
169
170        if (screenNum<0) screenNum = 0;
171
172        if (ss3d)
173        {
174            setThreadingModel(SingleThreaded);
175            setUpViewFor3DSphericalDisplay(radius, collar, screenNum, intensityMap.get());
176        }
177        else
178        {
179            setThreadingModel(SingleThreaded);
180            setUpViewForPanoramicSphericalDisplay(radius, collar, screenNum, intensityMap.get());
181        }
182    }
183    else if (width>0 && height>0)
184    {
185        if (screenNum>=0) setUpViewInWindow(x, y, width, height, screenNum);
186        else setUpViewInWindow(x,y,width,height);
187
188    }
189    else if (screenNum>=0)
190    {
191        setUpViewOnSingleScreen(screenNum);
192    }
193
194}
195
196Viewer::Viewer(const osgViewer::Viewer& viewer, const osg::CopyOp& copyop):
197    osg::Object(true),
198    ViewerBase(viewer),
199    View(viewer,copyop)
200{
201    _viewerBase = this;
202}
203
204void Viewer::constructorInit()
205{
206    _eventVisitor = new osgGA::EventVisitor;
207    _eventVisitor->setActionAdapter(this);
208    _eventVisitor->setFrameStamp(_frameStamp.get());
209
210    _updateVisitor = new osgUtil::UpdateVisitor;
211    _updateVisitor->setFrameStamp(_frameStamp.get());
212
213    setViewerStats(new osg::Stats("Viewer"));
214}
215
216Viewer::~Viewer()
217{
218    //OSG_NOTICE<<"Viewer::~Viewer()"<<std::endl;
219
220    Threads threads;
221    getAllThreads(threads);
222
223    OSG_INFO<<"Viewer::~Viewer():: start destructor getThreads = "<<threads.size()<<std::endl;
224
225    stopThreading();
226
227    if (_scene.valid() && _scene->getDatabasePager())
228    {
229        _scene->getDatabasePager()->cancel();
230        _scene->setDatabasePager(0);
231    }
232
233    Contexts contexts;
234    getContexts(contexts);
235
236    // clear out all the previously assigned operations
237    for(Contexts::iterator citr = contexts.begin();
238        citr != contexts.end();
239        ++citr)
240    {
241        (*citr)->close();
242    }
243
244    //OSG_NOTICE<<"finish Viewer::~Viewer()"<<std::endl;
245
246    getAllThreads(threads);
247
248    OSG_INFO<<"Viewer::~Viewer() end destructor getThreads = "<<threads.size()<<std::endl;
249}
250
251void Viewer::take(osg::View& rhs)
252{
253    osgViewer::View::take(rhs);
254
255#if 1
256    osgViewer::Viewer* rhs_viewer = dynamic_cast<osgViewer::Viewer*>(&rhs);
257    if (rhs_viewer)
258    {
259        // variables left to take.
260        _done = rhs_viewer->_done;
261        _keyEventSetsDone = rhs_viewer->_keyEventSetsDone;
262        _quitEventSetsDone = rhs_viewer->_quitEventSetsDone;
263        _threadingModel = rhs_viewer->_threadingModel;
264        _threadsRunning = rhs_viewer->_threadsRunning;
265        _endBarrierPosition = rhs_viewer->_endBarrierPosition;
266        _startRenderingBarrier = rhs_viewer->_startRenderingBarrier;
267        _endRenderingDispatchBarrier = rhs_viewer->_endRenderingDispatchBarrier;
268        _endDynamicDrawBlock = rhs_viewer->_endDynamicDrawBlock;
269        _cameraWithFocus = rhs_viewer->_cameraWithFocus;
270        _eventVisitor = rhs_viewer->_eventVisitor;
271        _updateOperations = rhs_viewer->_updateOperations;
272        _updateVisitor = rhs_viewer->_updateVisitor;
273        _realizeOperation = rhs_viewer->_realizeOperation;
274        _currentContext = rhs_viewer->_currentContext;
275
276
277        // objects to clear
278        rhs_viewer->_done = true;
279        rhs_viewer->_startRenderingBarrier = 0;
280        rhs_viewer->_endRenderingDispatchBarrier = 0;
281        rhs_viewer->_endDynamicDrawBlock = 0;
282        rhs_viewer->_cameraWithFocus = 0;
283        rhs_viewer->_eventVisitor = 0;
284        rhs_viewer->_updateOperations = 0;
285        rhs_viewer->_updateVisitor = 0;
286        rhs_viewer->_realizeOperation = 0;
287        rhs_viewer->_currentContext = 0;
288    }
289#endif
290}
291
292bool Viewer::readConfiguration(const std::string& filename)
293{
294    OSG_INFO<<"Viewer::readConfiguration("<<filename<<")"<<std::endl;
295
296    osg::ref_ptr<osg::Object> object = osgDB::readObjectFile(filename);
297    if (!object)
298    {
299        //OSG_NOTICE<<"Error: Unable to load configuration file \""<<filename<<"\""<<std::endl;
300        return false;
301    }
302
303    CompositeViewer* compositeViewer = dynamic_cast<CompositeViewer*>(object.get());
304    if (compositeViewer)
305    {
306        OSG_NOTICE<<"Error: Config file \""<<filename<<"\" containing CompositeViewer cannot be loaded by Viewer."<<std::endl;
307        return false;
308    }
309
310    View* view = dynamic_cast<osgViewer::View*>(object.get());
311    if (view)
312    {
313        take(*view);
314
315        return true;
316    }
317    else
318    {
319        OSG_NOTICE<<"Error: Config file \""<<filename<<"\" does not contain a valid Viewer configuration."<<std::endl;
320        return false;
321    }
322}
323
324bool Viewer::isRealized() const
325{
326    Contexts contexts;
327    const_cast<Viewer*>(this)->getContexts(contexts);
328
329    unsigned int numRealizedWindows = 0;
330
331    // clear out all the previously assigned operations
332    for(Contexts::iterator citr = contexts.begin();
333        citr != contexts.end();
334        ++citr)
335    {
336        if ((*citr)->isRealized()) ++numRealizedWindows;
337    }
338
339    return numRealizedWindows > 0;
340}
341
342bool Viewer::checkNeedToDoFrame()
343{
344    if (_requestRedraw) return true;
345    if (_requestContinousUpdate) return true;
346
347
348    // If the database pager is going to update the scene the render flag is
349    // set so that the updates show up
350    if(getDatabasePager()->requiresUpdateSceneGraph() || getDatabasePager()->getRequestsInProgress()) return true;
351
352    // if there update callbacks then we need to do frame.
353    if (_camera->getUpdateCallback()) return true;
354    if (getSceneData()!=0 && getSceneData()->getNumChildrenRequiringUpdateTraversal()>0) return true;
355
356    // now do a eventTraversal to see if any events might require a new frame.
357    eventTraversal();
358
359    // now check if any of the event handles have prompted a redraw.
360    if (_requestRedraw) return true;
361    if (_requestContinousUpdate) return true;
362
363    return false;
364}
365
366int Viewer::run()
367{
368    if (!getCameraManipulator() && getCamera()->getAllowEventFocus())
369    {
370        setCameraManipulator(new osgGA::TrackballManipulator());
371    }
372
373    setReleaseContextAtEndOfFrameHint(false);
374
375    return ViewerBase::run();
376}
377
378void Viewer::setStartTick(osg::Timer_t tick)
379{
380    View::setStartTick(tick);
381
382    Contexts contexts;
383    getContexts(contexts,false);
384
385    getEventQueue()->setStartTick(_startTick);
386    for(Contexts::iterator citr = contexts.begin();
387        citr != contexts.end();
388        ++citr)
389    {
390        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
391        if (gw)
392        {
393            gw->getEventQueue()->setStartTick(_startTick);
394        }
395    }
396}
397
398void Viewer::setReferenceTime(double time)
399{
400    osg::Timer_t tick = osg::Timer::instance()->tick();
401    double currentTime = osg::Timer::instance()->delta_s(_startTick, tick);
402    double delta_ticks = (time-currentTime)*(osg::Timer::instance()->getSecondsPerTick());
403    if (delta_ticks>=0) tick += osg::Timer_t(delta_ticks);
404    else tick -= osg::Timer_t(-delta_ticks);
405
406    // assign the new start tick
407    setStartTick(tick);
408}
409
410
411void Viewer::setSceneData(osg::Node* node)
412{
413    setReferenceTime(0.0);
414
415    View::setSceneData(node);
416}
417
418GraphicsWindowEmbedded* Viewer::setUpViewerAsEmbeddedInWindow(int x, int y, int width, int height)
419{
420    setThreadingModel(SingleThreaded);
421    osgViewer::GraphicsWindowEmbedded* gw = new osgViewer::GraphicsWindowEmbedded(x,y,width,height);
422    getCamera()->setViewport(new osg::Viewport(0,0,width,height));
423    getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width)/static_cast<double>(height), 1.0f, 10000.0f);
424    getCamera()->setGraphicsContext(gw);
425    return gw;
426}
427
428void Viewer::realize()
429{
430    //OSG_INFO<<"Viewer::realize()"<<std::endl;
431
432    setCameraWithFocus(0);
433
434    Contexts contexts;
435    getContexts(contexts);
436
437    if (contexts.empty())
438    {
439        OSG_INFO<<"Viewer::realize() - No valid contexts found, setting up view across all screens."<<std::endl;
440
441        // no windows are already set up so set up a default view
442
443        const char* ptr = 0;
444        if ((ptr = getenv("OSG_CONFIG_FILE")) != 0)
445        {
446            readConfiguration(ptr);
447        }
448        else
449        {
450            int screenNum = -1;
451            if ((ptr = getenv("OSG_SCREEN")) != 0)
452            {
453                if (strlen(ptr)!=0) screenNum = atoi(ptr);
454                else screenNum = -1;
455            }
456
457            int x = -1, y = -1, width = -1, height = -1;
458            if ((ptr = getenv("OSG_WINDOW")) != 0)
459            {
460                std::istringstream iss(ptr);
461                iss >> x >> y >> width >> height;
462            }
463
464            if (width>0 && height>0)
465            {
466                if (screenNum>=0) setUpViewInWindow(x, y, width, height, screenNum);
467                else setUpViewInWindow(x,y,width,height);
468            }
469            else if (screenNum>=0)
470            {
471                setUpViewOnSingleScreen(screenNum);
472            }
473            else
474            {
475                setUpViewAcrossAllScreens();
476            }
477        }
478
479        getContexts(contexts);
480    }
481
482    if (contexts.empty())
483    {
484        OSG_NOTICE<<"Viewer::realize() - failed to set up any windows"<<std::endl;
485        _done = true;
486        return;
487    }
488
489    unsigned int maxTexturePoolSize = osg::DisplaySettings::instance()->getMaxTexturePoolSize();
490    if (_camera->getDisplaySettings()) maxTexturePoolSize = std::max(maxTexturePoolSize, _camera->getDisplaySettings()->getMaxTexturePoolSize());
491    if (_displaySettings.valid()) maxTexturePoolSize = std::max(maxTexturePoolSize, _displaySettings->getMaxTexturePoolSize());
492
493    unsigned int maxBufferObjectPoolSize = osg::DisplaySettings::instance()->getMaxBufferObjectPoolSize();
494    if (_displaySettings.valid()) maxBufferObjectPoolSize = std::max(maxBufferObjectPoolSize, _displaySettings->getMaxBufferObjectPoolSize());
495    if (_camera->getDisplaySettings()) maxBufferObjectPoolSize = std::max(maxBufferObjectPoolSize, _camera->getDisplaySettings()->getMaxBufferObjectPoolSize());
496
497    for(Contexts::iterator citr = contexts.begin();
498        citr != contexts.end();
499        ++citr)
500    {
501        osg::GraphicsContext* gc = *citr;
502
503        // set the pool sizes, 0 the default will result in no GL object pools.
504        gc->getState()->setMaxTexturePoolSize(maxTexturePoolSize);
505        gc->getState()->setMaxBufferObjectPoolSize(maxBufferObjectPoolSize);
506
507        gc->realize();
508
509        if (_realizeOperation.valid() && gc->valid())
510        {
511            gc->makeCurrent();
512
513            (*_realizeOperation)(gc);
514
515            gc->releaseContext();
516        }
517    }
518
519    // attach contexts to _incrementalCompileOperation if attached.
520    if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
521
522    bool grabFocus = true;
523    if (grabFocus)
524    {
525        for(Contexts::iterator citr = contexts.begin();
526            citr != contexts.end();
527            ++citr)
528        {
529            osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
530            if (gw)
531            {
532                gw->grabFocusIfPointerInWindow();
533            }
534        }
535    }
536
537    // initialize the global timer to be relative to the current time.
538    osg::Timer::instance()->setStartTick();
539
540    // pass on the start tick to all the associated event queues
541    setStartTick(osg::Timer::instance()->getStartTick());
542
543    setUpThreading();
544
545    if (osg::DisplaySettings::instance()->getCompileContextsHint())
546    {
547        int numProcessors = OpenThreads::GetNumberOfProcessors();
548        int processNum = 0;
549
550        for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i)
551        {
552            osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i);
553
554            if (gc)
555            {
556                gc->createGraphicsThread();
557                gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
558                gc->getGraphicsThread()->startThread();
559
560                ++processNum;
561            }
562        }
563    }
564
565    osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
566    if (getCamera()->getViewport())
567    {
568        osg::Viewport* viewport = getCamera()->getViewport();
569        eventState->setInputRange( viewport->x(), viewport->y(), viewport->x() + viewport->width(), viewport->y() + viewport->height());
570    }
571    else
572    {
573        eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
574    }
575}
576
577
578
579void Viewer::advance(double simulationTime)
580{
581    if (_done) return;
582
583    double previousReferenceTime = _frameStamp->getReferenceTime();
584    unsigned int previousFrameNumber = _frameStamp->getFrameNumber();
585
586    _frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1);
587
588    _frameStamp->setReferenceTime( osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick()) );
589
590    if (simulationTime==USE_REFERENCE_TIME)
591    {
592        _frameStamp->setSimulationTime(_frameStamp->getReferenceTime());
593    }
594    else
595    {
596        _frameStamp->setSimulationTime(simulationTime);
597    }
598
599    if (getViewerStats() && getViewerStats()->collectStats("frame_rate"))
600    {
601        // update previous frame stats
602        double deltaFrameTime = _frameStamp->getReferenceTime() - previousReferenceTime;
603        getViewerStats()->setAttribute(previousFrameNumber, "Frame duration", deltaFrameTime);
604        getViewerStats()->setAttribute(previousFrameNumber, "Frame rate", 1.0/deltaFrameTime);
605
606        // update current frames stats
607        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Reference time", _frameStamp->getReferenceTime());
608    }
609
610
611    if (osg::Referenced::getDeleteHandler())
612    {
613        osg::Referenced::getDeleteHandler()->flush();
614        osg::Referenced::getDeleteHandler()->setFrameNumber(_frameStamp->getFrameNumber());
615    }
616
617}
618
619void Viewer::eventTraversal()
620{
621    if (_done) return;
622
623    double cutOffTime = (_runFrameScheme==ON_DEMAND) ? DBL_MAX : _frameStamp->getReferenceTime();
624
625    double beginEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
626
627    // OSG_NOTICE<<"Viewer::frameEventTraversal()."<<std::endl;
628
629    // need to copy events from the GraphicsWindow's into local EventQueue;
630    osgGA::EventQueue::Events events;
631
632    Contexts contexts;
633    getContexts(contexts);
634
635    // set done if there are no windows
636    checkWindowStatus(contexts);
637    if (_done) return;
638
639    osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
640    osg::Matrix masterCameraVPW = getCamera()->getViewMatrix() * getCamera()->getProjectionMatrix();
641    if (getCamera()->getViewport())
642    {
643        osg::Viewport* viewport = getCamera()->getViewport();
644        masterCameraVPW *= viewport->computeWindowMatrix();
645    }
646
647
648    // get events from user Devices attached to Viewer.
649    for(Devices::iterator eitr = _eventSources.begin();
650        eitr != _eventSources.end();
651        ++eitr)
652    {
653        osgGA::Device* es = eitr->get();
654        if (es->getCapabilities() & osgGA::Device::RECEIVE_EVENTS)
655            es->checkEvents();
656
657        // open question, will we need to reproject mouse coordinates into current view's coordinate frame as is down for GraphicsWindow provided events?
658        // for now assume now and just get the events directly without any reprojection.
659        es->getEventQueue()->takeEvents(events, cutOffTime);
660    }
661
662    // get events from all windows attached to Viewer.
663    for(Contexts::iterator citr = contexts.begin();
664        citr != contexts.end();
665        ++citr)
666    {
667        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
668        if (gw)
669        {
670            gw->checkEvents();
671
672            osgGA::EventQueue::Events gw_events;
673            gw->getEventQueue()->takeEvents(gw_events, cutOffTime);
674
675            osgGA::EventQueue::Events::iterator itr;
676            for(itr = gw_events.begin();
677                itr != gw_events.end();
678                ++itr)
679            {
680                osgGA::GUIEventAdapter* event = itr->get();
681
682                bool pointerEvent = false;
683
684                float x = event->getX();
685                float y = event->getY();
686
687                bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
688                if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
689
690                switch(event->getEventType())
691                {
692                    case(osgGA::GUIEventAdapter::PUSH):
693                    case(osgGA::GUIEventAdapter::RELEASE):
694                    case(osgGA::GUIEventAdapter::DOUBLECLICK):
695                    case(osgGA::GUIEventAdapter::DRAG):
696                    case(osgGA::GUIEventAdapter::MOVE):
697                    {
698                        pointerEvent = true;
699
700                        if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
701                        {
702                            osg::GraphicsContext::Cameras& cameras = gw->getCameras();
703                            for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
704                                citr != cameras.end();
705                                ++citr)
706                            {
707                                osg::Camera* camera = *citr;
708                                if (camera->getView()==this &&
709                                    camera->getAllowEventFocus() &&
710                                    camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
711                                {
712                                    osg::Viewport* viewport = camera ? camera->getViewport() : 0;
713                                    if (viewport &&
714                                        x >= viewport->x() && y >= viewport->y() &&
715                                        x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
716                                    {
717                                        // OSG_NOTICE<<"setCamera with focus "<<camera->getName()<<" x="<<x<<" y="<<y<<std::endl;
718                                        setCameraWithFocus(camera);
719                                    }
720                                }
721                            }
722                        }
723
724                        break;
725                    }
726                    default:
727                        break;
728                }
729
730                if (pointerEvent)
731                {
732                    if (getCameraWithFocus())
733                    {
734                        if (getCameraWithFocus()!=getCamera())
735                        {
736                            osg::Viewport* viewport = getCameraWithFocus()->getViewport();
737                            osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
738                            if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
739
740                            osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
741
742                            osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
743
744                            x = new_coord.x();
745                            y = new_coord.y();
746                        }
747
748                        // OSG_NOTICE<<"pointer event new_coord.x()="<<new_coord.x()<<" new_coord.y()="<<new_coord.y()<<std::endl;
749
750                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
751                        event->setX(x);
752                        event->setY(y);
753                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
754
755                    }
756                    else
757                    {
758                        x = eventState->getXmin() + (x/double(gw->getTraits()->width))*(eventState->getXmax() - eventState->getXmin());
759                        y = eventState->getYmin() + (y/double(gw->getTraits()->height))*(eventState->getYmax() - eventState->getYmin());
760                        // OSG_NOTICE<<"new x = "<<x<<" new y = "<<y<<std::endl;
761
762                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
763                        event->setX(x);
764                        event->setY(y);
765                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
766                    }
767
768                    // pass along the new pointer events details to the eventState of the viewer
769                    eventState->setX(x);
770                    eventState->setY(y);
771                    eventState->setButtonMask(event->getButtonMask());
772                    eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
773
774                }
775                else
776                {
777                    event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
778                    event->setX(eventState->getX());
779                    event->setY(eventState->getY());
780                    event->setButtonMask(eventState->getButtonMask());
781                    event->setMouseYOrientation(eventState->getMouseYOrientation());
782                }
783                //OSG_NOTICE<<"   mouse x = "<<event->getX()<<" y="<<event->getY()<<std::endl;
784                // OSG_NOTICE<<"   mouse Xmin = "<<event->getXmin()<<" Ymin="<<event->getYmin()<<" xMax="<<event->getXmax()<<" Ymax="<<event->getYmax()<<std::endl;
785            }
786
787            for(itr = gw_events.begin();
788                itr != gw_events.end();
789                ++itr)
790            {
791                osgGA::GUIEventAdapter* event = itr->get();
792                switch(event->getEventType())
793                {
794                    case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
795                    {
796                        bool wasThreading = areThreadsRunning();
797                        if (wasThreading) stopThreading();
798
799                        gw->close();
800                        _currentContext = NULL;
801
802                        if (wasThreading) startThreading();
803
804                        break;
805                    }
806                    default:
807                        break;
808                }
809            }
810
811            events.insert(events.end(), gw_events.begin(), gw_events.end());
812
813        }
814    }
815
816    // pass on the coorindates of the main camera to make sure the frame event is scaled appropriately.
817    if (getCamera()->getViewport())
818    {
819        osg::Viewport* viewport = getCamera()->getViewport();
820        eventState->setInputRange( viewport->x(), viewport->y(), viewport->x() + viewport->width(), viewport->y() + viewport->height());
821    }
822    else
823    {
824        eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
825    }
826
827    // create a frame event for the new frame.
828    _eventQueue->frame( getFrameStamp()->getReferenceTime() );
829
830    // OSG_NOTICE<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
831
832    _eventQueue->takeEvents(events, cutOffTime);
833
834
835#if 0
836    // OSG_NOTICE<<"Events "<<events.size()<<std::endl;
837    for(osgGA::EventQueue::Events::iterator itr = events.begin();
838        itr != events.end();
839        ++itr)
840    {
841        osgGA::GUIEventAdapter* event = itr->get();
842        switch(event->getEventType())
843        {
844            case(osgGA::GUIEventAdapter::PUSH):
845                OSG_NOTICE<<"  PUSH "<<event->getButton()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
846                break;
847            case(osgGA::GUIEventAdapter::RELEASE):
848                OSG_NOTICE<<"  RELEASE "<<event->getButton()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
849                break;
850            case(osgGA::GUIEventAdapter::DRAG):
851                OSG_NOTICE<<"  DRAG "<<event->getButtonMask()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
852                break;
853            case(osgGA::GUIEventAdapter::MOVE):
854                OSG_NOTICE<<"  MOVE "<<event->getButtonMask()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
855                break;
856            case(osgGA::GUIEventAdapter::SCROLL):
857                OSG_NOTICE<<"  SCROLL "<<event->getScrollingMotion()<<std::endl;
858                break;
859            case(osgGA::GUIEventAdapter::KEYDOWN):
860                OSG_NOTICE<<"  KEYDOWN '"<<(char)event->getKey()<<"'"<<std::endl;
861                break;
862            case(osgGA::GUIEventAdapter::KEYUP):
863                OSG_NOTICE<<"  KEYUP '"<<(char)event->getKey()<<"'"<<std::endl;
864                break;
865            case(osgGA::GUIEventAdapter::RESIZE):
866                OSG_NOTICE<<"  RESIZE "<<event->getWindowX()<<"/"<<event->getWindowY()<<" x "<<event->getWindowWidth()<<"/"<<event->getWindowHeight() << std::endl;
867                break;
868            case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
869                OSG_NOTICE<<"  QUIT_APPLICATION " << std::endl;
870                break;
871            case(osgGA::GUIEventAdapter::FRAME):
872                // OSG_NOTICE<<"  FRAME "<<std::endl;
873                break;
874            default:
875                // OSG_NOTICE<<"  Event not handled"<<std::endl;
876                break;
877        }
878    }
879#endif
880
881    // OSG_NOTICE<<"Events "<<events.size()<<std::endl;
882
883    if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
884    {
885        for(osgGA::EventQueue::Events::iterator itr = events.begin();
886            itr != events.end();
887            ++itr)
888        {
889            osgGA::GUIEventAdapter* event = itr->get();
890            switch(event->getEventType())
891            {
892                case(osgGA::GUIEventAdapter::KEYUP):
893                    if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
894                    break;
895
896                case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
897                    if (_quitEventSetsDone) _done = true;
898                    break;
899
900                default:
901                    break;
902            }
903        }
904    }
905
906    if (_done) return;
907
908    if (_eventVisitor.valid() && getSceneData())
909    {
910        _eventVisitor->setFrameStamp(getFrameStamp());
911        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
912
913        for(osgGA::EventQueue::Events::iterator itr = events.begin();
914            itr != events.end();
915            ++itr)
916        {
917            osgGA::GUIEventAdapter* event = itr->get();
918
919            _eventVisitor->reset();
920            _eventVisitor->addEvent( event );
921
922            getSceneData()->accept(*_eventVisitor);
923
924            // Do EventTraversal for slaves with their own subgraph
925            for(unsigned int i=0; i<getNumSlaves(); ++i)
926            {
927                osg::View::Slave& slave = getSlave(i);
928                osg::Camera* camera = slave._camera.get();
929                if(camera && !slave._useMastersSceneData)
930                {
931                    camera->accept(*_eventVisitor);
932                }
933            }
934
935
936            // call any camera event callbacks, but only traverse that callback, don't traverse its subgraph
937            // leave that to the scene update traversal.
938            osg::NodeVisitor::TraversalMode tm = _eventVisitor->getTraversalMode();
939            _eventVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
940
941            if (_camera.valid() && _camera->getEventCallback()) _camera->accept(*_eventVisitor);
942
943            for(unsigned int i=0; i<getNumSlaves(); ++i)
944            {
945                osg::View::Slave& slave = getSlave(i);
946                osg::Camera* camera = slave._camera.get();
947                if (camera && slave._useMastersSceneData && camera->getEventCallback())
948                {
949                    camera->accept(*_eventVisitor);
950                }
951            }
952
953            _eventVisitor->setTraversalMode(tm);
954
955        }
956    }
957
958
959    for(osgGA::EventQueue::Events::iterator itr = events.begin();
960        itr != events.end();
961        ++itr)
962    {
963        osgGA::GUIEventAdapter* event = itr->get();
964
965        for(EventHandlers::iterator hitr = _eventHandlers.begin();
966            hitr != _eventHandlers.end();
967            ++hitr)
968        {
969            (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this, 0, _eventVisitor.get());
970        }
971
972    }
973
974    for(osgGA::EventQueue::Events::iterator itr = events.begin();
975        itr != events.end();
976        ++itr)
977    {
978        osgGA::GUIEventAdapter* event = itr->get();
979        if (_cameraManipulator.valid())
980        {
981            _cameraManipulator->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this);
982        }
983    }
984
985    if (getViewerStats() && getViewerStats()->collectStats("event"))
986    {
987        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
988
989        // update current frames stats
990        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal begin time", beginEventTraversal);
991        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal end time", endEventTraversal);
992        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal time taken", endEventTraversal-beginEventTraversal);
993    }
994
995}
996
997void Viewer::updateTraversal()
998{
999    if (_done) return;
1000
1001    double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1002
1003    _updateVisitor->reset();
1004    _updateVisitor->setFrameStamp(getFrameStamp());
1005    _updateVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
1006
1007    _scene->updateSceneGraph(*_updateVisitor);
1008
1009    // if we have a shared state manager prune any unused entries
1010    if (osgDB::Registry::instance()->getSharedStateManager())
1011        osgDB::Registry::instance()->getSharedStateManager()->prune();
1012
1013    // update the Registry object cache.
1014    osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(*getFrameStamp());
1015    osgDB::Registry::instance()->removeExpiredObjectsInCache(*getFrameStamp());
1016
1017
1018    if (_updateOperations.valid())
1019    {
1020        _updateOperations->runOperations(this);
1021    }
1022
1023    if (_incrementalCompileOperation.valid())
1024    {
1025        // merge subgraphs that have been compiled by the incremental compiler operation.
1026        _incrementalCompileOperation->mergeCompiledSubgraphs(getFrameStamp());
1027    }
1028
1029    {
1030        // Do UpdateTraversal for slaves with their own subgraph
1031        for(unsigned int i=0; i<getNumSlaves(); ++i)
1032        {
1033            osg::View::Slave& slave = getSlave(i);
1034            osg::Camera* camera = slave._camera.get();
1035            if(camera && !slave._useMastersSceneData)
1036            {
1037                camera->accept(*_updateVisitor);
1038            }
1039        }
1040    }
1041
1042    {
1043        // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
1044        // leave that to the scene update traversal.
1045        osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode();
1046        _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
1047
1048        if (_camera.valid() && _camera->getUpdateCallback()) _camera->accept(*_updateVisitor);
1049
1050        for(unsigned int i=0; i<getNumSlaves(); ++i)
1051        {
1052            osg::View::Slave& slave = getSlave(i);
1053            osg::Camera* camera = slave._camera.get();
1054            if (camera && slave._useMastersSceneData && camera->getUpdateCallback())
1055            {
1056                camera->accept(*_updateVisitor);
1057            }
1058        }
1059
1060        _updateVisitor->setTraversalMode(tm);
1061    }
1062
1063    if (_cameraManipulator.valid())
1064    {
1065        setFusionDistance( getCameraManipulator()->getFusionDistanceMode(),
1066                            getCameraManipulator()->getFusionDistanceValue() );
1067
1068        _cameraManipulator->updateCamera(*_camera);
1069    }
1070
1071    updateSlaves();
1072
1073    if (getViewerStats() && getViewerStats()->collectStats("update"))
1074    {
1075        double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1076
1077        // update current frames stats
1078        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal);
1079        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal);
1080        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal);
1081    }
1082}
1083
1084void Viewer::getScenes(Scenes& scenes, bool onlyValid)
1085{
1086    scenes.clear();
1087    scenes.push_back(_scene.get());
1088}
1089
1090void Viewer::getViews(Views& views, bool onlyValid)
1091{
1092    views.clear();
1093    views.push_back(this);
1094}
1095
1096void Viewer::getAllThreads(Threads& threads, bool onlyActive)
1097{
1098    threads.clear();
1099
1100    OperationThreads operationThreads;
1101    getOperationThreads(operationThreads);
1102
1103    for(OperationThreads::iterator itr = operationThreads.begin();
1104        itr != operationThreads.end();
1105        ++itr)
1106    {
1107        threads.push_back(*itr);
1108    }
1109
1110
1111    if (_scene.valid())
1112    {
1113        osgDB::DatabasePager* dp = _scene->getDatabasePager();
1114        if (dp)
1115        {
1116            for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
1117            {
1118                osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
1119                if (!onlyActive || dt->isRunning())
1120                {
1121                    threads.push_back(dt);
1122                }
1123            }
1124        }
1125    }
1126}
1127
1128
1129void Viewer::getOperationThreads(OperationThreads& threads, bool onlyActive)
1130{
1131    threads.clear();
1132
1133    Contexts contexts;
1134    getContexts(contexts);
1135    for(Contexts::iterator gcitr = contexts.begin();
1136        gcitr != contexts.end();
1137        ++gcitr)
1138    {
1139        osg::GraphicsContext* gc = *gcitr;
1140        if (gc->getGraphicsThread() &&
1141            (!onlyActive || gc->getGraphicsThread()->isRunning()) )
1142        {
1143            threads.push_back(gc->getGraphicsThread());
1144        }
1145    }
1146
1147    Cameras cameras;
1148    getCameras(cameras);
1149    for(Cameras::iterator citr = cameras.begin();
1150        citr != cameras.end();
1151        ++citr)
1152    {
1153        osg::Camera* camera = *citr;
1154        if (camera->getCameraThread() &&
1155            (!onlyActive || camera->getCameraThread()->isRunning()) )
1156        {
1157            threads.push_back(camera->getCameraThread());
1158        }
1159    }
1160
1161}
1162
1163void Viewer::getContexts(Contexts& contexts, bool onlyValid)
1164{
1165    typedef std::set<osg::GraphicsContext*> ContextSet;
1166    ContextSet contextSet;
1167
1168    contexts.clear();
1169
1170    if (_camera.valid() &&
1171        _camera->getGraphicsContext() &&
1172        (_camera->getGraphicsContext()->valid() || !onlyValid))
1173    {
1174        contextSet.insert(_camera->getGraphicsContext());
1175        contexts.push_back(_camera->getGraphicsContext());
1176    }
1177
1178    for(unsigned int i=0; i<getNumSlaves(); ++i)
1179    {
1180        Slave& slave = getSlave(i);
1181        osg::GraphicsContext* sgc = slave._camera.valid() ? slave._camera->getGraphicsContext() : 0;
1182        if (sgc && (sgc->valid() || !onlyValid))
1183        {
1184            if (contextSet.count(sgc)==0)
1185            {
1186                contextSet.insert(sgc);
1187                contexts.push_back(sgc);
1188            }
1189        }
1190    }
1191}
1192
1193void Viewer::getCameras(Cameras& cameras, bool onlyActive)
1194{
1195    cameras.clear();
1196
1197    if (_camera.valid() &&
1198        (!onlyActive || (_camera->getGraphicsContext() && _camera->getGraphicsContext()->valid())) ) cameras.push_back(_camera.get());
1199
1200    for(Slaves::iterator itr = _slaves.begin();
1201        itr != _slaves.end();
1202        ++itr)
1203    {
1204        if (itr->_camera.valid() &&
1205            (!onlyActive || (itr->_camera->getGraphicsContext() && itr->_camera->getGraphicsContext()->valid())) ) cameras.push_back(itr->_camera.get());
1206    }
1207}
1208
1209
1210double Viewer::elapsedTime()
1211{
1212    return osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1213}
1214
1215
1216void Viewer::getUsage(osg::ApplicationUsage& usage) const
1217{
1218    if (_cameraManipulator.valid())
1219    {
1220        _cameraManipulator->getUsage(usage);
1221    }
1222
1223    for(EventHandlers::const_iterator hitr = _eventHandlers.begin();
1224        hitr != _eventHandlers.end();
1225        ++hitr)
1226    {
1227        (*hitr)->getUsage(usage);
1228    }
1229}
Note: See TracBrowser for help on using the browser.