root/OpenSceneGraph/trunk/examples/osgspheresegment/osgspheresegment.cpp @ 5195

Revision 5195, 25.2 kB (checked in by robert, 8 years ago)

Added a setRadius into the screen space LOD.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osgProducer/Viewer>
2
3#include <osg/Group>
4#include <osg/Geode>
5#include <osg/ShapeDrawable>
6#include <osg/Texture2D>
7#include <osg/PositionAttitudeTransform>
8#include <osg/MatrixTransform>
9#include <osg/Geometry>
10
11#include <osgUtil/SmoothingVisitor>
12
13#include <osgDB/ReadFile>
14
15#include <osgText/Text>
16
17#include <osgSim/SphereSegment>
18#include <osgSim/OverlayNode>
19
20#include <osgParticle/ExplosionEffect>
21#include <osgParticle/SmokeEffect>
22#include <osgParticle/FireEffect>
23#include <osgParticle/ParticleSystemUpdater>
24
25#include <osg/io_utils>
26
27// for the grid data..
28#include "../osghangglide/terrain_coords.h"
29
30osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
31{
32    // set up the animation path
33    osg::AnimationPath* animationPath = new osg::AnimationPath;
34    animationPath->setLoopMode(osg::AnimationPath::LOOP);
35   
36    int numSamples = 40;
37    float yaw = 0.0f;
38    float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);
39    float roll = osg::inDegrees(30.0f);
40   
41    double time=0.0f;
42    double time_delta = looptime/(double)numSamples;
43    for(int i=0;i<numSamples;++i)
44    {
45        osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
46        osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));
47       
48        animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
49
50        yaw += yaw_delta;
51        time += time_delta;
52
53    }
54    return animationPath;   
55}
56
57
58
59class IntersectionUpdateCallback : public osg::NodeCallback
60{
61        virtual void operator()(osg::Node* /*node*/, osg::NodeVisitor* nv)
62        {
63            if (!root_ || !terrain_ || !ss_ || !intersectionGroup_)
64            {
65                osg::notify(osg::NOTICE)<<"IntersectionUpdateCallback not set up correctly."<<std::endl;
66                return;
67            }
68       
69            //traverse(node,nv);
70            frameCount_++;
71            if (frameCount_ > 200)
72            {
73                // first we need find the transformation matrix that takes
74                // the terrain into the coordinate frame of the sphere segment.
75                osg::Matrixd terrainLocalToWorld;
76                osg::MatrixList terrain_worldMatrices = terrain_->getWorldMatrices(root_.get());
77                if (terrain_worldMatrices.empty()) terrainLocalToWorld.makeIdentity();
78                else if (terrain_worldMatrices.size()==1) terrainLocalToWorld = terrain_worldMatrices.front();
79                else
80                {
81                    osg::notify(osg::NOTICE)<<"IntersectionUpdateCallback: warning cannot interestect with multiple terrain instances, just uses first one."<<std::endl;
82                    terrainLocalToWorld = terrain_worldMatrices.front();
83                }
84               
85                // sphere segment is easier as this callback is attached to the node, so the node visitor has the unique path to it already.
86                osg::Matrixd ssWorldToLocal = osg::computeWorldToLocal(nv->getNodePath());
87               
88                // now we can compute the terrain to ss transform
89                osg::Matrixd possie = terrainLocalToWorld*ssWorldToLocal;
90               
91                osgSim::SphereSegment::LineList lines = ss_->computeIntersection(possie, terrain_.get());
92                if (!lines.empty())
93                {
94                    if (intersectionGroup_.valid())
95                    {
96                        // now we need to place the intersections which are in the SphereSegmenet's coordinate frame into
97                        // to the final position.
98                        osg::MatrixTransform* mt = new osg::MatrixTransform;
99                        mt->setMatrix(osg::computeLocalToWorld(nv->getNodePath()));
100                        intersectionGroup_->addChild(mt);
101                       
102                        // std::cout<<"matrix = "<<mt->getMatrix()<<std::endl;
103
104                        osg::Geode* geode = new osg::Geode;
105                        mt->addChild(geode);
106
107                        geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
108
109                        for(osgSim::SphereSegment::LineList::iterator itr=lines.begin();
110                           itr!=lines.end();
111                           ++itr)
112                        {
113                            osg::Geometry* geom = new osg::Geometry;
114                            geode->addDrawable(geom);
115
116                            osg::Vec3Array* vertices = itr->get();
117                            geom->setVertexArray(vertices);
118                            geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, vertices->getNumElements()));
119                        }
120                    }
121                }
122                else
123                {
124                       osg::notify(osg::NOTICE)<<"No intersections found"<<std::endl;
125                }
126
127                   
128                frameCount_ = 0;
129            }
130        }
131    public:
132    osg::observer_ptr<osg::Group> root_;
133    osg::observer_ptr<osg::Geode> terrain_;
134    osg::observer_ptr<osgSim::SphereSegment> ss_;
135    osg::observer_ptr<osg::Group> intersectionGroup_;
136    unsigned frameCount_;
137};
138
139
140osg::Node* createMovingModel(const osg::Vec3& center, float radius, osg::Geode * terrainGeode, osg::Group * root, bool createMovingRadar = false)
141{
142    float animationLength = 10.0f;
143
144    osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);
145
146    osg::Group* model = new osg::Group;
147
148    osg::Node* glider = osgDB::readNodeFile("glider.osg");
149    if (glider)
150    {
151        const osg::BoundingSphere& bs = glider->getBound();
152
153        float size = radius/bs.radius()*0.3f;
154        osg::MatrixTransform* positioned = new osg::MatrixTransform;
155        positioned->setDataVariance(osg::Object::STATIC);
156        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
157                                     osg::Matrix::scale(size,size,size)*
158                                     osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f));
159   
160        positioned->addChild(glider);
161   
162        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;   
163        xform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
164        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
165        xform->addChild(positioned);
166        model->addChild(xform);
167    }
168   
169    if (createMovingRadar)
170    {
171        // The IntersectionUpdateCallback has to have a safe place to put all its generated geometry into,
172        // and this group can't be in the parental chain of the callback otherwise we will end up invalidating
173        // traversal iterators.
174        osg::Group* intersectionGroup = new osg::Group;
175        root->addChild(intersectionGroup);
176   
177        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;   
178        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
179       
180        osgSim::SphereSegment * ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
181                                700.0f, // radius
182                                osg::DegreesToRadians(135.0f),
183                                osg::DegreesToRadians(240.0f),
184                                osg::DegreesToRadians(-60.0f),
185                                osg::DegreesToRadians(-40.0f),
186                                60);
187                               
188        IntersectionUpdateCallback * iuc = new IntersectionUpdateCallback;
189        iuc->frameCount_ = 0;
190        iuc->root_ = root;
191        iuc->terrain_ = terrainGeode;
192        iuc->ss_ = ss;
193        iuc->intersectionGroup_ = intersectionGroup;
194        ss->setUpdateCallback(iuc);
195        ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
196        ss->setSideColor(osg::Vec4(0.5f,1.0f,1.0f,0.1f));
197        xform->addChild(ss);
198        model->addChild(xform);
199    }
200 
201    osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
202    if (cessna)
203    {
204        const osg::BoundingSphere& bs = cessna->getBound();
205
206        osgText::Text* text = new osgText::Text;
207        float size = radius/bs.radius()*0.3f;
208
209        text->setPosition(bs.center());
210        text->setText("Cessna");
211        text->setAlignment(osgText::Text::CENTER_CENTER);
212        text->setAxisAlignment(osgText::Text::SCREEN);
213        text->setCharacterSize(40.0f);
214        text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
215       
216        osg::Geode* geode = new osg::Geode;
217        geode->addDrawable(text);
218   
219        osg::LOD* lod = new osg::LOD;
220        lod->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN);
221        lod->setRadius(cessna->getBound().radius());
222        lod->addChild(geode,0.0f,100.0f);
223        lod->addChild(cessna,100.0f,10000.0f);
224
225
226        osg::MatrixTransform* positioned = new osg::MatrixTransform;
227        positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
228        positioned->setDataVariance(osg::Object::STATIC);
229        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
230                                     osg::Matrix::scale(size,size,size)*
231                                     osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f));
232   
233        //positioned->addChild(cessna);
234        positioned->addChild(lod);
235   
236        osg::MatrixTransform* xform = new osg::MatrixTransform;
237        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
238        xform->addChild(positioned);
239       
240        model->addChild(xform);
241    }
242   
243    return model;
244}
245
246osg::Group* createOverlay(const osg::Vec3& center, float radius)
247{
248    osg::Group* group = new osg::Group;
249   
250    // create a grid of lines.
251    {
252        osg::Geometry* geom = new osg::Geometry;
253       
254        unsigned int num_rows = 10;
255
256        osg::Vec3 left = center+osg::Vec3(-radius,-radius,0.0f);
257        osg::Vec3 right = center+osg::Vec3(radius,-radius,0.0f);
258        osg::Vec3 delta_row = osg::Vec3(0.0f,2.0f*radius/float(num_rows-1),0.0f);
259
260        osg::Vec3 top = center+osg::Vec3(-radius,radius,0.0f);
261        osg::Vec3 bottom = center+osg::Vec3(-radius,-radius,0.0f);
262        osg::Vec3 delta_column = osg::Vec3(2.0f*radius/float(num_rows-1),0.0f,0.0f);
263
264        osg::Vec3Array* vertices = new osg::Vec3Array;
265        for(unsigned int i=0; i<num_rows; ++i)
266        {
267            vertices->push_back(left);
268            vertices->push_back(right);
269            left += delta_row;
270            right += delta_row;
271
272            vertices->push_back(top);
273            vertices->push_back(bottom);
274            top += delta_column;
275            bottom += delta_column;
276        }
277       
278        geom->setVertexArray(vertices);
279
280        osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
281        color[0].set(0,0,0,255);
282        geom->setColorArray(&color);
283        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
284
285        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,vertices->getNumElements()));
286
287        geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
288
289        osg::Geode* geode = new osg::Geode;
290        geode->addDrawable(geom);
291        group->addChild(geode);       
292    }
293   
294    return group;
295}
296
297osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y)
298{
299    osgUtil::IntersectVisitor iv;
300    osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment;
301
302    const osg::BoundingSphere& bs = subgraph->getBound();
303    float zMax = bs.center().z()+bs.radius();
304    float zMin = bs.center().z()-bs.radius();
305   
306    segDown->set(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax));
307    iv.addLineSegment(segDown.get());
308
309    subgraph->accept(iv);
310
311    if (iv.hits())
312    {
313        osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get());
314        if (!hitList.empty())
315        {
316            osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
317            return  ip;
318        }
319    }
320
321    return osg::Vec3(x,y,0.0f);
322}
323
324
325//////////////////////////////////////////////////////////////////////////////
326// MAIN SCENE GRAPH BUILDING FUNCTION
327//////////////////////////////////////////////////////////////////////////////
328
329void build_world(osg::Group *root, unsigned int testCase)
330{
331
332    // create terrain
333    osg::ref_ptr<osg::Geode> terrainGeode = 0;
334    {
335        terrainGeode = new osg::Geode;
336
337        osg::StateSet* stateset = new osg::StateSet();
338        osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
339        if (image)
340        {
341            osg::Texture2D* texture = new osg::Texture2D;
342            texture->setImage(image);
343            stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
344        }
345
346        terrainGeode->setStateSet( stateset );
347
348       
349        {
350            unsigned int numColumns = 38;
351            unsigned int numRows = 39;
352            unsigned int r, c;
353           
354            osg::Vec3 origin(0.0f,0.0f,0.0f);
355            osg::Vec3 size(1000.0f,1000.0f,250.0f);
356
357            osg::Geometry* geometry = new osg::Geometry;
358
359            osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows));
360            osg::Vec2Array& tc = *(new osg::Vec2Array(numColumns*numRows));
361            osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
362
363            color[0].set(255,255,255,255);
364
365            float rowCoordDelta = size.y()/(float)(numRows-1);
366            float columnCoordDelta = size.x()/(float)(numColumns-1);
367
368            float rowTexDelta = 1.0f/(float)(numRows-1);
369            float columnTexDelta = 1.0f/(float)(numColumns-1);
370
371            // compute z range of z values of grid data so we can scale it.
372            float min_z = FLT_MAX;
373            float max_z = -FLT_MAX;
374            for(r=0;r<numRows;++r)
375            {
376                for(c=0;c<numColumns;++c)
377                {
378                    min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
379                    max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
380                }
381            }
382
383            float scale_z = size.z()/(max_z-min_z);
384
385            osg::Vec3 pos = origin;
386            osg::Vec2 tex(0.0f,0.0f);
387            int vi=0;
388            for(r=0;r<numRows;++r)
389            {
390                pos.x() = origin.x();
391                tex.x() = 0.0f;
392                for(c=0;c<numColumns;++c)
393                {
394                    v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
395                    tc[vi] = tex;
396                    pos.x()+=columnCoordDelta;
397                    tex.x()+=columnTexDelta;
398                    ++vi;
399                }
400                pos.y() += rowCoordDelta;
401                tex.y() += rowTexDelta;
402            }
403
404            geometry->setVertexArray(&v);
405            geometry->setTexCoordArray(0, &tc);
406            geometry->setColorArray(&color);
407            geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
408
409            for(r=0;r<numRows-1;++r)
410            {
411                osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
412                geometry->addPrimitiveSet(&drawElements);
413                int ei=0;
414                for(c=0;c<numColumns;++c)
415                {
416                    drawElements[ei++] = (r+1)*numColumns+c;
417                    drawElements[ei++] = (r)*numColumns+c;
418                }
419            }
420           
421            osgUtil::SmoothingVisitor smoother;
422            smoother.smooth(*geometry);
423           
424            terrainGeode->addDrawable(geometry);
425        }
426       
427    }   
428
429
430    // create sphere segment
431    osg::ref_ptr<osgSim::SphereSegment> ss = 0;
432    {
433
434        osg::Matrix terrainToSS;
435
436        switch(testCase)
437        {
438            case(0):       
439                ss = new osgSim::SphereSegment(
440                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
441                                510.0f, // radius
442                                osg::DegreesToRadians(135.0f),
443                                osg::DegreesToRadians(240.0f),
444                                osg::DegreesToRadians(-10.0f),
445                                osg::DegreesToRadians(30.0f),
446                                60);
447                root->addChild(ss.get());
448                break;
449            case(1):       
450                ss = new osgSim::SphereSegment(
451                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
452                                510.0f, // radius
453                                osg::DegreesToRadians(45.0f),
454                                osg::DegreesToRadians(240.0f),
455                                osg::DegreesToRadians(-10.0f),
456                                osg::DegreesToRadians(30.0f),
457                                60);
458                root->addChild(ss.get());
459                break;
460            case(2):       
461                ss = new osgSim::SphereSegment(
462                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
463                                510.0f, // radius
464                                osg::DegreesToRadians(5.0f),
465                                osg::DegreesToRadians(355.0f),
466                                osg::DegreesToRadians(-10.0f),
467                                osg::DegreesToRadians(30.0f),
468                                60);
469                root->addChild(ss.get());
470                break;
471            case(3):       
472                ss = new osgSim::SphereSegment(
473                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
474                                510.0f, // radius
475                                osg::DegreesToRadians(0.0f),
476                                osg::DegreesToRadians(360.0f),
477                                osg::DegreesToRadians(-10.0f),
478                                osg::DegreesToRadians(30.0f),
479                                60);
480                root->addChild(ss.get());
481                break;
482            case(4):       
483            {
484                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
485                                700.0f, // radius
486                                osg::DegreesToRadians(135.0f),
487                                osg::DegreesToRadians(240.0f),
488                                osg::DegreesToRadians(-60.0f),
489                                osg::DegreesToRadians(-40.0f),
490                                60);
491                 
492                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
493               
494                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
495                                          -0.180627, -0.983552, -6.93889e-18, 0,
496                                          -0.491776, 0.0903136, 0.866025, 0,
497                                          598.217, 481.957, 100, 1));
498                mt->addChild(ss.get());
499               
500                terrainToSS.invert(mt->getMatrix());
501                                               
502                root->addChild(mt.get());
503                break;
504            }
505            case(5):       
506            {
507                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
508                                700.0f, // radius
509                                osg::DegreesToRadians(35.0f),
510                                osg::DegreesToRadians(135.0f),
511                                osg::DegreesToRadians(-60.0f),
512                                osg::DegreesToRadians(-40.0f),
513                                60);
514                 
515                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
516               
517                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
518                                          -0.180627, -0.983552, -6.93889e-18, 0,
519                                          -0.491776, 0.0903136, 0.866025, 0,
520                                          598.217, 481.957, 100, 1));
521                mt->addChild(ss.get());
522               
523                terrainToSS.invert(mt->getMatrix());
524                                               
525                root->addChild(mt.get());
526                break;
527            }
528            case(6):       
529            {
530                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
531                                700.0f, // radius
532                                osg::DegreesToRadians(-45.0f),
533                                osg::DegreesToRadians(45.0f),
534                                osg::DegreesToRadians(-60.0f),
535                                osg::DegreesToRadians(-40.0f),
536                                60);
537                 
538                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
539               
540                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
541                                          -0.180627, -0.983552, -6.93889e-18, 0,
542                                          -0.491776, 0.0903136, 0.866025, 0,
543                                          598.217, 481.957, 100, 1));
544                mt->addChild(ss.get());
545               
546                terrainToSS.invert(mt->getMatrix());
547                                               
548                root->addChild(mt.get());
549                break;
550            }
551        };
552       
553        if (ss.valid())
554        {
555            ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
556            ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f));
557
558            if (!ss->getParents().empty())
559            {
560                ss->getParent(0)->addChild(ss->computeIntersectionSubgraph(terrainToSS, terrainGeode.get()));
561            }
562       
563        }
564    }
565   
566
567    root->addChild(terrainGeode.get());
568
569    // create particle effects
570    {   
571        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),100.0f,100.0f);
572
573        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f);
574        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f);
575        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 10.0f);
576
577        root->addChild(explosion);
578        root->addChild(smoke);
579        root->addChild(fire);
580    }
581   
582    // create particle effects
583    {   
584        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),200.0f,100.0f);
585
586        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f);
587        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f);
588        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 1.0f);
589
590        root->addChild(explosion);
591        root->addChild(smoke);
592        root->addChild(fire);
593    }
594   
595   
596    bool createMovingRadar = true;
597   
598    // create the moving models.
599    {
600        root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f, terrainGeode.get(), root, createMovingRadar));
601    }
602}
603
604
605//////////////////////////////////////////////////////////////////////////////
606// main()
607//////////////////////////////////////////////////////////////////////////////
608
609
610int main(int argc, char **argv)
611{
612    // use an ArgumentParser object to manage the program arguments.
613    osg::ArgumentParser arguments(&argc,argv);
614   
615    // set up the usage document, in case we need to print out how to use this program.
616    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of particle systems.");
617    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
618    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
619   
620
621    // construct the viewer.
622    osgProducer::Viewer viewer(arguments);
623
624    // set up the value with sensible default event handlers.
625    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
626
627    // get details on keyboard and mouse bindings used by the viewer.
628    viewer.getUsage(*arguments.getApplicationUsage());
629
630    // if user request help write it out to cout.
631    unsigned int testCase = 0;
632    if (arguments.read("-t", testCase)) {}
633
634
635    // if user request help write it out to cout.
636    if (arguments.read("-h") || arguments.read("--help"))
637    {
638        arguments.getApplicationUsage()->write(std::cout);
639        return 1;
640    }
641
642    // any option left unread are converted into errors to write out later.
643    arguments.reportRemainingOptionsAsUnrecognized();
644
645    // report any errors if they have occured when parsing the program aguments.
646    if (arguments.errors())
647    {
648        arguments.writeErrorMessages(std::cout);
649        return 1;
650    }
651   
652    osg::Group *root = new osg::Group;
653    build_world(root, testCase);
654   
655    // add a viewport to the viewer and attach the scene graph.
656    viewer.setSceneData(root);
657       
658    // create the windows and run the threads.
659    viewer.realize();
660
661    while( !viewer.done() )
662    {
663        // wait for all cull and draw threads to complete.
664        viewer.sync();
665
666        // update the scene by traversing it with the the update visitor which will
667        // call all node update callbacks and animations.
668        viewer.update();
669         
670        // fire off the cull and draw traversals of the scene.
671        viewer.frame();
672       
673    }
674   
675    // wait for all cull and draw threads to complete before exit.
676    viewer.sync();
677
678    return 0;
679}
Note: See TracBrowser for help on using the browser.