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

Revision 3994, 12.3 kB (checked in by robert, 9 years ago)

Added #include <osg/io_utils>

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