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

Last change on this file since 145 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
Line 
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
17
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;
25}
26
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
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
53        // Configure osg to use KdTrees
54        osgDB::Registry::instance()->setBuildKdTreesHint(osgDB::ReaderWriter::Options::BUILD_KDTREES);
55
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
63        rootNode = new osg::CoordinateSystemNode;       // todo memleakf
64        rootNode->setEllipsoidModel(new osg::EllipsoidModel());
65
66        // Test memory leak (todo)
67        double* test = new double[1000];
68
69        #ifdef USE_SPACENAVIGATOR
70                mouse = NULL;
71        #endif
72
73        //osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( 8 );
74
75        // Show model
76        viewer->setSceneData( rootNode );
77
78        osg::Group* distortedSceneGraph = NULL;
79#ifdef USE_DISTORTION
80        // Initialize distortion
81        OSG_NOTIFY( osg::ALWAYS ) << "Using distortion." << std::endl;
82        distortion = new visual_distortion( viewer, arguments, configFilename );
83        distortion->initialize( rootNode, viewer->getCamera()->getClearColor() );
84        distortedSceneGraph = distortion->getDistortedSceneGraph();
85#endif
86
87#ifdef USE_SKY_SILVERLINING
88        // Initialize sky
89        sky = new visual_skySilverLining( viewer, configFilename );
90        sky->init(distortedSceneGraph, rootNode);       // Without distortion: distortedSceneGraph=NULL
91#endif
92
93        // Initialize DataIO interface
94        visual_dataIO::getInstance()->init(viewer, arguments, configFilename);
95
96        // Add manipulators for user interaction - after dataIO to be able to skip it in slaves rendering machines.
97        addManipulators();
98
99        loadTerrain(arguments);
100
101        // create the windows and run the threads.
102        viewer->realize();
103
104        // parse Configuration file
105        parseConfigFile(arguments);
106
107        // All modules are initialized - now check arguments for any unused parameter.
108        checkCommandlineArgumentsForFinalErrors();
109
110        // Run visual main loop
111        mainLoop();
112}
113
114void visual_core::mainLoop()
115{
116        int framestoScenerySetup = 5;
117        // run main loop
118        while( !viewer->done() )
119    {
120                // setup scenery
121                if(framestoScenerySetup-- == 0)
122                        setupScenery();
123
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       
132                // perform all queued events
133                viewer->eventTraversal();
134
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
149        // Shutdown Dbug HUD
150        if(hud.valid())
151                hud->shutdown();
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
167        // Shutdown data
168        rootNode = NULL;
169
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
182
183        // Destroy osgViewer
184        viewer = NULL;
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        {
197        OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl;
198        return false;
199    }   
200
201        return false;
202}
203
204void visual_core::addManipulators()
205{
206        if(!visual_dataIO::getInstance()->isSlave()) // set up the camera manipulators if not slave.
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() );
248    }   // If not Slave END
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
275void visual_core::parseConfigFile(osg::ArgumentParser& arguments_)
276{
277        if( configFilename != "" )
278        {
279                xmlDoc *doc = NULL;
280                xmlNode *root_element = NULL;
281               
282                doc = xmlReadFile(configFilename.c_str(), NULL, 0);
283                if (doc == NULL)
284                {
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);
291
292                        // Parse the XML document.
293                        checkXMLNode(root_element);
294
295                        // free the document
296                        xmlFreeDoc(doc);;
297                }
298                // Free the global variables that may have been allocated by the parser.
299                xmlCleanupParser();
300
301        }       // IF configfile exists
302}
303
304void visual_core::checkXMLNode(xmlNode * a_node)
305{
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;
312
313                        // Iterate to the next nodes to configure modules and scenery.
314                        checkXMLNode(cur_node->children);               
315                }
316
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
337}
338
339void visual_core::parseModule(xmlNode * a_node)
340{
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        } 
361        OSG_ALWAYS << "Module '" << name << "' found. Enabled = " << enabled << std::endl;
362
363        // Pass the nodes to the corresponding modules...
364        if(name == "core") this->config(a_node);
365
366}
367
368void visual_core::parseScenery(xmlNode * a_node)
369{
370        OSG_ALWAYS << "parseScenery()" << std::endl;
371}
372
373void visual_core::config(xmlNode * a_node)
374{
375        // Currently no configuration options fpr the core module are available.
376}
377
378bool visual_core::checkCommandlineArgumentsForFinalErrors()
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{
416
417        // Sky settings:       
418        sky->setTime(15,30,00);
419        sky->setVisibility(50000);
420        sky->addWindVolume( 0.0, 15000.0, 25.0, 90.0 );
421       
422        //sky->addCloudLayer( 0, 20000, 20000, 600.0, 1000.0, 0.5, CUMULONIMBUS_CAPPILATUS );
423        //sky->addCloudLayer( 1, 5000000, 5000000, 600.0, 7351.0, 0.2, CIRRUS_FIBRATUS );
424        //sky->addCloudLayer( 2, 50000, 50000, 600.0, 7351.0, 0.2, CIRROCUMULUS );
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 );
428
429        //sky->setSlotPrecipitation( 1, 0.0, 0.0, 0.0, 25.0 );
430
431
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
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
443
444        osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );       // todo memleak
445        testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
446        testObj3->loadGeometry( "../models/saenger1.flt" );
447        testObj3->addUpdater( new object_updater(testObj3) );   // todo memleak
448       
449
450        osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );       // todo memleak
451        testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
452        testObj4->loadGeometry( "../models/saenger2.flt" );
453        testObj4->addUpdater( new object_updater(testObj4) );   // todo memleak
454        testObj4->addLabel("testLabel", "LabelTest!!\nnächste Zeile :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
455
456        osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );        // todo memleak
457        testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
458        testObj5->loadGeometry( "../models/saengerCombine.flt" );
459        //testObj5->setScale( 2 );
460        testObj5->addUpdater( new object_updater(testObj5) );   // todo memleak
461
462#ifdef USE_SPACENAVIGATOR
463        // Manipulatoren auf dieses Objekt binden (Primärobjekt)
464        if (objectMountedCameraManip.valid())
465                objectMountedCameraManip->setAttachedObject( testObj4 );
466        if (mouseTrackerManip.valid())
467        {
468                mouseTrackerManip->setTrackNode( testObj4->getGeometry() );
469                mouseTrackerManip->setMinimumDistance( 100 );
470        }
471#endif
472
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        }
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();
502        hud = new visual_debug_hud();
503        hud->init( viewer, rootNode );
504       
505       
506
507        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
508        //test->init( rootNode, viewer );
509
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 );
523
524        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
525}
Note: See TracBrowser for help on using the repository browser.