source: experimental/TerrainTest/osgterrain.cpp @ 165

Last change on this file since 165 was 165, checked in by Torben Dannhauer, 13 years ago
File size: 8.1 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    // obtain the vertical scale
178    float verticalScale = 1.0f;
179    while(arguments.read("-v",verticalScale)) {}
180
181    // obtain the sample ratio
182    float sampleRatio = 1.0f;
183    while(arguments.read("-r",sampleRatio)) {}
184
185    osgTerrain::TerrainTile::BlendingPolicy blendingPolicy = osgTerrain::TerrainTile::INHERIT;
186    std::string strBlendingPolicy;
187    while(arguments.read("--blending-policy", strBlendingPolicy))
188    {
189        if (strBlendingPolicy == "INHERIT") blendingPolicy = osgTerrain::TerrainTile::INHERIT;
190        else if (strBlendingPolicy == "DO_NOT_SET_BLENDING") blendingPolicy = osgTerrain::TerrainTile::DO_NOT_SET_BLENDING;
191        else if (strBlendingPolicy == "ENABLE_BLENDING") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING;
192        else if (strBlendingPolicy == "ENABLE_BLENDING_WHEN_ALPHA_PRESENT") blendingPolicy = osgTerrain::TerrainTile::ENABLE_BLENDING_WHEN_ALPHA_PRESENT;
193    }
194
195    // load the nodes from the commandline arguments.
196    osg::Node* rootnode = osgDB::readNodeFiles(arguments);
197
198    if (!rootnode)
199    {
200        osg::notify(osg::NOTICE)<<"Warning: no valid data loaded, please specify a database on the command line."<<std::endl;
201        return 1;
202    }
203
204    osgTerrain::Terrain* terrain = findTopMostNodeOfType<osgTerrain::Terrain>(rootnode);
205    if (!terrain)
206    {
207        terrain = new osgTerrain::Terrain;
208        terrain->addChild(rootnode);
209
210        rootnode = terrain;
211    }
212
213    terrain->setSampleRatio(sampleRatio);
214    terrain->setVerticalScale(verticalScale);
215    terrain->setBlendingPolicy(blendingPolicy);
216        osg::ref_ptr<osgTerrain::TerrainTechnique> myT = new osgTerrain::myTerrainTechnique();
217        terrain->setTerrainTechniquePrototype( myT );
218
219        //// Manually set the terrain technque for a tile ( his example, the first found tile) works, but then the whole database has to be processed
220        //osgTerrain::TerrainTile* tile = findTopMostNodeOfType<osgTerrain::TerrainTile>(rootnode);
221        //if(tile)
222        //{
223        //      tile->setTerrainTechnique( myT );
224        //}
225
226        // Use Tile load Callback
227        osg::ref_ptr<osgTerrain::myTileLoadedCallback> tlcb = new osgTerrain::myTileLoadedCallback( terrain);
228        osgTerrain::TerrainTile::setTileLoadedCallback(tlcb);
229
230    // register our custom handler for adjust Terrain settings
231    viewer.addEventHandler(new TerrainHandler(terrain));
232
233    // add a viewport to the viewer and attach the scene graph.
234    viewer.setSceneData( rootnode );
235
236
237    // run the viewers main loop
238    return viewer.run();
239
240}
Note: See TracBrowser for help on using the repository browser.