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

Revision 6698, 13.5 kB (checked in by robert, 10 years ago)

Made the near far ratio lower to allow one to be near the terrain before clipping
comes in to effect

  • 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 <osgViewer/Viewer>
20#include <osgViewer/StatsHandler>
21#include <osgViewer/HelpHandler>
22#include <osgViewer/ViewerEventHandlers>
23
24#include <osg/Group>
25#include <osg/Geode>
26#include <osg/ShapeDrawable>
27#include <osg/Texture2D>
28#include <osg/PositionAttitudeTransform>
29#include <osg/MatrixTransform>
30#include <osg/CoordinateSystemNode>
31
32#include <osgDB/FileUtils>
33#include <osgDB/ReadFile>
34
35#include <osgText/Text>
36
37#include <osg/CoordinateSystemNode>
38
39#include <osgSim/OverlayNode>
40#include <osgSim/SphereSegment>
41
42#include <osgGA/NodeTrackerManipulator>
43#include <osgGA/StateSetManipulator>
44#include <osgGA/TrackballManipulator>
45#include <osgGA/FlightManipulator>
46#include <osgGA/DriveManipulator>
47#include <osgGA/KeySwitchMatrixManipulator>
48#include <osgGA/AnimationPathManipulator>
49#include <osgGA/TerrainManipulator>
50
51#include <iostream>
52
53osg::Node* createEarth()
54{
55    osg::TessellationHints* hints = new osg::TessellationHints;
56    hints->setDetailRatio(5.0f);
57
58   
59    osg::ShapeDrawable* sd = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0,0.0,0.0), osg::WGS_84_RADIUS_POLAR), hints);
60   
61    osg::Geode* geode = new osg::Geode;
62    geode->addDrawable(sd);
63   
64    std::string filename = osgDB::findDataFile("Images/land_shallow_topo_2048.jpg");
65    geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile(filename)));
66   
67    osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode;
68    csn->setEllipsoidModel(new osg::EllipsoidModel());
69    csn->addChild(geode);
70   
71    return csn;
72   
73}
74
75
76class ModelPositionCallback : public osg::NodeCallback
77{
78public:
79
80    ModelPositionCallback(double speed):
81        _latitude(0.0),
82        _longitude(0.0),
83        _height(100000.0),
84        _speed(speed)
85    {
86        _rotation.makeRotate(osg::DegreesToRadians(90.0),0.0,0.0,1.0);
87    }
88   
89    void updateParameters()
90    {
91        _longitude += _speed * ((2.0*osg::PI)/360.0)/20.0;
92    }
93
94
95    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
96    {
97        updateParameters();
98       
99        osg::NodePath nodePath = nv->getNodePath();
100
101        osg::MatrixTransform* mt = nodePath.empty() ? 0 : dynamic_cast<osg::MatrixTransform*>(nodePath.back());
102        if (mt)
103        {
104            osg::CoordinateSystemNode* csn = 0;
105
106            // find coordinate system node from our parental chain
107            unsigned int i;
108            for(i=0; i<nodePath.size() && csn==0; ++i)
109            {
110                csn = dynamic_cast<osg::CoordinateSystemNode*>(nodePath[i]);
111            }
112           
113            if (csn)
114            {
115
116
117                osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
118                if (ellipsoid)
119                {
120                    osg::Matrix inheritedMatrix;
121                    for(i+=1; i<nodePath.size()-1; ++i)
122                    {
123                        osg::Transform* transform = nodePath[i]->asTransform();
124                        if (transform) transform->computeLocalToWorldMatrix(inheritedMatrix, nv);
125                    }
126                   
127                    osg::Matrixd matrix(inheritedMatrix);
128
129                    //osg::Matrixd matrix;
130                    ellipsoid->computeLocalToWorldTransformFromLatLongHeight(_latitude,_longitude,_height,matrix);
131                    matrix.preMult(osg::Matrix::rotate(_rotation));
132                   
133                    mt->setMatrix(matrix);
134                }
135
136            }       
137        }
138           
139        traverse(node,nv);
140    }   
141   
142    double                  _latitude;
143    double                  _longitude;
144    double                  _height;
145    osg::Quat               _rotation;
146    double                  _speed;
147};
148
149
150class FindNamedNodeVisitor : public osg::NodeVisitor
151{
152public:
153    FindNamedNodeVisitor(const std::string& name):
154        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
155        _name(name) {}
156   
157    virtual void apply(osg::Node& node)
158    {
159        if (node.getName()==_name)
160        {
161            _foundNodes.push_back(&node);
162        }
163        traverse(node);
164    }
165   
166    typedef std::vector< osg::ref_ptr<osg::Node> > NodeList;
167
168    std::string _name;
169    NodeList _foundNodes;
170};
171
172
173int main(int argc, char **argv)
174{
175    // use an ArgumentParser object to manage the program arguments.
176    osg::ArgumentParser arguments(&argc,argv);
177   
178    // set up the usage document, in case we need to print out how to use this program.
179    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of node tracker.");
180    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
181    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
182   
183
184    // construct the viewer.
185    osgViewer::Viewer viewer;
186
187    // add the state manipulator
188    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
189   
190    // add the thread model handler
191    viewer.addEventHandler(new osgViewer::ThreadingHandler);
192
193    // add the window size toggle handler
194    viewer.addEventHandler(new osgViewer::WindowSizeHandler);
195       
196    // add the stats handler
197    viewer.addEventHandler(new osgViewer::StatsHandler);
198
199    // add the help handler
200    viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
201
202    // set the near far ration computation up.
203    viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
204    viewer.getCamera()->setNearFarRatio(0.000003f);
205
206
207    double speed = 1.0;
208    while (arguments.read("-f") || arguments.read("--fixed")) speed = 0.0;
209
210
211    osg::Quat rotation;
212    osg::Vec4 vec4;
213    while (arguments.read("--rotate-model",vec4[0],vec4[1],vec4[2],vec4[3]))
214    {
215        osg::Quat local_rotate;
216        local_rotate.makeRotate(osg::DegreesToRadians(vec4[0]),vec4[1],vec4[2],vec4[3]);
217       
218        rotation = rotation * local_rotate;
219    }
220
221    osg::NodeCallback* nc = 0;
222    std::string flightpath_filename;
223    while (arguments.read("--flight-path",flightpath_filename))
224    {
225        std::ifstream fin(flightpath_filename.c_str());
226        if (fin)
227        {
228            osg::AnimationPath* path = new osg::AnimationPath;
229            path->read(fin);
230            nc = new osg::AnimationPathCallback(path);
231        }
232    }
233   
234    osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
235    std::string mode;
236    while (arguments.read("--tracker-mode",mode))
237    {
238        if (mode=="NODE_CENTER_AND_ROTATION") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
239        else if (mode=="NODE_CENTER_AND_AZIM") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM;
240        else if (mode=="NODE_CENTER") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
241        else
242        {
243            std::cout<<"Unrecognized --tracker-mode option "<<mode<<", valid options are:"<<std::endl;
244            std::cout<<"    NODE_CENTER_AND_ROTATION"<<std::endl;
245            std::cout<<"    NODE_CENTER_AND_AZIM"<<std::endl;
246            std::cout<<"    NODE_CENTER"<<std::endl;
247            return 1;
248        }
249    }
250   
251   
252    osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
253    while (arguments.read("--rotation-mode",mode))
254    {
255        if (mode=="TRACKBALL") rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
256        else if (mode=="ELEVATION_AZIM") rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
257        else
258        {
259            std::cout<<"Unrecognized --rotation-mode option "<<mode<<", valid options are:"<<std::endl;
260            std::cout<<"    TRACKBALL"<<std::endl;
261            std::cout<<"    ELEVATION_AZIM"<<std::endl;
262            return 1;
263        }
264    }
265
266    bool useOverlay = true;
267    while (arguments.read("--no-overlay") || arguments.read("-n")) useOverlay = false;
268   
269    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
270    while (arguments.read("--object")) technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
271    while (arguments.read("--ortho") || arguments.read("--orthographic")) technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
272    while (arguments.read("--persp") || arguments.read("--perspective")) technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY;
273   
274
275
276    // if user request help write it out to cout.
277    if (arguments.read("-h") || arguments.read("--help"))
278    {
279        arguments.getApplicationUsage()->write(std::cout);
280        return 1;
281    }
282
283    // any option left unread are converted into errors to write out later.
284    arguments.reportRemainingOptionsAsUnrecognized();
285
286    // report any errors if they have occured when parsing the program aguments.
287    if (arguments.errors())
288    {
289        arguments.writeErrorMessages(std::cout);
290        return 1;
291    }
292   
293    // read the scene from the list of file specified commandline args.
294    osg::ref_ptr<osg::Node> root = osgDB::readNodeFiles(arguments);
295
296    if (!root) root = createEarth();
297   
298    if (!root) return 0;
299
300    // add a viewport to the viewer and attach the scene graph.
301    viewer.setSceneData(root.get());
302
303    osg::ref_ptr<osgGA::NodeTrackerManipulator> tm;
304
305    osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(root.get());
306    if (csn)
307    {
308
309        osg::ref_ptr<osgSim::OverlayNode> overlayNode;
310        if (useOverlay)
311        {
312            overlayNode = new osgSim::OverlayNode(technique);
313           
314            // insert the OverlayNode between the coordinate system node and its children.
315            for(unsigned int i=0; i<csn->getNumChildren(); ++i)
316            {
317                overlayNode->addChild( csn->getChild(i) );
318            }
319
320            csn->removeChildren(0, csn->getNumChildren());
321            csn->addChild(overlayNode.get());
322           
323            // tell the overlay node to continously update its overlay texture
324            // as we know we'll be tracking a moving target.
325            overlayNode->setContinuousUpdate(true);
326        }
327       
328       
329        osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
330        if (cessna)
331        {
332            double s = 200000.0 / cessna->getBound().radius();
333       
334            osg::MatrixTransform* scaler = new osg::MatrixTransform;
335            scaler->addChild(cessna);
336            scaler->setMatrix(osg::Matrixd::scale(s,s,s)*osg::Matrixd::rotate(rotation));
337            scaler->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);       
338       
339            if (false)
340            {
341                osgSim::SphereSegment* ss = new osgSim::SphereSegment(
342                                    osg::Vec3(0.0f,0.0f,0.0f), // center
343                                    19.9f, // radius
344                                    osg::DegreesToRadians(135.0f),
345                                    osg::DegreesToRadians(240.0f),
346                                    osg::DegreesToRadians(-10.0f),
347                                    osg::DegreesToRadians(30.0f),
348                                    60);
349                                   
350                scaler->addChild(ss);
351            }
352
353            osg::MatrixTransform* mt = new osg::MatrixTransform;
354            mt->addChild(scaler);
355
356
357            if (!nc) nc = new ModelPositionCallback(speed);
358
359            mt->setUpdateCallback(nc);
360           
361            csn->addChild(mt);
362           
363            // if we are using an overaly node, use the cessna subgraph as the overlay subgraph
364            if (overlayNode.valid())
365            {
366                overlayNode->setOverlaySubgraph(mt);
367            }
368
369            tm = new osgGA::NodeTrackerManipulator;
370            tm->setTrackerMode(trackerMode);
371            tm->setRotationMode(rotationMode);
372            tm->setTrackNode(scaler);
373        }
374        else
375        {
376             std::cout<<"Failed to read cessna.osg"<<std::endl;
377        }
378       
379    }   
380
381
382    // set up camera manipulators.
383    {
384        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
385
386        if (tm.valid()) keyswitchManipulator->addMatrixManipulator( '0', "Trackball", tm.get() );
387        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
388        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
389        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
390        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
391
392        viewer.setCameraManipulator( keyswitchManipulator.get() );
393    }
394   
395
396    viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
397
398    return viewer.run();
399}
Note: See TracBrowser for help on using the browser.