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

Revision 8998, 26.6 kB (checked in by robert, 6 years ago)

Replaced usage of depreacted IntersectVisitor? with IntersectionVisitor?

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