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

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

changed updater from degreet to radian

now osgvisual uses internally rad, whiel the XML configuration file uses degree to be human readable.

File size: 18.0 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
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                        for (xmlNode *modelNode = cur_node->children; modelNode; modelNode = modelNode->next)
282                        {
283                                std::string name=reinterpret_cast<const char*>(modelNode->name);
284                                if(cur_node->type == XML_ELEMENT_NODE && name == "model")
285                                {
286                                        visual_object::createNodeFromXMLConfig(rootNode, modelNode);
287                                }
288                        }
289                }
290
291#ifdef USE_SKY_SILVERLINING
292                if(cur_node->type == XML_ELEMENT_NODE && node_name == "datetime")
293                {
294                        int hour, minute;
295                        int day=0,month=0,year=0;
296
297                        xmlAttr  *attr = cur_node->properties;
298                        while ( attr ) 
299                        { 
300                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
301                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
302                                if( attr_name == "day" ) day = util::strToInt(attr_value);
303                                if( attr_name == "month" ) month = util::strToInt(attr_value);
304                                if( attr_name == "year" ) year = util::strToInt(attr_value);
305                                if( attr_name == "hour" ) hour = util::strToInt(attr_value);
306                                if( attr_name == "minute" ) minute = util::strToInt(attr_value);
307
308                                attr = attr->next; 
309                        }
310                        if(sky.valid())
311                        {
312                                if(day!=0 && month!=0 && year!=0)
313                                        sky->setDate(year, month, day);
314                                sky->setTime(hour,minute,00);
315                        }
316                }
317
318                if(cur_node->type == XML_ELEMENT_NODE && node_name == "visibility")
319                {
320                        float range = 50000, turbidity=2.2;
321                        xmlAttr  *attr = cur_node->properties;
322                        while ( attr ) 
323                        { 
324                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
325                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
326                                if( attr_name == "range" ) range = util::strToDouble(attr_value);
327                                if( attr_name == "turbidity" ) turbidity = util::strToDouble(attr_value);
328
329                                attr = attr->next; 
330                        }
331
332                        if(sky.valid())
333                        {
334                                sky->setVisibility( range );
335                                sky->setTurbidity( turbidity );
336                        }
337                }
338
339                if(cur_node->type == XML_ELEMENT_NODE && node_name == "clouds")
340                {
341                        if(sky.valid())
342                                sky->configureCloudlayerbyXML( cur_node );
343                }
344
345                if(cur_node->type == XML_ELEMENT_NODE && node_name == "windlayer")
346                {
347                        float bottom = 0.0, top=5000.0, speed=25.0, direction=0.0;
348                        xmlAttr  *attr = cur_node->properties;
349                        while ( attr ) 
350                        { 
351                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
352                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
353                                if( attr_name == "bottom" ) bottom = util::strToDouble(attr_value);
354                                if( attr_name == "top" ) top = util::strToDouble(attr_value);
355                                if( attr_name == "speed" ) speed = util::strToDouble(attr_value);
356                                if( attr_name == "direction" ) direction = util::strToDouble(attr_value);
357
358                                attr = attr->next; 
359                        }
360                        if(sky.valid())
361                        {
362                                sky->addWindVolume( bottom, top, speed, direction );
363                        }
364                }
365
366                // Track Node
367
368#endif
369        }// FOR all nodes END
370
371}
372
373bool visual_core::checkCommandlineArgumentsForFinalErrors()
374{
375        // Setup Application Usage
376        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
377        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
378    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [OSG options] -c XML-Configurationfile");
379        arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
380        arguments.getApplicationUsage()->addCommandLineOption("-c or --config","XML configuration filename");
381
382
383    // if user request help write it out to cout.
384    if (arguments.read("-h") || arguments.read("--help"))
385    {
386        arguments.getApplicationUsage()->write(std::cout);
387                //cause the viewer to exit and shut down clean.
388        viewer->setDone(true);
389    }
390
391    // report any errors if they have occurred when parsing the program arguments.
392    if (arguments.errors())
393    {
394        arguments.writeErrorMessages(std::cout);
395                //cause the viewer to exit and shut down clean.
396        viewer->setDone(true);
397    }
398
399         // any option left unread are converted into errors to write out later.
400    arguments.reportRemainingOptionsAsUnrecognized();
401
402    // report any errors if they have occurred when parsing the program arguments.
403    if (arguments.errors())
404    {
405        arguments.writeErrorMessages(std::cout);
406        return false;
407    }
408        return true;
409}
410
411void visual_core::setupScenery()
412{
413        // Parse Scenery from Configuration file
414        xmlDoc* tmpDoc;
415        xmlNode* sceneryNode = util::getSceneryXMLConfig(configFilename, tmpDoc);
416        parseScenery(sceneryNode);
417        if(sceneryNode)
418        {
419                xmlFreeDoc(tmpDoc); xmlCleanupParser();
420        }
421
422
423        //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
424        //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
425        ///* using a huge cylinder to test position & orientation */
426        //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
427        //testObj->addUpdater( new object_updater(testObj) );
428
429        //osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );       // todo memleak
430        ////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
431        //testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
432        //testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
433        ////testObj2->addUpdater( new object_updater(testObj2) );
434
435        //osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );     // todo memleak
436        //testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
437        //testObj3->loadGeometry( "../models/saenger1.flt" );
438        //testObj3->addUpdater( new object_updater(testObj3) );
439        //
440
441        osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );       // todo memleak
442        testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
443        testObj4->loadGeometry( "../models/saenger2.flt" );
444        testObj4->addUpdater( new object_updater(testObj4) );
445        testObj4->addLabel("testLabel", "Object4 :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
446
447        //osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );      // todo memleak
448        //testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
449        //testObj5->loadGeometry( "../models/saengerCombine.flt" );
450        ////testObj5->setScale( 2 );
451        //testObj5->addUpdater( new object_updater(testObj5) );
452
453        trackNode( testObj4 );
454
455        // Load EDDF
456        //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
457        //if( !osgDB::fileExists(filename) )
458        //{
459        //      OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
460        //}
461        //// read model
462        //osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
463        //if (tmpModel.valid())
464        //      rootNode->addChild( tmpModel );
465       
466 
467        visual_draw2D::getInstance()->init( rootNode, viewer );
468        //osg::ref_ptr<visual_hud> hud = new visual_hud();
469        hud = new visual_debug_hud();
470        hud->init( viewer, rootNode );
471       
472       
473
474        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
475        //test->init( rootNode, viewer );
476
477        //// Creating Testclasses
478        //osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
479        //osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
480        //osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
481        //test->setFrameID( 22 );
482        //test->setName("ugamoep");
483        //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
484        //testSlot->setVariableName(std::string("HalloName"));
485        //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
486        //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
487        //testSlot->setValue( 0.12345 );
488        //test->addExecuter( testEx );
489        //test->addSlot( testSlot );
490
491        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
492
493}
494
495void visual_core::trackNode( osg::Node* node_ )
496{
497        if(!node_)
498                return;
499
500        osg::Node* node = NULL;
501        // Check if tracked node is a visual_object
502        osgVisual::visual_object* trackedObject = dynamic_cast<osgVisual::visual_object*>(node_);
503        if(trackedObject)
504        {
505                node = trackedObject->getGeometry();
506
507                // Object mounted manipulator ( Only working with visual_object, not with osg::Node )
508                if (objectMountedCameraManip.valid())
509                        objectMountedCameraManip->setAttachedObject( trackedObject );
510        }
511        else
512                node = node_;
513
514        // Spacemouse Node Tracker
515#ifdef USE_SPACENAVIGATOR
516        if (mouseTrackerManip.valid())
517        {
518                mouseTrackerManip->setTrackNode( node );
519                mouseTrackerManip->setMinimumDistance( 100 );
520        }
521#endif
522
523        // Classical OSG Nodetracker
524        if(nt.valid())
525        {
526                osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
527                osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
528                nt->setTrackerMode(trackerMode);
529                nt->setRotationMode(rotationMode);
530                nt->setMinimumDistance( 100 );
531                nt->setTrackNode( node );
532                nt->setAutoComputeHomePosition( true );
533                nt->setDistance( 250 );
534        }
535}
Note: See TracBrowser for help on using the repository browser.