root/OpenSceneGraph/trunk/applications/present3D/present3D.cpp @ 10526

Revision 10526, 24.9 kB (checked in by robert, 5 years ago)

Added a viewer.frame() call prior to the useCursor(false) calls to avoid a threading crash under X11

Line 
1/* -*-c++-*- Present3D - Copyright (C) 1999-2006 Robert Osfield
2 *
3 * This software is open source and may be redistributed and/or modified under 
4 * the terms of the GNU General Public License (GPL) version 2.0.
5 * The full license is in LICENSE.txt file included with this distribution,.
6 *
7 * This software is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * include LICENSE.txt for more details.
11*/
12
13#include <osg/Geometry>
14#include <osg/CameraNode>
15#include <osg/Texture2D>
16#include <osg/Notify>
17
18
19#include <osgDB/ReadFile>
20#include <osgDB/WriteFile>
21#include <osgDB/FileNameUtils>
22#include <osgUtil/Optimizer>
23#include <osgUtil/SceneView>
24
25#include <osgViewer/Viewer>
26#include <osgViewer/ViewerEventHandlers>
27
28#include <OpenThreads/Thread>
29
30#include <osgGA/TrackballManipulator>
31#include <osgGA/FlightManipulator>
32#include <osgGA/DriveManipulator>
33#include <osgGA/KeySwitchMatrixManipulator>
34#include <osgGA/AnimationPathManipulator>
35#include <osgGA/TerrainManipulator>
36#include <osgGA/AnimationPathManipulator>
37#include <osgGA/StateSetManipulator>
38
39#include <osgPresentation/SlideEventHandler>
40#include <osgPresentation/SlideShowConstructor>
41
42#include "ReadShowFile.h"
43#include "PointsEventHandler.h"
44#include "Cluster.h"
45#include "ExportHTML.h"
46
47
48#include <sstream>
49#include <fstream>
50#include <iostream>
51
52#include <string.h>
53
54#ifdef USE_SDL
55    #include "SDLIntegration.h"
56#endif
57
58#if OSG_LIBRARY_STATIC
59
60    // include the plugins we need
61    USE_OSGPLUGIN(ive)
62    USE_OSGPLUGIN(osg)
63    USE_OSGPLUGIN(p3d)
64    USE_OSGPLUGIN(paths)
65
66    USE_OSGPLUGIN(freetype)
67    USE_OSGPLUGIN(rgb)
68    USE_OSGPLUGIN(png)
69    USE_OSGPLUGIN(jpeg)
70
71    USE_OSGPLUGIN(ffmpeg)
72    USE_OSGPLUGIN(pdf)
73
74    USE_OSGPLUGIN(OpenFlight)
75    USE_OSGPLUGIN(obj)
76
77    USE_OSGPLUGIN(curl)
78
79
80    // include the platform specific GraphicsWindow implementation.
81    USE_GRAPHICSWINDOW()
82
83#endif
84
85static const char* s_version = "1.4 beta";
86
87void setViewer(osgViewer::Viewer& viewer, float width, float height, float distance)
88{
89    double vfov = osg::RadiansToDegrees(atan2(height/2.0f,distance)*2.0);
90    // double hfov = osg::RadiansToDegrees(atan2(width/2.0f,distance)*2.0);
91
92    viewer.getCamera()->setProjectionMatrixAsPerspective( vfov, width/height, 0.1, 1000.0);
93}
94
95class FollowMouseCallback: public osgGA::GUIEventHandler
96{
97    public:
98   
99        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&, osg::Object* object, osg::NodeVisitor*)
100        {
101
102            switch(ea.getEventType())
103            {
104                case(osgGA::GUIEventAdapter::MOVE):
105                case(osgGA::GUIEventAdapter::DRAG):
106                {
107                    osg::Camera* camera = dynamic_cast<osg::Camera*>(object);
108                    if (camera)
109                    {
110                        double x = ea.getXnormalized();
111                        double y = ea.getYnormalized();
112
113                        camera->setViewMatrix(osg::Matrixd::translate(x,y,0.0));
114                    }
115                    break;
116                }
117                case(osgGA::GUIEventAdapter::KEYDOWN):
118                {
119                    if (ea.getKey()=='c')
120                    {
121                        osg::Camera* camera = dynamic_cast<osg::Camera*>(object);
122                        if (camera)
123                        {
124                            for(unsigned int i=0; i< camera->getNumChildren(); ++i)
125                            {
126                                osg::Node* node = camera->getChild(i);
127                                node->setNodeMask(
128                                    node->getNodeMask()!=0 ?
129                                    0 :
130                                    0xffffff);
131                            }
132                        }
133                    }
134                    break;
135                }
136                default:
137                    break;
138            }
139            return false;
140        }
141               
142        virtual void accept(osgGA::GUIEventHandlerVisitor& v)
143        {
144            v.visit(*this);
145        }
146
147};
148 
149osg::Node* createCursorSubgraph(const std::string& filename, float size)
150{
151    osg::Geode* geode = new osg::Geode;
152
153    osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(-size*0.5f,-size*0.5f,0.0f),osg::Vec3(size,0.0f,0.0f),osg::Vec3(0.0f,size,0.0f));
154
155    osg::Image* image = osgDB::readImageFile(osgDB::findDataFile(filename));
156    if (image)
157    {
158        osg::StateSet* stateset = geom->getOrCreateStateSet();
159        stateset->setTextureAttributeAndModes(0, new osg::Texture2D(image),osg::StateAttribute::ON);
160        stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
161        stateset->setRenderBinDetails(1000, "DepthSortedBin");
162    }
163   
164    geode->addDrawable(geom);
165   
166    osg::CameraNode* camera = new osg::CameraNode;
167
168    // set the projection matrix
169    camera->setProjectionMatrix(osg::Matrix::ortho2D(-1,1,-1,1));
170
171    // set the view matrix   
172    camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
173    camera->setViewMatrix(osg::Matrix::identity());
174
175    // only clear the depth buffer
176    camera->setClearMask(GL_DEPTH_BUFFER_BIT);
177
178    // draw subgraph after main camera view.
179    camera->setRenderOrder(osg::CameraNode::NESTED_RENDER);
180
181    camera->addChild(geode);
182   
183    camera->setEventCallback(new FollowMouseCallback());
184   
185    return camera;
186
187}
188
189
190enum P3DApplicationType
191{
192    VIEWER,
193    MASTER,
194    SLAVE
195};
196
197
198
199int main( int argc, char **argv )
200{
201    // use an ArgumentParser object to manage the program arguments.
202    osg::ArgumentParser arguments(&argc,argv);
203   
204    // set up the usage document, in case we need to print out how to use this program.
205    arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
206    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the application for presenting 3D interactive slide shows.");
207    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
208    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
209    arguments.getApplicationUsage()->addCommandLineOption("-a","Turn auto stepping on by default");
210    arguments.getApplicationUsage()->addCommandLineOption("-d <float>","Time duration in seconds between layers/slides");
211    arguments.getApplicationUsage()->addCommandLineOption("-s <float> <float> <float>","width, height, distance and of the screen away from the viewer");
212    arguments.getApplicationUsage()->addCommandLineOption("--viewer","Start Present3D as the viewer version.");
213    arguments.getApplicationUsage()->addCommandLineOption("--authoring","Start Presen3D as the authoring version, license required.");
214    arguments.getApplicationUsage()->addCommandLineOption("--master","Start Present3D as the master version, license required.");
215    arguments.getApplicationUsage()->addCommandLineOption("--slave","Start Present3D as the slave version, license required.");
216    arguments.getApplicationUsage()->addCommandLineOption("--publishing","Start Present3D as the publishing version, license required.");
217    arguments.getApplicationUsage()->addCommandLineOption("--timeDelayOnNewSlideWithMovies","Set the time delay on new slide with movies, done to allow movie threads to get in sync with rendering thread.");
218    arguments.getApplicationUsage()->addCommandLineOption("--targetFrameRate","Set the target frame rate, defaults to 80Hz.");
219    arguments.getApplicationUsage()->addCommandLineOption("--version","Report the Present3D version.");
220    arguments.getApplicationUsage()->addCommandLineOption("--print <filename>","Print out slides to a series of image files.");
221    arguments.getApplicationUsage()->addCommandLineOption("--html <filename>","Print out slides to a series of html & image files.");
222    arguments.getApplicationUsage()->addCommandLineOption("--loop","Switch on looping of presentation.");
223    arguments.getApplicationUsage()->addCommandLineOption("--devices","Print the Video input capability via QuickTime and exit.");
224
225    // add alias from xml to p3d to provide backwards compatibility for old p3d files.
226    osgDB::Registry::instance()->addFileExtensionAlias("xml","p3d");
227
228    // if user requests devices video capability.
229    if (arguments.read("-devices") || arguments.read("--devices"))
230    {
231        // Force load QuickTime plugin, probe video capability, exit
232        osgDB::readImageFile("devices.live");
233        return 1;
234    }
235
236
237    // read any env vars from presentations before we create viewer to make sure the viewer
238    // utilises these env vars
239    if (p3d::readEnvVars(arguments))
240    {
241        osg::DisplaySettings::instance()->readEnvironmentalVariables();
242    }
243
244
245#ifdef USE_SDL
246    SDLIntegration sdlIntegration;
247   
248    osg::notify(osg::INFO)<<"USE_SDL"<<std::endl;
249#endif   
250   
251    bool doSetViewer = true;
252    std::string configurationFile;
253
254    // check env vars for configuration file
255    const char* str = getenv("PRESENT3D_CONFIG_FILE");
256    if (!str) str = getenv("OSG_CONFIG_FILE");
257    if (str) configurationFile = str;
258
259    // check command line parameters for configuration file.
260    while (arguments.read("-c",configurationFile)) {}
261
262    osg::Vec4 clearColor(0.0f,0.0f,0.0f,0.0f);
263   
264    while (arguments.read("--clear-color",clearColor[0],clearColor[1],clearColor[2],clearColor[3])) {}
265
266    // construct the viewer.
267    osgViewer::Viewer viewer(arguments);
268   
269    // set clear colour to black by default.
270    viewer.getCamera()->setClearColor(clearColor);
271
272    if (!configurationFile.empty())
273    {
274        viewer.readConfiguration(configurationFile);
275        doSetViewer = false;
276    }
277   
278    // set up stereo masks
279    viewer.getCamera()->setCullMask(0xffffffff);
280    viewer.getCamera()->setCullMaskLeft(0x00000001);
281    viewer.getCamera()->setCullMaskRight(0x00000002);   
282
283    // set up the camera manipulators.
284    {
285        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
286
287        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
288        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
289        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
290        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
291
292        std::string pathfile;
293        char keyForAnimationPath = '5';
294        while (arguments.read("-p",pathfile))
295        {
296            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
297            if (apm || !apm->valid())
298            {
299                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
300                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
301                keyswitchManipulator->selectMatrixManipulator(num);
302                ++keyForAnimationPath;
303            }
304        }
305
306        viewer.setCameraManipulator( keyswitchManipulator.get() );
307    }
308
309    // add the state manipulator
310    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
311
312    // add the state manipulator
313    viewer.addEventHandler( new osgViewer::StatsHandler() );
314
315    viewer.addEventHandler( new osgViewer::WindowSizeHandler() );
316
317    // neeed to address.
318    // viewer.getScene()->getUpdateVisitor()->setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
319
320
321    const char* p3dCursor = getenv("P3D_CURSOR");
322    std::string cursorFileName( p3dCursor ? p3dCursor : "");
323    while (arguments.read("--cursor",cursorFileName)) {}
324
325
326    while (arguments.read("--set-viewer")) { doSetViewer = true; }
327   
328    while (arguments.read("--no-set-viewer")) { doSetViewer = false; }
329   
330
331    // cluster related entries.
332    int socketNumber=8100;
333    while (arguments.read("-n",socketNumber)) {}
334
335    float camera_fov=-1.0f;
336    while (arguments.read("-f",camera_fov)) {}
337
338    float camera_offset=45.0f;
339    while (arguments.read("-o",camera_offset)) {}
340
341
342    std::string exportName;
343    while (arguments.read("--print",exportName)) {}
344
345    while (arguments.read("--html",exportName)) {}
346
347    // read any time delay argument.
348    float timeDelayBetweenSlides = 1.0f;
349    while (arguments.read("-d",timeDelayBetweenSlides)) {}
350
351    bool autoSteppingActive = false;
352    while (arguments.read("-a")) autoSteppingActive = true;
353
354    bool loopPresentation = false;
355    while (arguments.read("--loop")) loopPresentation = true;
356
357
358    // register the slide event handler - which moves the presentation from slide to slide, layer to layer.
359    osgPresentation::SlideEventHandler* seh = new osgPresentation::SlideEventHandler(&viewer);
360    viewer.addEventHandler(seh);
361
362    seh->setAutoSteppingActive(autoSteppingActive);
363    seh->setTimeDelayBetweenSlides(timeDelayBetweenSlides);
364    seh->setLoopPresentation(loopPresentation);
365
366    double targetFrameRate = 80.0;
367    while (arguments.read("--targetFrameRate",targetFrameRate)) {}
368
369
370    // set the time delay
371    float timeDelayOnNewSlideWithMovies = 0.4f;
372    while (arguments.read("--timeDelayOnNewSlideWithMovies",timeDelayOnNewSlideWithMovies)) {}
373    seh->setTimeDelayOnNewSlideWithMovies(timeDelayOnNewSlideWithMovies);
374
375    // set up optimizer options
376    unsigned int optimizer_options = osgUtil::Optimizer::DEFAULT_OPTIMIZATIONS;
377    bool relase_and_compile = false;
378    while (arguments.read("--release-and-compile"))
379    {
380        relase_and_compile = true;
381    }
382    seh->setReleaseAndCompileOnEachNewSlide(relase_and_compile);
383    if (relase_and_compile)
384    {
385        // make sure that imagery stays around after being applied to textures.
386        viewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true,false);
387        // optimizer_options &= ~osgUtil::Optimizer::OPTIMIZE_TEXTURE_SETTINGS;
388        // viewer.setRealizeSceneViewOptions(viewer.getRealizeSceneViewOptions() & ~osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
389    }
390//
391//     osgDB::Registry::instance()->getOrCreateDatabasePager()->setUnrefImageDataAfterApplyPolicy(true,false);
392//     optimizer_options &= ~osgUtil::Optimizer::OPTIMIZE_TEXTURE_SETTINGS;
393//     osg::Texture::getTextureObjectManager()->setExpiryDelay(0.0f);
394//     osgDB::Registry::instance()->getOrCreateDatabasePager()->setExpiryDelay(1.0f);
395
396    // register the handler for modifying the point size
397    PointsEventHandler* peh = new PointsEventHandler;
398    viewer.addEventHandler(peh);
399   
400    // osg::DisplaySettings::instance()->setSplitStereoAutoAjustAspectRatio(false);
401
402    float width = osg::DisplaySettings::instance()->getScreenWidth();
403    float height = osg::DisplaySettings::instance()->getScreenHeight();
404    float distance = osg::DisplaySettings::instance()->getScreenDistance();
405    bool sizesSpecified = false;
406    while (arguments.read("-s", width, height, distance))
407    {
408        sizesSpecified = true;
409       
410        osg::DisplaySettings::instance()->setScreenDistance(distance);
411        osg::DisplaySettings::instance()->setScreenHeight(height);
412        osg::DisplaySettings::instance()->setScreenWidth(width);
413    }
414
415    // get details on keyboard and mouse bindings used by the viewer.
416    viewer.getUsage(*arguments.getApplicationUsage());
417
418    // if user request help write it out to cout.
419    if (arguments.read("-h") || arguments.read("--help"))
420    {
421        arguments.getApplicationUsage()->write(osg::notify(osg::NOTICE));
422        return 1;
423    }
424
425    P3DApplicationType P3DApplicationType = VIEWER;
426
427    str = getenv("PRESENT3D_TYPE");
428    if (str)
429    {
430        if (strcmp(str,"viewer")==0) P3DApplicationType = VIEWER;
431        else if (strcmp(str,"master")==0) P3DApplicationType = MASTER;
432        else if (strcmp(str,"slave")==0) P3DApplicationType = SLAVE;
433    }
434       
435    while (arguments.read("--viewer")) { P3DApplicationType = VIEWER; }
436    while (arguments.read("--master")) { P3DApplicationType = MASTER; }
437    while (arguments.read("--slave")) { P3DApplicationType = SLAVE; }
438   
439    while (arguments.read("--version"))
440    {
441        std::string appTypeName = "invalid";
442        switch(P3DApplicationType)
443        {
444            case(VIEWER): appTypeName = "viewer"; break;
445            case(MASTER): appTypeName = "master"; break;
446            case(SLAVE): appTypeName = "slave"; break;
447        }
448
449        osg::notify(osg::NOTICE)<<std::endl;
450        osg::notify(osg::NOTICE)<<"Present3D "<<appTypeName<<" version : "<<s_version<<std::endl;
451        osg::notify(osg::NOTICE)<<std::endl;
452
453        return 0;
454    }
455
456    // any option left unread are converted into errors to write out later.
457    //arguments.reportRemainingOptionsAsUnrecognized();
458
459    // report any errors if they have ocured when parsing the program aguments.
460    if (arguments.errors())
461    {
462        arguments.writeErrorMessages(osg::notify(osg::INFO));
463        return 1;
464    }
465
466
467    // read files name from arguments.
468    p3d::FileNameList xmlFiles, normalFiles;
469    if (!p3d::getFileNames(arguments, xmlFiles, normalFiles))
470    {
471        osg::notify(osg::NOTICE)<<std::endl;
472        osg::notify(osg::NOTICE)<<"No file specified, please specify and file to load."<<std::endl;
473        osg::notify(osg::NOTICE)<<std::endl;
474        return 1;
475    }
476
477
478
479    bool viewerInitialized = false;
480    if (!xmlFiles.empty())
481    {
482        osg::ref_ptr<osg::Node> holdingModel = p3d::readHoldingSlide(xmlFiles.front());
483
484        if (holdingModel.valid())
485        {
486            viewer.setSceneData(holdingModel.get());
487
488            seh->selectSlide(0);
489
490            if (!viewerInitialized)
491            {
492                // pass the global stateset to the point event handler so that it can
493                // alter the point size of all points in the scene.
494                peh->setStateSet(viewer.getCamera()->getOrCreateStateSet());
495
496                // create the windows and run the threads.
497                viewer.realize();
498
499                if (doSetViewer) setViewer(viewer, width, height, distance);
500
501                viewerInitialized = true;
502            }
503
504            seh->home();
505
506            // render a frame
507            viewer.frame();
508        }
509    }
510
511    osg::Timer timer;
512    osg::Timer_t start_tick = timer.tick();
513
514
515    osg::ref_ptr<osgDB::ReaderWriter::Options> cacheAllOption = new osgDB::ReaderWriter::Options;
516    cacheAllOption->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_ALL);
517   
518    osgDB::Registry::instance()->setOptions(cacheAllOption.get());
519
520    // read the scene from the list of file specified commandline args.
521    osg::ref_ptr<osg::Node> loadedModel = p3d::readShowFiles(arguments,cacheAllOption.get()); // osgDB::readNodeFiles(arguments, cacheAllOption.get());
522
523
524    osgDB::Registry::instance()->setOptions( 0 );
525
526
527    // if no model has been successfully loaded report failure.
528    if (!loadedModel)
529    {
530        osg::notify(osg::INFO) << arguments.getApplicationName() <<": No data loaded" << std::endl;
531        return 1;
532    }
533
534    osg::Timer_t end_tick = timer.tick();
535
536    osg::notify(osg::INFO) << "Time to load = "<<timer.delta_s(start_tick,end_tick)<<std::endl;
537
538
539    if (loadedModel->getNumDescriptions()>0)
540    {
541        for(unsigned int i=0; i<loadedModel->getNumDescriptions(); ++i)
542        {
543            const std::string& desc = loadedModel->getDescription(i);
544            if (desc=="loop")
545            {
546                osg::notify(osg::NOTICE)<<"Enabling looping"<<std::endl;
547                seh->setLoopPresentation(true);
548            }
549            else if (desc=="auto")
550            {
551                osg::notify(osg::NOTICE)<<"Enabling auto run"<<std::endl;
552                seh->setAutoSteppingActive(true);
553            }
554        }
555    }
556
557
558#if 1
559    // add back in enabling of the GL_ALPHA_TEST to get around the core OSG no longer setting it by default for opaque bins.
560    // the alpha test is required for the volume rendering alpha clipping to work.
561    loadedModel->getOrCreateStateSet()->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
562#endif
563
564
565    // optimize the scene graph, remove rendundent nodes and state etc.
566    osgUtil::Optimizer optimizer;
567    optimizer.optimize(loadedModel.get(), optimizer_options);
568
569    if (!cursorFileName.empty())
570    {
571        osg::ref_ptr<osg::Group> group = new osg::Group;
572        group->addChild(loadedModel.get());
573        group->addChild(createCursorSubgraph(cursorFileName, 0.05f));
574       
575        loadedModel = group.get();
576    }
577
578    // set the scene to render
579    viewer.setSceneData(loadedModel.get());
580
581    if (!viewerInitialized)
582    {
583        // pass the global stateset to the point event handler so that it can
584        // alter the point size of all points in the scene.
585        peh->setStateSet(viewer.getCamera()->getOrCreateStateSet());
586
587        // create the windows and run the threads.
588        viewer.realize();
589
590        if (doSetViewer) setViewer(viewer, width, height, distance);
591
592        viewerInitialized = true;
593    }
594
595    if (!cursorFileName.empty())
596    {
597        // have to add a frame in here to avoid problems with X11 threading issue on switching off the cursor
598        // not yet sure why it makes a difference, but it at least fixes the crash that would otherwise occur
599        // under X11.
600        viewer.frame();
601
602        // switch off the cursor
603        osgViewer::Viewer::Windows windows;
604        viewer.getWindows(windows);
605        for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
606            itr != windows.end();
607            ++itr)
608        {
609            (*itr)->useCursor(false);
610        }
611    }
612
613    // pass the model to the slide event handler so it knows which to manipulate.
614    seh->set(loadedModel.get());
615    seh->selectSlide(0);
616
617    seh->home();
618   
619    // osgDB::writeNodeFile(*loadedModel,"saved.osg");
620   
621    osg::Timer_t startOfFrameTick = osg::Timer::instance()->tick();
622    double targetFrameTime = 1.0/targetFrameRate;
623   
624    if (exportName.empty())
625    {
626        // objects for managing the broadcasting and recieving of camera packets.
627        CameraPacket cp;
628        Broadcaster  bc;
629        Receiver     rc;
630        bc.setPort(static_cast<short int>(socketNumber));
631        rc.setPort(static_cast<short int>(socketNumber));
632
633        bool masterKilled = false;
634        DataConverter scratchPad(1024);
635
636        while( !viewer.done() && !masterKilled)
637        {
638            // wait for all cull and draw threads to complete.
639            viewer.advance();
640
641            osg::Timer_t currentTick = osg::Timer::instance()->tick();
642            double deltaTime = osg::Timer::instance()->delta_s(startOfFrameTick, currentTick);
643
644
645            if (deltaTime<targetFrameTime)
646            {
647                OpenThreads::Thread::microSleep(static_cast<unsigned int>((targetFrameTime-deltaTime)*1000000.0));
648            }
649
650            startOfFrameTick =  osg::Timer::instance()->tick();
651
652#if 0           
653            if (kmcb)
654            {
655                double time = kmcb->getTime();
656                viewer.getFrameStamp()->setReferenceTime(time);
657            }
658#endif
659
660#ifdef USE_SDL
661            sdlIntegration.update(viewer);
662#endif
663
664            if (P3DApplicationType==MASTER)
665            {
666                // take camera zero as the guide.
667                osg::Matrix modelview(viewer.getCamera()->getViewMatrix());
668               
669                cp.setPacket(modelview,viewer.getFrameStamp());
670               
671                // cp.readEventQueue(viewer);
672
673                scratchPad.reset();
674                scratchPad.write(cp);
675
676                scratchPad.reset();
677                scratchPad.read(cp);
678
679                bc.setBuffer(scratchPad._startPtr, scratchPad._numBytes);
680               
681                std::cout << "bc.sync()"<<scratchPad._numBytes<<std::endl;
682
683                bc.sync();
684            }
685            else if (P3DApplicationType==SLAVE)
686            {
687                rc.setBuffer(scratchPad._startPtr, scratchPad._numBytes);
688
689                rc.sync();
690               
691                scratchPad.reset();
692                scratchPad.read(cp);
693   
694                // cp.writeEventQueue(viewer);
695
696                if (cp.getMasterKilled())
697                {
698                    std::cout << "Received master killed."<<std::endl;
699                    // break out of while (!done) loop since we've now want to shut down.
700                    masterKilled = true;
701                }
702            }
703
704            // update the scene by traversing it with the the update visitor which will
705            // call all node update callbacks and animations.
706            viewer.eventTraversal();
707
708            // update the scene by traversing it with the the update visitor which will
709            // call all node update callbacks and animations.
710            viewer.updateTraversal();
711
712            if (P3DApplicationType==SLAVE)
713            {
714                osg::Matrix modelview;
715                cp.getModelView(modelview,camera_offset);
716
717                viewer.getCamera()->setViewMatrix(modelview);
718            }
719
720            // fire off the cull and draw traversals of the scene.
721            if(!masterKilled)
722                viewer.renderingTraversals();
723        }
724    }
725    else
726    {
727        ExportHTML::write(seh, viewer, exportName);
728    }
729           
730    return 0;
731}
Note: See TracBrowser for help on using the browser.