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

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