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

Revision 12529, 27.8 kB (checked in by robert, 3 years ago)

Replaced .osg with .osgt file usage

  • 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
159class RotateUpdateCallback : public osg::NodeCallback
160{
161public:
162    RotateUpdateCallback() { i=0;}
163        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
164        {
165            osgSim::SphereSegment * ss = dynamic_cast<osgSim::SphereSegment *>(node);
166            if (ss)
167            {
168                ss->setArea(osg::Vec3(cos(i/(2*osg::PI)),sin(i/(2*osg::PI)),0), osg::PI_2, osg::PI_2);
169               
170                i += 0.1f;
171            }
172
173        }
174protected:
175    float i;
176};
177
178osg::Node* createMovingModel(const osg::Vec3& center, float radius, osg::Geode * terrainGeode, osg::Group * root, bool createMovingRadar = false)
179{
180    float animationLength = 10.0f;
181
182    osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);
183
184    osg::Group* model = new osg::Group;
185
186    osg::Node* glider = osgDB::readNodeFile("glider.osgt");
187    if (glider)
188    {
189        const osg::BoundingSphere& bs = glider->getBound();
190
191        float size = radius/bs.radius()*0.3f;
192        osg::MatrixTransform* positioned = new osg::MatrixTransform;
193        positioned->setDataVariance(osg::Object::STATIC);
194        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
195                                     osg::Matrix::scale(size,size,size)*
196                                     osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f));
197   
198        positioned->addChild(glider);
199   
200        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;   
201        xform->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
202        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
203        xform->addChild(positioned);
204        model->addChild(xform);
205    }
206   
207    if (createMovingRadar)
208    {
209        // The IntersectionUpdateCallback has to have a safe place to put all its generated geometry into,
210        // and this group can't be in the parental chain of the callback otherwise we will end up invalidating
211        // traversal iterators.
212        osg::Group* intersectionGroup = new osg::Group;
213        root->addChild(intersectionGroup);
214   
215        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;   
216        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
217       
218        osgSim::SphereSegment * ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
219                                700.0f, // radius
220                                osg::DegreesToRadians(135.0f),
221                                osg::DegreesToRadians(240.0f),
222                                osg::DegreesToRadians(-60.0f),
223                                osg::DegreesToRadians(-40.0f),
224                                60);
225                               
226        IntersectionUpdateCallback * iuc = new IntersectionUpdateCallback;
227        iuc->frameCount_ = 0;
228        iuc->root_ = root;
229        iuc->terrain_ = terrainGeode;
230        iuc->ss_ = ss;
231        iuc->intersectionGroup_ = intersectionGroup;
232        ss->setUpdateCallback(iuc);
233        ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
234        ss->setSideColor(osg::Vec4(0.5f,1.0f,1.0f,0.1f));
235        xform->addChild(ss);
236        model->addChild(xform);
237    }
238 
239    osg::Node* cessna = osgDB::readNodeFile("cessna.osgt");
240    if (cessna)
241    {
242        const osg::BoundingSphere& bs = cessna->getBound();
243
244        osgText::Text* text = new osgText::Text;
245        float size = radius/bs.radius()*0.3f;
246
247        text->setPosition(bs.center());
248        text->setText("Cessna");
249        text->setAlignment(osgText::Text::CENTER_CENTER);
250        text->setAxisAlignment(osgText::Text::SCREEN);
251        text->setCharacterSize(40.0f);
252        text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
253       
254        osg::Geode* geode = new osg::Geode;
255        geode->addDrawable(text);
256   
257        osg::LOD* lod = new osg::LOD;
258        lod->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN);
259        lod->setRadius(cessna->getBound().radius());
260        lod->addChild(geode,0.0f,100.0f);
261        lod->addChild(cessna,100.0f,10000.0f);
262
263
264        osg::MatrixTransform* positioned = new osg::MatrixTransform;
265        positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
266        positioned->setDataVariance(osg::Object::STATIC);
267        positioned->setMatrix(osg::Matrix::translate(-bs.center())*
268                                     osg::Matrix::scale(size,size,size)*
269                                     osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f));
270   
271        //positioned->addChild(cessna);
272        positioned->addChild(lod);
273   
274        osg::MatrixTransform* xform = new osg::MatrixTransform;
275        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
276        xform->addChild(positioned);
277       
278        model->addChild(xform);
279    }
280   
281    return model;
282}
283
284osg::Group* createOverlay(const osg::Vec3& center, float radius)
285{
286    osg::Group* group = new osg::Group;
287   
288    // create a grid of lines.
289    {
290        osg::Geometry* geom = new osg::Geometry;
291       
292        unsigned int num_rows = 10;
293
294        osg::Vec3 left = center+osg::Vec3(-radius,-radius,0.0f);
295        osg::Vec3 right = center+osg::Vec3(radius,-radius,0.0f);
296        osg::Vec3 delta_row = osg::Vec3(0.0f,2.0f*radius/float(num_rows-1),0.0f);
297
298        osg::Vec3 top = center+osg::Vec3(-radius,radius,0.0f);
299        osg::Vec3 bottom = center+osg::Vec3(-radius,-radius,0.0f);
300        osg::Vec3 delta_column = osg::Vec3(2.0f*radius/float(num_rows-1),0.0f,0.0f);
301
302        osg::Vec3Array* vertices = new osg::Vec3Array;
303        for(unsigned int i=0; i<num_rows; ++i)
304        {
305            vertices->push_back(left);
306            vertices->push_back(right);
307            left += delta_row;
308            right += delta_row;
309
310            vertices->push_back(top);
311            vertices->push_back(bottom);
312            top += delta_column;
313            bottom += delta_column;
314        }
315       
316        geom->setVertexArray(vertices);
317
318        osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
319        color[0].set(0,0,0,255);
320        geom->setColorArray(&color);
321        geom->setColorBinding(osg::Geometry::BIND_OVERALL);
322
323        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,vertices->getNumElements()));
324
325        geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
326
327        osg::Geode* geode = new osg::Geode;
328        geode->addDrawable(geom);
329        group->addChild(geode);       
330    }
331   
332    return group;
333}
334
335osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y)
336{
337    const osg::BoundingSphere& bs = subgraph->getBound();
338    float zMax = bs.center().z()+bs.radius();
339    float zMin = bs.center().z()-bs.radius();
340   
341    osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector =
342        new osgUtil::LineSegmentIntersector(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax));
343
344    osgUtil::IntersectionVisitor iv(intersector.get());
345
346    subgraph->accept(iv);
347
348    if (intersector->containsIntersections())
349    {
350        return intersector->getFirstIntersection().getWorldIntersectPoint();
351    }
352
353    return osg::Vec3(x,y,0.0f);
354}
355
356
357//////////////////////////////////////////////////////////////////////////////
358// MAIN SCENE GRAPH BUILDING FUNCTION
359//////////////////////////////////////////////////////////////////////////////
360
361void build_world(osg::Group *root, unsigned int testCase, bool useOverlay, osgSim::OverlayNode::OverlayTechnique technique)
362{
363
364    // create terrain
365    osg::ref_ptr<osg::Geode> terrainGeode = 0;
366    {
367        terrainGeode = new osg::Geode;
368
369        osg::StateSet* stateset = new osg::StateSet();
370        osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
371        if (image)
372        {
373            osg::Texture2D* texture = new osg::Texture2D;
374            texture->setImage(image);
375            stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
376        }
377
378        terrainGeode->setStateSet( stateset );
379
380       
381        {
382            unsigned int numColumns = 38;
383            unsigned int numRows = 39;
384            unsigned int r, c;
385           
386            osg::Vec3 origin(0.0f,0.0f,0.0f);
387            osg::Vec3 size(1000.0f,1000.0f,250.0f);
388
389            osg::Geometry* geometry = new osg::Geometry;
390
391            osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows));
392            osg::Vec2Array& tc = *(new osg::Vec2Array(numColumns*numRows));
393            osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
394
395            color[0].set(255,255,255,255);
396
397            float rowCoordDelta = size.y()/(float)(numRows-1);
398            float columnCoordDelta = size.x()/(float)(numColumns-1);
399
400            float rowTexDelta = 1.0f/(float)(numRows-1);
401            float columnTexDelta = 1.0f/(float)(numColumns-1);
402
403            // compute z range of z values of grid data so we can scale it.
404            float min_z = FLT_MAX;
405            float max_z = -FLT_MAX;
406            for(r=0;r<numRows;++r)
407            {
408                for(c=0;c<numColumns;++c)
409                {
410                    min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
411                    max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
412                }
413            }
414
415            float scale_z = size.z()/(max_z-min_z);
416
417            osg::Vec3 pos = origin;
418            osg::Vec2 tex(0.0f,0.0f);
419            int vi=0;
420            for(r=0;r<numRows;++r)
421            {
422                pos.x() = origin.x();
423                tex.x() = 0.0f;
424                for(c=0;c<numColumns;++c)
425                {
426                    v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
427                    tc[vi] = tex;
428                    pos.x()+=columnCoordDelta;
429                    tex.x()+=columnTexDelta;
430                    ++vi;
431                }
432                pos.y() += rowCoordDelta;
433                tex.y() += rowTexDelta;
434            }
435
436            geometry->setVertexArray(&v);
437            geometry->setTexCoordArray(0, &tc);
438            geometry->setColorArray(&color);
439            geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
440
441            for(r=0;r<numRows-1;++r)
442            {
443                osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
444                geometry->addPrimitiveSet(&drawElements);
445                int ei=0;
446                for(c=0;c<numColumns;++c)
447                {
448                    drawElements[ei++] = (r+1)*numColumns+c;
449                    drawElements[ei++] = (r)*numColumns+c;
450                }
451            }
452           
453            osgUtil::SmoothingVisitor smoother;
454            smoother.smooth(*geometry);
455           
456            terrainGeode->addDrawable(geometry);
457        }
458       
459    }   
460
461
462    // create sphere segment
463    osg::ref_ptr<osgSim::SphereSegment> ss = 0;
464    {
465
466        osg::Matrix terrainToSS;
467
468        switch(testCase)
469        {
470            case(0):       
471                ss = new osgSim::SphereSegment(
472                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
473                                510.0f, // radius
474                                osg::DegreesToRadians(135.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(1):       
482                ss = new osgSim::SphereSegment(
483                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
484                                510.0f, // radius
485                                osg::DegreesToRadians(45.0f),
486                                osg::DegreesToRadians(240.0f),
487                                osg::DegreesToRadians(-10.0f),
488                                osg::DegreesToRadians(30.0f),
489                                60);
490                root->addChild(ss.get());
491                break;
492            case(2):       
493                ss = new osgSim::SphereSegment(
494                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
495                                510.0f, // radius
496                                osg::DegreesToRadians(5.0f),
497                                osg::DegreesToRadians(355.0f),
498                                osg::DegreesToRadians(-10.0f),
499                                osg::DegreesToRadians(30.0f),
500                                60);
501                root->addChild(ss.get());
502                break;
503            case(3):       
504                ss = new osgSim::SphereSegment(
505                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
506                                510.0f, // radius
507                                osg::DegreesToRadians(0.0f),
508                                osg::DegreesToRadians(360.0f),
509                                osg::DegreesToRadians(-10.0f),
510                                osg::DegreesToRadians(30.0f),
511                                60);
512                root->addChild(ss.get());
513                break;
514            case(4):       
515            {
516                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
517                                700.0f, // radius
518                                osg::DegreesToRadians(135.0f),
519                                osg::DegreesToRadians(240.0f),
520                                osg::DegreesToRadians(-60.0f),
521                                osg::DegreesToRadians(-40.0f),
522                                60);
523                 
524                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
525               
526                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
527                                          -0.180627, -0.983552, -6.93889e-18, 0,
528                                          -0.491776, 0.0903136, 0.866025, 0,
529                                          598.217, 481.957, 100, 1));
530                mt->addChild(ss.get());
531               
532                terrainToSS.invert(mt->getMatrix());
533                                               
534                root->addChild(mt.get());
535                break;
536            }
537            case(5):       
538            {
539                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
540                                700.0f, // radius
541                                osg::DegreesToRadians(35.0f),
542                                osg::DegreesToRadians(135.0f),
543                                osg::DegreesToRadians(-60.0f),
544                                osg::DegreesToRadians(-40.0f),
545                                60);
546                 
547                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
548               
549                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
550                                          -0.180627, -0.983552, -6.93889e-18, 0,
551                                          -0.491776, 0.0903136, 0.866025, 0,
552                                          598.217, 481.957, 100, 1));
553                mt->addChild(ss.get());
554               
555                terrainToSS.invert(mt->getMatrix());
556                                               
557                root->addChild(mt.get());
558                break;
559            }
560            case(6):       
561            {
562                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
563                                700.0f, // radius
564                                osg::DegreesToRadians(-45.0f),
565                                osg::DegreesToRadians(45.0f),
566                                osg::DegreesToRadians(-60.0f),
567                                osg::DegreesToRadians(-40.0f),
568                                60);
569                 
570                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;             
571               
572                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
573                                          -0.180627, -0.983552, -6.93889e-18, 0,
574                                          -0.491776, 0.0903136, 0.866025, 0,
575                                          598.217, 481.957, 100, 1));
576                mt->addChild(ss.get());
577               
578                terrainToSS.invert(mt->getMatrix());
579                                               
580                root->addChild(mt.get());
581                break;
582            }
583            case(7):       
584            {
585                ss = new osgSim::SphereSegment(
586                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
587                                510.0f, // radius
588                                osg::DegreesToRadians(-240.0f),
589                                osg::DegreesToRadians(-135.0f),
590                                osg::DegreesToRadians(-10.0f),
591                                osg::DegreesToRadians(30.0f),
592                                60);
593                ss->setUpdateCallback(new RotateUpdateCallback());
594                root->addChild(ss.get());
595                break;
596            }
597        };
598       
599        if (ss.valid())
600        {
601            ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
602            ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f));
603
604            if (!ss->getParents().empty())
605            {
606                ss->getParent(0)->addChild(ss->computeIntersectionSubgraph(terrainToSS, terrainGeode.get()));
607            }
608       
609        }
610    }
611   
612
613    if (useOverlay)
614    {
615        osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode(technique);
616        overlayNode->getOrCreateStateSet()->setTextureAttribute(1, new osg::TexEnv(osg::TexEnv::DECAL));
617
618        const osg::BoundingSphere& bs = terrainGeode->getBound();
619        osg::Group* overlaySubgraph = createOverlay(bs.center(), bs.radius()*0.5f);
620        overlaySubgraph->addChild(ss.get());
621        overlayNode->setOverlaySubgraph(overlaySubgraph);
622        overlayNode->setOverlayTextureSizeHint(1024);
623        overlayNode->setOverlayBaseHeight(0.0);
624        overlayNode->addChild(terrainGeode.get());
625
626        root->addChild(overlayNode);
627    }
628    else
629    {
630      root->addChild(terrainGeode.get());
631    }
632   
633    // create particle effects
634    {   
635        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),100.0f,100.0f);
636
637        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f);
638        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f);
639        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 10.0f);
640
641        root->addChild(explosion);
642        root->addChild(smoke);
643        root->addChild(fire);
644    }
645   
646    // create particle effects
647    {   
648        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),200.0f,100.0f);
649
650        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f);
651        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f);
652        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 1.0f);
653
654        root->addChild(explosion);
655        root->addChild(smoke);
656        root->addChild(fire);
657    }
658   
659   
660    bool createMovingRadar = true;
661   
662    // create the moving models.
663    {
664        root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f, terrainGeode.get(), root, createMovingRadar));
665    }
666}
667
668
669//////////////////////////////////////////////////////////////////////////////
670// main()
671//////////////////////////////////////////////////////////////////////////////
672
673
674int main(int argc, char **argv)
675{
676    // use an ArgumentParser object to manage the program arguments.
677    osg::ArgumentParser arguments(&argc,argv);
678   
679    // set up the usage document, in case we need to print out how to use this program.
680    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of particle systems.");
681    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
682    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
683   
684
685    // construct the viewer.
686    osgViewer::Viewer viewer(arguments);
687
688    // if user request help write it out to cout.
689    unsigned int testCase = 0;
690    while (arguments.read("-t", testCase)) {}
691
692    bool useOverlay = false;
693    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
694    while (arguments.read("--object")) { useOverlay = true; technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; }
695    while (arguments.read("--ortho") || arguments.read("--orthographic")) { useOverlay = true; technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; }
696    while (arguments.read("--persp") || arguments.read("--perspective")) { useOverlay = true; technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY; }
697   
698
699    // if user request help write it out to cout.
700    if (arguments.read("-h") || arguments.read("--help"))
701    {
702        arguments.getApplicationUsage()->write(std::cout);
703        return 1;
704    }
705
706    // any option left unread are converted into errors to write out later.
707    arguments.reportRemainingOptionsAsUnrecognized();
708
709    // report any errors if they have occurred when parsing the program arguments.
710    if (arguments.errors())
711    {
712        arguments.writeErrorMessages(std::cout);
713        return 1;
714    }
715   
716    osg::Group *root = new osg::Group;
717    build_world(root, testCase, useOverlay, technique);
718   
719    // add a viewport to the viewer and attach the scene graph.
720    viewer.setSceneData(root);
721       
722    return viewer.run();
723}
Note: See TracBrowser for help on using the browser.