source: osgVisual/trunk/src/core/visual_core.cpp @ 182

Last change on this file since 182 was 182, checked in by Torben Dannhauer, 13 years ago

Adapted Sky_Silverlining to be aware of the XML configuration. The sky can now be disabled by XML configuration.

All calls to sky must be wrapped with if(sky.valid()) { ...} to ensure that it is only called when available.

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