root/OpenSceneGraph/trunk/examples/osgsimulation/osgsimulation.cpp @ 5122

Revision 5122, 12.8 kB (checked in by robert, 9 years ago)

Reorganised the Group::removeChild and Geode::removeDrawable methods so
that removeChild(Node*), removeChild(uint) and equivilant Geode methods are
now inline methods, not designed to be overriden, and seperated out the
multiple remove method to be called removeChildren(uint, uint) which is
now the only virtual method. There removeChildren is now the method to
override in subclasses.

This reorganisation requires some call code to be rename removeChild usage
to removeChildren.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#ifdef WIN32
2/////////////////////////////////////////////////////////////////////////////
3// Disable unavoidable warning messages:
4
5//  4103: used #pragma pack to change alignment
6//  4114: same type qualifier used more than once
7//  4201: nonstandard extension used : nameless struct/union
8//  4237: "keyword" reserved for future use
9//  4251: class needs to have dll-interface to export class
10//  4275: non DLL-interface class used as base for DLL-interface class
11//  4290: C++ Exception Specification ignored
12//  4503: decorated name length exceeded, name was truncated
13//  4786: string too long - truncated to 255 characters
14
15#pragma warning(disable : 4103 4114 4201 4237 4251 4275 4290 4503 4335 4786)
16
17#endif // WIN32
18
19#include <osgProducer/Viewer>
20
21#include <osg/Group>
22#include <osg/Geode>
23#include <osg/ShapeDrawable>
24#include <osg/Texture2D>
25#include <osg/PositionAttitudeTransform>
26#include <osg/MatrixTransform>
27#include <osg/CoordinateSystemNode>
28
29#include <osgDB/FileUtils>
30#include <osgDB/ReadFile>
31
32#include <osgText/Text>
33
34#include <osgTerrain/DataSet>
35
36#include <osgSim/OverlayNode>
37
38#include <osgGA/NodeTrackerManipulator>
39
40class GraphicsContext {
41    public:
42        GraphicsContext()
43        {
44            rs = new Producer::RenderSurface;
45            rs->setWindowRectangle(0,0,1,1);
46            rs->useBorder(false);
47            rs->useConfigEventThread(false);
48            rs->realize();
49        }
50
51        virtual ~GraphicsContext()
52        {
53        }
54       
55    private:
56        Producer::ref_ptr<Producer::RenderSurface> rs;
57};
58
59osg::Node* createEarth()
60{
61    osg::ref_ptr<osg::Node> scene;
62   
63    {
64        std::string filename = osgDB::findDataFile("Images/land_shallow_topo_2048.jpg");
65
66        // make osgTerrain::DataSet quieter..
67        osgTerrain::DataSet::setNotifyOffset(1);
68
69        osg::ref_ptr<osgTerrain::DataSet> dataSet = new osgTerrain::DataSet;
70
71        // register the source imagery
72        {
73            osgTerrain::DataSet::Source* source = new osgTerrain::DataSet::Source(osgTerrain::DataSet::Source::IMAGE, filename);
74
75            source->setCoordinateSystemPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS);
76            source->setCoordinateSystem(osgTerrain::DataSet::coordinateSystemStringToWTK("WGS84"));
77
78             source->setGeoTransformPolicy(osgTerrain::DataSet::Source::PREFER_CONFIG_SETTINGS_BUT_SCALE_BY_FILE_RESOLUTION);
79            source->setGeoTransformFromRange(-180.0, 180.0, -90.0, 90.0);
80
81            dataSet->addSource(source);
82        }
83
84        // set up destination database paramters.
85        dataSet->setDatabaseType(osgTerrain::DataSet::LOD_DATABASE);
86        dataSet->setConvertFromGeographicToGeocentric(true);
87        dataSet->setDestinationName("test.osg");
88
89        // load the source data and record sizes.
90        dataSet->loadSources();
91
92        GraphicsContext context;
93        dataSet->createDestination(30);
94
95        if (dataSet->getDatabaseType()==osgTerrain::DataSet::LOD_DATABASE) dataSet->buildDestination();
96        else dataSet->writeDestination();
97       
98        scene = dataSet->getDestinationRootNode();
99       
100        // now we must get rid of all the old OpenGL objects before we start using the scene graph again
101        // otherwise it'll end up in an inconsistent state.
102        scene->releaseGLObjects(dataSet->getState());
103        osg::Texture::flushAllDeletedTextureObjects(0);
104        osg::Drawable::flushAllDeletedDisplayLists(0);
105    }
106       
107    return scene.release();
108   
109}
110
111
112class ModelPositionCallback : public osg::NodeCallback
113{
114public:
115
116    ModelPositionCallback():
117        _latitude(0.0),
118        _longitude(0.0),
119        _height(100000.0)
120    {
121        _rotation.makeRotate(osg::DegreesToRadians(90.0),0.0,0.0,1.0);
122    }
123   
124    void updateParameters()
125    {
126        _longitude += ((2.0*osg::PI)/360.0)/20.0;
127    }
128
129
130    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
131    {
132        updateParameters();
133       
134        osg::NodePath nodePath = nv->getNodePath();
135
136        osg::MatrixTransform* mt = nodePath.empty() ? 0 : dynamic_cast<osg::MatrixTransform*>(nodePath.back());
137        if (mt)
138        {
139            osg::CoordinateSystemNode* csn = 0;
140
141            // find coordinate system node from our parental chain
142            unsigned int i;
143            for(i=0; i<nodePath.size() && csn==0; ++i)
144            {
145                csn = dynamic_cast<osg::CoordinateSystemNode*>(nodePath[i]);
146            }
147           
148            if (csn)
149            {
150
151
152                osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
153                if (ellipsoid)
154                {
155                    osg::Matrix inheritedMatrix;
156                    for(i+=1; i<nodePath.size()-1; ++i)
157                    {
158                        osg::Transform* transform = nodePath[i]->asTransform();
159                        if (transform) transform->computeLocalToWorldMatrix(inheritedMatrix, nv);
160                    }
161                   
162                    osg::Matrixd matrix(inheritedMatrix);
163
164                    //osg::Matrixd matrix;
165                    ellipsoid->computeLocalToWorldTransformFromLatLongHeight(_latitude,_longitude,_height,matrix);
166                    matrix.preMult(osg::Matrix::rotate(_rotation));
167                   
168                    mt->setMatrix(matrix);
169                }
170
171            }       
172        }
173           
174        traverse(node,nv);
175    }   
176   
177    double                  _latitude;
178    double                  _longitude;
179    double                  _height;
180    osg::Quat               _rotation;
181};
182
183
184class FindNamedNodeVisitor : public osg::NodeVisitor
185{
186public:
187    FindNamedNodeVisitor(const std::string& name):
188        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
189        _name(name) {}
190   
191    virtual void apply(osg::Node& node)
192    {
193        if (node.getName()==_name)
194        {
195            _foundNodes.push_back(&node);
196        }
197        traverse(node);
198    }
199   
200    typedef std::vector< osg::ref_ptr<osg::Node> > NodeList;
201
202    std::string _name;
203    NodeList _foundNodes;
204};
205
206
207int main(int argc, char **argv)
208{
209    // use an ArgumentParser object to manage the program arguments.
210    osg::ArgumentParser arguments(&argc,argv);
211   
212    // set up the usage document, in case we need to print out how to use this program.
213    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of particle systems.");
214    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] image_file_left_eye image_file_right_eye");
215    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
216   
217
218    // construct the viewer.
219    osgProducer::Viewer viewer(arguments);
220
221    // set up the value with sensible default event handlers.
222    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
223
224    viewer.getCullSettings().setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
225    viewer.getCullSettings().setNearFarRatio(0.00001f);
226
227    // get details on keyboard and mouse bindings used by the viewer.
228    viewer.getUsage(*arguments.getApplicationUsage());
229
230    osg::Quat rotation;
231    osg::Vec4 vec4;
232    while (arguments.read("--rotate-model",vec4[0],vec4[1],vec4[2],vec4[3]))
233    {
234        osg::Quat local_rotate;
235        local_rotate.makeRotate(osg::DegreesToRadians(vec4[0]),vec4[1],vec4[2],vec4[3]);
236       
237        rotation = rotation * local_rotate;
238    }
239
240    osg::NodeCallback* nc = 0;
241    std::string flightpath_filename;
242    while (arguments.read("--flight-path",flightpath_filename))
243    {
244        std::ifstream fin(flightpath_filename.c_str());
245        if (fin)
246        {
247            osg::AnimationPath* path = new osg::AnimationPath;
248            path->read(fin);
249            nc = new osg::AnimationPathCallback(path);
250        }
251    }
252   
253    osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
254    std::string mode;
255    while (arguments.read("--tracker-mode",mode))
256    {
257        if (mode=="NODE_CENTER_AND_ROTATION") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
258        else if (mode=="NODE_CENTER_AND_AZIM") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM;
259        else if (mode=="NODE_CENTER") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
260        else
261        {
262            std::cout<<"Unrecognized --tracker-mode option "<<mode<<", valid options are:"<<std::endl;
263            std::cout<<"    NODE_CENTER_AND_ROTATION"<<std::endl;
264            std::cout<<"    NODE_CENTER_AND_AZIM"<<std::endl;
265            std::cout<<"    NODE_CENTER"<<std::endl;
266            return 1;
267        }
268    }
269   
270   
271    osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
272    while (arguments.read("--rotation-mode",mode))
273    {
274        if (mode=="TRACKBALL") rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
275        else if (mode=="ELEVATION_AZIM") rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
276        else
277        {
278            std::cout<<"Unrecognized --rotation-mode option "<<mode<<", valid options are:"<<std::endl;
279            std::cout<<"    TRACKBALL"<<std::endl;
280            std::cout<<"    ELEVATION_AZIM"<<std::endl;
281            return 1;
282        }
283    }
284
285    // if user request help write it out to cout.
286    if (arguments.read("-h") || arguments.read("--help"))
287    {
288        arguments.getApplicationUsage()->write(std::cout);
289        return 1;
290    }
291
292    // any option left unread are converted into errors to write out later.
293    arguments.reportRemainingOptionsAsUnrecognized();
294
295    // report any errors if they have occured when parsing the program aguments.
296    if (arguments.errors())
297    {
298        arguments.writeErrorMessages(std::cout);
299        return 1;
300    }
301   
302    // read the scene from the list of file specified commandline args.
303    osg::ref_ptr<osg::Node> root = osgDB::readNodeFiles(arguments);
304
305    if (!root) root = createEarth();
306   
307    if (!root) return 0;
308
309    // add a viewport to the viewer and attach the scene graph.
310    viewer.setSceneData(root.get());
311
312    osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(root.get());
313    if (csn)
314    {
315
316        bool insertOverlayNode = true;
317        osg::ref_ptr<osgSim::OverlayNode> overlayNode;
318        if (insertOverlayNode)
319        {
320       
321            overlayNode = new osgSim::OverlayNode;
322           
323            // insert the OverlayNode between the coordinate system node and its children.
324            for(unsigned int i=0; i<csn->getNumChildren(); ++i)
325            {
326                overlayNode->addChild( csn->getChild(i) );
327            }
328
329            csn->removeChildren(0, csn->getNumChildren());
330            csn->addChild(overlayNode.get());
331           
332            // tell the overlay node to continously update its overlay texture
333            // as we know we'll be tracking a moving target.
334            overlayNode->setContinuousUpdate(true);
335        }
336       
337       
338        osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
339        if (cessna)
340        {
341            double s = 200000.0 / cessna->getBound().radius();
342       
343            osg::MatrixTransform* scaler = new osg::MatrixTransform;
344            scaler->addChild(cessna);
345            scaler->setMatrix(osg::Matrixd::scale(s,s,s)*osg::Matrixd::rotate(rotation));
346            scaler->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);       
347       
348            osg::MatrixTransform* mt = new osg::MatrixTransform;
349            mt->addChild(scaler);
350
351
352            if (!nc) nc = new ModelPositionCallback;
353
354            mt->setUpdateCallback(nc);
355
356            csn->addChild(mt);
357           
358            // if we are using an overaly node, use the cessna subgraph as the overlay subgraph
359            if (overlayNode.valid())
360            {
361                overlayNode->setOverlaySubgraph(mt);
362            }
363
364            osgGA::NodeTrackerManipulator* tm = new osgGA::NodeTrackerManipulator;
365            tm->setTrackerMode(trackerMode);
366            tm->setRotationMode(rotationMode);
367            tm->setTrackNode(scaler);
368
369            unsigned int num = viewer.addCameraManipulator(tm);
370            viewer.selectCameraManipulator(num);
371        }
372        else
373        {
374             std::cout<<"Failed to read cessna.osg"<<std::endl;
375        }
376       
377    }   
378
379       
380
381    // create the windows and run the threads.
382    viewer.realize();
383
384    while( !viewer.done() )
385    {
386        // wait for all cull and draw threads to complete.
387        viewer.sync();
388
389        // update the scene by traversing it with the the update visitor which will
390        // call all node update callbacks and animations.
391        viewer.update();
392         
393        // fire off the cull and draw traversals of the scene.
394        viewer.frame();
395       
396    }
397   
398    // wait for all cull and draw threads to complete before exit.
399    viewer.sync();
400
401    return 0;
402}
Note: See TracBrowser for help on using the browser.