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

Revision 13172, 42.1 kB (checked in by robert, 13 minutes ago)

From Paul Martz, fixed placement of OpenGL header so that it gets generated and placed in the build directory as per the Config file

  • 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        es->checkEvents();
655
656        // open question, will we need to reproject mouse coordinates into current view's coordinate frame as is down for GraphicsWindow provided events?
657        // for now assume now and just get the events directly without any reprojection.
658        es->getEventQueue()->takeEvents(events, cutOffTime);
659    }
660
661    // get events from all windows attached to Viewer.
662    for(Contexts::iterator citr = contexts.begin();
663        citr != contexts.end();
664        ++citr)
665    {
666        osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
667        if (gw)
668        {
669            gw->checkEvents();
670
671            osgGA::EventQueue::Events gw_events;
672            gw->getEventQueue()->takeEvents(gw_events, cutOffTime);
673
674            osgGA::EventQueue::Events::iterator itr;
675            for(itr = gw_events.begin();
676                itr != gw_events.end();
677                ++itr)
678            {
679                osgGA::GUIEventAdapter* event = itr->get();
680
681                bool pointerEvent = false;
682
683                float x = event->getX();
684                float y = event->getY();
685
686                bool invert_y = event->getMouseYOrientation()==osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS;
687                if (invert_y && gw->getTraits()) y = gw->getTraits()->height - y;
688
689                switch(event->getEventType())
690                {
691                    case(osgGA::GUIEventAdapter::PUSH):
692                    case(osgGA::GUIEventAdapter::RELEASE):
693                    case(osgGA::GUIEventAdapter::DOUBLECLICK):
694                    case(osgGA::GUIEventAdapter::DRAG):
695                    case(osgGA::GUIEventAdapter::MOVE):
696                    {
697                        pointerEvent = true;
698
699                        if (event->getEventType()!=osgGA::GUIEventAdapter::DRAG || !getCameraWithFocus())
700                        {
701                            osg::GraphicsContext::Cameras& cameras = gw->getCameras();
702                            for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
703                                citr != cameras.end();
704                                ++citr)
705                            {
706                                osg::Camera* camera = *citr;
707                                if (camera->getView()==this &&
708                                    camera->getAllowEventFocus() &&
709                                    camera->getRenderTargetImplementation()==osg::Camera::FRAME_BUFFER)
710                                {
711                                    osg::Viewport* viewport = camera ? camera->getViewport() : 0;
712                                    if (viewport &&
713                                        x >= viewport->x() && y >= viewport->y() &&
714                                        x <= (viewport->x()+viewport->width()) && y <= (viewport->y()+viewport->height()) )
715                                    {
716                                        // OSG_NOTICE<<"setCamera with focus "<<camera->getName()<<" x="<<x<<" y="<<y<<std::endl;
717                                        setCameraWithFocus(camera);
718                                    }
719                                }
720                            }
721                        }
722
723                        break;
724                    }
725                    default:
726                        break;
727                }
728
729                if (pointerEvent)
730                {
731                    if (getCameraWithFocus())
732                    {
733                        if (getCameraWithFocus()!=getCamera())
734                        {
735                            osg::Viewport* viewport = getCameraWithFocus()->getViewport();
736                            osg::Matrix localCameraVPW = getCameraWithFocus()->getViewMatrix() * getCameraWithFocus()->getProjectionMatrix();
737                            if (viewport) localCameraVPW *= viewport->computeWindowMatrix();
738
739                            osg::Matrix matrix( osg::Matrix::inverse(localCameraVPW) * masterCameraVPW );
740
741                            osg::Vec3d new_coord = osg::Vec3d(x,y,0.0) * matrix;
742
743                            x = new_coord.x();
744                            y = new_coord.y();
745                        }
746
747                        // OSG_NOTICE<<"pointer event new_coord.x()="<<new_coord.x()<<" new_coord.y()="<<new_coord.y()<<std::endl;
748
749                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
750                        event->setX(x);
751                        event->setY(y);
752                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
753
754                    }
755                    else
756                    {
757                        x = eventState->getXmin() + (x/double(gw->getTraits()->width))*(eventState->getXmax() - eventState->getXmin());
758                        y = eventState->getYmin() + (y/double(gw->getTraits()->height))*(eventState->getYmax() - eventState->getYmin());
759                        // OSG_NOTICE<<"new x = "<<x<<" new y = "<<y<<std::endl;
760
761                        event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
762                        event->setX(x);
763                        event->setY(y);
764                        event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
765                    }
766
767                    // pass along the new pointer events details to the eventState of the viewer
768                    eventState->setX(x);
769                    eventState->setY(y);
770                    eventState->setButtonMask(event->getButtonMask());
771                    eventState->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
772
773                }
774                else
775                {
776                    event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax());
777                    event->setX(eventState->getX());
778                    event->setY(eventState->getY());
779                    event->setButtonMask(eventState->getButtonMask());
780                    event->setMouseYOrientation(eventState->getMouseYOrientation());
781                }
782                //OSG_NOTICE<<"   mouse x = "<<event->getX()<<" y="<<event->getY()<<std::endl;
783                // OSG_NOTICE<<"   mouse Xmin = "<<event->getXmin()<<" Ymin="<<event->getYmin()<<" xMax="<<event->getXmax()<<" Ymax="<<event->getYmax()<<std::endl;
784            }
785
786            for(itr = gw_events.begin();
787                itr != gw_events.end();
788                ++itr)
789            {
790                osgGA::GUIEventAdapter* event = itr->get();
791                switch(event->getEventType())
792                {
793                    case(osgGA::GUIEventAdapter::CLOSE_WINDOW):
794                    {
795                        bool wasThreading = areThreadsRunning();
796                        if (wasThreading) stopThreading();
797
798                        gw->close();
799                        _currentContext = NULL;
800
801                        if (wasThreading) startThreading();
802
803                        break;
804                    }
805                    default:
806                        break;
807                }
808            }
809
810            events.insert(events.end(), gw_events.begin(), gw_events.end());
811
812        }
813    }
814
815    // pass on the coorindates of the main camera to make sure the frame event is scaled appropriately.
816    if (getCamera()->getViewport())
817    {
818        osg::Viewport* viewport = getCamera()->getViewport();
819        eventState->setInputRange( viewport->x(), viewport->y(), viewport->x() + viewport->width(), viewport->y() + viewport->height());
820    }
821    else
822    {
823        eventState->setInputRange(-1.0, -1.0, 1.0, 1.0);
824    }
825
826    // create a frame event for the new frame.
827    _eventQueue->frame( getFrameStamp()->getReferenceTime() );
828
829    // OSG_NOTICE<<"mouseEventState Xmin = "<<eventState->getXmin()<<" Ymin="<<eventState->getYmin()<<" xMax="<<eventState->getXmax()<<" Ymax="<<eventState->getYmax()<<std::endl;
830
831    _eventQueue->takeEvents(events, cutOffTime);
832
833
834#if 0
835    // OSG_NOTICE<<"Events "<<events.size()<<std::endl;
836    for(osgGA::EventQueue::Events::iterator itr = events.begin();
837        itr != events.end();
838        ++itr)
839    {
840        osgGA::GUIEventAdapter* event = itr->get();
841        switch(event->getEventType())
842        {
843            case(osgGA::GUIEventAdapter::PUSH):
844                OSG_NOTICE<<"  PUSH "<<event->getButton()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
845                break;
846            case(osgGA::GUIEventAdapter::RELEASE):
847                OSG_NOTICE<<"  RELEASE "<<event->getButton()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
848                break;
849            case(osgGA::GUIEventAdapter::DRAG):
850                OSG_NOTICE<<"  DRAG "<<event->getButtonMask()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
851                break;
852            case(osgGA::GUIEventAdapter::MOVE):
853                OSG_NOTICE<<"  MOVE "<<event->getButtonMask()<<" x="<<event->getX()<<" y="<<event->getY()<<std::endl;
854                break;
855            case(osgGA::GUIEventAdapter::SCROLL):
856                OSG_NOTICE<<"  SCROLL "<<event->getScrollingMotion()<<std::endl;
857                break;
858            case(osgGA::GUIEventAdapter::KEYDOWN):
859                OSG_NOTICE<<"  KEYDOWN '"<<(char)event->getKey()<<"'"<<std::endl;
860                break;
861            case(osgGA::GUIEventAdapter::KEYUP):
862                OSG_NOTICE<<"  KEYUP '"<<(char)event->getKey()<<"'"<<std::endl;
863                break;
864            case(osgGA::GUIEventAdapter::RESIZE):
865                OSG_NOTICE<<"  RESIZE "<<event->getWindowX()<<"/"<<event->getWindowY()<<" x "<<event->getWindowWidth()<<"/"<<event->getWindowHeight() << std::endl;
866                break;
867            case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
868                OSG_NOTICE<<"  QUIT_APPLICATION " << std::endl;
869                break;
870            case(osgGA::GUIEventAdapter::FRAME):
871                // OSG_NOTICE<<"  FRAME "<<std::endl;
872                break;
873            default:
874                // OSG_NOTICE<<"  Event not handled"<<std::endl;
875                break;
876        }
877    }
878#endif
879
880    // OSG_NOTICE<<"Events "<<events.size()<<std::endl;
881
882    if ((_keyEventSetsDone!=0) || _quitEventSetsDone)
883    {
884        for(osgGA::EventQueue::Events::iterator itr = events.begin();
885            itr != events.end();
886            ++itr)
887        {
888            osgGA::GUIEventAdapter* event = itr->get();
889            switch(event->getEventType())
890            {
891                case(osgGA::GUIEventAdapter::KEYUP):
892                    if (_keyEventSetsDone && event->getKey()==_keyEventSetsDone) _done = true;
893                    break;
894
895                case(osgGA::GUIEventAdapter::QUIT_APPLICATION):
896                    if (_quitEventSetsDone) _done = true;
897                    break;
898
899                default:
900                    break;
901            }
902        }
903    }
904
905    if (_done) return;
906
907    if (_eventVisitor.valid() && getSceneData())
908    {
909        _eventVisitor->setFrameStamp(getFrameStamp());
910        _eventVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
911
912        for(osgGA::EventQueue::Events::iterator itr = events.begin();
913            itr != events.end();
914            ++itr)
915        {
916            osgGA::GUIEventAdapter* event = itr->get();
917
918            _eventVisitor->reset();
919            _eventVisitor->addEvent( event );
920
921            getSceneData()->accept(*_eventVisitor);
922
923            // Do EventTraversal for slaves with their own subgraph
924            for(unsigned int i=0; i<getNumSlaves(); ++i)
925            {
926                osg::View::Slave& slave = getSlave(i);
927                osg::Camera* camera = slave._camera.get();
928                if(camera && !slave._useMastersSceneData)
929                {
930                    camera->accept(*_eventVisitor);
931                }
932            }
933
934
935            // call any camera event callbacks, but only traverse that callback, don't traverse its subgraph
936            // leave that to the scene update traversal.
937            osg::NodeVisitor::TraversalMode tm = _eventVisitor->getTraversalMode();
938            _eventVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
939
940            if (_camera.valid() && _camera->getEventCallback()) _camera->accept(*_eventVisitor);
941
942            for(unsigned int i=0; i<getNumSlaves(); ++i)
943            {
944                osg::View::Slave& slave = getSlave(i);
945                osg::Camera* camera = slave._camera.get();
946                if (camera && slave._useMastersSceneData && camera->getEventCallback())
947                {
948                    camera->accept(*_eventVisitor);
949                }
950            }
951
952            _eventVisitor->setTraversalMode(tm);
953
954        }
955    }
956
957
958    for(osgGA::EventQueue::Events::iterator itr = events.begin();
959        itr != events.end();
960        ++itr)
961    {
962        osgGA::GUIEventAdapter* event = itr->get();
963
964        for(EventHandlers::iterator hitr = _eventHandlers.begin();
965            hitr != _eventHandlers.end();
966            ++hitr)
967        {
968            (*hitr)->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this, 0, _eventVisitor.get());
969        }
970
971    }
972
973    for(osgGA::EventQueue::Events::iterator itr = events.begin();
974        itr != events.end();
975        ++itr)
976    {
977        osgGA::GUIEventAdapter* event = itr->get();
978        if (_cameraManipulator.valid())
979        {
980            _cameraManipulator->handleWithCheckAgainstIgnoreHandledEventsMask( *event, *this);
981        }
982    }
983
984    if (getViewerStats() && getViewerStats()->collectStats("event"))
985    {
986        double endEventTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
987
988        // update current frames stats
989        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal begin time", beginEventTraversal);
990        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal end time", endEventTraversal);
991        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Event traversal time taken", endEventTraversal-beginEventTraversal);
992    }
993
994}
995
996void Viewer::updateTraversal()
997{
998    if (_done) return;
999
1000    double beginUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1001
1002    _updateVisitor->reset();
1003    _updateVisitor->setFrameStamp(getFrameStamp());
1004    _updateVisitor->setTraversalNumber(getFrameStamp()->getFrameNumber());
1005
1006    _scene->updateSceneGraph(*_updateVisitor);
1007
1008    // if we have a shared state manager prune any unused entries
1009    if (osgDB::Registry::instance()->getSharedStateManager())
1010        osgDB::Registry::instance()->getSharedStateManager()->prune();
1011
1012    // update the Registry object cache.
1013    osgDB::Registry::instance()->updateTimeStampOfObjectsInCacheWithExternalReferences(*getFrameStamp());
1014    osgDB::Registry::instance()->removeExpiredObjectsInCache(*getFrameStamp());
1015
1016
1017    if (_updateOperations.valid())
1018    {
1019        _updateOperations->runOperations(this);
1020    }
1021
1022    if (_incrementalCompileOperation.valid())
1023    {
1024        // merge subgraphs that have been compiled by the incremental compiler operation.
1025        _incrementalCompileOperation->mergeCompiledSubgraphs(getFrameStamp());
1026    }
1027
1028    {
1029        // Do UpdateTraversal for slaves with their own subgraph
1030        for(unsigned int i=0; i<getNumSlaves(); ++i)
1031        {
1032            osg::View::Slave& slave = getSlave(i);
1033            osg::Camera* camera = slave._camera.get();
1034            if(camera && !slave._useMastersSceneData)
1035            {
1036                camera->accept(*_updateVisitor);
1037            }
1038        }
1039    }
1040
1041    {
1042        // call any camera update callbacks, but only traverse that callback, don't traverse its subgraph
1043        // leave that to the scene update traversal.
1044        osg::NodeVisitor::TraversalMode tm = _updateVisitor->getTraversalMode();
1045        _updateVisitor->setTraversalMode(osg::NodeVisitor::TRAVERSE_NONE);
1046
1047        if (_camera.valid() && _camera->getUpdateCallback()) _camera->accept(*_updateVisitor);
1048
1049        for(unsigned int i=0; i<getNumSlaves(); ++i)
1050        {
1051            osg::View::Slave& slave = getSlave(i);
1052            osg::Camera* camera = slave._camera.get();
1053            if (camera && slave._useMastersSceneData && camera->getUpdateCallback())
1054            {
1055                camera->accept(*_updateVisitor);
1056            }
1057        }
1058
1059        _updateVisitor->setTraversalMode(tm);
1060    }
1061
1062    if (_cameraManipulator.valid())
1063    {
1064        setFusionDistance( getCameraManipulator()->getFusionDistanceMode(),
1065                            getCameraManipulator()->getFusionDistanceValue() );
1066
1067        _cameraManipulator->updateCamera(*_camera);
1068    }
1069
1070    updateSlaves();
1071
1072    if (getViewerStats() && getViewerStats()->collectStats("update"))
1073    {
1074        double endUpdateTraversal = osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1075
1076        // update current frames stats
1077        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal begin time", beginUpdateTraversal);
1078        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal end time", endUpdateTraversal);
1079        getViewerStats()->setAttribute(_frameStamp->getFrameNumber(), "Update traversal time taken", endUpdateTraversal-beginUpdateTraversal);
1080    }
1081}
1082
1083void Viewer::getScenes(Scenes& scenes, bool onlyValid)
1084{
1085    scenes.clear();
1086    scenes.push_back(_scene.get());
1087}
1088
1089void Viewer::getViews(Views& views, bool onlyValid)
1090{
1091    views.clear();
1092    views.push_back(this);
1093}
1094
1095void Viewer::getAllThreads(Threads& threads, bool onlyActive)
1096{
1097    threads.clear();
1098
1099    OperationThreads operationThreads;
1100    getOperationThreads(operationThreads);
1101
1102    for(OperationThreads::iterator itr = operationThreads.begin();
1103        itr != operationThreads.end();
1104        ++itr)
1105    {
1106        threads.push_back(*itr);
1107    }
1108
1109
1110    if (_scene.valid())
1111    {
1112        osgDB::DatabasePager* dp = _scene->getDatabasePager();
1113        if (dp)
1114        {
1115            for(unsigned int i=0; i<dp->getNumDatabaseThreads(); ++i)
1116            {
1117                osgDB::DatabasePager::DatabaseThread* dt = dp->getDatabaseThread(i);
1118                if (!onlyActive || dt->isRunning())
1119                {
1120                    threads.push_back(dt);
1121                }
1122            }
1123        }
1124    }
1125}
1126
1127
1128void Viewer::getOperationThreads(OperationThreads& threads, bool onlyActive)
1129{
1130    threads.clear();
1131
1132    Contexts contexts;
1133    getContexts(contexts);
1134    for(Contexts::iterator gcitr = contexts.begin();
1135        gcitr != contexts.end();
1136        ++gcitr)
1137    {
1138        osg::GraphicsContext* gc = *gcitr;
1139        if (gc->getGraphicsThread() &&
1140            (!onlyActive || gc->getGraphicsThread()->isRunning()) )
1141        {
1142            threads.push_back(gc->getGraphicsThread());
1143        }
1144    }
1145
1146    Cameras cameras;
1147    getCameras(cameras);
1148    for(Cameras::iterator citr = cameras.begin();
1149        citr != cameras.end();
1150        ++citr)
1151    {
1152        osg::Camera* camera = *citr;
1153        if (camera->getCameraThread() &&
1154            (!onlyActive || camera->getCameraThread()->isRunning()) )
1155        {
1156            threads.push_back(camera->getCameraThread());
1157        }
1158    }
1159
1160}
1161
1162void Viewer::getContexts(Contexts& contexts, bool onlyValid)
1163{
1164    typedef std::set<osg::GraphicsContext*> ContextSet;
1165    ContextSet contextSet;
1166
1167    contexts.clear();
1168
1169    if (_camera.valid() &&
1170        _camera->getGraphicsContext() &&
1171        (_camera->getGraphicsContext()->valid() || !onlyValid))
1172    {
1173        contextSet.insert(_camera->getGraphicsContext());
1174        contexts.push_back(_camera->getGraphicsContext());
1175    }
1176
1177    for(unsigned int i=0; i<getNumSlaves(); ++i)
1178    {
1179        Slave& slave = getSlave(i);
1180        osg::GraphicsContext* sgc = slave._camera.valid() ? slave._camera->getGraphicsContext() : 0;
1181        if (sgc && (sgc->valid() || !onlyValid))
1182        {
1183            if (contextSet.count(sgc)==0)
1184            {
1185                contextSet.insert(sgc);
1186                contexts.push_back(sgc);
1187            }
1188        }
1189    }
1190}
1191
1192void Viewer::getCameras(Cameras& cameras, bool onlyActive)
1193{
1194    cameras.clear();
1195
1196    if (_camera.valid() &&
1197        (!onlyActive || (_camera->getGraphicsContext() && _camera->getGraphicsContext()->valid())) ) cameras.push_back(_camera.get());
1198
1199    for(Slaves::iterator itr = _slaves.begin();
1200        itr != _slaves.end();
1201        ++itr)
1202    {
1203        if (itr->_camera.valid() &&
1204            (!onlyActive || (itr->_camera->getGraphicsContext() && itr->_camera->getGraphicsContext()->valid())) ) cameras.push_back(itr->_camera.get());
1205    }
1206}
1207
1208
1209double Viewer::elapsedTime()
1210{
1211    return osg::Timer::instance()->delta_s(_startTick, osg::Timer::instance()->tick());
1212}
1213
1214
1215void Viewer::getUsage(osg::ApplicationUsage& usage) const
1216{
1217    if (_cameraManipulator.valid())
1218    {
1219        _cameraManipulator->getUsage(usage);
1220    }
1221
1222    for(EventHandlers::const_iterator hitr = _eventHandlers.begin();
1223        hitr != _eventHandlers.end();
1224        ++hitr)
1225    {
1226        (*hitr)->getUsage(usage);
1227    }
1228}
Note: See TracBrowser for help on using the browser.