root/OpenSceneGraph/trunk/examples/osgterrain/osgterrain.cpp @ 13861

Revision 12292, 8.0 kB (checked in by robert, 4 years ago)

Ran svn propset -R svn:eol-style native . on the OpenSceneGraph

  • Property svn:eol-style set to native
Line 
1/* OpenSceneGraph example, osgterrain.
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 <osg/ArgumentParser>
20#include <osgDB/ReadFile>
21
22#include <osgViewer/Viewer>
23#include <osgViewer/ViewerEventHandlers>
24
25#include <osgGA/TrackballManipulator>
26#include <osgGA/FlightManipulator>
27#include <osgGA/DriveManipulator>
28#include <osgGA/KeySwitchMatrixManipulator>
29#include <osgGA/StateSetManipulator>
30#include <osgGA/AnimationPathManipulator>
31#include <osgGA/TerrainManipulator>
32
33#include <osgTerrain/Terrain>
34#include <osgTerrain/TerrainTile>
35#include <osgTerrain/GeometryTechnique>
36#include <osgTerrain/Layer>
37
38#include <iostream>
39
40template<class T>
41class FindTopMostNodeOfTypeVisitor : public osg::NodeVisitor
42{
43public:
44    FindTopMostNodeOfTypeVisitor():
45        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
46        _foundNode(0)
47    {}
48
49    void apply(osg::Node& node)
50    {
51        T* result = dynamic_cast<T*>(&node);
52        if (result)
53        {
54            _foundNode = result;
55        }
56        else
57        {
58            traverse(node);
59        }
60    }
61
62    T* _foundNode;
63};
64
65template<class T>
66T* findTopMostNodeOfType(osg::Node* node)
67{
68    if (!node) return 0;
69
70    FindTopMostNodeOfTypeVisitor<T> fnotv;
71    node->accept(fnotv);
72
73    return fnotv._foundNode;
74}
75
76// class to handle events with a pick
77class TerrainHandler : public osgGA::GUIEventHandler {
78public:
79
80    TerrainHandler(osgTerrain::Terrain* terrain):
81        _terrain(terrain) {}
82
83    bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
84    {
85        switch(ea.getEventType())
86        {
87            case(osgGA::GUIEventAdapter::KEYDOWN):
88            {
89                if (ea.getKey()=='r')
90                {
91                    _terrain->setSampleRatio(_terrain->getSampleRatio()*0.5);
92                    osg::notify(osg::NOTICE)<<"Sample ratio "<<_terrain->getSampleRatio()<<std::endl;
93                    return true;
94                }
95                else if (ea.getKey()=='R')
96                {
97                    _terrain->setSampleRatio(_terrain->getSampleRatio()/0.5);
98                    osg::notify(osg::NOTICE)<<"Sample ratio "<<_terrain->getSampleRatio()<<std::endl;
99                    return true;
100                }
101                else if (ea.getKey()=='v')
102                {
103                    _terrain->setVerticalScale(_terrain->getVerticalScale()*1.25);
104                    osg::notify(osg::NOTICE)<<"Vertical scale "<<_terrain->getVerticalScale()<<std::endl;
105                    return true;
106                }
107                else if (ea.getKey()=='V')
108                {
109                    _terrain->setVerticalScale(_terrain->getVerticalScale()/1.25);
110                    osg::notify(osg::NOTICE)<<"Vertical scale "<<_terrain->getVerticalScale()<<std::endl;
111                    return true;
112                }
113
114                return false;
115            }
116            default:
117                return false;
118        }
119    }
120
121protected:
122
123    ~TerrainHandler() {}
124
125    osg::ref_ptr<osgTerrain::Terrain>  _terrain;
126};
127
128int main(int argc, char** argv)
129{
130    osg::ArgumentParser arguments(&argc, argv);
131
132    // construct the viewer.
133    osgViewer::Viewer viewer(arguments);
134
135    // set up the camera manipulators.
136    {
137        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
138
139        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
140        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
141        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
142        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
143
144        std::string pathfile;
145        char keyForAnimationPath = '5';
146        while (arguments.read("-p",pathfile))
147        {
148            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
149            if (apm || !apm->valid())
150            {
151                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
152                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
153                keyswitchManipulator->selectMatrixManipulator(num);
154                ++keyForAnimationPath;
155            }
156        }
157
158        viewer.setCameraManipulator( keyswitchManipulator.get() );
159    }
160
161
162    // add the state manipulator
163    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
164
165    // add the stats handler
166    viewer.addEventHandler(new osgViewer::StatsHandler);
167
168    // add the record camera path handler
169    viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);
170
171    // add the window size toggle handler
172    viewer.addEventHandler(new osgViewer::WindowSizeHandler);
173
174    // obtain the vertical scale
175    float verticalScale = 1.0f;
176    while(arguments.read("-v",verticalScale)) {}
177
178    // obtain the sample ratio
179    float sampleRatio = 1.0f;
180    while(arguments.read("-r",sampleRatio)) {}
181
182    osgTerrain::TerrainTile::BlendingPolicy blendingPolicy = osgTerrain::TerrainTile::INHERIT;
183    std::string strBlendingPolicy;
184    while(arguments.read("--blending-policy", strBlendingPolicy))
185    {
186        if (strBlendingPolicy == "INHERIT") blendingPolicy = osgTerrain::TerrainTile::INHERIT;
187        else if (strBlendingPolicy == "DO_NOT_SET_BLENDING") blendingPolicy = osgTerrain::TerrainTile::DO_NOT_SET_BLENDING;
188        else if (strBlendingPolicy == "ENABLE_BLENDING") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING;
189        else if (strBlendingPolicy == "ENABLE_BLENDING_WHEN_ALPHA_PRESENT") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT;
190    }
191
192    // load the nodes from the commandline arguments.
193    osg::ref_ptr<osg::Node> rootnode = osgDB::readNodeFiles(arguments);
194
195    if (!rootnode)
196    {
197        osg::notify(osg::NOTICE)<<"Warning: no valid data loaded, please specify a database on the command line."<<std::endl;
198        return 1;
199    }
200
201    osg::ref_ptr<osgTerrain::Terrain> terrain = findTopMostNodeOfType<osgTerrain::Terrain>(rootnode.get());
202    if (!terrain)
203    {
204        // no Terrain node present insert one above the loaded model.
205        terrain = new osgTerrain::Terrain;
206
207        // if CoordinateSystemNode is present copy it's contents into the Terrain, and discard it.
208        osg::CoordinateSystemNode* csn = findTopMostNodeOfType<osg::CoordinateSystemNode>(rootnode.get());
209        if (csn)
210        {
211            terrain->set(*csn);
212            for(unsigned int i=0; i<csn->getNumChildren();++i)
213            {
214                terrain->addChild(csn->getChild(i));
215            }
216        }
217        else
218        {
219            terrain->addChild(rootnode.get());
220        }
221
222        rootnode = terrain.get();
223    }
224
225    terrain->setSampleRatio(sampleRatio);
226    terrain->setVerticalScale(verticalScale);
227    terrain->setBlendingPolicy(blendingPolicy);
228
229    // register our custom handler for adjust Terrain settings
230    viewer.addEventHandler(new TerrainHandler(terrain.get()));
231
232    // add a viewport to the viewer and attach the scene graph.
233    viewer.setSceneData( rootnode.get() );
234
235
236    // run the viewers main loop
237    return viewer.run();
238
239}
Note: See TracBrowser for help on using the browser.