]> git.mxchange.org Git - flightgear.git/blob - src/Main/fgviewer.cxx
Win32 fix and suppress one warning
[flightgear.git] / src / Main / fgviewer.cxx
1 #ifdef HAVE_CONFIG_H
2 #  include "config.h"
3 #endif
4
5 #include <iostream>
6 #include <cstdlib>
7
8 #include <osg/ArgumentParser>
9 #include <osg/Fog>
10 #include <osgDB/ReadFile>
11 #include <osgDB/Registry>
12 #include <osgDB/WriteFile>
13 #include <osgViewer/Renderer>
14 #include <osgViewer/Viewer>
15 #include <osgViewer/ViewerEventHandlers>
16 #include <osgGA/KeySwitchMatrixManipulator>
17 #include <osgGA/TrackballManipulator>
18 #include <osgGA/FlightManipulator>
19 #include <osgGA/DriveManipulator>
20 #include <osgGA/TerrainManipulator>
21 #include <osgGA/StateSetManipulator>
22
23 #include <simgear/props/props.hxx>
24 #include <simgear/props/props_io.hxx>
25 #include <simgear/misc/sg_path.hxx>
26 #include <simgear/scene/material/EffectCullVisitor.hxx>
27 #include <simgear/scene/material/matlib.hxx>
28 #include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx>
29 #include <simgear/scene/tgdb/userdata.hxx>
30 #include <simgear/scene/tgdb/TileEntry.hxx>
31 #include <simgear/scene/model/ModelRegistry.hxx>
32 #include <simgear/scene/model/modellib.hxx>
33
34 #include <Scenery/scenery.hxx>
35
36 #include "fg_init.hxx"
37 #include "fg_props.hxx"
38 #include "globals.hxx"
39 #include "options.hxx"
40
41 class DummyLoadHelper : public simgear::ModelLoadHelper {
42 public:
43     virtual osg::Node *loadTileModel(const string& modelPath, bool)
44     {
45         try {
46             SGSharedPtr<SGPropertyNode> prop = new SGPropertyNode;
47             return simgear::SGModelLib::loadModel(modelPath,
48                                                   globals->get_props());
49         } catch (...) {
50             std::cerr << "Error loading \"" << modelPath << "\"" << std::endl;
51             return 0;
52         }
53     }
54 };
55
56 class GraphDumpHandler : public  osgGA::GUIEventHandler
57 {
58 public:
59     GraphDumpHandler() : _keyDump('d') {}
60     void setKeyDump(int key) { _keyDump = key; }
61     int getKeyDump() const { return _keyDump; }
62     bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
63
64     /** Get the keyboard and mouse usage of this manipulator.*/
65     virtual void getUsage(osg::ApplicationUsage& usage) const;
66 protected:
67     int _keyDump;
68 };
69
70 static void dumpOut(osg::Node* node)
71 {
72     char filename[24];
73     static int count = 1;
74
75     FGRenderer *renderer = globals->get_renderer();
76
77     while (count < 1000) {
78         FILE *fp;
79         snprintf(filename, 24, "fgviewer-%03d.osg", count++);
80         if ( (fp = fopen(filename, "r")) == NULL )
81             break;
82         fclose(fp);
83     }
84
85     if (osgDB::writeNodeFile(*node, filename))
86         std::cerr << "Entire scene graph saved to \"" << filename << "\".\n";
87     else
88         std::cerr << "Failed to save to \"" << filename << "\".\n";
89 }
90
91 bool GraphDumpHandler::handle(const osgGA::GUIEventAdapter& ea,
92                               osgGA::GUIActionAdapter& aa)
93 {
94     osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
95     if (!view)
96         return false;
97     if (ea.getHandled())
98         return false;
99     switch(ea.getEventType()) {
100     case osgGA::GUIEventAdapter::KEYUP:
101         if (ea.getKey() == _keyDump) {
102             dumpOut(view->getScene()->getSceneData());
103             return true;
104         }
105         break;
106     default:
107         return false;
108     }
109     return false;
110 }
111
112 void GraphDumpHandler::getUsage(osg::ApplicationUsage& usage) const
113 {
114     std::ostringstream ostr;
115     ostr << char(_keyDump);
116             usage.addKeyboardMouseBinding(ostr.str(),
117                                           "Dump scene graph to file");
118 }
119
120 int
121 fgviewerMain(int argc, char** argv)
122 {
123
124     sgUserDataInit(0);
125     DummyLoadHelper dummyLoadHelper;
126     simgear::TileEntry::setModelLoadHelper(&dummyLoadHelper);
127
128     // use an ArgumentParser object to manage the program arguments.
129     osg::ArgumentParser arguments(&argc, argv);
130
131     // construct the viewer.
132     osgViewer::Viewer viewer(arguments);
133     osg::Camera* camera = viewer.getCamera();
134     osgViewer::Renderer* renderer
135         = static_cast<osgViewer::Renderer*>(camera->getRenderer());
136     for (int i = 0; i < 2; ++i) {
137         osgUtil::SceneView* sceneView = renderer->getSceneView(i);
138         sceneView->setCullVisitor(new simgear::EffectCullVisitor);
139     }
140     // Shaders expect valid fog
141     osg::StateSet* cameraSS = camera->getOrCreateStateSet();
142     osg::Fog* fog = new osg::Fog;
143     fog->setMode(osg::Fog::EXP2);
144     fog->setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0));
145     fog->setDensity(.0000001);
146     cameraSS->setAttributeAndModes(fog);
147     // ... for some reason, get rid of that FIXME!
148     viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
149
150     // set up the camera manipulators.
151     osgGA::KeySwitchMatrixManipulator* keyswitchManipulator;
152     keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
153
154     osgGA::MatrixManipulator* mm = new osgGA::TrackballManipulator;
155     keyswitchManipulator->addMatrixManipulator('1', "Trackball", mm);
156     mm = new osgGA::FlightManipulator;
157     keyswitchManipulator->addMatrixManipulator('2', "Flight", mm);
158     mm = new osgGA::DriveManipulator;
159     keyswitchManipulator->addMatrixManipulator('3', "Drive", mm);
160     mm = new osgGA::TerrainManipulator;
161     keyswitchManipulator->addMatrixManipulator('4', "Terrain", mm);
162
163     viewer.setCameraManipulator(keyswitchManipulator);
164
165     // Usefull stats
166     viewer.addEventHandler(new osgViewer::HelpHandler);
167     viewer.addEventHandler(new osgViewer::StatsHandler);
168     viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
169     // Same FIXME ...
170     // viewer.addEventHandler(new osgViewer::ThreadingHandler);
171     viewer.addEventHandler(new osgViewer::LODScaleHandler);
172     viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
173
174     viewer.addEventHandler(new GraphDumpHandler);
175
176     // Extract files to load from arguments now; this way fgInitConfig
177     // won't choke on them.
178     string_list dataFiles;
179     for (int i = arguments.argc() - 1; i >= 0; --i) {
180         if (arguments.isOption(i)) {
181             break;
182         } else {
183             dataFiles.insert(dataFiles.begin(), arguments[i]);
184             arguments.remove(i);
185         }
186     }
187
188     // A subset of full flightgear initialization.
189     // Allocate global data structures.  This needs to happen before
190     // we parse command line options
191
192     globals = new FGGlobals;
193
194     fgInitFGRoot(arguments.argc(), arguments.argv());
195     if ( !fgInitConfig(arguments.argc(), arguments.argv()) ) {
196         SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." );
197         exit(-1);
198     }
199
200     osgDB::FilePathList filePathList
201         = osgDB::Registry::instance()->getDataFilePathList();
202     filePathList.push_back(globals->get_fg_root());
203
204     string_list path_list = globals->get_fg_scenery();
205     for (unsigned i = 0; i < path_list.size(); ++i) {
206         filePathList.push_back(path_list[i]);
207     }
208
209     globals->set_matlib( new SGMaterialLib );
210     simgear::SGModelLib::init(globals->get_fg_root());
211
212     // Initialize the material property subsystem.
213
214     SGPath mpath( globals->get_fg_root() );
215     mpath.append( "materials.xml" );
216     if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(),
217             globals->get_props()) ) {
218         SG_LOG( SG_GENERAL, SG_ALERT, "Error loading material lib!" );
219         exit(-1);
220     }
221
222     globals->set_scenery( new FGScenery );
223     globals->get_scenery()->init();
224     globals->get_scenery()->bind();
225
226     // The file path list must be set in the registry.
227     osgDB::Registry::instance()->getDataFilePathList() = filePathList;
228
229     SGReaderWriterBTGOptions* btgOptions = new SGReaderWriterBTGOptions;
230     btgOptions->getDatabasePathList() = filePathList;
231     btgOptions->setMatlib(globals->get_matlib());
232     btgOptions->setUseRandomObjects(fgGetBool("/sim/rendering/random-objects", false));
233     btgOptions->setUseRandomVegetation(fgGetBool("/sim/rendering/random-vegetation", false));
234
235     // read the scene from the list of file specified command line args.
236     osg::ref_ptr<osg::Node> loadedModel;
237     loadedModel = osgDB::readNodeFiles(dataFiles, btgOptions);
238
239     // if no model has been successfully loaded report failure.
240     if (!loadedModel.valid()) {
241         std::cerr << arguments.getApplicationName()
242                   << ": No data loaded" << std::endl;
243         return EXIT_FAILURE;
244     }
245
246     // pass the loaded scene graph to the viewer.
247     viewer.setSceneData(loadedModel.get());
248
249     return viewer.run();
250 }