root/OpenSceneGraph/trunk/examples/osgcluster/osgcluster.cpp @ 6051

Revision 6051, 18.7 kB (checked in by robert, 7 years ago)

Added osg::FrameStamp::set/getSimulationTime().

Added setting of osg_SimulationTime and osg_DeltaSimulationTime to the uniforms set by SceneView?

Added frame(double simulationTime) and advance(double simulationTime) parameters to
osgViewer::SimpleViewer?, Vewer and CompositeViewer?.

Updated various examples and Nodes to use SimulationTime? where appropriate.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#ifdef USE_MEM_CHECK
2#include <mcheck.h>
3#endif
4
5#include <osg/Group>
6#include <osg/Notify>
7
8#include <osgDB/Registry>
9#include <osgDB/ReadFile>
10
11#include <osgGA/TrackballManipulator>
12#include <osgViewer/Viewer>
13
14#include <osg/Quat>
15#include <osg/io_utils>
16
17#include <iostream>
18
19#if defined (WIN32) && !defined(__CYGWIN__)
20#include <winsock.h>
21#endif
22
23#include "receiver.h"
24#include "broadcaster.h"
25
26
27const unsigned int MAX_NUM_EVENTS = 10;
28const unsigned int SWAP_BYTES_COMPARE = 0x12345678;
29class CameraPacket {
30    public:
31   
32   
33        CameraPacket():_masterKilled(false)
34        {
35            _byte_order = SWAP_BYTES_COMPARE;
36        }
37       
38        void setPacket(const osg::Matrix& matrix,const osg::FrameStamp* frameStamp)
39        {
40            _matrix = matrix;
41            if (frameStamp)
42            {
43                _frameStamp    = *frameStamp;
44            }
45        }
46       
47        void getModelView(osg::Matrix& matrix,float angle_offset=0.0f)
48        {
49       
50            matrix = _matrix * osg::Matrix::rotate(osg::DegreesToRadians(angle_offset),0.0f,1.0f,0.0f);
51        }
52       
53        void readEventQueue(osgViewer::Viewer& viewer);
54       
55        void writeEventQueue(osgViewer::Viewer& viewer);
56
57        void setMasterKilled(const bool flag) { _masterKilled = flag; }
58        const bool getMasterKilled() const { return _masterKilled; }
59       
60        unsigned int    _byte_order;
61        bool            _masterKilled;
62        osg::Matrix     _matrix;
63
64        // note don't use a ref_ptr as used elsewhere for FrameStamp
65        // since we don't want to copy the pointer - but the memory.
66        // FrameStamp doesn't have a private destructor to allow
67        // us to do this, even though its a reference counted object.   
68        osg::FrameStamp  _frameStamp;
69       
70        osgGA::EventQueue::Events _events;
71       
72};
73
74class DataConverter
75{
76    public:
77
78        DataConverter(unsigned int numBytes):
79            _startPtr(0),
80            _endPtr(0),
81            _swapBytes(false),
82            _currentPtr(0)
83        {
84            _currentPtr = _startPtr = new char[numBytes];
85            _endPtr = _startPtr+numBytes;
86            _numBytes = numBytes;
87        }
88
89        char* _startPtr;
90        char* _endPtr;
91        unsigned int _numBytes;
92        bool _swapBytes;
93
94        char* _currentPtr;
95       
96        void reset()
97        {
98            _currentPtr = _startPtr;
99        }
100
101        inline void write1(char* ptr)
102        {
103            if (_currentPtr+1>=_endPtr) return;
104
105            *(_currentPtr++) = *(ptr);
106        }
107
108        inline void read1(char* ptr)
109        {
110            if (_currentPtr+1>=_endPtr) return;
111
112            *(ptr) = *(_currentPtr++);
113        }
114
115        inline void write2(char* ptr)
116        {
117            if (_currentPtr+2>=_endPtr) return;
118
119            *(_currentPtr++) = *(ptr++);
120            *(_currentPtr++) = *(ptr);
121        }
122
123        inline void read2(char* ptr)
124        {
125            if (_currentPtr+2>=_endPtr) return;
126
127            if (_swapBytes)
128            {
129                *(ptr+1) = *(_currentPtr++);
130                *(ptr) = *(_currentPtr++);
131            }
132            else
133            {
134                *(ptr++) = *(_currentPtr++);
135                *(ptr) = *(_currentPtr++);
136            }
137        }
138
139        inline void write4(char* ptr)
140        {
141            if (_currentPtr+4>=_endPtr) return;
142
143            *(_currentPtr++) = *(ptr++);
144            *(_currentPtr++) = *(ptr++);
145            *(_currentPtr++) = *(ptr++);
146            *(_currentPtr++) = *(ptr);
147        }
148
149        inline void read4(char* ptr)
150        {
151            if (_currentPtr+4>=_endPtr) return;
152
153            if (_swapBytes)
154            {
155                *(ptr+3) = *(_currentPtr++);
156                *(ptr+2) = *(_currentPtr++);
157                *(ptr+1) = *(_currentPtr++);
158                *(ptr) = *(_currentPtr++);
159            }
160            else
161            {
162                *(ptr++) = *(_currentPtr++);
163                *(ptr++) = *(_currentPtr++);
164                *(ptr++) = *(_currentPtr++);
165                *(ptr) = *(_currentPtr++);
166            }
167        }
168
169        inline void write8(char* ptr)
170        {
171            if (_currentPtr+8>=_endPtr) return;
172
173            *(_currentPtr++) = *(ptr++);
174            *(_currentPtr++) = *(ptr++);
175            *(_currentPtr++) = *(ptr++);
176            *(_currentPtr++) = *(ptr++);
177
178            *(_currentPtr++) = *(ptr++);
179            *(_currentPtr++) = *(ptr++);
180            *(_currentPtr++) = *(ptr++);
181            *(_currentPtr++) = *(ptr);
182        }
183
184        inline void read8(char* ptr)
185        {
186            char* endPtr = _currentPtr+8;
187            if (endPtr>=_endPtr) return;
188
189            if (_swapBytes)
190            {
191                *(ptr+7) = *(_currentPtr++);
192                *(ptr+6) = *(_currentPtr++);
193                *(ptr+5) = *(_currentPtr++);
194                *(ptr+4) = *(_currentPtr++);
195
196                *(ptr+3) = *(_currentPtr++);
197                *(ptr+2) = *(_currentPtr++);
198                *(ptr+1) = *(_currentPtr++);
199                *(ptr) = *(_currentPtr++);
200            }
201            else
202            {
203                *(ptr++) = *(_currentPtr++);
204                *(ptr++) = *(_currentPtr++);
205                *(ptr++) = *(_currentPtr++);
206                *(ptr++) = *(_currentPtr++);
207
208                *(ptr++) = *(_currentPtr++);
209                *(ptr++) = *(_currentPtr++);
210                *(ptr++) = *(_currentPtr++);
211                *(ptr) = *(_currentPtr++);
212            }
213        }
214
215        inline void writeChar(char c)               { write1(&c); }
216        inline void writeUChar(unsigned char c)     { write1((char*)&c); }
217        inline void writeShort(short c)             { write2((char*)&c); }
218        inline void writeUShort(unsigned short c)   { write2((char*)&c); }
219        inline void writeInt(int c)                 { write4((char*)&c); }
220        inline void writeUInt(unsigned int c)       { write4((char*)&c); }
221        inline void writeFloat(float c)             { write4((char*)&c); }
222        inline void writeDouble(double c)           { write8((char*)&c); }
223
224        inline char readChar() { char c; read1(&c); return c; }
225        inline unsigned char readUChar() { unsigned char c; read1((char*)&c); return c; }
226        inline short readShort() { short c; read2((char*)&c); return c; }
227        inline unsigned short readUShort() { unsigned short c; read2((char*)&c); return c; }
228        inline int readInt() { int c; read4((char*)&c); return c; }
229        inline unsigned int readUInt() { unsigned int c; read4((char*)&c); return c; }
230        inline float readFloat() { float c; read4((char*)&c); return c; }
231        inline double readDouble() { double c; read8((char*)&c); return c; }
232
233        void write(const osg::FrameStamp& fs)
234        {
235            osg::notify(osg::NOTICE)<<"writeFramestamp = "<<fs.getFrameNumber()<<" "<<fs.getReferenceTime()<<std::endl;
236
237            writeUInt(fs.getFrameNumber());
238            writeDouble(fs.getReferenceTime());
239            writeDouble(fs.getSimulationTime());
240        }
241
242        void read(osg::FrameStamp& fs)
243        {
244            fs.setFrameNumber(readUInt());
245            fs.setReferenceTime(readDouble());
246            fs.setSimulationTime(readDouble());
247
248            osg::notify(osg::NOTICE)<<"readFramestamp = "<<fs.getFrameNumber()<<" "<<fs.getReferenceTime()<<std::endl;
249        }
250
251        void write(const osg::Matrix& matrix)
252        {
253            writeDouble(matrix(0,0));
254            writeDouble(matrix(0,1));
255            writeDouble(matrix(0,2));
256            writeDouble(matrix(0,3));
257
258            writeDouble(matrix(1,0));
259            writeDouble(matrix(1,1));
260            writeDouble(matrix(1,2));
261            writeDouble(matrix(1,3));
262
263            writeDouble(matrix(2,0));
264            writeDouble(matrix(2,1));
265            writeDouble(matrix(2,2));
266            writeDouble(matrix(2,3));
267
268            writeDouble(matrix(3,0));
269            writeDouble(matrix(3,1));
270            writeDouble(matrix(3,2));
271            writeDouble(matrix(3,3));
272
273            osg::notify(osg::NOTICE)<<"writeMatrix = "<<matrix<<std::endl;
274
275        }
276
277        void read(osg::Matrix& matrix)
278        {
279            matrix(0,0) = readDouble();
280            matrix(0,1) = readDouble();
281            matrix(0,2) = readDouble();
282            matrix(0,3) = readDouble();
283
284            matrix(1,0) = readDouble();
285            matrix(1,1) = readDouble();
286            matrix(1,2) = readDouble();
287            matrix(1,3) = readDouble();
288
289            matrix(2,0) = readDouble();
290            matrix(2,1) = readDouble();
291            matrix(2,2) = readDouble();
292            matrix(2,3) = readDouble();
293
294            matrix(3,0) = readDouble();
295            matrix(3,1) = readDouble();
296            matrix(3,2) = readDouble();
297            matrix(3,3) = readDouble();
298
299            osg::notify(osg::NOTICE)<<"readMatrix = "<<matrix<<std::endl;
300
301        }
302
303        void write(const osgGA::GUIEventAdapter& event)
304        {
305            writeUInt(event.getEventType());
306            writeUInt(event.getKey());
307            writeUInt(event.getButton());
308            writeInt(event.getWindowX());
309            writeInt(event.getWindowY());
310            writeUInt(event.getWindowWidth());
311            writeUInt(event.getWindowHeight());
312            writeFloat(event.getXmin());
313            writeFloat(event.getYmin());
314            writeFloat(event.getXmax());
315            writeFloat(event.getYmax());
316            writeFloat(event.getX());
317            writeFloat(event.getY());
318            writeUInt(event.getButtonMask());
319            writeUInt(event.getModKeyMask());
320            writeDouble(event.getTime());
321        }
322
323        void read(osgGA::GUIEventAdapter& event)
324        {
325            event.setEventType((osgGA::GUIEventAdapter::EventType)readUInt());
326            event.setKey(readUInt());
327            event.setButton(readUInt());
328            int x = readInt();
329            int y = readInt();
330            int width = readUInt();
331            int height = readUInt();
332            event.setWindowRectangle(x,y,width,height);
333            float xmin = readFloat();
334            float ymin = readFloat();
335            float xmax = readFloat();
336            float ymax = readFloat();
337            event.setInputRange(xmin,ymin,xmax,ymax);
338            event.setX(readFloat());
339            event.setY(readFloat());
340            event.setButtonMask(readUInt());
341            event.setModKeyMask(readUInt());
342            event.setTime(readDouble());
343        }
344       
345        void write(CameraPacket& cameraPacket)
346        {
347            writeUInt(cameraPacket._byte_order);
348           
349            writeUInt(cameraPacket._masterKilled);
350           
351            write(cameraPacket._matrix);
352            write(cameraPacket._frameStamp);
353       
354            writeUInt(cameraPacket._events.size());
355            for(osgGA::EventQueue::Events::iterator itr = cameraPacket._events.begin();
356                itr != cameraPacket._events.end();
357                ++itr)
358            {
359                write(*(*itr));
360            }
361        }
362
363        void read(CameraPacket& cameraPacket)
364        {
365            cameraPacket._byte_order = readUInt();
366            if (cameraPacket._byte_order != SWAP_BYTES_COMPARE)
367            {
368                _swapBytes = !_swapBytes;
369            }
370           
371            cameraPacket._masterKilled = readUInt();
372           
373            read(cameraPacket._matrix);
374            read(cameraPacket._frameStamp);
375       
376            cameraPacket._events.clear();
377            unsigned int numEvents = readUInt();
378            for(unsigned int i=0;i<numEvents;++i)
379            {
380                osgGA::GUIEventAdapter* event = new osgGA::GUIEventAdapter;
381                read(*(event));
382                cameraPacket._events.push_back(event);
383            }
384        }
385};
386
387void CameraPacket::readEventQueue(osgViewer::Viewer& viewer)
388{
389    _events.clear();
390
391    viewer.getEventQueue()->copyEvents(_events);
392
393    osg::notify(osg::INFO)<<"written events = "<<_events.size()<<std::endl;
394}
395
396void CameraPacket::writeEventQueue(osgViewer::Viewer& viewer)
397{
398    osg::notify(osg::INFO)<<"recieved events = "<<_events.size()<<std::endl;
399
400    viewer.getEventQueue()->appendEvents(_events);
401}
402
403
404
405enum ViewerMode
406{
407    STAND_ALONE,
408    SLAVE,
409    MASTER
410};
411
412int main( int argc, char **argv )
413{
414    // use an ArgumentParser object to manage the program arguments.
415    osg::ArgumentParser arguments(&argc,argv);
416   
417    // set up the usage document, in case we need to print out how to use this program.
418    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates how to approach implementation of clustering.");
419    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
420    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
421    arguments.getApplicationUsage()->addCommandLineOption("-m","Set viewer to MASTER mode, sending view via packets.");
422    arguments.getApplicationUsage()->addCommandLineOption("-s","Set viewer to SLAVE mode, reciving view via packets.");
423    arguments.getApplicationUsage()->addCommandLineOption("-n <int>","Socket number to transmit packets");
424    arguments.getApplicationUsage()->addCommandLineOption("-f <float>","Field of view of camera");
425    arguments.getApplicationUsage()->addCommandLineOption("-o <float>","Offset angle of camera");
426   
427    // construct the viewer.
428    osgViewer::Viewer viewer;
429
430
431    // read up the osgcluster specific arguments.
432    ViewerMode viewerMode = STAND_ALONE;
433    while (arguments.read("-m")) viewerMode = MASTER;
434    while (arguments.read("-s")) viewerMode = SLAVE;
435   
436    int socketNumber=8100;
437    while (arguments.read("-n",socketNumber)) ;
438
439    float camera_fov=-1.0f;
440    while (arguments.read("-f",camera_fov))
441    {
442    }
443
444    float camera_offset=45.0f;
445    while (arguments.read("-o",camera_offset)) ;
446
447
448    // if user request help write it out to cout.
449    if (arguments.read("-h") || arguments.read("--help"))
450    {
451        arguments.getApplicationUsage()->write(std::cout);
452        return 1;
453    }
454
455    // any option left unread are converted into errors to write out later.
456    arguments.reportRemainingOptionsAsUnrecognized();
457
458    // report any errors if they have occured when parsing the program aguments.
459    if (arguments.errors())
460    {
461        arguments.writeErrorMessages(std::cout);
462        return 1;
463    }
464   
465    if (arguments.argc()<=1)
466    {
467        arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION);
468        return 1;
469    }
470
471    // load model.
472    osg::ref_ptr<osg::Node> rootnode = osgDB::readNodeFiles(arguments);
473
474    // set the scene to render
475    viewer.setSceneData(rootnode.get());
476
477    if (camera_fov>0.0f)
478    {
479        double fovy, aspectRatio, zNear, zFar;
480        viewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio,zNear, zFar);
481       
482        double original_fov = atan(tan(osg::DegreesToRadians(fovy)*0.5)*aspectRatio)*2.0;
483        std::cout << "setting lens perspective : original "<<original_fov<<"  "<<fovy<<std::endl;
484       
485        fovy = atan(tan(osg::DegreesToRadians(camera_fov)*0.5)/aspectRatio)*2.0;
486        viewer.getCamera()->setProjectionMatrixAsPerspective(fovy, aspectRatio,zNear, zFar);
487   
488        viewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio,zNear, zFar);
489        original_fov = atan(tan(osg::DegreesToRadians(fovy)*0.5)*aspectRatio)*2.0;
490        std::cout << "setting lens perspective : new "<<original_fov<<"  "<<fovy<<std::endl;
491    }
492
493    viewer.setCameraManipulator(new osgGA::TrackballManipulator());
494
495
496    // create the windows and run the threads.
497    viewer.realize();
498
499
500    CameraPacket *cp = new CameraPacket;
501
502    // objects for managing the broadcasting and recieving of camera packets.
503    Broadcaster     bc;
504    Receiver        rc;
505
506    bc.setPort(static_cast<short int>(socketNumber));
507    rc.setPort(static_cast<short int>(socketNumber));
508
509    bool masterKilled = false;
510   
511    DataConverter scratchPad(1024);
512
513    while( !viewer.done() && !masterKilled )
514    {
515        osg::Timer_t startTick = osg::Timer::instance()->tick();
516                 
517        viewer.advance();
518
519        // special handling for working as a cluster.
520        switch (viewerMode)
521        {
522        case(MASTER):
523            {
524               
525                // take camera zero as the guide.
526                osg::Matrix modelview(viewer.getCamera()->getViewMatrix());
527               
528                cp->setPacket(modelview,viewer.getFrameStamp());
529               
530                cp->readEventQueue(viewer);
531
532                scratchPad.reset();
533                scratchPad.write(*cp);
534
535                scratchPad.reset();
536                scratchPad.read(*cp);
537
538                bc.setBuffer(scratchPad._startPtr, scratchPad._numBytes);
539               
540                std::cout << "bc.sync()"<<scratchPad._numBytes<<std::endl;
541
542                bc.sync();
543               
544            }
545            break;
546        case(SLAVE):
547            {
548
549                rc.setBuffer(scratchPad._startPtr, scratchPad._numBytes);
550
551                rc.sync();
552               
553                scratchPad.reset();
554                scratchPad.read(*cp);
555   
556                cp->writeEventQueue(viewer);
557
558                if (cp->getMasterKilled())
559                {
560                    std::cout << "Received master killed."<<std::endl;
561                    // break out of while (!done) loop since we've now want to shut down.
562                    masterKilled = true;
563                }
564            }
565            break;
566        default:
567            // no need to anything here, just a normal interactive viewer.
568            break;
569        }
570         
571        osg::Timer_t endTick = osg::Timer::instance()->tick();
572       
573        osg::notify(osg::INFO)<<"Time to do cluster sync "<<osg::Timer::instance()->delta_m(startTick,endTick)<<std::endl;
574
575        // update the scene by traversing it with the the update visitor which will
576        // call all node update callbacks and animations.
577        viewer.eventTraversal();
578        viewer.updateTraversal();
579
580        if (viewerMode==SLAVE)
581        {
582            osg::Matrix modelview;
583            cp->getModelView(modelview,camera_offset);
584       
585            viewer.getCamera()->setViewMatrix(modelview);
586        }
587
588        // fire off the cull and draw traversals of the scene.
589        if(!masterKilled)
590            viewer.renderingTraversals();
591       
592    }
593
594    // if we are master clean up by telling all slaves that we're going down.
595    if (viewerMode==MASTER)
596    {
597        // need to broadcast my death.
598        cp->setPacket(osg::Matrix::identity(),viewer.getFrameStamp());
599        cp->setMasterKilled(true);
600
601        bc.setBuffer(cp, sizeof( CameraPacket ));
602        bc.sync();
603
604        std::cout << "Broadcasting death."<<std::endl;
605
606    }
607
608    return 0;
609}
Note: See TracBrowser for help on using the browser.