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

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

osgVisual now compiles and configure cloudlayer via XML.

todo at all:
cluster: channelname is currently not defined by XML. Should it be?
sky: precipitation has to be activated
XML: model configuration must be implemented
XML: only lowercase in attribute names
XML: cloudlayer should be crapped in a node called cloudlayers.

File size: 18.2 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, configFilename);
89
90        // Add manipulators for user interaction - after dataIO to be able to skip it in slaves rendering machines.
91        addManipulators();
92
93        // create the windows and run the threads.
94        viewer->realize();
95
96        loadTerrain(arguments);
97
98        // All modules are initialized - now check arguments for any unused parameter.
99        checkCommandlineArgumentsForFinalErrors();
100
101        // Run visual main loop
102        mainLoop();
103}
104
105void visual_core::mainLoop()
106{
107        int framestoScenerySetup = 5;
108        // run main loop
109        while( !viewer->done() )
110    {
111                // setup scenery
112                if(framestoScenerySetup-- == 0)
113                        setupScenery();
114
115                // next frame please....
116        viewer->advance();
117
118                /*double hat, hot, lat, lon, height;
119                util::getWGS84ofCamera( viewer->getCamera(), rootNode, lat, lon, height);
120                if (util::queryHeightOfTerrain( hot, rootNode, lat, lon) && util::queryHeightAboveTerrainInWGS84( hat, rootNode, lat, lon, height ) )
121                        OSG_NOTIFY( osg::ALWAYS ) << "HOT is: " << hot << ", HAT is: " << hat << std::endl;*/
122       
123                // perform all queued events
124                viewer->eventTraversal();
125
126                // update the scene by traversing it with the the update visitor which will
127        // call all node update callbacks and animations.
128        viewer->updateTraversal();
129               
130        // Render the Frame.
131        viewer->renderingTraversals();
132
133    }   // END WHILE
134}
135
136void visual_core::shutdown()
137{
138        OSG_NOTIFY( osg::ALWAYS ) << "Shutdown visual_core..." << std::endl;
139
140        // Shutdown Dbug HUD
141        if(hud.valid())
142                hud->shutdown();
143        // Unset scene data
144        viewer->setSceneData( NULL );
145
146#ifdef USE_SKY_SILVERLINING
147        // Shutdown sky
148        if( sky.valid() )
149                sky->shutdown();
150#endif
151
152#ifdef USE_DISTORTION
153        // Shutdown distortion
154        if( distortion.valid() )
155                distortion->shutdown();
156#endif
157
158        // Shutdown data
159        rootNode = NULL;
160
161        // Shutdown dataIO
162        visual_dataIO::getInstance()->shutdown();
163
164       
165#ifdef USE_SPACENAVIGATOR
166        //Delete SpaceMouse driver
167        if(mouse)
168        {
169                mouse->shutdown();
170                delete mouse;
171        }
172#endif
173
174        // Destroy osgViewer
175        viewer = NULL;
176}
177
178bool visual_core::loadTerrain(osg::ArgumentParser& arguments_)
179{
180        osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(util::getTerrainFromXMLConfig(configFilename));
181        if( model.valid() )
182        {
183        rootNode->addChild( model.get() );
184                return true;
185        }
186        else
187        {
188        OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl;
189        return false;
190    }   
191
192        return false;
193}
194
195void visual_core::addManipulators()
196{
197        if(!visual_dataIO::getInstance()->isSlave()) // set up the camera manipulators if not slave.
198    {
199        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
200
201        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
202        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
203        keyswitchManipulator->addMatrixManipulator( '3', "Terrain", new osgGA::TerrainManipulator() );
204                nt = new osgGA::NodeTrackerManipulator();
205                keyswitchManipulator->addMatrixManipulator( '4', "NodeTrackerManipulator", nt );
206               
207#ifdef USE_SPACENAVIGATOR
208                // SpaceNavigator manipulator
209                mouse = new SpaceMouse();
210                mouse->initialize();
211                mouseTrackerManip = new NodeTrackerSpaceMouse(mouse);
212                mouseTrackerManip->setTrackerMode(NodeTrackerSpaceMouse::NODE_CENTER);
213                mouseTrackerManip->setRotationMode(NodeTrackerSpaceMouse::ELEVATION_AZIM);
214                mouseTrackerManip->setAutoComputeHomePosition( true );
215                keyswitchManipulator->addMatrixManipulator( '5', "Spacemouse Node Tracker", mouseTrackerManip );
216                keyswitchManipulator->addMatrixManipulator( '6', "Spacemouse Free (Airplane)", new FreeManipulator(mouse) );
217#endif
218
219                // objectMounted Manipulator for Camera control by Nodes
220                objectMountedCameraManip = new objectMountedManipulator();
221                keyswitchManipulator->addMatrixManipulator( '7', "Object mounted Camera", objectMountedCameraManip );
222
223                // Animation path manipulator
224                std::string pathfile = util::getAnimationPathFromXMLConfig(configFilename);
225        char keyForAnimationPath = '8';
226                if( pathfile != "" )
227        {
228            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
229            if (apm || !apm->valid()) 
230            {
231                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
232                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
233                keyswitchManipulator->selectMatrixManipulator(num);
234                ++keyForAnimationPath;
235            }
236        }
237
238        viewer->setCameraManipulator( keyswitchManipulator.get() );
239    }   // If not Slave END
240
241    // add the state manipulator
242    viewer->addEventHandler( new osgGA::StateSetManipulator(rootNode->getOrCreateStateSet()) );
243   
244    // add the thread model handler
245    viewer->addEventHandler(new osgViewer::ThreadingHandler);
246
247    // add the window size toggle handler
248    viewer->addEventHandler(new osgViewer::WindowSizeHandler);
249       
250    // add the stats handler
251    viewer->addEventHandler(new osgViewer::StatsHandler);
252
253    // add the help handler
254    viewer->addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
255
256    // add the record camera path handler
257    viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
258
259    // add the LOD Scale handler
260    viewer->addEventHandler(new osgViewer::LODScaleHandler);
261
262    // add the screen capture handler
263    viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
264}
265
266void visual_core::parseScenery(xmlNode* a_node)
267{
268        OSG_ALWAYS << "parseScenery()" << std::endl;
269
270        a_node = a_node->children;
271
272        for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
273        {
274                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
275
276                // terrain is parsend seperately
277                // animationpath is parsend seperately
278
279                if(cur_node->type == XML_ELEMENT_NODE && node_name == "models")
280                {
281                        /*
282                        <models>
283                          <model filename="cessna" type="plain" label="TestText!" dynamic="yes">
284                                <position lat="47.12345" lon="11.234567" alt="1500.0"></position>
285                                <attitude rot_x="0.0" rot_y="0.0" rot_z="0.0"></attitude>
286                                <cameraoffset>
287                                  <translation trans_x="0.0" trans_y="0.0" trans_z="0.0"></translation>
288                                  <rotation rot_x="0.0" rot_y="0.0" rot_z="0.0"></rotation>
289                                </cameraoffset>
290                          </model>
291                        </models>
292                        */
293                }
294
295                if(cur_node->type == XML_ELEMENT_NODE && node_name == "datetime")
296                {
297                        int hour, minute;
298                        int day=0,month=0,year=0;
299
300                        xmlAttr  *attr = cur_node->properties;
301                        while ( attr ) 
302                        { 
303                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
304                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
305                                if( attr_name == "day" )
306                                {
307                                        std::stringstream sstr(attr_value);
308                                        sstr >> day;
309                                }
310                                if( attr_name == "month" )
311                                {
312                                        std::stringstream sstr(attr_value);
313                                        sstr >> month;
314                                }
315                                if( attr_name == "year" )
316                                {
317                                        std::stringstream sstr(attr_value);
318                                        sstr >> year;
319                                }
320                                if( attr_name == "hour" )
321                                {
322                                        std::stringstream sstr(attr_value);
323                                        sstr >> hour;
324                                }
325                                if( attr_name == "minute" )
326                                {
327                                        std::stringstream sstr(attr_value);
328                                        sstr >> minute;
329                                }
330                                attr = attr->next; 
331                        }
332                        if(sky.valid())
333                        {
334                                if(day!=0 && month!=0 && year!=0)
335                                        sky->setDate(year, month, day);
336                                sky->setTime(hour,minute,00);
337                        }
338
339                }
340
341                if(cur_node->type == XML_ELEMENT_NODE && node_name == "visibility")
342                {
343                        float range = 50000, turbidity=2.2;
344                        xmlAttr  *attr = cur_node->properties;
345                        while ( attr ) 
346                        { 
347                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
348                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
349                                if( attr_name == "range" )
350                                {
351                                        std::stringstream sstr(attr_value);
352                                        sstr >> range;
353                                }
354                                if( attr_name == "turbidity" )
355                                {
356                                        std::stringstream sstr(attr_value);
357                                        sstr >> turbidity;
358                                }
359                                attr = attr->next; 
360                        }
361                        if(sky.valid())
362                        {
363                                sky->setVisibility( range );
364                                sky->setTurbidity( turbidity );
365                        }
366                }
367
368                if(cur_node->type == XML_ELEMENT_NODE && node_name == "cloudlayer")
369                {
370                        if(sky.valid())
371                                sky->configureCloudlayerbyXML( cur_node );
372                }
373
374                if(cur_node->type == XML_ELEMENT_NODE && node_name == "windlayer")
375                {
376                        float bottom = 0.0, top=5000.0, speed=25.0, direction=0.0;
377                        xmlAttr  *attr = cur_node->properties;
378                        while ( attr ) 
379                        { 
380                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
381                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
382                                if( attr_name == "bottom" )
383                                {
384                                        std::stringstream sstr(attr_value);
385                                        sstr >> bottom;
386                                }
387                                if( attr_name == "top" )
388                                {
389                                        std::stringstream sstr(attr_value);
390                                        sstr >> top;
391                                }
392                                if( attr_name == "speed" )
393                                {
394                                        std::stringstream sstr(attr_value);
395                                        sstr >> speed;
396                                }
397                                if( attr_name == "direction" )
398                                {
399                                        std::stringstream sstr(attr_value);
400                                        sstr >> direction;
401                                }
402                                attr = attr->next; 
403                        }
404                        if(sky.valid())
405                        {
406                                sky->addWindVolume( bottom, top, speed, direction );
407                        }
408                }
409        }// FOR all nodes END
410
411}
412
413bool visual_core::checkCommandlineArgumentsForFinalErrors()
414{
415        // Setup Application Usage
416        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
417        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
418    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] Terrain_filename");
419        arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
420
421    // if user request help write it out to cout.
422    if (arguments.read("-h") || arguments.read("--help"))
423    {
424        arguments.getApplicationUsage()->write(std::cout);
425                //cause the viewer to exit and shut down clean.
426        viewer->setDone(true);
427    }
428
429    // report any errors if they have occurred when parsing the program arguments.
430    if (arguments.errors())
431    {
432        arguments.writeErrorMessages(std::cout);
433                //cause the viewer to exit and shut down clean.
434        viewer->setDone(true);
435    }
436
437         // any option left unread are converted into errors to write out later.
438    arguments.reportRemainingOptionsAsUnrecognized();
439
440    // report any errors if they have occurred when parsing the program arguments.
441    if (arguments.errors())
442    {
443        arguments.writeErrorMessages(std::cout);
444        return false;
445    }
446        return true;
447}
448
449void visual_core::setupScenery()
450{
451        // Parse Scenery from Configuration file
452        xmlDoc* tmpDoc;
453        xmlNode* sceneryNode = util::getSceneryXMLConfig(configFilename, tmpDoc);
454        parseScenery(sceneryNode);
455        if(sceneryNode)
456        {
457                xmlFreeDoc(tmpDoc); xmlCleanupParser();
458        }
459
460
461
462        // Sky settings:
463        if(sky.valid())
464        {
465
466        }
467
468
469        //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
470        //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
471        ///* using a huge cylinder to test position & orientation */
472        //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
473        //testObj->addUpdater( new object_updater(testObj) );
474
475        //osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );       // todo memleak
476        ////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
477        //testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
478        //testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
479        ////testObj2->addUpdater( new object_updater(testObj2) );       // todo memleak
480
481        osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );       // todo memleak
482        testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
483        testObj3->loadGeometry( "../models/saenger1.flt" );
484        testObj3->addUpdater( new object_updater(testObj3) );   // todo memleak
485       
486
487        osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );       // todo memleak
488        testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
489        testObj4->loadGeometry( "../models/saenger2.flt" );
490        testObj4->addUpdater( new object_updater(testObj4) );   // todo memleak
491        testObj4->addLabel("testLabel", "LabelTest!!\nnächste Zeile :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
492
493        osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );        // todo memleak
494        testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
495        testObj5->loadGeometry( "../models/saengerCombine.flt" );
496        //testObj5->setScale( 2 );
497        testObj5->addUpdater( new object_updater(testObj5) );   // todo memleak
498
499#ifdef USE_SPACENAVIGATOR
500        // Manipulatoren auf dieses Objekt binden (Primärobjekt)
501        if (objectMountedCameraManip.valid())
502                objectMountedCameraManip->setAttachedObject( testObj4 );
503        if (mouseTrackerManip.valid())
504        {
505                mouseTrackerManip->setTrackNode( testObj4->getGeometry() );
506                mouseTrackerManip->setMinimumDistance( 100 );
507        }
508#endif
509
510        if(nt.valid())
511        {
512                osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
513                osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
514                nt->setTrackerMode(trackerMode);
515                nt->setRotationMode(rotationMode);
516                //nt->setAutoComputeHomePosition( true );
517                nt->setMinimumDistance( 100 );
518                nt->setTrackNode(testObj4->getGeometry());
519                //nt->computeHomePosition();
520                nt->setAutoComputeHomePosition( true );
521                nt->setDistance( 250 );
522        }
523
524
525        // Load EDDF
526        //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
527        //if( !osgDB::fileExists(filename) )
528        //{
529        //      OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
530        //}
531        //// read model
532        //osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
533        //if (tmpModel.valid())
534        //      rootNode->addChild( tmpModel );
535       
536 
537        visual_draw2D::getInstance()->init( rootNode, viewer );
538        //osg::ref_ptr<visual_hud> hud = new visual_hud();
539        hud = new visual_debug_hud();
540        hud->init( viewer, rootNode );
541       
542       
543
544        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
545        //test->init( rootNode, viewer );
546
547        //// Creating Testclasses
548        //osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
549        //osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
550        //osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
551        //test->setFrameID( 22 );
552        //test->setName("ugamoep");
553        //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
554        //testSlot->setVariableName(std::string("HalloName"));
555        //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
556        //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
557        //testSlot->setValue( 0.12345 );
558        //test->addExecuter( testEx );
559        //test->addSlot( testSlot );
560
561        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
562
563}
Note: See TracBrowser for help on using the repository browser.