]> git.mxchange.org Git - flightgear.git/blob - utils/fgviewer/fgviewer.cxx
Merge branch 'next' of git://gitorious.org/fg/flightgear into next
[flightgear.git] / utils / fgviewer / fgviewer.cxx
1 #include <iostream>
2 #include <cstdlib>
3
4 #include <osg/ArgumentParser>
5 #include <osgDB/ReadFile>
6 #include <osgViewer/Viewer>
7 #include <osgViewer/ViewerEventHandlers>
8 #include <osgGA/KeySwitchMatrixManipulator>
9 #include <osgGA/TrackballManipulator>
10 #include <osgGA/FlightManipulator>
11 #include <osgGA/DriveManipulator>
12 #include <osgGA/TerrainManipulator>
13
14 #include <simgear/props/props.hxx>
15 #include <simgear/props/props_io.hxx>
16 #include <simgear/misc/sg_path.hxx>
17 #include <simgear/scene/material/matlib.hxx>
18 #include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx>
19 #include <simgear/scene/tgdb/userdata.hxx>
20 #include <simgear/scene/tgdb/TileEntry.hxx>
21 #include <simgear/scene/model/ModelRegistry.hxx>
22 #include <simgear/scene/model/modellib.hxx>
23
24 class DummyLoadHelper : public simgear::ModelLoadHelper {
25 public:
26     virtual osg::Node *loadTileModel(const string& modelPath, bool)
27     {
28         try {
29             SGSharedPtr<SGPropertyNode> prop = new SGPropertyNode;
30             return simgear::SGModelLib::loadModel(modelPath, prop);
31         } catch (...) {
32             std::cerr << "Error loading \"" << modelPath << "\"" << std::endl;
33             return 0;
34         }
35     }
36 };
37
38 int
39 main(int argc, char** argv)
40 {
41     // Just reference simgears reader writer stuff so that the globals get
42     // pulled in by the linker ...
43     // FIXME: make that more explicit clear and call an initialization function
44     simgear::ModelRegistry::instance();
45     sgUserDataInit(0);
46     DummyLoadHelper dummyLoadHelper;
47     simgear::TileEntry::setModelLoadHelper(&dummyLoadHelper);
48
49     // use an ArgumentParser object to manage the program arguments.
50     osg::ArgumentParser arguments(&argc, argv);
51
52     // construct the viewer.
53     osgViewer::Viewer viewer(arguments);
54     // ... for some reason, get rid of that FIXME!
55     viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
56     
57     // set up the camera manipulators.
58     osgGA::KeySwitchMatrixManipulator* keyswitchManipulator;
59     keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
60     
61     keyswitchManipulator->addMatrixManipulator('1', "Trackball",
62                                                new osgGA::TrackballManipulator);
63     keyswitchManipulator->addMatrixManipulator('2', "Flight",
64                                                new osgGA::FlightManipulator);
65     keyswitchManipulator->addMatrixManipulator('3', "Drive",
66                                                new osgGA::DriveManipulator);
67     keyswitchManipulator->addMatrixManipulator('4', "Terrain",
68                                                new osgGA::TerrainManipulator);
69     
70     viewer.setCameraManipulator(keyswitchManipulator);
71
72     // Usefull stats
73     viewer.addEventHandler(new osgViewer::HelpHandler);
74     viewer.addEventHandler(new osgViewer::StatsHandler);
75     // Same FIXME ...
76     // viewer.addEventHandler(new osgViewer::ThreadingHandler);
77     viewer.addEventHandler(new osgViewer::LODScaleHandler);
78     viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
79
80     const char *fg_root_env = std::getenv("FG_ROOT");
81     std::string fg_root;
82     if (fg_root_env)
83         fg_root = fg_root_env;
84     else
85 #if defined(PKGDATADIR)
86         fg_root = PKGDATADIR;
87 #else
88         fg_root = ".";
89 #endif
90
91     osgDB::FilePathList filePathList;
92     filePathList.push_back(fg_root);
93
94     const char *fg_scenery_env = std::getenv("FG_SCENERY");
95     string_list path_list;
96     if (fg_scenery_env) {
97         path_list = sgPathSplit(fg_scenery_env);
98     } else {
99         SGPath path(fg_root);
100         path.append("Scenery");
101         path_list.push_back(path.str());
102     }
103     for (unsigned i = 0; i < path_list.size(); ++i) {
104         SGPath pt(path_list[i]), po(path_list[i]);
105         pt.append("Terrain");
106         po.append("Objects");
107         filePathList.push_back(path_list[i]);
108         filePathList.push_back(pt.str());
109         filePathList.push_back(po.str());
110     }
111
112     SGSharedPtr<SGPropertyNode> props = new SGPropertyNode;
113     try {
114         SGPath preferencesFile = fg_root;
115         preferencesFile.append("preferences.xml");
116         readProperties(preferencesFile.str(), props);
117     } catch (...) {
118         // In case of an error, at least make summer :)
119         props->getNode("sim/startup/season", true)->setStringValue("summer");
120
121         std::cerr << "Problems loading FlightGear preferences.\n"
122                   << "Probably FG_ROOT is not properly set." << std::endl;
123     }
124     SGMaterialLib* ml = new SGMaterialLib;
125     SGPath mpath(fg_root);
126     mpath.append("materials.xml");
127     try {
128         ml->load(fg_root, mpath.str(), props);
129     } catch (...) {
130         std::cerr << "Problems loading FlightGear materials.\n"
131                   << "Probably FG_ROOT is not properly set." << std::endl;
132     }
133
134     // The file path list must be set in the registry.
135     osgDB::Registry::instance()->getDataFilePathList() = filePathList;
136     
137     SGReaderWriterBTGOptions* btgOptions = new SGReaderWriterBTGOptions;
138     btgOptions->getDatabasePathList() = filePathList;
139     btgOptions->setMatlib(ml);
140     
141     // read the scene from the list of file specified command line args.
142     osg::ref_ptr<osg::Node> loadedModel;
143     loadedModel = osgDB::readNodeFiles(arguments, btgOptions);
144
145     // if no model has been successfully loaded report failure.
146     if (!loadedModel.valid()) {
147         std::cerr << arguments.getApplicationName()
148                   << ": No data loaded" << std::endl;
149         return EXIT_FAILURE;
150     }
151     
152     // pass the loaded scene graph to the viewer.
153     viewer.setSceneData(loadedModel.get());
154     
155     return viewer.run();
156 }