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

Revision 5159, 13.5 kB (checked in by robert, 8 years ago)

added SphereSegment? test code segment, commented out at pressent.

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