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

Revision 6941, 26.8 kB (checked in by robert, 7 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

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