Get fgviewer working as a part of fgfs
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.
This commit is contained in:
parent
bb2e5fb2c9
commit
3bce312213
6 changed files with 277 additions and 1 deletions
|
@ -1876,6 +1876,13 @@
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\Main\fg_props.hxx">
|
RelativePath="..\..\src\Main\fg_props.hxx">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\Main\fgviewer.cxx">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\src\Main\fgviewer.hxx">
|
||||||
|
</File>
|
||||||
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\src\Main\FGEventHandler.cxx">
|
RelativePath="..\..\src\Main\FGEventHandler.cxx">
|
||||||
</File>
|
</File>
|
||||||
|
|
|
@ -40,6 +40,7 @@ noinst_LIBRARIES = libMain.a
|
||||||
libMain_a_SOURCES = \
|
libMain_a_SOURCES = \
|
||||||
main.cxx main.hxx \
|
main.cxx main.hxx \
|
||||||
renderer.cxx renderer.hxx \
|
renderer.cxx renderer.hxx \
|
||||||
|
fgviewer.cxx fgviewer.hxx \
|
||||||
fg_commands.cxx fg_commands.hxx \
|
fg_commands.cxx fg_commands.hxx \
|
||||||
fg_init.cxx fg_init.hxx \
|
fg_init.cxx fg_init.hxx \
|
||||||
fg_io.cxx fg_io.hxx \
|
fg_io.cxx fg_io.hxx \
|
||||||
|
|
|
@ -51,6 +51,7 @@ using std::endl;
|
||||||
|
|
||||||
#include "main.hxx"
|
#include "main.hxx"
|
||||||
#include "globals.hxx"
|
#include "globals.hxx"
|
||||||
|
#include "fgviewer.hxx"
|
||||||
|
|
||||||
|
|
||||||
#include "fg_os.hxx"
|
#include "fg_os.hxx"
|
||||||
|
@ -208,12 +209,22 @@ int main ( int argc, char **argv ) {
|
||||||
#if defined( HAVE_BC5PLUS )
|
#if defined( HAVE_BC5PLUS )
|
||||||
_control87(MCW_EM, MCW_EM); /* defined in float.h */
|
_control87(MCW_EM, MCW_EM); /* defined in float.h */
|
||||||
#endif
|
#endif
|
||||||
|
bool fgviewer = false;
|
||||||
|
for (int i = 0; i < argc; ++i) {
|
||||||
|
if (!strcmp("--fgviewer", argv[i])) {
|
||||||
|
fgviewer = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: add other, more specific
|
// FIXME: add other, more specific
|
||||||
// exceptions.
|
// exceptions.
|
||||||
try {
|
try {
|
||||||
std::set_terminate(fg_terminate);
|
std::set_terminate(fg_terminate);
|
||||||
atexit(fgExitCleanup);
|
atexit(fgExitCleanup);
|
||||||
|
if (fgviewer)
|
||||||
|
fgviewerMain(argc, argv);
|
||||||
|
else
|
||||||
fgMainInit(argc, argv);
|
fgMainInit(argc, argv);
|
||||||
} catch (const sg_throwable &t) {
|
} catch (const sg_throwable &t) {
|
||||||
// We must use cerr rather than
|
// We must use cerr rather than
|
||||||
|
|
242
src/Main/fgviewer.cxx
Normal file
242
src/Main/fgviewer.cxx
Normal file
|
@ -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();
|
||||||
|
}
|
5
src/Main/fgviewer.hxx
Normal file
5
src/Main/fgviewer.hxx
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#ifndef __FG_FGVIEWER_HXX
|
||||||
|
#define __FG_FGVIEWER_HXX 1
|
||||||
|
|
||||||
|
int fgviewerMain(int argc, char** argv);
|
||||||
|
#endif
|
|
@ -1207,6 +1207,15 @@ fgOptFpe(const char* arg)
|
||||||
return FG_OPTIONS_OK;
|
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;
|
static map<string,size_t> fgOptionMap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1417,6 +1426,7 @@ struct OptionDesc {
|
||||||
{"parking-id", true, OPTION_FUNC, "", false, "", fgOptParking },
|
{"parking-id", true, OPTION_FUNC, "", false, "", fgOptParking },
|
||||||
{"version", false, OPTION_FUNC, "", false, "", fgOptVersion },
|
{"version", false, OPTION_FUNC, "", false, "", fgOptVersion },
|
||||||
{"enable-fpe", false, OPTION_FUNC, "", false, "", fgOptFpe},
|
{"enable-fpe", false, OPTION_FUNC, "", false, "", fgOptFpe},
|
||||||
|
{"fgviewer", false, OPTION_FUNC, "", false, "", fgOptFgviewer},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue