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

Revision 9475, 36.8 kB (checked in by robert, 6 years ago)

From Andy Skinner, fixes for Solaris build

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