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