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

Last change on this file since 148 was 148, checked in by Torben Dannhauer, 13 years ago
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
367void visual_core::parseScenery(xmlNode * a_node)
368{
369        OSG_ALWAYS << "parseScenery()" << std::endl;
370}
371
372void visual_core::config(xmlNode * a_node)
373{
374        // Currently no configuration options fpr the core module are available.
375}
376
377bool visual_core::checkCommandlineArgumentsForFinalErrors()
378{
379        // Setup Application Usage
380        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
381        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
382    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] Terrain_filename");
383        arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
384
385    // if user request help write it out to cout.
386    if (arguments.read("-h") || arguments.read("--help"))
387    {
388        arguments.getApplicationUsage()->write(std::cout);
389                //cause the viewer to exit and shut down clean.
390        viewer->setDone(true);
391    }
392
393    // report any errors if they have occurred when parsing the program arguments.
394    if (arguments.errors())
395    {
396        arguments.writeErrorMessages(std::cout);
397                //cause the viewer to exit and shut down clean.
398        viewer->setDone(true);
399    }
400
401         // any option left unread are converted into errors to write out later.
402    arguments.reportRemainingOptionsAsUnrecognized();
403
404    // report any errors if they have occurred when parsing the program arguments.
405    if (arguments.errors())
406    {
407        arguments.writeErrorMessages(std::cout);
408        return false;
409    }
410        return true;
411}
412
413void visual_core::setupScenery()
414{
415
416        // Sky settings:       
417        sky->setTime(15,30,00);
418        sky->setVisibility(50000);
419        sky->addWindVolume( 0.0, 15000.0, 25.0, 90.0 );
420       
421        //sky->addCloudLayer( 0, 20000, 20000, 600.0, 1000.0, 0.5, CUMULONIMBUS_CAPPILATUS );
422        //sky->addCloudLayer( 1, 5000000, 5000000, 600.0, 7351.0, 0.2, CIRRUS_FIBRATUS );
423        //sky->addCloudLayer( 2, 50000, 50000, 600.0, 7351.0, 0.2, CIRROCUMULUS );
424        ///sky->addCloudLayer( 2, 100000, 100000, 600.0, 2351.0, 0.75, STRATUS );
425        sky->addCloudLayer( 3, 50000, 50000, 1300.0, 700.0, 0.07, CUMULUS_CONGESTUS );
426        //sky->addCloudLayer( 1, 100000, 100000, 3500.0, 2000.0, 0.50, STRATOCUMULUS );
427
428        //sky->setSlotPrecipitation( 1, 0.0, 0.0, 0.0, 25.0 );
429
430
431        //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
432        //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
433        ///* using a huge cylinder to test position & orientation */
434        //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
435        //testObj->addUpdater( new object_updater(testObj) );
436
437        //osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );       // todo memleak
438        ////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
439        //testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
440        //testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
441        ////testObj2->addUpdater( new object_updater(testObj2) );       // todo memleak
442
443        osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );       // todo memleak
444        testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
445        testObj3->loadGeometry( "../models/saenger1.flt" );
446        testObj3->addUpdater( new object_updater(testObj3) );   // todo memleak
447       
448
449        osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );       // todo memleak
450        testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
451        testObj4->loadGeometry( "../models/saenger2.flt" );
452        testObj4->addUpdater( new object_updater(testObj4) );   // todo memleak
453        testObj4->addLabel("testLabel", "LabelTest!!\nnächste Zeile :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
454
455        osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );        // todo memleak
456        testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
457        testObj5->loadGeometry( "../models/saengerCombine.flt" );
458        //testObj5->setScale( 2 );
459        testObj5->addUpdater( new object_updater(testObj5) );   // todo memleak
460
461#ifdef USE_SPACENAVIGATOR
462        // Manipulatoren auf dieses Objekt binden (Primärobjekt)
463        if (objectMountedCameraManip.valid())
464                objectMountedCameraManip->setAttachedObject( testObj4 );
465        if (mouseTrackerManip.valid())
466        {
467                mouseTrackerManip->setTrackNode( testObj4->getGeometry() );
468                mouseTrackerManip->setMinimumDistance( 100 );
469        }
470#endif
471
472        if(nt.valid())
473        {
474                osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
475                osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
476                nt->setTrackerMode(trackerMode);
477                nt->setRotationMode(rotationMode);
478                //nt->setAutoComputeHomePosition( true );
479                nt->setMinimumDistance( 100 );
480                nt->setTrackNode(testObj4->getGeometry());
481                //nt->computeHomePosition();
482                nt->setAutoComputeHomePosition( true );
483                nt->setDistance( 250 );
484        }
485
486
487        // Load EDDF
488        //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
489        //if( !osgDB::fileExists(filename) )
490        //{
491        //      OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
492        //}
493        //// read model
494        //osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
495        //if (tmpModel.valid())
496        //      rootNode->addChild( tmpModel );
497       
498 
499        visual_draw2D::getInstance()->init( rootNode, viewer );
500        //osg::ref_ptr<visual_hud> hud = new visual_hud();
501        hud = new visual_debug_hud();
502        hud->init( viewer, rootNode );
503       
504       
505
506        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
507        //test->init( rootNode, viewer );
508
509        //// Creating Testclasses
510        //osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
511        //osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
512        //osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
513        //test->setFrameID( 22 );
514        //test->setName("ugamoep");
515        //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
516        //testSlot->setVariableName(std::string("HalloName"));
517        //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
518        //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
519        //testSlot->setValue( 0.12345 );
520        //test->addExecuter( testEx );
521        //test->addSlot( testSlot );
522
523        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
524}
Note: See TracBrowser for help on using the repository browser.