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

Revision 5157, 25.1 kB (checked in by robert, 8 years ago)

Added extra SphereSegment? intersection tests.

  • 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->addChild(geode,0.0f,100.0f);
222        lod->addChild(cessna,100.0f,10000.0f);
223
224
225        osg::MatrixTransform* positioned = new osg::MatrixTransform;
226        positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
227        positioned->setDataVariance(osg::Object::STATIC);
228        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
229                                     osg::Matrix::scale(size,size,size)*
230                                     osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f));
231   
232        //positioned->addChild(cessna);
233        positioned->addChild(lod);
234   
235        osg::MatrixTransform* xform = new osg::MatrixTransform;
236        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
237        xform->addChild(positioned);
238       
239        model->addChild(xform);
240    }
241   
242    return model;
243}
244
245osg::Group* createOverlay(const osg::Vec3& center, float radius)
246{
247    osg::Group* group = new osg::Group;
248   
249    // create a grid of lines.
250    {
251        osg::Geometry* geom = new osg::Geometry;
252       
253        unsigned int num_rows = 10;
254
255        osg::Vec3 left = center+osg::Vec3(-radius,-radius,0.0f);
256        osg::Vec3 right = center+osg::Vec3(radius,-radius,0.0f);
257        osg::Vec3 delta_row = osg::Vec3(0.0f,2.0f*radius/float(num_rows-1),0.0f);
258
259        osg::Vec3 top = center+osg::Vec3(-radius,radius,0.0f);
260        osg::Vec3 bottom = center+osg::Vec3(-radius,-radius,0.0f);
261        osg::Vec3 delta_column = osg::Vec3(2.0f*radius/float(num_rows-1),0.0f,0.0f);
262
263        osg::Vec3Array* vertices = new osg::Vec3Array;
264        for(unsigned int i=0; i<num_rows; ++i)
265        {
266            vertices->push_back(left);
267            vertices->push_back(right);
268            left += delta_row;
269            right += delta_row;
270
271            vertices->push_back(top);
272            vertices->push_back(bottom);
273            top += delta_column;
274            bottom += delta_column;
275        }
276       
277        geom->setVertexArray(vertices);
278
279        osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
280        color[0].set(0,0,0,255);
281        geom->setColorArray(&color);
282        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
283
284        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,vertices->getNumElements()));
285
286        geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
287
288        osg::Geode* geode = new osg::Geode;
289        geode->addDrawable(geom);
290        group->addChild(geode);       
291    }
292   
293    return group;
294}
295
296osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y)
297{
298    osgUtil::IntersectVisitor iv;
299    osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment;
300
301    const osg::BoundingSphere& bs = subgraph->getBound();
302    float zMax = bs.center().z()+bs.radius();
303    float zMin = bs.center().z()-bs.radius();
304   
305    segDown->set(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax));
306    iv.addLineSegment(segDown.get());
307
308    subgraph->accept(iv);
309
310    if (iv.hits())
311    {
312        osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get());
313        if (!hitList.empty())
314        {
315            osg::Vec3 ip = hitList.front().getWorldIntersectPoint();
316            return  ip;
317        }
318    }
319
320    return osg::Vec3(x,y,0.0f);
321}
322
323
324//////////////////////////////////////////////////////////////////////////////
325// MAIN SCENE GRAPH BUILDING FUNCTION
326//////////////////////////////////////////////////////////////////////////////
327
328void build_world(osg::Group *root, unsigned int testCase)
329{
330
331    // create terrain
332    osg::ref_ptr<osg::Geode> terrainGeode = 0;
333    {
334        terrainGeode = new osg::Geode;
335
336        osg::StateSet* stateset = new osg::StateSet();
337        osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
338        if (image)
339        {
340            osg::Texture2D* texture = new osg::Texture2D;
341            texture->setImage(image);
342            stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
343        }
344
345        terrainGeode->setStateSet( stateset );
346
347       
348        {
349            unsigned int numColumns = 38;
350            unsigned int numRows = 39;
351            unsigned int r, c;
352           
353            osg::Vec3 origin(0.0f,0.0f,0.0f);
354            osg::Vec3 size(1000.0f,1000.0f,250.0f);
355
356            osg::Geometry* geometry = new osg::Geometry;
357
358            osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows));
359            osg::Vec2Array& tc = *(new osg::Vec2Array(numColumns*numRows));
360            osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
361
362            color[0].set(255,255,255,255);
363
364            float rowCoordDelta = size.y()/(float)(numRows-1);
365            float columnCoordDelta = size.x()/(float)(numColumns-1);
366
367            float rowTexDelta = 1.0f/(float)(numRows-1);
368            float columnTexDelta = 1.0f/(float)(numColumns-1);
369
370            // compute z range of z values of grid data so we can scale it.
371            float min_z = FLT_MAX;
372            float max_z = -FLT_MAX;
373            for(r=0;r<numRows;++r)
374            {
375                for(c=0;c<numColumns;++c)
376                {
377                    min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
378                    max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
379                }
380            }
381
382            float scale_z = size.z()/(max_z-min_z);
383
384            osg::Vec3 pos = origin;
385            osg::Vec2 tex(0.0f,0.0f);
386            int vi=0;
387            for(r=0;r<numRows;++r)
388            {
389                pos.x() = origin.x();
390                tex.x() = 0.0f;
391                for(c=0;c<numColumns;++c)
392                {
393                    v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
394                    tc[vi] = tex;
395                    pos.x()+=columnCoordDelta;
396                    tex.x()+=columnTexDelta;
397                    ++vi;
398                }
399                pos.y() += rowCoordDelta;
400                tex.y() += rowTexDelta;
401            }
402
403            geometry->setVertexArray(&v);
404            geometry->setTexCoordArray(0, &tc);
405            geometry->setColorArray(&color);
406            geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
407
408            for(r=0;r<numRows-1;++r)
409            {
410                osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
411                geometry->addPrimitiveSet(&drawElements);
412                int ei=0;
413                for(c=0;c<numColumns;++c)
414                {
415                    drawElements[ei++] = (r+1)*numColumns+c;
416                    drawElements[ei++] = (r)*numColumns+c;
417                }
418            }
419           
420            osgUtil::SmoothingVisitor smoother;
421            smoother.smooth(*geometry);
422           
423            terrainGeode->addDrawable(geometry);
424        }
425       
426    }   
427
428
429    // create sphere segment
430    osg::ref_ptr<osgSim::SphereSegment> ss = 0;
431    {
432
433        osg::Matrix terrainToSS;
434
435        switch(testCase)
436        {
437            case(0):       
438                ss = new osgSim::SphereSegment(
439                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
440                                510.0f, // radius
441                                osg::DegreesToRadians(135.0f),
442                                osg::DegreesToRadians(240.0f),
443                                osg::DegreesToRadians(-10.0f),
444                                osg::DegreesToRadians(30.0f),
445                                60);
446                root->addChild(ss.get());
447                break;
448            case(1):       
449                ss = new osgSim::SphereSegment(
450                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
451                                510.0f, // radius
452                                osg::DegreesToRadians(45.0f),
453                                osg::DegreesToRadians(240.0f),
454                                osg::DegreesToRadians(-10.0f),
455                                osg::DegreesToRadians(30.0f),
456                                60);
457                root->addChild(ss.get());
458                break;
459            case(2):       
460                ss = new osgSim::SphereSegment(
461                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
462                                510.0f, // radius
463                                osg::DegreesToRadians(5.0f),
464                                osg::DegreesToRadians(355.0f),
465                                osg::DegreesToRadians(-10.0f),
466                                osg::DegreesToRadians(30.0f),
467                                60);
468                root->addChild(ss.get());
469                break;
470            case(3):       
471                ss = new osgSim::SphereSegment(
472                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
473                                510.0f, // radius
474                                osg::DegreesToRadians(0.0f),
475                                osg::DegreesToRadians(360.0f),
476                                osg::DegreesToRadians(-10.0f),
477                                osg::DegreesToRadians(30.0f),
478                                60);
479                root->addChild(ss.get());
480                break;
481            case(4):       
482            {
483                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
484                                700.0f, // radius
485                                osg::DegreesToRadians(135.0f),
486                                osg::DegreesToRadians(240.0f),
487                                osg::DegreesToRadians(-60.0f),
488                                osg::DegreesToRadians(-40.0f),
489                                60);
490                 
491                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
492               
493                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
494                                          -0.180627, -0.983552, -6.93889e-18, 0,
495                                          -0.491776, 0.0903136, 0.866025, 0,
496                                          598.217, 481.957, 100, 1));
497                mt->addChild(ss.get());
498               
499                terrainToSS.invert(mt->getMatrix());
500                                               
501                root->addChild(mt.get());
502                break;
503            }
504            case(5):       
505            {
506                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
507                                700.0f, // radius
508                                osg::DegreesToRadians(35.0f),
509                                osg::DegreesToRadians(135.0f),
510                                osg::DegreesToRadians(-60.0f),
511                                osg::DegreesToRadians(-40.0f),
512                                60);
513                 
514                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
515               
516                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
517                                          -0.180627, -0.983552, -6.93889e-18, 0,
518                                          -0.491776, 0.0903136, 0.866025, 0,
519                                          598.217, 481.957, 100, 1));
520                mt->addChild(ss.get());
521               
522                terrainToSS.invert(mt->getMatrix());
523                                               
524                root->addChild(mt.get());
525                break;
526            }
527            case(6):       
528            {
529                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
530                                700.0f, // radius
531                                osg::DegreesToRadians(-45.0f),
532                                osg::DegreesToRadians(45.0f),
533                                osg::DegreesToRadians(-60.0f),
534                                osg::DegreesToRadians(-40.0f),
535                                60);
536                 
537                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
538               
539                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
540                                          -0.180627, -0.983552, -6.93889e-18, 0,
541                                          -0.491776, 0.0903136, 0.866025, 0,
542                                          598.217, 481.957, 100, 1));
543                mt->addChild(ss.get());
544               
545                terrainToSS.invert(mt->getMatrix());
546                                               
547                root->addChild(mt.get());
548                break;
549            }
550        };
551       
552        if (ss.valid())
553        {
554            ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
555            ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f));
556
557            if (!ss->getParents().empty())
558            {
559                ss->getParent(0)->addChild(ss->computeIntersectionSubgraph(terrainToSS, terrainGeode.get()));
560            }
561       
562        }
563    }
564   
565
566    root->addChild(terrainGeode.get());
567
568    // create particle effects
569    {   
570        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),100.0f,100.0f);
571
572        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f);
573        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f);
574        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 10.0f);
575
576        root->addChild(explosion);
577        root->addChild(smoke);
578        root->addChild(fire);
579    }
580   
581    // create particle effects
582    {   
583        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),200.0f,100.0f);
584
585        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f);
586        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f);
587        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 1.0f);
588
589        root->addChild(explosion);
590        root->addChild(smoke);
591        root->addChild(fire);
592    }
593   
594   
595    bool createMovingRadar = true;
596   
597    // create the moving models.
598    {
599        root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f, terrainGeode.get(), root, createMovingRadar));
600    }
601}
602
603
604//////////////////////////////////////////////////////////////////////////////
605// main()
606//////////////////////////////////////////////////////////////////////////////
607
608
609int main(int argc, char **argv)
610{
611    // use an ArgumentParser object to manage the program arguments.
612    osg::ArgumentParser arguments(&argc,argv);
613   
614    // set up the usage document, in case we need to print out how to use this program.
615    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of particle systems.");
616    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
617    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
618   
619
620    // construct the viewer.
621    osgProducer::Viewer viewer(arguments);
622
623    // set up the value with sensible default event handlers.
624    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
625
626    // get details on keyboard and mouse bindings used by the viewer.
627    viewer.getUsage(*arguments.getApplicationUsage());
628
629    // if user request help write it out to cout.
630    unsigned int testCase = 0;
631    if (arguments.read("-t", testCase)) {}
632
633
634    // if user request help write it out to cout.
635    if (arguments.read("-h") || arguments.read("--help"))
636    {
637        arguments.getApplicationUsage()->write(std::cout);
638        return 1;
639    }
640
641    // any option left unread are converted into errors to write out later.
642    arguments.reportRemainingOptionsAsUnrecognized();
643
644    // report any errors if they have occured when parsing the program aguments.
645    if (arguments.errors())
646    {
647        arguments.writeErrorMessages(std::cout);
648        return 1;
649    }
650   
651    osg::Group *root = new osg::Group;
652    build_world(root, testCase);
653   
654    // add a viewport to the viewer and attach the scene graph.
655    viewer.setSceneData(root);
656       
657    // create the windows and run the threads.
658    viewer.realize();
659
660    while( !viewer.done() )
661    {
662        // wait for all cull and draw threads to complete.
663        viewer.sync();
664
665        // update the scene by traversing it with the the update visitor which will
666        // call all node update callbacks and animations.
667        viewer.update();
668         
669        // fire off the cull and draw traversals of the scene.
670        viewer.frame();
671       
672    }
673   
674    // wait for all cull and draw threads to complete before exit.
675    viewer.sync();
676
677    return 0;
678}
Note: See TracBrowser for help on using the browser.