#ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fg_init.hxx" #include "fg_props.hxx" #include "globals.hxx" #include "options.hxx" class DummyLoadHelper : public simgear::ModelLoadHelper { public: virtual osg::Node *loadTileModel(const string& modelPath, bool) { try { SGSharedPtr prop = new SGPropertyNode; return simgear::SGModelLib::loadModel(modelPath, globals->get_props()); } catch (...) { std::cerr << "Error loading \"" << modelPath << "\"" << std::endl; return 0; } } }; class GraphDumpHandler : public osgGA::GUIEventHandler { public: GraphDumpHandler() : _keyDump('d') {} void setKeyDump(int key) { _keyDump = key; } int getKeyDump() const { return _keyDump; } bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa); /** Get the keyboard and mouse usage of this manipulator.*/ virtual void getUsage(osg::ApplicationUsage& usage) const; protected: int _keyDump; }; static void dumpOut(osg::Node* node) { char filename[24]; static int count = 1; while (count < 1000) { FILE *fp; snprintf(filename, 24, "fgviewer-%03d.osg", count++); if ( (fp = fopen(filename, "r")) == NULL ) break; fclose(fp); } if (osgDB::writeNodeFile(*node, filename)) std::cerr << "Entire scene graph saved to \"" << filename << "\".\n"; else std::cerr << "Failed to save to \"" << filename << "\".\n"; } bool GraphDumpHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { osgViewer::View* view = dynamic_cast(&aa); if (!view) return false; if (ea.getHandled()) return false; switch(ea.getEventType()) { case osgGA::GUIEventAdapter::KEYUP: if (ea.getKey() == _keyDump) { dumpOut(view->getScene()->getSceneData()); return true; } break; default: return false; } return false; } void GraphDumpHandler::getUsage(osg::ApplicationUsage& usage) const { std::ostringstream ostr; ostr << char(_keyDump); usage.addKeyboardMouseBinding(ostr.str(), "Dump scene graph to file"); } int fgviewerMain(int argc, char** argv) { sgUserDataInit(0); DummyLoadHelper dummyLoadHelper; simgear::TileEntry::setModelLoadHelper(&dummyLoadHelper); // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc, argv); // construct the viewer. osgViewer::Viewer viewer(arguments); osg::Camera* camera = viewer.getCamera(); osgViewer::Renderer* renderer = static_cast(camera->getRenderer()); for (int i = 0; i < 2; ++i) { osgUtil::SceneView* sceneView = renderer->getSceneView(i); sceneView->setCullVisitor(new simgear::EffectCullVisitor); } // Shaders expect valid fog osg::StateSet* cameraSS = camera->getOrCreateStateSet(); osg::Fog* fog = new osg::Fog; fog->setMode(osg::Fog::EXP2); fog->setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0)); fog->setDensity(.0000001); cameraSS->setAttributeAndModes(fog); // ... for some reason, get rid of that FIXME! viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); // set up the camera manipulators. osgGA::KeySwitchMatrixManipulator* keyswitchManipulator; keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; osgGA::MatrixManipulator* mm = new osgGA::TrackballManipulator; keyswitchManipulator->addMatrixManipulator('1', "Trackball", mm); mm = new osgGA::FlightManipulator; keyswitchManipulator->addMatrixManipulator('2', "Flight", mm); mm = new osgGA::DriveManipulator; keyswitchManipulator->addMatrixManipulator('3', "Drive", mm); mm = new osgGA::TerrainManipulator; keyswitchManipulator->addMatrixManipulator('4', "Terrain", mm); viewer.setCameraManipulator(keyswitchManipulator); // Usefull stats viewer.addEventHandler(new osgViewer::HelpHandler); viewer.addEventHandler(new osgViewer::StatsHandler); viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); // Same FIXME ... // viewer.addEventHandler(new osgViewer::ThreadingHandler); viewer.addEventHandler(new osgViewer::LODScaleHandler); viewer.addEventHandler(new osgViewer::ScreenCaptureHandler); viewer.addEventHandler(new GraphDumpHandler); // Extract files to load from arguments now; this way fgInitConfig // won't choke on them. string_list dataFiles; for (int i = arguments.argc() - 1; i >= 0; --i) { if (arguments.isOption(i)) { break; } else { dataFiles.insert(dataFiles.begin(), arguments[i]); arguments.remove(i); } } // A subset of full flightgear initialization. // Allocate global data structures. This needs to happen before // we parse command line options globals = new FGGlobals; fgInitFGRoot(arguments.argc(), arguments.argv()); if ( !fgInitConfig(arguments.argc(), arguments.argv()) ) { SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." ); exit(-1); } osgDB::FilePathList filePathList = osgDB::Registry::instance()->getDataFilePathList(); filePathList.push_back(globals->get_fg_root()); string_list path_list = globals->get_fg_scenery(); for (unsigned i = 0; i < path_list.size(); ++i) { filePathList.push_back(path_list[i]); } globals->set_matlib( new SGMaterialLib ); simgear::SGModelLib::init(globals->get_fg_root()); // Initialize the material property subsystem. SGPath mpath( globals->get_fg_root() ); mpath.append( "materials.xml" ); if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(), globals->get_props()) ) { SG_LOG( SG_GENERAL, SG_ALERT, "Error loading material lib!" ); exit(-1); } globals->set_scenery( new FGScenery ); globals->get_scenery()->init(); globals->get_scenery()->bind(); // The file path list must be set in the registry. osgDB::Registry::instance()->getDataFilePathList() = filePathList; SGReaderWriterBTGOptions* btgOptions = new SGReaderWriterBTGOptions; btgOptions->getDatabasePathList() = filePathList; btgOptions->setMatlib(globals->get_matlib()); btgOptions->setUseRandomObjects(fgGetBool("/sim/rendering/random-objects", false)); btgOptions->setUseRandomVegetation(fgGetBool("/sim/rendering/random-vegetation", false)); // read the scene from the list of file specified command line args. osg::ref_ptr loadedModel; loadedModel = osgDB::readNodeFiles(dataFiles, btgOptions); // if no model has been successfully loaded report failure. if (!loadedModel.valid()) { std::cerr << arguments.getApplicationName() << ": No data loaded" << std::endl; return EXIT_FAILURE; } // pass the loaded scene graph to the viewer. viewer.setSceneData(loadedModel.get()); return viewer.run(); }