source: osgVisual/src/core/visual_core.cpp @ 144

Last change on this file since 144 was 144, checked in by Torben Dannhauer, 14 years ago

start to move osgVisual from argument based configuratiobn to xml file based configuration

File size: 17.9 KB
RevLine 
[31]1/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15*/
16
[86]17
[31]18#include <visual_core.h>
19
20using namespace osgVisual;
21
22visual_core::visual_core(osg::ArgumentParser& arguments_) : arguments(arguments_)
23{
24        OSG_NOTIFY( osg::ALWAYS ) << "visual_core instantiated." << std::endl;
[86]25}
[31]26
[86]27visual_core::~visual_core(void)
28{
29        OSG_NOTIFY( osg::ALWAYS ) << "visual_core destroyed." << std::endl;
30}
31
32void visual_core::initialize()
33{
34        OSG_NOTIFY( osg::ALWAYS ) << "Initialize visual_core..." << std::endl;
35
[144]36        // Check for config file to provide it to all modules during initialization.
37        if( arguments.read("-c", configFilename) || arguments.read("--config", configFilename) )
38        {
39                if( !osgDB::fileExists(configFilename) )
40                        configFilename = "";
41                else
42                        OSG_ALWAYS << "Using configuration file: " << configFilename << std::endl;
43        }
44
45xmlDoc* tmpDoc;
46util::getModuleXMLConfig( configFilename, "core", tmpDoc );
47if(tmpDoc)
48{
49        xmlFreeDoc(tmpDoc); xmlCleanupParser();
50}
51
52
[86]53        // Configure osg to use KdTrees
54        osgDB::Registry::instance()->setBuildKdTreesHint(osgDB::ReaderWriter::Options::BUILD_KDTREES);
55
[31]56        // Setup pathes
57        osgDB::Registry::instance()->getDataFilePathList().push_back( "D:\\DA\\osgVisual\\models" );
58       
59        // Setup viewer
60        viewer = new osgViewer::Viewer(arguments);
61
62        // Setup coordinate system node
[87]63        rootNode = new osg::CoordinateSystemNode;       // todo memleakf
[31]64        rootNode->setEllipsoidModel(new osg::EllipsoidModel());
65
66        // Test memory leak (todo)
[116]67        double* test = new double[1000];
[31]68
[55]69        #ifdef USE_SPACENAVIGATOR
70                mouse = NULL;
71        #endif
72
73        //osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( 8 );
[31]74
75        // Show model
76        viewer->setSceneData( rootNode );
77
[71]78        osg::Group* distortedSceneGraph = NULL;
[31]79#ifdef USE_DISTORTION
80        // Initialize distortion
[71]81        OSG_NOTIFY( osg::ALWAYS ) << "Using distortion." << std::endl;
[144]82        distortion = new visual_distortion( viewer, arguments, configFilename );
[31]83        distortion->initialize( rootNode, viewer->getCamera()->getClearColor() );
[71]84        distortedSceneGraph = distortion->getDistortedSceneGraph();
[31]85#endif
86
87#ifdef USE_SKY_SILVERLINING
88        // Initialize sky
[144]89        sky = new visual_skySilverLining( viewer, configFilename );
90        sky->init(distortedSceneGraph, rootNode);       // Without distortion: distortedSceneGraph=NULL
[31]91#endif
92
93        // Initialize DataIO interface
[144]94        visual_dataIO::getInstance()->init(viewer, arguments, configFilename);
[31]95
[144]96        // Add manipulators for user interaction - after dataIO to be able to skip it in slaves rendering machines.
[73]97        addManipulators();
98
[68]99        loadTerrain(arguments);
100
[31]101        // create the windows and run the threads.
102        viewer->realize();
103
[127]104        // parse Configuration file
105        parseConfigFile(arguments);
106
107        // All modules are initialized - now check arguments for any unused parameter.
108        checkCommandlineArgumentsForFinalErrors();
109
[31]110        // Run visual main loop
111        mainLoop();
112}
113
114void visual_core::mainLoop()
115{
[134]116        int framestoScenerySetup = 5;
[31]117        // run main loop
118        while( !viewer->done() )
119    {
[134]120                // setup scenery
121                if(framestoScenerySetup-- == 0)
122                        setupScenery();
123
[31]124                // next frame please....
125        viewer->advance();
126
127                /*double hat, hot, lat, lon, height;
128                util::getWGS84ofCamera( viewer->getCamera(), rootNode, lat, lon, height);
129                if (util::queryHeightOfTerrain( hot, rootNode, lat, lon) && util::queryHeightAboveTerrainInWGS84( hat, rootNode, lat, lon, height ) )
130                        OSG_NOTIFY( osg::ALWAYS ) << "HOT is: " << hot << ", HAT is: " << hat << std::endl;*/
131       
[70]132                // perform all queued events
133                viewer->eventTraversal();
134
[31]135                // update the scene by traversing it with the the update visitor which will
136        // call all node update callbacks and animations.
137        viewer->updateTraversal();
138               
139        // Render the Frame.
140        viewer->renderingTraversals();
141
142    }   // END WHILE
143}
144
145void visual_core::shutdown()
146{
147        OSG_NOTIFY( osg::ALWAYS ) << "Shutdown visual_core..." << std::endl;
148
[87]149        // Shutdown Dbug HUD
150        if(hud.valid())
151                hud->shutdown();
[31]152        // Unset scene data
153        viewer->setSceneData( NULL );
154
155#ifdef USE_SKY_SILVERLINING
156        // Shutdown sky
157        if( sky.valid() )
158                sky->shutdown();
159#endif
160
161#ifdef USE_DISTORTION
162        // Shutdown distortion
163        if( distortion.valid() )
164                distortion->shutdown();
165#endif
166
[87]167        // Shutdown data
168        rootNode = NULL;
169
[31]170        // Shutdown dataIO
171        visual_dataIO::getInstance()->shutdown();
172
173       
174#ifdef USE_SPACENAVIGATOR
175        //Delete SpaceMouse driver
176        if(mouse)
177        {
178                mouse->shutdown();
179                delete mouse;
180        }
181#endif
[86]182
183        // Destroy osgViewer
184        viewer = NULL;
[31]185}
186
187bool visual_core::loadTerrain(osg::ArgumentParser& arguments_)
188{
189        osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments_);
190        if( model.valid() )
191        {
192        rootNode->addChild( model.get() );
193                return true;
194        }
195        else
196        {
[58]197        OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl;
[31]198        return false;
199    }   
200
201        return false;
202}
203
204void visual_core::addManipulators()
205{
[73]206        if(!visual_dataIO::getInstance()->isSlave()) // set up the camera manipulators if not slave.
[31]207    {
208        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
209
210        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
211        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
212        keyswitchManipulator->addMatrixManipulator( '3', "Terrain", new osgGA::TerrainManipulator() );
213                nt = new osgGA::NodeTrackerManipulator();
214                keyswitchManipulator->addMatrixManipulator( '4', "NodeTrackerManipulator", nt );
215               
216#ifdef USE_SPACENAVIGATOR
217                // SpaceNavigator manipulator
218                mouse = new SpaceMouse();
219                mouse->initialize();
220                mouseTrackerManip = new NodeTrackerSpaceMouse(mouse);
221                mouseTrackerManip->setTrackerMode(NodeTrackerSpaceMouse::NODE_CENTER);
222                mouseTrackerManip->setRotationMode(NodeTrackerSpaceMouse::ELEVATION_AZIM);
223                mouseTrackerManip->setAutoComputeHomePosition( true );
224                keyswitchManipulator->addMatrixManipulator( '5', "Spacemouse Node Tracker", mouseTrackerManip );
225                keyswitchManipulator->addMatrixManipulator( '6', "Spacemouse Free (Airplane)", new FreeManipulator(mouse) );
226#endif
227
228                // objectMounted Manipulator for Camera control by Nodes
229                objectMountedCameraManip = new objectMountedManipulator();
230                keyswitchManipulator->addMatrixManipulator( '7', "Object mounted Camera", objectMountedCameraManip );
231
232                // Animation path manipulator
233        std::string pathfile;
234        char keyForAnimationPath = '8';
235        while (arguments.read("-p",pathfile))
236        {
237            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
238            if (apm || !apm->valid()) 
239            {
240                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
241                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
242                keyswitchManipulator->selectMatrixManipulator(num);
243                ++keyForAnimationPath;
244            }
245        }
246
247        viewer->setCameraManipulator( keyswitchManipulator.get() );
[73]248    }   // If not Slave END
[31]249
250    // add the state manipulator
251    viewer->addEventHandler( new osgGA::StateSetManipulator(rootNode->getOrCreateStateSet()) );
252   
253    // add the thread model handler
254    viewer->addEventHandler(new osgViewer::ThreadingHandler);
255
256    // add the window size toggle handler
257    viewer->addEventHandler(new osgViewer::WindowSizeHandler);
258       
259    // add the stats handler
260    viewer->addEventHandler(new osgViewer::StatsHandler);
261
262    // add the help handler
263    viewer->addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
264
265    // add the record camera path handler
266    viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
267
268    // add the LOD Scale handler
269    viewer->addEventHandler(new osgViewer::LODScaleHandler);
270
271    // add the screen capture handler
272    viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
273}
274
[125]275void visual_core::parseConfigFile(osg::ArgumentParser& arguments_)
276{
[144]277        if( configFilename != "" )
[125]278        {
[144]279                xmlDoc *doc = NULL;
280                xmlNode *root_element = NULL;
281               
282                doc = xmlReadFile(configFilename.c_str(), NULL, 0);
283                if (doc == NULL)
[125]284                {
[144]285                        OSG_ALWAYS << "visual_core::parseConfigFile() - ERROR: could not parse osgVisual config file" << configFilename  << std::endl;
286                }
287                else
288                {
289                        //  Get the root element node
290                        root_element = xmlDocGetRootElement(doc);
[67]291
[144]292                        // Parse the XML document.
293                        checkXMLNode(root_element);
[125]294
[144]295                        // free the document
296                        xmlFreeDoc(doc);;
297                }
298                // Free the global variables that may have been allocated by the parser.
299                xmlCleanupParser();
[125]300
[144]301        }       // IF configfile exists
[125]302}
303
304void visual_core::checkXMLNode(xmlNode * a_node)
305{
[127]306  for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
307        {
308                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
309                if(cur_node->type == XML_ELEMENT_NODE && node_name == "osgvisualconfiguration")
310                {
311                        OSG_DEBUG << "XML node osgvisualconfiguration found" << std::endl;
[144]312
[127]313                        // Iterate to the next nodes to configure modules and scenery.
314                        checkXMLNode(cur_node->children);               
315                }
[125]316
[127]317        if (cur_node->type == XML_ELEMENT_NODE && node_name == "module")
318                {
319                        OSG_DEBUG << "XML node module found" << std::endl;
320
321                        parseModule(cur_node);
322       
323            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
324                        //OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
325        }       // IF(module) END
326
327                if (cur_node->type == XML_ELEMENT_NODE && node_name == "scenery")
328                {
329                        OSG_DEBUG << "XML node scenery found" << std::endl;
330
331                        parseScenery(cur_node);
332       
333            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
334                        //OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
335        }       // IF(scenery) END
336    }   // FOR END
[125]337}
338
[127]339void visual_core::parseModule(xmlNode * a_node)
340{
[128]341        OSG_ALWAYS << "parseModule()" << std::endl;
342
343// Extract infos
344        std::string name = "";
345        bool enabled = false;
346
347        xmlAttr  *attr = a_node->properties;
348        while ( attr ) 
349        { 
350                std::string attr_name=reinterpret_cast<const char*>(attr->name);
351                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
352                if( attr_name == "name" )
353                        name = reinterpret_cast<const char*>(attr->children->content);
354                if( attr_name == "enabled" && attr_value== "yes" )
355                        enabled = true;
356                if( attr_name == "enabled" && attr_value== "no" )
357                        enabled = false;
358
359                attr = attr->next; 
360        } 
[144]361        OSG_ALWAYS << "Module '" << name << "' found. Enabled = " << enabled << std::endl;
[128]362
[129]363        // Pass the nodes to the corresponding modules...
364        if(name == "core") this->config(a_node);
[128]365
[127]366}
367
[125]368void visual_core::parseScenery(xmlNode * a_node)
369{
[128]370        OSG_ALWAYS << "parseScenery()" << std::endl;
[125]371}
372
[129]373void visual_core::config(xmlNode * a_node)
374{
375        // Currently no configuration options fpr the core module are available.
376}
377
[67]378bool visual_core::checkCommandlineArgumentsForFinalErrors()
[31]379{
380        // Setup Application Usage
381        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
382        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
383    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] Terrain_filename");
384        arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
385
386    // if user request help write it out to cout.
387    if (arguments.read("-h") || arguments.read("--help"))
388    {
389        arguments.getApplicationUsage()->write(std::cout);
390                //cause the viewer to exit and shut down clean.
391        viewer->setDone(true);
392    }
393
394    // report any errors if they have occurred when parsing the program arguments.
395    if (arguments.errors())
396    {
397        arguments.writeErrorMessages(std::cout);
398                //cause the viewer to exit and shut down clean.
399        viewer->setDone(true);
400    }
401
402         // any option left unread are converted into errors to write out later.
403    arguments.reportRemainingOptionsAsUnrecognized();
404
405    // report any errors if they have occurred when parsing the program arguments.
406    if (arguments.errors())
407    {
408        arguments.writeErrorMessages(std::cout);
409        return false;
410    }
411        return true;
412}
413
414void visual_core::setupScenery()
415{
[122]416
417        // Sky settings:       
[144]418        sky->setTime(15,30,00);
[122]419        sky->setVisibility(50000);
[144]420        sky->addWindVolume( 0.0, 15000.0, 25.0, 90.0 );
[122]421       
[136]422        //sky->addCloudLayer( 0, 20000, 20000, 600.0, 1000.0, 0.5, CUMULONIMBUS_CAPPILATUS );
[130]423        //sky->addCloudLayer( 1, 5000000, 5000000, 600.0, 7351.0, 0.2, CIRRUS_FIBRATUS );
[133]424        //sky->addCloudLayer( 2, 50000, 50000, 600.0, 7351.0, 0.2, CIRROCUMULUS );
[144]425        ///sky->addCloudLayer( 2, 100000, 100000, 600.0, 2351.0, 0.75, STRATUS );
426        sky->addCloudLayer( 3, 50000, 50000, 1300.0, 700.0, 0.07, CUMULUS_CONGESTUS );
427        //sky->addCloudLayer( 1, 100000, 100000, 3500.0, 2000.0, 0.50, STRATOCUMULUS );
[135]428
[143]429        //sky->setSlotPrecipitation( 1, 0.0, 0.0, 0.0, 25.0 );
[122]430
[143]431
[31]432        //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
433        //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
434        ///* using a huge cylinder to test position & orientation */
435        //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
436        //testObj->addUpdater( new object_updater(testObj) );
437
[115]438        //osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );       // todo memleak
439        ////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
440        //testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
441        //testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
442        ////testObj2->addUpdater( new object_updater(testObj2) );       // todo memleak
[31]443
[87]444        osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );       // todo memleak
[31]445        testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
446        testObj3->loadGeometry( "../models/saenger1.flt" );
[87]447        testObj3->addUpdater( new object_updater(testObj3) );   // todo memleak
[31]448       
449
[87]450        osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );       // todo memleak
[31]451        testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
452        testObj4->loadGeometry( "../models/saenger2.flt" );
[87]453        testObj4->addUpdater( new object_updater(testObj4) );   // todo memleak
[31]454        testObj4->addLabel("testLabel", "LabelTest!!\nnächste Zeile :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
455
[87]456        osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );        // todo memleak
[31]457        testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
458        testObj5->loadGeometry( "../models/saengerCombine.flt" );
459        //testObj5->setScale( 2 );
[87]460        testObj5->addUpdater( new object_updater(testObj5) );   // todo memleak
[31]461
462#ifdef USE_SPACENAVIGATOR
463        // Manipulatoren auf dieses Objekt binden (Primärobjekt)
464        if (objectMountedCameraManip.valid())
[115]465                objectMountedCameraManip->setAttachedObject( testObj4 );
[31]466        if (mouseTrackerManip.valid())
467        {
[115]468                mouseTrackerManip->setTrackNode( testObj4->getGeometry() );
[31]469                mouseTrackerManip->setMinimumDistance( 100 );
470        }
471#endif
472
[73]473        if(nt.valid())
474        {
475                osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
476                osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
477                nt->setTrackerMode(trackerMode);
478                nt->setRotationMode(rotationMode);
479                //nt->setAutoComputeHomePosition( true );
480                nt->setMinimumDistance( 100 );
481                nt->setTrackNode(testObj4->getGeometry());
482                //nt->computeHomePosition();
483                nt->setAutoComputeHomePosition( true );
484                nt->setDistance( 250 );
485        }
[31]486
487
488        // Load EDDF
489        //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
490        //if( !osgDB::fileExists(filename) )
491        //{
492        //      OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
493        //}
494        //// read model
495        //osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
496        //if (tmpModel.valid())
497        //      rootNode->addChild( tmpModel );
498       
499 
500        visual_draw2D::getInstance()->init( rootNode, viewer );
501        //osg::ref_ptr<visual_hud> hud = new visual_hud();
[87]502        hud = new visual_debug_hud();
[31]503        hud->init( viewer, rootNode );
504       
[122]505       
[31]506
507        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
508        //test->init( rootNode, viewer );
509
[69]510        //// Creating Testclasses
511        //osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
512        //osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
513        //osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
514        //test->setFrameID( 22 );
515        //test->setName("ugamoep");
516        //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
517        //testSlot->setVariableName(std::string("HalloName"));
518        //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
519        //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
520        //testSlot->setValue( 0.12345 );
521        //test->addExecuter( testEx );
522        //test->addSlot( testSlot );
[31]523
[69]524        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
[31]525}
Note: See TracBrowser for help on using the repository browser.