]> git.mxchange.org Git - flightgear.git/commitdiff
Get fgviewer working as a part of fgfs
authortimoore <timoore>
Mon, 10 Aug 2009 21:43:55 +0000 (21:43 +0000)
committerTim Moore <timoore@redhat.com>
Wed, 12 Aug 2009 21:45:54 +0000 (23:45 +0200)
Move fgviewer code into fgfs binary. Its osgViewer-style main function is
called from bootstrap.cxx if the --fgviewer argument is passed to fgfs.

Use fgfs initialization functions in fgviewer codepath. Read
command-line arguments and autosave.xml.

projects/VC7.1/FlightGear.vcproj
src/Main/Makefile.am
src/Main/bootstrap.cxx
src/Main/fgviewer.cxx [new file with mode: 0644]
src/Main/fgviewer.hxx [new file with mode: 0644]
src/Main/options.cxx

index 317a3a6b2778e8a6771986b93a8da795c70eb0a1..55c10c9f99fad301953b9a0608511b43f37e44c1 100755 (executable)
                        <File
                                RelativePath="..\..\src\Main\fg_props.hxx">
                        </File>
+                       <File
+                               RelativePath="..\..\src\Main\fgviewer.cxx">
+                       </File>
+                       <File
+                               RelativePath="..\..\src\Main\fgviewer.hxx">
+                       </File>
+
                        <File
                                RelativePath="..\..\src\Main\FGEventHandler.cxx">
                        </File>
index 9ff54a2edced08ba6c4ebdd5662fcef40cbb07eb..041e69033727e2d6cd6b7d2b1a9e7b806f4c417d 100644 (file)
@@ -40,6 +40,7 @@ noinst_LIBRARIES = libMain.a
 libMain_a_SOURCES = \
        main.cxx main.hxx \
        renderer.cxx renderer.hxx \
+       fgviewer.cxx fgviewer.hxx \
        fg_commands.cxx fg_commands.hxx \
        fg_init.cxx fg_init.hxx \
        fg_io.cxx fg_io.hxx \
index 9f2fcbb6df20121b845c8de68f9dd33002db1317..f4c24345dba3ee70367dddb7fda15b9cf80a329d 100644 (file)
@@ -51,6 +51,7 @@ using std::endl;
 
 #include "main.hxx"
 #include "globals.hxx"
+#include "fgviewer.hxx"
 
 
 #include "fg_os.hxx"
@@ -208,13 +209,23 @@ int main ( int argc, char **argv ) {
 #if defined( HAVE_BC5PLUS )
     _control87(MCW_EM, MCW_EM);  /* defined in float.h */
 #endif
+    bool fgviewer = false;
+    for (int i = 0; i < argc; ++i) {
+        if (!strcmp("--fgviewer", argv[i])) {
+            fgviewer = true;
+            break;
+        }
+    }
 
     // FIXME: add other, more specific
     // exceptions.
     try {
         std::set_terminate(fg_terminate);
         atexit(fgExitCleanup);
-        fgMainInit(argc, argv);
+        if (fgviewer)
+            fgviewerMain(argc, argv);
+        else
+            fgMainInit(argc, argv);
     } catch (const sg_throwable &t) {
                             // We must use cerr rather than
                             // logging, since logging may be
diff --git a/src/Main/fgviewer.cxx b/src/Main/fgviewer.cxx
new file mode 100644 (file)
index 0000000..6e6e040
--- /dev/null
@@ -0,0 +1,242 @@
+#include <iostream>
+#include <cstdlib>
+
+#include <osg/ArgumentParser>
+#include <osg/Fog>
+#include <osgDB/ReadFile>
+#include <osgDB/Registry>
+#include <osgDB/WriteFile>
+#include <osgViewer/Renderer>
+#include <osgViewer/Viewer>
+#include <osgViewer/ViewerEventHandlers>
+#include <osgGA/KeySwitchMatrixManipulator>
+#include <osgGA/TrackballManipulator>
+#include <osgGA/FlightManipulator>
+#include <osgGA/DriveManipulator>
+#include <osgGA/TerrainManipulator>
+#include <osgGA/StateSetManipulator>
+
+#include <simgear/props/props.hxx>
+#include <simgear/props/props_io.hxx>
+#include <simgear/misc/sg_path.hxx>
+#include <simgear/scene/material/EffectCullVisitor.hxx>
+#include <simgear/scene/material/matlib.hxx>
+#include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx>
+#include <simgear/scene/tgdb/userdata.hxx>
+#include <simgear/scene/tgdb/TileEntry.hxx>
+#include <simgear/scene/model/ModelRegistry.hxx>
+#include <simgear/scene/model/modellib.hxx>
+
+#include <Scenery/scenery.hxx>
+
+#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<SGPropertyNode> prop = new SGPropertyNode;
+            return simgear::SGModelLib::loadModel(modelPath, prop);
+        } 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;
+
+    FGRenderer *renderer = globals->get_renderer();
+
+    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<osgViewer::View*>(&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;
+    }
+}
+
+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<osgViewer::Renderer*>(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());
+
+    // read the scene from the list of file specified command line args.
+    osg::ref_ptr<osg::Node> 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();
+}
diff --git a/src/Main/fgviewer.hxx b/src/Main/fgviewer.hxx
new file mode 100644 (file)
index 0000000..82cdf5e
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef __FG_FGVIEWER_HXX
+#define __FG_FGVIEWER_HXX 1
+
+int fgviewerMain(int argc, char** argv);
+#endif
index 6305fe7f352b6dc61a4c47460686bc896ae5be8f..685d61ff1ea26a62969b297f5a2d00d640b870df 100644 (file)
@@ -1207,6 +1207,15 @@ fgOptFpe(const char* arg)
     return FG_OPTIONS_OK;
 }
 
+static int
+fgOptFgviewer(const char* arg)
+{
+    // Actually handled in bootstrap.cxx
+    return FG_OPTIONS_OK;
+}
+
+
+
 static map<string,size_t> fgOptionMap;
 
 /*
@@ -1417,6 +1426,7 @@ struct OptionDesc {
     {"parking-id",                   true,  OPTION_FUNC,   "", false, "", fgOptParking  },
     {"version",                      false, OPTION_FUNC,   "", false, "", fgOptVersion },
     {"enable-fpe",                  false, OPTION_FUNC,   "", false, "", fgOptFpe},
+    {"fgviewer",                    false, OPTION_FUNC,   "", false, "", fgOptFgviewer},
     {0}
 };