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

Revision 13574, 26.9 kB (checked in by robert, 9 days ago)

Added shaders to support experimental shader based displacement mapping technique osgTerrain::ShaderTerrain?.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[6941]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
[5959]19#include <osgViewer/Viewer>
[3934]20
21#include <osg/Group>
[2213]22#include <osg/Geode>
23#include <osg/ShapeDrawable>
24#include <osg/Texture2D>
[3934]25#include <osg/PositionAttitudeTransform>
[2213]26#include <osg/MatrixTransform>
[4508]27#include <osg/Geometry>
[2213]28
[4512]29#include <osgUtil/SmoothingVisitor>
30
[3934]31#include <osgDB/ReadFile>
[2213]32
33#include <osgText/Text>
34
35#include <osgSim/SphereSegment>
[4506]36#include <osgSim/OverlayNode>
[2213]37
[3934]38#include <osgParticle/ExplosionEffect>
39#include <osgParticle/SmokeEffect>
40#include <osgParticle/FireEffect>
41#include <osgParticle/ParticleSystemUpdater>
[2213]42
[5157]43#include <osg/io_utils>
44
[5959]45#include <iostream>
46
[3934]47// for the grid data..
48#include "../osghangglide/terrain_coords.h"
49
50osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
[2213]51{
[13574]52    // set up the animation path
[3934]53    osg::AnimationPath* animationPath = new osg::AnimationPath;
54    animationPath->setLoopMode(osg::AnimationPath::LOOP);
[13574]55
[3934]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);
[13574]60
[3934]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)));
[13574]67
[3934]68        animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
[2213]69
[3934]70        yaw += yaw_delta;
71        time += time_delta;
[2213]72
[3934]73    }
[13574]74    return animationPath;
[3934]75}
76
[5049]77
78
79class IntersectionUpdateCallback : public osg::NodeCallback
[2213]80{
[5049]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            }
[13574]88
[5049]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                }
[13574]104
[5049]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());
[13574]107
[5049]108                // now we can compute the terrain to ss transform
109                osg::Matrixd possie = terrainLocalToWorld*ssWorldToLocal;
[13574]110
[5049]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);
[13574]121
[5157]122                        // std::cout<<"matrix = "<<mt->getMatrix()<<std::endl;
[5049]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
[13574]147
[5049]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
[11605]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);
[13574]169
[11605]170                i += 0.1f;
171            }
[5049]172
[11605]173        }
174protected:
175    float i;
176};
177
[5157]178osg::Node* createMovingModel(const osg::Vec3& center, float radius, osg::Geode * terrainGeode, osg::Group * root, bool createMovingRadar = false)
[5049]179{
[3934]180    float animationLength = 10.0f;
181
182    osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);
183
184    osg::Group* model = new osg::Group;
185
[12529]186    osg::Node* glider = osgDB::readNodeFile("glider.osgt");
[3934]187    if (glider)
[2740]188    {
[3934]189        const osg::BoundingSphere& bs = glider->getBound();
[2213]190
[3934]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));
[13574]197
[3934]198        positioned->addChild(glider);
[13574]199
200        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;
[3934]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    }
[13574]206
[5157]207    if (createMovingRadar)
[5049]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);
[13574]214
215        osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;
[5049]216        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));
[13574]217
[5049]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),
[5157]222                                osg::DegreesToRadians(-60.0f),
223                                osg::DegreesToRadians(-40.0f),
[5049]224                                60);
[13574]225
[5049]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    }
[13574]238
[12529]239    osg::Node* cessna = osgDB::readNodeFile("cessna.osgt");
[3934]240    if (cessna)
241    {
242        const osg::BoundingSphere& bs = cessna->getBound();
[2213]243
[3934]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);
[4588]252        text->setCharacterSizeMode(osgText::Text::OBJECT_COORDS);
[13574]253
[3934]254        osg::Geode* geode = new osg::Geode;
255        geode->addDrawable(text);
[13574]256
[3934]257        osg::LOD* lod = new osg::LOD;
258        lod->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN);
[5195]259        lod->setRadius(cessna->getBound().radius());
[3934]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));
[13574]270
[3934]271        //positioned->addChild(cessna);
272        positioned->addChild(lod);
[13574]273
[3934]274        osg::MatrixTransform* xform = new osg::MatrixTransform;
275        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
276        xform->addChild(positioned);
[13574]277
[3934]278        model->addChild(xform);
[2740]279    }
[13574]280
[3934]281    return model;
[2213]282}
283
[4508]284osg::Group* createOverlay(const osg::Vec3& center, float radius)
285{
286    osg::Group* group = new osg::Group;
[13574]287
[4508]288    // create a grid of lines.
289    {
290        osg::Geometry* geom = new osg::Geometry;
[13574]291
[4508]292        unsigned int num_rows = 10;
[3934]293
[4508]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        }
[13574]315
[4508]316        geom->setVertexArray(vertices);
[4539]317
318        osg::Vec4ubArray& color = *(new osg::Vec4ubArray(1));
319        color[0].set(0,0,0,255);
[13574]320        geom->setColorArray(&color, osg::Array::BIND_OVERALL);
[4539]321
[13574]322        geom->addPrimitiveSet(new osg::DrawArrays(GL_LINES,0,vertices->getNumElements()));
[4508]323
[4539]324        geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
325
[4508]326        osg::Geode* geode = new osg::Geode;
327        geode->addDrawable(geom);
[13574]328        group->addChild(geode);
[4508]329    }
[13574]330
[4508]331    return group;
332}
333
[3934]334osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y)
[2213]335{
[3934]336    const osg::BoundingSphere& bs = subgraph->getBound();
337    float zMax = bs.center().z()+bs.radius();
338    float zMin = bs.center().z()-bs.radius();
[13574]339
340    osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector =
[8998]341        new osgUtil::LineSegmentIntersector(osg::Vec3(x,y,zMin),osg::Vec3(x,y,zMax));
[2213]342
[8998]343    osgUtil::IntersectionVisitor iv(intersector.get());
344
[3934]345    subgraph->accept(iv);
346
[8998]347    if (intersector->containsIntersections())
[3934]348    {
[8998]349        return intersector->getFirstIntersection().getWorldIntersectPoint();
[3934]350    }
351
352    return osg::Vec3(x,y,0.0f);
[2213]353}
354
[3934]355
356//////////////////////////////////////////////////////////////////////////////
357// MAIN SCENE GRAPH BUILDING FUNCTION
358//////////////////////////////////////////////////////////////////////////////
359
[6779]360void build_world(osg::Group *root, unsigned int testCase, bool useOverlay, osgSim::OverlayNode::OverlayTechnique technique)
[2213]361{
[3934]362
363    // create terrain
[4506]364    osg::ref_ptr<osg::Geode> terrainGeode = 0;
[3934]365    {
[4506]366        terrainGeode = new osg::Geode;
367
[3934]368        osg::StateSet* stateset = new osg::StateSet();
369        osg::Image* image = osgDB::readImageFile("Images/lz.rgb");
370        if (image)
371        {
[4805]372            osg::Texture2D* texture = new osg::Texture2D;
373            texture->setImage(image);
374            stateset->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
[3934]375        }
376
377        terrainGeode->setStateSet( stateset );
378
[13574]379
[4512]380        {
381            unsigned int numColumns = 38;
382            unsigned int numRows = 39;
383            unsigned int r, c;
[13574]384
[4512]385            osg::Vec3 origin(0.0f,0.0f,0.0f);
386            osg::Vec3 size(1000.0f,1000.0f,250.0f);
[3934]387
[4512]388            osg::Geometry* geometry = new osg::Geometry;
[3934]389
[4512]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            {
[4805]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                }
[4512]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;
[4805]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;
[4512]427                    pos.x()+=columnCoordDelta;
428                    tex.x()+=columnTexDelta;
429                    ++vi;
[4805]430                }
[4512]431                pos.y() += rowCoordDelta;
432                tex.y() += rowTexDelta;
433            }
434
435            geometry->setVertexArray(&v);
436            geometry->setTexCoordArray(0, &tc);
[13574]437            geometry->setColorArray(&color, osg::Array::BIND_OVERALL);
[4512]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;
[4805]444                for(c=0;c<numColumns;++c)
445                {
446                    drawElements[ei++] = (r+1)*numColumns+c;
447                    drawElements[ei++] = (r)*numColumns+c;
448                }
[4512]449            }
[13574]450
[4512]451            osgUtil::SmoothingVisitor smoother;
452            smoother.smooth(*geometry);
[13574]453
[4512]454            terrainGeode->addDrawable(geometry);
[3934]455        }
456
[13574]457    }
[4506]458
[13574]459
[3934]460    // create sphere segment
[4506]461    osg::ref_ptr<osgSim::SphereSegment> ss = 0;
[3934]462    {
[4563]463
[5157]464        osg::Matrix terrainToSS;
465
[4563]466        switch(testCase)
467        {
[13574]468            case(0):
[4563]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);
[5157]477                root->addChild(ss.get());
[4563]478                break;
[13574]479            case(1):
[4563]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);
[5157]488                root->addChild(ss.get());
[4563]489                break;
[13574]490            case(2):
[4563]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);
[5157]499                root->addChild(ss.get());
[4563]500                break;
[13574]501            case(3):
[4563]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);
[5157]510                root->addChild(ss.get());
[4563]511                break;
[13574]512            case(4):
[5157]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);
[13574]521
522                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
523
[5157]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());
[13574]529
[5157]530                terrainToSS.invert(mt->getMatrix());
[13574]531
[5157]532                root->addChild(mt.get());
533                break;
534            }
[13574]535            case(5):
[5157]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);
[13574]544
545                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
546
[5157]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());
[13574]552
[5157]553                terrainToSS.invert(mt->getMatrix());
[13574]554
[5157]555                root->addChild(mt.get());
556                break;
557            }
[13574]558            case(6):
[5157]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);
[13574]567
568                osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
569
[5157]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());
[13574]575
[5157]576                terrainToSS.invert(mt->getMatrix());
[13574]577
[5157]578                root->addChild(mt.get());
579                break;
580            }
[13574]581            case(7):
[11605]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            }
[4563]595        };
[13574]596
[5157]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));
[4525]601
[5157]602            if (!ss->getParents().empty())
603            {
604                ss->getParent(0)->addChild(ss->computeIntersectionSubgraph(terrainToSS, terrainGeode.get()));
605            }
[13574]606
[4525]607        }
[4510]608    }
[4508]609
[13574]610
[6779]611    if (useOverlay)
612    {
613        osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode(technique);
614        overlayNode->getOrCreateStateSet()->setTextureAttribute(1, new osg::TexEnv(osg::TexEnv::DECAL));
[4506]615
[6779]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    }
[13574]630
[3934]631    // create particle effects
[13574]632    {
[4506]633        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),100.0f,100.0f);
[3934]634
[3941]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);
[3934]638
[3941]639        root->addChild(explosion);
640        root->addChild(smoke);
641        root->addChild(fire);
642    }
[13574]643
[3941]644    // create particle effects
[13574]645    {
[4506]646        osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),200.0f,100.0f);
[3934]647
[3941]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);
[3934]655    }
[13574]656
657
[5157]658    bool createMovingRadar = true;
[13574]659
[3934]660    // create the moving models.
661    {
[5157]662        root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f, terrainGeode.get(), root, createMovingRadar));
[3934]663    }
664}
665
666
667//////////////////////////////////////////////////////////////////////////////
668// main()
669//////////////////////////////////////////////////////////////////////////////
670
671
672int main(int argc, char **argv)
673{
[2213]674    // use an ArgumentParser object to manage the program arguments.
675    osg::ArgumentParser arguments(&argc,argv);
[13574]676
[2213]677    // set up the usage document, in case we need to print out how to use this program.
[3934]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");
[2213]680    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
681
[13574]682
[2213]683    // construct the viewer.
[7019]684    osgViewer::Viewer viewer(arguments);
[2213]685
686    // if user request help write it out to cout.
[4563]687    unsigned int testCase = 0;
[6779]688    while (arguments.read("-t", testCase)) {}
[4563]689
[6779]690    bool useOverlay = false;
[6767]691    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
[6779]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; }
[4563]695
[13574]696
[4563]697    // if user request help write it out to cout.
[2213]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
[7648]707    // report any errors if they have occurred when parsing the program arguments.
[2213]708    if (arguments.errors())
709    {
710        arguments.writeErrorMessages(std::cout);
711        return 1;
712    }
[13574]713
[3934]714    osg::Group *root = new osg::Group;
[6779]715    build_world(root, testCase, useOverlay, technique);
[13574]716
[3934]717    // add a viewport to the viewer and attach the scene graph.
718    viewer.setSceneData(root);
[13574]719
[5959]720    return viewer.run();
[2213]721}
Note: See TracBrowser for help on using the browser.