source: experimental/TerrainTest/osgterrain.cpp @ 217

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