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

Revision 13574, 26.9 kB (checked in by robert, 14 hours ago)

From Jason Beverage, "It looks like the Callback header got accidentally removed from the CMakeLists.txt in the submission yesterday for the geometry instancing example."

  • 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, osg::Array::BIND_OVERALL);
321
322        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,vertices->getNumElements()));
323
324        geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
325
326        osg::Geode* geode = new osg::Geode;
327        geode->addDrawable(geom);
328        group->addChild(geode);
329    }
330
331    return group;
332}
333
334osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y)
335{
336    const osg::BoundingSphere& bs = subgraph->getBound();
337    float zMax = bs.center().z()+bs.radius();
338    float zMin = bs.center().z()-bs.radius();
339
340    osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector =
341        new osgUtil::LineSegmentIntersector(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax));
342
343    osgUtil::IntersectionVisitor iv(intersector.get());
344
345    subgraph->accept(iv);
346
347    if (intersector->containsIntersections())
348    {
349        return intersector->getFirstIntersection().getWorldIntersectPoint();
350    }
351
352    return osg::Vec3(x,y,0.0f);
353}
354
355
356//////////////////////////////////////////////////////////////////////////////
357// MAIN SCENE GRAPH BUILDING FUNCTION
358//////////////////////////////////////////////////////////////////////////////
359
360void build_world(osg::Group *root, unsigned int testCase, bool useOverlay, osgSim::OverlayNode::OverlayTechnique technique)
361{
362
363    // create terrain
364    osg::ref_ptr<osg::Geode> terrainGeode = 0;
365    {
366        terrainGeode = new osg::Geode;
367
368        osg::StateSet* stateset = new osg::StateSet();
369        osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
370        if (image)
371        {
372            osg::Texture2D* texture = new osg::Texture2D;
373            texture->setImage(image);
374            stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
375        }
376
377        terrainGeode->setStateSet( stateset );
378
379
380        {
381            unsigned int numColumns = 38;
382            unsigned int numRows = 39;
383            unsigned int r, c;
384
385            osg::Vec3 origin(0.0f,0.0f,0.0f);
386            osg::Vec3 size(1000.0f,1000.0f,250.0f);
387
388            osg::Geometry* geometry = new osg::Geometry;
389
390            osg::Vec3Array& v = *(new osg::Vec3Array(numColumns*numRows));
391            osg::Vec2Array& tc = *(new osg::Vec2Array(numColumns*numRows));
392            osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
393
394            color[0].set(255,255,255,255);
395
396            float rowCoordDelta = size.y()/(float)(numRows-1);
397            float columnCoordDelta = size.x()/(float)(numColumns-1);
398
399            float rowTexDelta = 1.0f/(float)(numRows-1);
400            float columnTexDelta = 1.0f/(float)(numColumns-1);
401
402            // compute z range of z values of grid data so we can scale it.
403            float min_z = FLT_MAX;
404            float max_z = -FLT_MAX;
405            for(r=0;r<numRows;++r)
406            {
407                for(c=0;c<numColumns;++c)
408                {
409                    min_z = osg::minimum(min_z,vertex[r+c*numRows][2]);
410                    max_z = osg::maximum(max_z,vertex[r+c*numRows][2]);
411                }
412            }
413
414            float scale_z = size.z()/(max_z-min_z);
415
416            osg::Vec3 pos = origin;
417            osg::Vec2 tex(0.0f,0.0f);
418            int vi=0;
419            for(r=0;r<numRows;++r)
420            {
421                pos.x() = origin.x();
422                tex.x() = 0.0f;
423                for(c=0;c<numColumns;++c)
424                {
425                    v[vi].set(pos.x(),pos.y(),pos.z()+(vertex[r+c*numRows][2]-min_z)*scale_z);
426                    tc[vi] = tex;
427                    pos.x()+=columnCoordDelta;
428                    tex.x()+=columnTexDelta;
429                    ++vi;
430                }
431                pos.y() += rowCoordDelta;
432                tex.y() += rowTexDelta;
433            }
434
435            geometry->setVertexArray(&v);
436            geometry->setTexCoordArray(0, &tc);
437            geometry->setColorArray(&color, osg::Array::BIND_OVERALL);
438
439            for(r=0;r<numRows-1;++r)
440            {
441                osg::DrawElementsUShort& drawElements = *(new osg::DrawElementsUShort(GL_QUAD_STRIP,2*numColumns));
442                geometry->addPrimitiveSet(&drawElements);
443                int ei=0;
444                for(c=0;c<numColumns;++c)
445                {
446                    drawElements[ei++] = (r+1)*numColumns+c;
447                    drawElements[ei++] = (r)*numColumns+c;
448                }
449            }
450
451            osgUtil::SmoothingVisitor smoother;
452            smoother.smooth(*geometry);
453
454            terrainGeode->addDrawable(geometry);
455        }
456
457    }
458
459
460    // create sphere segment
461    osg::ref_ptr<osgSim::SphereSegment> ss = 0;
462    {
463
464        osg::Matrix terrainToSS;
465
466        switch(testCase)
467        {
468            case(0):
469                ss = new osgSim::SphereSegment(
470                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
471                                510.0f, // radius
472                                osg::DegreesToRadians(135.0f),
473                                osg::DegreesToRadians(240.0f),
474                                osg::DegreesToRadians(-10.0f),
475                                osg::DegreesToRadians(30.0f),
476                                60);
477                root->addChild(ss.get());
478                break;
479            case(1):
480                ss = new osgSim::SphereSegment(
481                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
482                                510.0f, // radius
483                                osg::DegreesToRadians(45.0f),
484                                osg::DegreesToRadians(240.0f),
485                                osg::DegreesToRadians(-10.0f),
486                                osg::DegreesToRadians(30.0f),
487                                60);
488                root->addChild(ss.get());
489                break;
490            case(2):
491                ss = new osgSim::SphereSegment(
492                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
493                                510.0f, // radius
494                                osg::DegreesToRadians(5.0f),
495                                osg::DegreesToRadians(355.0f),
496                                osg::DegreesToRadians(-10.0f),
497                                osg::DegreesToRadians(30.0f),
498                                60);
499                root->addChild(ss.get());
500                break;
501            case(3):
502                ss = new osgSim::SphereSegment(
503                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
504                                510.0f, // radius
505                                osg::DegreesToRadians(0.0f),
506                                osg::DegreesToRadians(360.0f),
507                                osg::DegreesToRadians(-10.0f),
508                                osg::DegreesToRadians(30.0f),
509                                60);
510                root->addChild(ss.get());
511                break;
512            case(4):
513            {
514                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
515                                700.0f, // radius
516                                osg::DegreesToRadians(135.0f),
517                                osg::DegreesToRadians(240.0f),
518                                osg::DegreesToRadians(-60.0f),
519                                osg::DegreesToRadians(-40.0f),
520                                60);
521
522                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
523
524                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
525                                          -0.180627, -0.983552, -6.93889e-18, 0,
526                                          -0.491776, 0.0903136, 0.866025, 0,
527                                          598.217, 481.957, 100, 1));
528                mt->addChild(ss.get());
529
530                terrainToSS.invert(mt->getMatrix());
531
532                root->addChild(mt.get());
533                break;
534            }
535            case(5):
536            {
537                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
538                                700.0f, // radius
539                                osg::DegreesToRadians(35.0f),
540                                osg::DegreesToRadians(135.0f),
541                                osg::DegreesToRadians(-60.0f),
542                                osg::DegreesToRadians(-40.0f),
543                                60);
544
545                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
546
547                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
548                                          -0.180627, -0.983552, -6.93889e-18, 0,
549                                          -0.491776, 0.0903136, 0.866025, 0,
550                                          598.217, 481.957, 100, 1));
551                mt->addChild(ss.get());
552
553                terrainToSS.invert(mt->getMatrix());
554
555                root->addChild(mt.get());
556                break;
557            }
558            case(6):
559            {
560                ss = new osgSim::SphereSegment(osg::Vec3d(0.0,0.0,0.0),
561                                700.0f, // radius
562                                osg::DegreesToRadians(-45.0f),
563                                osg::DegreesToRadians(45.0f),
564                                osg::DegreesToRadians(-60.0f),
565                                osg::DegreesToRadians(-40.0f),
566                                60);
567
568                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
569
570                mt->setMatrix(osg::Matrix(-0.851781, 0.156428, -0.5, 0,
571                                          -0.180627, -0.983552, -6.93889e-18, 0,
572                                          -0.491776, 0.0903136, 0.866025, 0,
573                                          598.217, 481.957, 100, 1));
574                mt->addChild(ss.get());
575
576                terrainToSS.invert(mt->getMatrix());
577
578                root->addChild(mt.get());
579                break;
580            }
581            case(7):
582            {
583                ss = new osgSim::SphereSegment(
584                                computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center
585                                510.0f, // radius
586                                osg::DegreesToRadians(-240.0f),
587                                osg::DegreesToRadians(-135.0f),
588                                osg::DegreesToRadians(-10.0f),
589                                osg::DegreesToRadians(30.0f),
590                                60);
591                ss->setUpdateCallback(new RotateUpdateCallback());
592                root->addChild(ss.get());
593                break;
594            }
595        };
596
597        if (ss.valid())
598        {
599            ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f));
600            ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f));
601
602            if (!ss->getParents().empty())
603            {
604                ss->getParent(0)->addChild(ss->computeIntersectionSubgraph(terrainToSS, terrainGeode.get()));
605            }
606
607        }
608    }
609
610
611    if (useOverlay)
612    {
613        osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode(technique);
614        overlayNode->getOrCreateStateSet()->setTextureAttribute(1, new osg::TexEnv(osg::TexEnv::DECAL));
615
616        const osg::BoundingSphere& bs = terrainGeode->getBound();
617        osg::Group* overlaySubgraph = createOverlay(bs.center(), bs.radius()*0.5f);
618        overlaySubgraph->addChild(ss.get());
619        overlayNode->setOverlaySubgraph(overlaySubgraph);
620        overlayNode->setOverlayTextureSizeHint(1024);
621        overlayNode->setOverlayBaseHeight(0.0);
622        overlayNode->addChild(terrainGeode.get());
623
624        root->addChild(overlayNode);
625    }
626    else
627    {
628      root->addChild(terrainGeode.get());
629    }
630
631    // create particle effects
632    {
633        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),100.0f,100.0f);
634
635        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f);
636        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f);
637        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 10.0f);
638
639        root->addChild(explosion);
640        root->addChild(smoke);
641        root->addChild(fire);
642    }
643
644    // create particle effects
645    {
646        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),200.0f,100.0f);
647
648        osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f);
649        osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f);
650        osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, 1.0f);
651
652        root->addChild(explosion);
653        root->addChild(smoke);
654        root->addChild(fire);
655    }
656
657
658    bool createMovingRadar = true;
659
660    // create the moving models.
661    {
662        root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f, terrainGeode.get(), root, createMovingRadar));
663    }
664}
665
666
667//////////////////////////////////////////////////////////////////////////////
668// main()
669//////////////////////////////////////////////////////////////////////////////
670
671
672int main(int argc, char **argv)
673{
674    // use an ArgumentParser object to manage the program arguments.
675    osg::ArgumentParser arguments(&argc,argv);
676
677    // set up the usage document, in case we need to print out how to use this program.
678    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of particle systems.");
679    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
680    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
681
682
683    // construct the viewer.
684    osgViewer::Viewer viewer(arguments);
685
686    // if user request help write it out to cout.
687    unsigned int testCase = 0;
688    while (arguments.read("-t", testCase)) {}
689
690    bool useOverlay = false;
691    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
692    while (arguments.read("--object")) { useOverlay = true; technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; }
693    while (arguments.read("--ortho") || arguments.read("--orthographic")) { useOverlay = true; technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY; }
694    while (arguments.read("--persp") || arguments.read("--perspective")) { useOverlay = true; technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY; }
695
696
697    // if user request help write it out to cout.
698    if (arguments.read("-h") || arguments.read("--help"))
699    {
700        arguments.getApplicationUsage()->write(std::cout);
701        return 1;
702    }
703
704    // any option left unread are converted into errors to write out later.
705    arguments.reportRemainingOptionsAsUnrecognized();
706
707    // report any errors if they have occurred when parsing the program arguments.
708    if (arguments.errors())
709    {
710        arguments.writeErrorMessages(std::cout);
711        return 1;
712    }
713
714    osg::Group *root = new osg::Group;
715    build_world(root, testCase, useOverlay, technique);
716
717    // add a viewport to the viewer and attach the scene graph.
718    viewer.setSceneData(root);
719
720    return viewer.run();
721}
Note: See TracBrowser for help on using the browser.