source: experimental/TerrainTest/osgterrain.cpp @ 164

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