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

Last change on this file since 228 was 228, checked in by Torben Dannhauer, 13 years ago
File size: 18.8 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 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        currentTrackingID = -1;
27}
28
29visual_core::~visual_core(void)
30{
31        OSG_NOTIFY( osg::ALWAYS ) << "visual_core destroyed." << std::endl;
32}
33
34void visual_core::initialize()
35{
36        OSG_NOTIFY( osg::ALWAYS ) << "Initialize visual_core..." << std::endl;
37
38        // Check for config file to provide it to all modules during initialization.
39        if( arguments.read("-c", configFilename) || arguments.read("--config", configFilename) )
40        {
41                if( !osgDB::fileExists(configFilename) )
42                        configFilename = "";
43                else
44                        OSG_ALWAYS << "Using configuration file: " << configFilename << std::endl;
45        }
46
47        // Configure osg to use KdTrees
48        osgDB::Registry::instance()->setBuildKdTreesHint(osgDB::ReaderWriter::Options::BUILD_KDTREES);
49
50        // Setup pathes
51        osgDB::Registry::instance()->getDataFilePathList().push_back( "D:\\DA\\osgVisual\\models" );
52       
53        // Setup viewer
54        viewer = new osgViewer::Viewer(arguments);
55
56        // Setup coordinate system node
57        rootNode = new osg::CoordinateSystemNode;       // todo memleakf
58        rootNode->setEllipsoidModel(new osg::EllipsoidModel());
59
60        // Test memory leak (todo)
61        double* test = new double[1000];
62
63        #ifdef USE_SPACENAVIGATOR
64                mouse = NULL;
65        #endif
66
67        //osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( 8 );
68
69        // Show model
70        viewer->setSceneData( rootNode );
71
72        osg::Group* distortedSceneGraph = NULL;
73#ifdef USE_DISTORTION
74        // Initialize distortion
75        distortion = new visual_distortion( viewer, arguments, configFilename );
76        distortedSceneGraph = distortion->initialize( rootNode, viewer->getCamera()->getClearColor() );
77#endif
78
79#ifdef USE_SKY_SILVERLINING
80        // Initialize sky
81        bool disabled = false;  // to ask if the skyp is disabled or enabled
82        sky = new visual_skySilverLining( viewer, configFilename, disabled );
83        if(disabled)
84                sky = NULL;
85        if(sky.valid())
86                sky->init(distortedSceneGraph, rootNode);       // Without distortion: distortedSceneGraph=NULL
87#endif
88
89        // Initialize DataIO interface
90        visual_dataIO::getInstance()->init(viewer, configFilename);
91
92        // Add manipulators for user interaction - after dataIO to be able to skip it in slaves rendering machines.
93        addManipulators();
94
95        // create the windows and run the threads.
96        viewer->realize();
97
98        loadTerrain(arguments);
99
100        // All modules are initialized - now check arguments for any unused parameter.
101        checkCommandlineArgumentsForFinalErrors();
102
103        // Run visual main loop
104        mainLoop();
105}
106
107void visual_core::mainLoop()
108{
109        int framestoScenerySetup = 5;
110        // run main loop
111        while( !viewer->done() )
112    {
113                // setup scenery
114                if(framestoScenerySetup-- == 0)
115                        setupScenery();
116
117                // next frame please....
118        viewer->advance();
119
120                /*double hat, hot, lat, lon, height;
121                util::getWGS84ofCamera( viewer->getCamera(), rootNode, lat, lon, height);
122                if (util::queryHeightOfTerrain( hot, rootNode, lat, lon) && util::queryHeightAboveTerrainInWGS84( hat, rootNode, lat, lon, height ) )
123                        OSG_NOTIFY( osg::ALWAYS ) << "HOT is: " << hot << ", HAT is: " << hat << std::endl;*/
124       
125                // perform all queued events
126                viewer->eventTraversal();
127
128                // update the scene by traversing it with the the update visitor which will
129        // call all node update callbacks and animations.
130        viewer->updateTraversal();
131               
132        // Render the Frame.
133        viewer->renderingTraversals();
134
135    }   // END WHILE
136}
137
138void visual_core::shutdown()
139{
140        OSG_NOTIFY( osg::ALWAYS ) << "Shutdown visual_core..." << std::endl;
141
142        // Shutdown Dbug HUD
143        if(hud.valid())
144                hud->shutdown();
145        // Unset scene data
146        viewer->setSceneData( NULL );
147
148#ifdef USE_SKY_SILVERLINING
149        // Shutdown sky
150        if( sky.valid() )
151                sky->shutdown();
152#endif
153
154#ifdef USE_DISTORTION
155        // Shutdown distortion
156        if( distortion.valid() )
157                distortion->shutdown();
158#endif
159
160        // Shutdown data
161        rootNode = NULL;
162
163        // Shutdown dataIO
164        visual_dataIO::getInstance()->shutdown();
165
166       
167#ifdef USE_SPACENAVIGATOR
168        //Delete SpaceMouse driver
169        if(mouse)
170        {
171                mouse->shutdown();
172                delete mouse;
173        }
174#endif
175
176        // Destroy osgViewer
177        viewer = NULL;
178}
179
180bool visual_core::loadTerrain(osg::ArgumentParser& arguments_)
181{
182        osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(util::getTerrainFromXMLConfig(configFilename));
183        if( model.valid() )
184        {
185        rootNode->addChild( model.get() );
186                return true;
187        }
188        else
189        {
190        OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl;
191        return false;
192    }   
193
194        return false;
195}
196
197void visual_core::addManipulators()
198{
199        if(!visual_dataIO::getInstance()->isSlave()) // set up the camera manipulators if not slave.
200    {
201        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
202
203        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
204        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
205        keyswitchManipulator->addMatrixManipulator( '3', "Terrain", new osgGA::TerrainManipulator() );
206                nt = new osgGA::NodeTrackerManipulator();
207                nt->setTrackNode(NULL);
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 = util::getAnimationPathFromXMLConfig(configFilename);
228        char keyForAnimationPath = '8';
229                if( 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::parseScenery(xmlNode* a_node)
270{
271        OSG_ALWAYS << "parseScenery()" << std::endl;
272
273        a_node = a_node->children;
274
275        for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
276        {
277                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
278
279                // terrain is parsend seperately
280                // animationpath is parsend seperately
281
282                if(cur_node->type == XML_ELEMENT_NODE && node_name == "models")
283                {
284                        for (xmlNode *modelNode = cur_node->children; modelNode; modelNode = modelNode->next)
285                        {
286                                std::string name=reinterpret_cast<const char*>(modelNode->name);
287                                if(modelNode->type == XML_ELEMENT_NODE && name == "model")
288                                {
289                                        visual_object::createNodeFromXMLConfig(rootNode, modelNode);
290                                }
291                                if(modelNode->type == XML_ELEMENT_NODE && name == "trackmodel")
292                                {
293                                        // Extract track-ID and track the model
294                                        xmlAttr  *attr = modelNode->properties;
295                                        while ( attr ) 
296                                        { 
297                                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
298                                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
299                                                if( attr_name == "id" ) trackNode( util::strToInt(attr_value) );
300
301
302                                                attr = attr->next; 
303                                        }
304                                       
305                                }
306                        }
307                }
308
309#ifdef USE_SKY_SILVERLINING
310                if(cur_node->type == XML_ELEMENT_NODE && node_name == "datetime")
311                {
312                        int hour, minute;
313                        int day=0,month=0,year=0;
314
315                        xmlAttr  *attr = cur_node->properties;
316                        while ( attr ) 
317                        { 
318                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
319                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
320                                if( attr_name == "day" ) day = util::strToInt(attr_value);
321                                if( attr_name == "month" ) month = util::strToInt(attr_value);
322                                if( attr_name == "year" ) year = util::strToInt(attr_value);
323                                if( attr_name == "hour" ) hour = util::strToInt(attr_value);
324                                if( attr_name == "minute" ) minute = util::strToInt(attr_value);
325
326                                attr = attr->next; 
327                        }
328                        if(sky.valid())
329                        {
330                                if(day!=0 && month!=0 && year!=0)
331                                        sky->setDate(year, month, day);
332                                sky->setTime(hour,minute,00);
333                        }
334                }
335
336                if(cur_node->type == XML_ELEMENT_NODE && node_name == "visibility")
337                {
338                        float range = 50000, turbidity=2.2;
339                        xmlAttr  *attr = cur_node->properties;
340                        while ( attr ) 
341                        { 
342                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
343                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
344                                if( attr_name == "range" ) range = util::strToDouble(attr_value);
345                                if( attr_name == "turbidity" ) turbidity = util::strToDouble(attr_value);
346
347                                attr = attr->next; 
348                        }
349
350                        if(sky.valid())
351                        {
352                                sky->setVisibility( range );
353                                sky->setTurbidity( turbidity );
354                        }
355                }
356
357                if(cur_node->type == XML_ELEMENT_NODE && node_name == "clouds")
358                {
359                        if(sky.valid())
360                                sky->configureCloudlayerbyXML( cur_node );
361                }
362
363                if(cur_node->type == XML_ELEMENT_NODE && node_name == "windlayer")
364                {
365                        float bottom = 0.0, top=5000.0, speed=25.0, direction=0.0;
366                        xmlAttr  *attr = cur_node->properties;
367                        while ( attr ) 
368                        { 
369                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
370                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
371                                if( attr_name == "bottom" ) bottom = util::strToDouble(attr_value);
372                                if( attr_name == "top" ) top = util::strToDouble(attr_value);
373                                if( attr_name == "speed" ) speed = util::strToDouble(attr_value);
374                                if( attr_name == "direction" ) direction = util::strToDouble(attr_value);
375
376                                attr = attr->next; 
377                        }
378                        if(sky.valid())
379                        {
380                                sky->addWindVolume( bottom, top, speed, direction );
381                        }
382                }
383
384                // Track Node
385
386#endif
387        }// FOR all nodes END
388
389}
390
391bool visual_core::checkCommandlineArgumentsForFinalErrors()
392{
393        // Setup Application Usage
394        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
395        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
396    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [OSG options] -c XML-Configurationfile");
397        arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
398        arguments.getApplicationUsage()->addCommandLineOption("-c or --config","XML configuration filename");
399
400
401    // if user request help write it out to cout.
402    if (arguments.read("-h") || arguments.read("--help"))
403    {
404        arguments.getApplicationUsage()->write(std::cout);
405                //cause the viewer to exit and shut down clean.
406        viewer->setDone(true);
407    }
408
409    // report any errors if they have occurred when parsing the program arguments.
410    if (arguments.errors())
411    {
412        arguments.writeErrorMessages(std::cout);
413                //cause the viewer to exit and shut down clean.
414        viewer->setDone(true);
415    }
416
417         // any option left unread are converted into errors to write out later.
418    arguments.reportRemainingOptionsAsUnrecognized();
419
420    // report any errors if they have occurred when parsing the program arguments.
421    if (arguments.errors())
422    {
423        arguments.writeErrorMessages(std::cout);
424        return false;
425    }
426        return true;
427}
428
429void visual_core::setupScenery()
430{
431        // Parse Scenery from Configuration file
432        xmlDoc* tmpDoc;
433        xmlNode* sceneryNode = util::getSceneryXMLConfig(configFilename, tmpDoc);
434        parseScenery(sceneryNode);
435        if(sceneryNode)
436        {
437                xmlFreeDoc(tmpDoc); xmlCleanupParser();
438        }
439
440
441        //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
442        //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
443        ///* using a huge cylinder to test position & orientation */
444        //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
445        //testObj->addUpdater( new object_updater(testObj) );
446
447        //osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );       // todo memleak
448        ////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
449        //testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
450        //testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
451        ////testObj2->addUpdater( new object_updater(testObj2) );
452
453        //osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );     // todo memleak
454        //testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
455        //testObj3->loadGeometry( "../models/saenger1.flt" );
456        //testObj3->addUpdater( new object_updater(testObj3) );
457        //
458
459        osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );       // todo memleak
460        testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
461        testObj4->loadGeometry( "../models/saenger2.flt" );
462        testObj4->addUpdater( new object_updater(testObj4) );
463        testObj4->addLabel("testLabel", "Object4 :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
464
465        //osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );      // todo memleak
466        //testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
467        //testObj5->loadGeometry( "../models/saengerCombine.flt" );
468        ////testObj5->setScale( 2 );
469        //testObj5->addUpdater( new object_updater(testObj5) );
470
471        //trackNode( testObj4 );
472
473        // Load EDDF
474        //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
475        //if( !osgDB::fileExists(filename) )
476        //{
477        //      OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
478        //}
479        //// read model
480        //osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
481        //if (tmpModel.valid())
482        //      rootNode->addChild( tmpModel );
483       
484 
485        visual_draw2D::getInstance()->init( rootNode, viewer );
486        //osg::ref_ptr<visual_hud> hud = new visual_hud();
487        hud = new visual_debug_hud();
488        hud->init( viewer, rootNode );
489       
490       
491
492        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
493        //test->init( rootNode, viewer );
494
495        //// Creating Testclasses
496        //osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
497        //osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
498        //osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
499        //test->setFrameID( 22 );
500        //test->setName("ugamoep");
501        //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
502        //testSlot->setVariableName(std::string("HalloName"));
503        //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
504        //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
505        //testSlot->setValue( 0.12345 );
506        //test->addExecuter( testEx );
507        //test->addSlot( testSlot );
508
509        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
510
511}
512
513void visual_core::trackNode( osg::Node* node_ )
514{
515        if(!node_)
516                return;
517
518        osg::Node* node = NULL;
519        // Check if tracked node is a visual_object
520        osgVisual::visual_object* trackedObject = dynamic_cast<osgVisual::visual_object*>(node_);
521        if(trackedObject)
522        {
523                node = trackedObject->getGeometry();
524
525                // Object mounted manipulator ( Only working with visual_object, not with osg::Node )
526                if (objectMountedCameraManip.valid())
527                        objectMountedCameraManip->setAttachedObject( trackedObject );
528        }
529        else
530                node = node_;
531
532        // Spacemouse Node Tracker
533#ifdef USE_SPACENAVIGATOR
534        if (mouseTrackerManip.valid())
535        {
536                mouseTrackerManip->setTrackNode( node );
537                mouseTrackerManip->setMinimumDistance( 100 );
538        }
539#endif
540
541        // Classical OSG Nodetracker
542        if(nt.valid())
543        {
544                osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
545                osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
546                nt->setTrackerMode(trackerMode);
547                nt->setRotationMode(rotationMode);
548                nt->setMinimumDistance( 100 );
549                nt->setTrackNode( node );
550                nt->setAutoComputeHomePosition( true );
551                nt->setDistance( 250 );
552        }
553}
554
555void visual_core::trackNode( int trackingID )
556{
557        osg::ref_ptr<osg::Node> tmp = visual_object::findNodeByTrackingID(trackingID, rootNode);
558        if(tmp.valid())
559        {
560                currentTrackingID = trackingID;
561                trackNode(tmp);
562        }
563}
Note: See TracBrowser for help on using the repository browser.