8 #include <osg/ArgumentParser>
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>
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>
34 #include <Scenery/scenery.hxx>
36 #include "fg_init.hxx"
37 #include "fg_props.hxx"
38 #include "globals.hxx"
39 #include "options.hxx"
41 class DummyLoadHelper : public simgear::ModelLoadHelper {
43 virtual osg::Node *loadTileModel(const string& modelPath, bool)
46 SGSharedPtr<SGPropertyNode> prop = new SGPropertyNode;
47 return simgear::SGModelLib::loadModel(modelPath,
48 globals->get_props());
50 std::cerr << "Error loading \"" << modelPath << "\"" << std::endl;
56 class GraphDumpHandler : public osgGA::GUIEventHandler
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);
64 /** Get the keyboard and mouse usage of this manipulator.*/
65 virtual void getUsage(osg::ApplicationUsage& usage) const;
70 static void dumpOut(osg::Node* node)
75 FGRenderer *renderer = globals->get_renderer();
77 while (count < 1000) {
79 snprintf(filename, 24, "fgviewer-%03d.osg", count++);
80 if ( (fp = fopen(filename, "r")) == NULL )
85 if (osgDB::writeNodeFile(*node, filename))
86 std::cerr << "Entire scene graph saved to \"" << filename << "\".\n";
88 std::cerr << "Failed to save to \"" << filename << "\".\n";
91 bool GraphDumpHandler::handle(const osgGA::GUIEventAdapter& ea,
92 osgGA::GUIActionAdapter& aa)
94 osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
99 switch(ea.getEventType()) {
100 case osgGA::GUIEventAdapter::KEYUP:
101 if (ea.getKey() == _keyDump) {
102 dumpOut(view->getScene()->getSceneData());
112 void GraphDumpHandler::getUsage(osg::ApplicationUsage& usage) const
114 std::ostringstream ostr;
115 ostr << char(_keyDump);
116 usage.addKeyboardMouseBinding(ostr.str(),
117 "Dump scene graph to file");
121 fgviewerMain(int argc, char** argv)
125 DummyLoadHelper dummyLoadHelper;
126 simgear::TileEntry::setModelLoadHelper(&dummyLoadHelper);
128 // use an ArgumentParser object to manage the program arguments.
129 osg::ArgumentParser arguments(&argc, argv);
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);
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);
150 // set up the camera manipulators.
151 osgGA::KeySwitchMatrixManipulator* keyswitchManipulator;
152 keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
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);
163 viewer.setCameraManipulator(keyswitchManipulator);
166 viewer.addEventHandler(new osgViewer::HelpHandler);
167 viewer.addEventHandler(new osgViewer::StatsHandler);
168 viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
170 // viewer.addEventHandler(new osgViewer::ThreadingHandler);
171 viewer.addEventHandler(new osgViewer::LODScaleHandler);
172 viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
174 viewer.addEventHandler(new GraphDumpHandler);
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)) {
183 dataFiles.insert(dataFiles.begin(), arguments[i]);
188 // A subset of full flightgear initialization.
189 // Allocate global data structures. This needs to happen before
190 // we parse command line options
192 globals = new FGGlobals;
194 fgInitFGRoot(arguments.argc(), arguments.argv());
195 if ( !fgInitConfig(arguments.argc(), arguments.argv()) ) {
196 SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." );
200 osgDB::FilePathList filePathList
201 = osgDB::Registry::instance()->getDataFilePathList();
202 filePathList.push_back(globals->get_fg_root());
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]);
209 globals->set_matlib( new SGMaterialLib );
210 simgear::SGModelLib::init(globals->get_fg_root());
212 // Initialize the material property subsystem.
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!" );
222 globals->set_scenery( new FGScenery );
223 globals->get_scenery()->init();
224 globals->get_scenery()->bind();
226 // The file path list must be set in the registry.
227 osgDB::Registry::instance()->getDataFilePathList() = filePathList;
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));
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);
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;
246 // pass the loaded scene graph to the viewer.
247 viewer.setSceneData(loadedModel.get());