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

Revision 5076, 13.9 kB (checked in by robert, 8 years ago)

Added beginings osgprecipitation example.

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