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

Revision 1697, 11.3 kB (checked in by robert, 12 years ago)

Ported osgGLUT based src/Demos across to being osgProducer based, and placed
them in the new examples/ directory.

  • 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 <osgProducer/Viewer>
12
13#include <osg/Quat>
14
15#if defined (WIN32)
16#include <winsock.h>
17#endif
18
19#include "receiver.h"
20#include "broadcaster.h"
21
22typedef unsigned char * BytePtr;
23template <class T>
24inline void swapBytes(  T &s )
25{
26    if( sizeof( T ) == 1 ) return;
27
28    T d = s;
29    BytePtr sptr = (BytePtr)&s;
30    BytePtr dptr = &(((BytePtr)&d)[sizeof(T)-1]);
31
32    for( unsigned int i = 0; i < sizeof(T); i++ )
33        *(sptr++) = *(dptr--);
34}
35
36class CameraPacket {
37    public:
38   
39        CameraPacket():_masterKilled(false)
40        {
41            _byte_order = 0x12345678;
42        }
43       
44        void setPacket(const osg::Camera& camera,const osg::FrameStamp* frameStamp)
45        {
46            _eye    = camera.getEyePoint();
47            _center = camera.getCenterPoint();
48            _up     = camera.getUpVector();
49            if (frameStamp)
50            {
51                _frameStamp    = *frameStamp;
52            }
53        }
54       
55        void getCamera(osg::Camera& camera,float angle_offset=0.0f)
56        {
57       
58            osg::Vec3 lv = _center-_eye;
59            osg::Matrix matrix;
60            matrix.makeIdentity();
61            matrix.makeRotate(angle_offset,_up.x(),_up.y(),_up.z());
62            lv = lv*matrix;
63       
64            camera.setLookAt(_eye,_eye+lv,_up);
65                       
66        }
67       
68        void getSceneViewUpdate(osgUtil::SceneView& sv)
69        {
70            // note pass a separate reference counted FrameStamp
71            // rather than this frame stamp as it can get overwritten.
72            sv.setFrameStamp(new osg::FrameStamp(_frameStamp));
73        }
74
75
76        void checkByteOrder( void )
77        {
78            if( _byte_order == 0x78563412 )  // We're backwards
79            {
80                swapBytes( _byte_order );
81                swapBytes( _masterKilled );
82                swapBytes( _eye[0] );
83                swapBytes( _eye[1] );
84                swapBytes( _eye[2] );
85                swapBytes( _center[0] );
86                swapBytes( _center[1] );
87                swapBytes( _center[2] );
88                swapBytes( _up[0] );
89                swapBytes( _up[1] );
90                swapBytes( _up[2] );
91                swapBytes( _attachMatrix );
92                for( int i = 0; i < 16; i++ )
93                    swapBytes( _matrix.ptr()[i] );
94            }
95        }
96
97       
98        void setMasterKilled(const bool flag) { _masterKilled = flag; }
99        const bool getMasterKilled() const { return _masterKilled; }
100       
101        unsigned long   _byte_order;
102        bool            _masterKilled;
103        osg::Vec3       _eye;
104        osg::Vec3       _center;
105        osg::Vec3       _up;
106        bool            _attachMatrix;
107        osg::Matrix     _matrix;
108
109        // note don't use a ref_ptr as used elsewhere for FrameStamp
110        // since we don't want to copy the pointer - but the memory.
111        // FrameStamp doesn't have a private destructor to allow
112        // us to do this, even though its a reference counted object.   
113        osg::FrameStamp  _frameStamp;
114       
115};
116
117// using namespace osgUtil required to get round VisualStudio's inablility
118// to handle osgUtil::SceneView::app() in the code below, only SceneView::app
119// works..but this breaks the IRIX build, unless you have the osgUtil??!
120// Robert Osfield, July 2002.
121using namespace osgUtil;
122
123class MySceneView : public SceneView {
124
125    public:
126   
127        enum ViewerMode
128        {
129            STAND_ALONE,
130            SLAVE,
131            MASTER
132        };
133   
134        MySceneView(ViewerMode viewerMode,int socketNumber,float camera_fov, float camera_offset):
135            _viewerMode(viewerMode),_socketNumber(socketNumber),
136            _camera_fov(camera_fov), _camera_offset(camera_offset)
137        {
138            setDefaults();
139            getCamera()->setAdjustAspectRatioMode(osg::Camera::ADJUST_VERTICAL);
140            getCamera()->setFOV(camera_fov,camera_fov*(600.0f/800.0f),1.0f,1000.0f);
141           
142            _bc.setPort(socketNumber);
143            _rc.setPort(socketNumber);
144        };
145       
146        ~MySceneView()
147        {
148            if (_viewerMode==MASTER)
149            {
150                // need to broadcast my death.
151                CameraPacket cp;
152                cp.setPacket(*getCamera(),getFrameStamp());
153                cp.setMasterKilled(true);
154               
155                _bc.setBuffer(&cp, sizeof( CameraPacket ));
156                _bc.sync();
157               
158                std::cout << "broadcasting death"<<std::endl;
159               
160            }
161        }
162       
163        // override the basic SceneView::app traversal.
164        virtual void update()
165        {
166            SceneView::update();
167            switch (_viewerMode)
168            {
169            case(MASTER):
170                {
171                    CameraPacket cp;
172                    cp.setPacket(*getCamera(),getFrameStamp());
173
174                    _bc.setBuffer(&cp, sizeof( CameraPacket ));
175                    _bc.sync();
176
177                }
178                break;
179            case(SLAVE):
180                {
181                    CameraPacket cp;
182
183                    _rc.setBuffer(&cp, sizeof( CameraPacket ));
184                    _rc.sync();
185
186                    cp.checkByteOrder();
187
188
189                    cp.getCamera(*getCamera(),_camera_offset);
190                    cp.getSceneViewUpdate(*this);
191                   
192                    if (cp.getMasterKilled())
193                    {
194                        std::cout << "recieved master killed"<<std::endl;
195                        _viewerMode = STAND_ALONE;
196                    }
197                }
198                break;
199            default:
200                // no need to anything here, just a normal interactive viewer.
201                break;
202            }
203        }
204       
205    protected:
206   
207        ViewerMode      _viewerMode;
208        int             _socketNumber;
209        float           _camera_fov;
210        float           _camera_offset;
211        unsigned long   _byte_order;
212       
213
214        Broadcaster     _bc;
215        Receiver        _rc;
216
217
218};
219
220/*
221 * Function to read several files (typically one) as specified on the command
222 * line, and return them in an osg::Node
223 */
224osg::Node* getNodeFromFiles(int argc,char **argv,
225                            MySceneView::ViewerMode& viewerMode, int& socketNumber,
226                            float& camera_fov, float& camera_offset)
227{
228    osg::Node *rootnode = new osg::Node;
229
230    int i;
231
232    typedef std::vector<osg::Node*> NodeList;
233    NodeList nodeList;
234    for( i = 1; i < argc; i++ )
235    {
236
237        if (argv[i][0]=='-')
238        {
239            switch(argv[i][1])
240            {
241
242                case('m'):
243                    viewerMode = MySceneView::MASTER;
244                    break;
245                case('s'):
246                    viewerMode = MySceneView::SLAVE;
247                    break;
248                case('n'):
249                    ++i;
250                    if (i<argc)
251                    {
252                        socketNumber = atoi(argv[i]);
253                    }
254                    break;
255                case('f'):
256                    ++i;
257                    if (i<argc)
258                    {
259                        camera_fov = atoi(argv[i]);
260                    }
261                    break;
262                case('o'):
263                    ++i;
264                    if (i<argc)
265                    {
266                        camera_offset = atoi(argv[i]);
267                    }
268                    break;
269                   
270                case('l'):
271                    ++i;
272                    if (i<argc)
273                    {
274                        osgDB::Registry::instance()->loadLibrary(argv[i]);
275                    }
276                    break;
277                case('e'):
278                    ++i;
279                    if (i<argc)
280                    {
281                        std::string libName = osgDB::Registry::instance()->createLibraryNameForExt(argv[i]);
282                        osgDB::Registry::instance()->loadLibrary(libName);
283                    }
284                    break;
285            }
286        } else
287        {
288            osg::Node *node = osgDB::readNodeFile( argv[i] );
289
290            if( node != (osg::Node *)0L )
291            {
292                if (node->getName().empty()) node->setName( argv[i] );
293                nodeList.push_back(node);
294            }
295        }
296
297    }
298
299    if (nodeList.size()==0)
300    {
301        osg::notify(osg::WARN) << "No data loaded."<<std::endl;
302        exit(0);
303    }
304   
305   
306/*
307    if (master) osg::notify(osg::NOTICE)<<"set to MASTER, broadcasting on socketNumber "<<socketNumber<<std::endl;
308    else osg::notify(osg::NOTICE)<<"set to SLAVE, reciving on socketNumber "<<socketNumber<<std::endl;
309   
310*/
311   
312
313    if (nodeList.size()==1)
314    {
315        rootnode = nodeList.front();
316    }
317    else                         // size >1
318    {
319        osg::Group* group = new osg::Group();
320        for(NodeList::iterator itr=nodeList.begin();
321            itr!=nodeList.end();
322            ++itr)
323        {
324            group->addChild(*itr);
325        }
326
327        rootnode = group;
328    }
329
330    return rootnode;
331}
332
333
334int main( int argc, char **argv )
335{
336
337    // use an ArgumentParser object to manage the program arguments.
338    osg::ArgumentParser arguments(&argc,argv);
339   
340    // set up the usage document, in case we need to print out how to use this program.
341    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getProgramName()+" [options] filename ...");
342    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
343   
344    // construct the viewer.
345    osgProducer::Viewer viewer(arguments);
346
347    // set up the value with sensible default event handlers.
348    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
349
350    // get details on keyboard and mouse bindings used by the viewer.
351    viewer.getUsage(*arguments.getApplicationUsage());
352
353    // if user request help write it out to cout.
354    if (arguments.read("-h") || arguments.read("--help"))
355    {
356        arguments.getApplicationUsage()->write(std::cout);
357        return 1;
358    }
359
360    // any option left unread are converted into errors to write out later.
361    arguments.reportRemainingOptionsAsUnrecognized();
362
363    // report any errors if they have occured when parsing the program aguments.
364    if (arguments.errors())
365    {
366        arguments.writeErrorMessages(std::cout);
367        return 1;
368    }
369
370
371    osg::Timer timer;
372    osg::Timer_t before_load = timer.tick();
373   
374    MySceneView::ViewerMode viewerMode = MySceneView::STAND_ALONE;
375    int socketNumber=8100;
376    float camera_fov=45.0f;
377    float camera_offset=45.0f;
378
379    osg::Node* rootnode = getNodeFromFiles( argc, argv, viewerMode, socketNumber,camera_fov,camera_offset);
380   
381    osg::Timer_t after_load = timer.tick();
382    std::cout << "Time for load = "<<timer.delta_s(before_load,after_load)<<" seconds"<<std::endl;
383
384    osg::ref_ptr<MySceneView> mySceneView = new MySceneView(viewerMode,socketNumber,camera_fov,osg::inDegrees(camera_offset));
385    mySceneView->setSceneData(rootnode);
386   
387    // set the scene to render
388    viewer.setSceneData(mySceneView.get());
389
390    // create the windows and run the threads.
391    viewer.realize(Producer::CameraGroup::ThreadPerCamera);
392
393    while( !viewer.done() )
394    {
395        // wait for all cull and draw threads to complete.
396        viewer.sync();
397
398        // update the scene by traversing it with the the update visitor which will
399        // call all node update callbacks and animations.
400        viewer.update();
401         
402        // fire off the cull and draw traversals of the scene.
403        viewer.frame();
404       
405    }
406
407    return 0;
408}
Note: See TracBrowser for help on using the browser.