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

Last change on this file since 364 was 364, checked in by Torben Dannhauer, 12 years ago
File size: 15.6 KB
RevLine 
[221]1/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 Torben Dannhauer
[31]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
[86]17
[31]18#include <visual_core.h>
[273]19#include <visual_util.h>
20#include <osgTerrain/Terrain>
[324]21#include <osgDB/FileNameUtils>
[31]22
23using namespace osgVisual;
24
25visual_core::visual_core(osg::ArgumentParser& arguments_) : arguments(arguments_)
26{
27        OSG_NOTIFY( osg::ALWAYS ) << "visual_core instantiated." << std::endl;
[86]28}
[31]29
[86]30visual_core::~visual_core(void)
31{
32        OSG_NOTIFY( osg::ALWAYS ) << "visual_core destroyed." << std::endl;
33}
34
35void visual_core::initialize()
36{
37        OSG_NOTIFY( osg::ALWAYS ) << "Initialize visual_core..." << std::endl;
38
[144]39        // Check for config file to provide it to all modules during initialization.
40        if( arguments.read("-c", configFilename) || arguments.read("--config", configFilename) )
41        {
42                if( !osgDB::fileExists(configFilename) )
43                        configFilename = "";
44                else
45                        OSG_ALWAYS << "Using configuration file: " << configFilename << std::endl;
46        }
47
[86]48        // Configure osg to use KdTrees
49        osgDB::Registry::instance()->setBuildKdTreesHint(osgDB::ReaderWriter::Options::BUILD_KDTREES);
50
[305]51        // Configure Multisampling
52        osg::DisplaySettings::instance()->setNumMultiSamples(4);
53
[31]54        // Setup pathes
[364]55        osgDB::Registry::instance()->getDataFilePathList().push_front("H:\AllInOnDB");
[31]56        osgDB::Registry::instance()->getDataFilePathList().push_back( "D:\\DA\\osgVisual\\models" );
[364]57
[31]58       
59        // Setup viewer
60        viewer = new osgViewer::Viewer(arguments);
61
62        // Setup coordinate system node
[87]63        rootNode = new osg::CoordinateSystemNode;       // todo memleakf
[31]64        rootNode->setEllipsoidModel(new osg::EllipsoidModel());
65
66        // Test memory leak (todo)
[116]67        double* test = new double[1000];
[31]68
[55]69        //osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( 8 );
[31]70
71        // Show model
72        viewer->setSceneData( rootNode );
73
[71]74        osg::Group* distortedSceneGraph = NULL;
[31]75#ifdef USE_DISTORTION
76        // Initialize distortion
[144]77        distortion = new visual_distortion( viewer, arguments, configFilename );
[151]78        distortedSceneGraph = distortion->initialize( rootNode, viewer->getCamera()->getClearColor() );
[31]79#endif
80
81#ifdef USE_SKY_SILVERLINING
82        // Initialize sky
[182]83        bool disabled = false;  // to ask if the skyp is disabled or enabled
84        sky = new visual_skySilverLining( viewer, configFilename, disabled );
85        if(disabled)
86                sky = NULL;
87        if(sky.valid())
88                sky->init(distortedSceneGraph, rootNode);       // Without distortion: distortedSceneGraph=NULL
[31]89#endif
90
91        // Initialize DataIO interface
[185]92        visual_dataIO::getInstance()->init(viewer, configFilename);
[31]93
[144]94        // Add manipulators for user interaction - after dataIO to be able to skip it in slaves rendering machines.
[231]95        manipulators = new core_manipulator();
96        manipulators->init( viewer, arguments, configFilename, rootNode);
[73]97
[31]98        // create the windows and run the threads.
99        viewer->realize();
100
[189]101        loadTerrain(arguments);
102
[127]103        // All modules are initialized - now check arguments for any unused parameter.
104        checkCommandlineArgumentsForFinalErrors();
105
[31]106        // Run visual main loop
107        mainLoop();
108}
109
110void visual_core::mainLoop()
111{
[134]112        int framestoScenerySetup = 5;
[31]113        // run main loop
114        while( !viewer->done() )
115    {
[134]116                // setup scenery
117                if(framestoScenerySetup-- == 0)
118                        setupScenery();
119
[31]120                // next frame please....
121        viewer->advance();
122
123                /*double hat, hot, lat, lon, height;
124                util::getWGS84ofCamera( viewer->getCamera(), rootNode, lat, lon, height);
125                if (util::queryHeightOfTerrain( hot, rootNode, lat, lon) && util::queryHeightAboveTerrainInWGS84( hat, rootNode, lat, lon, height ) )
126                        OSG_NOTIFY( osg::ALWAYS ) << "HOT is: " << hot << ", HAT is: " << hat << std::endl;*/
127       
[70]128                // perform all queued events
129                viewer->eventTraversal();
130
[31]131                // update the scene by traversing it with the the update visitor which will
132        // call all node update callbacks and animations.
133        viewer->updateTraversal();
134               
135        // Render the Frame.
136        viewer->renderingTraversals();
137
138    }   // END WHILE
139}
140
141void visual_core::shutdown()
142{
143        OSG_NOTIFY( osg::ALWAYS ) << "Shutdown visual_core..." << std::endl;
144
[87]145        // Shutdown Dbug HUD
146        if(hud.valid())
147                hud->shutdown();
[31]148        // Unset scene data
149        viewer->setSceneData( NULL );
150
151#ifdef USE_SKY_SILVERLINING
152        // Shutdown sky
153        if( sky.valid() )
154                sky->shutdown();
155#endif
156
157#ifdef USE_DISTORTION
158        // Shutdown distortion
159        if( distortion.valid() )
160                distortion->shutdown();
161#endif
162
[87]163        // Shutdown data
164        rootNode = NULL;
165
[31]166        // Shutdown dataIO
167        visual_dataIO::getInstance()->shutdown();
168
[231]169        // Shutdown manipulators
170        if(manipulators.valid())
171                manipulators->shutdown();
[86]172
173        // Destroy osgViewer
174        viewer = NULL;
[31]175}
176
177bool visual_core::loadTerrain(osg::ArgumentParser& arguments_)
178{
[324]179        std::vector<std::string> terrainFile = util::getTerrainFromXMLConfig(configFilename);
180
181        // Add each terrain path to the FilePath list to help OSG to find the subtiles.
182        for(unsigned int i=0;i<terrainFile.size();i++)
183                osgDB::Registry::instance()->getDataFilePathList().push_back(osgDB::getFilePath(terrainFile[i]));
184
185        osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(terrainFile);
[31]186        if( model.valid() )
187        {
[273]188        osgTerrain::Terrain* terrain = util::findTopMostNodeOfType<osgTerrain::Terrain>(model.get());
189                if (!terrain)
190                {
191                        terrain = new osgTerrain::Terrain;
192                        terrain->addChild(model.get());
193
194                        model = terrain;                       
195                }
196                rootNode->addChild( terrain );
[31]197                return true;
198        }
199        else
200        {
[58]201        OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl;
[31]202        return false;
203    }   
204
205        return false;
206}
207
[188]208void visual_core::parseScenery(xmlNode* a_node)
[125]209{
[128]210        OSG_ALWAYS << "parseScenery()" << std::endl;
[125]211
[188]212        a_node = a_node->children;
213
214        for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
215        {
216                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
217
[194]218                // terrain is parsend seperately
[364]219                // animationpath is parsend seperately in util::getAnimationPathFromXMLConfig(..) which invokes this function.
[188]220
221                if(cur_node->type == XML_ELEMENT_NODE && node_name == "models")
222                {
[202]223                        for (xmlNode *modelNode = cur_node->children; modelNode; modelNode = modelNode->next)
224                        {
[203]225                                std::string name=reinterpret_cast<const char*>(modelNode->name);
[227]226                                if(modelNode->type == XML_ELEMENT_NODE && name == "model")
[203]227                                {
228                                        visual_object::createNodeFromXMLConfig(rootNode, modelNode);
229                                }
[227]230                                if(modelNode->type == XML_ELEMENT_NODE && name == "trackmodel")
[225]231                                {
[226]232                                        // Extract track-ID and track the model
[227]233                                        xmlAttr  *attr = modelNode->properties;
[226]234                                        while ( attr ) 
235                                        { 
236                                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
237                                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
[231]238                                                if( attr_name == "id" ) manipulators->trackNode( util::strToInt(attr_value) );
[234]239                                                if( attr_name == "updater_slot" ) manipulators->setTrackingIdUpdaterSlot(attr_value);
[226]240                                                attr = attr->next; 
241                                        }
242                                       
[225]243                                }
[202]244                        }
[188]245                }
246
[211]247#ifdef USE_SKY_SILVERLINING
[188]248                if(cur_node->type == XML_ELEMENT_NODE && node_name == "datetime")
249                {
[248]250                        int day=-1, month=-1, year=-1, hour=-1, minute=-1;
[189]251
252                        xmlAttr  *attr = cur_node->properties;
253                        while ( attr ) 
254                        { 
255                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
256                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
[219]257                                if( attr_name == "day" ) day = util::strToInt(attr_value);
258                                if( attr_name == "month" ) month = util::strToInt(attr_value);
259                                if( attr_name == "year" ) year = util::strToInt(attr_value);
260                                if( attr_name == "hour" ) hour = util::strToInt(attr_value);
261                                if( attr_name == "minute" ) minute = util::strToInt(attr_value);
262
[189]263                                attr = attr->next; 
264                        }
265                        if(sky.valid())
266                        {
267                                if(day!=0 && month!=0 && year!=0)
268                                        sky->setDate(year, month, day);
269                                sky->setTime(hour,minute,00);
270                        }
[188]271                }
272
273                if(cur_node->type == XML_ELEMENT_NODE && node_name == "visibility")
274                {
[195]275                        float range = 50000, turbidity=2.2;
276                        xmlAttr  *attr = cur_node->properties;
277                        while ( attr ) 
278                        { 
279                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
280                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
[219]281                                if( attr_name == "range" ) range = util::strToDouble(attr_value);
282                                if( attr_name == "turbidity" ) turbidity = util::strToDouble(attr_value);
283
[195]284                                attr = attr->next; 
285                        }
[211]286
[195]287                        if(sky.valid())
288                        {
289                                sky->setVisibility( range );
290                                sky->setTurbidity( turbidity );
291                        }
[188]292                }
293
[200]294                if(cur_node->type == XML_ELEMENT_NODE && node_name == "clouds")
[188]295                {
[198]296                        if(sky.valid())
297                                sky->configureCloudlayerbyXML( cur_node );
[188]298                }
299
300                if(cur_node->type == XML_ELEMENT_NODE && node_name == "windlayer")
301                {
[195]302                        float bottom = 0.0, top=5000.0, speed=25.0, direction=0.0;
303                        xmlAttr  *attr = cur_node->properties;
304                        while ( attr ) 
305                        { 
306                                std::string attr_name=reinterpret_cast<const char*>(attr->name);
307                                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
[219]308                                if( attr_name == "bottom" ) bottom = util::strToDouble(attr_value);
309                                if( attr_name == "top" ) top = util::strToDouble(attr_value);
310                                if( attr_name == "speed" ) speed = util::strToDouble(attr_value);
311                                if( attr_name == "direction" ) direction = util::strToDouble(attr_value);
312
[195]313                                attr = attr->next; 
314                        }
315                        if(sky.valid())
316                        {
317                                sky->addWindVolume( bottom, top, speed, direction );
318                        }
[188]319                }
[212]320
321                // Track Node
322
[211]323#endif
[188]324        }// FOR all nodes END
325
[129]326}
327
[67]328bool visual_core::checkCommandlineArgumentsForFinalErrors()
[31]329{
330        // Setup Application Usage
331        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
332        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
[212]333    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [OSG options] -c XML-Configurationfile");
[31]334        arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
[212]335        arguments.getApplicationUsage()->addCommandLineOption("-c or --config","XML configuration filename");
[31]336
[212]337
[31]338    // if user request help write it out to cout.
339    if (arguments.read("-h") || arguments.read("--help"))
340    {
341        arguments.getApplicationUsage()->write(std::cout);
342                //cause the viewer to exit and shut down clean.
343        viewer->setDone(true);
344    }
345
346    // report any errors if they have occurred when parsing the program arguments.
347    if (arguments.errors())
348    {
349        arguments.writeErrorMessages(std::cout);
350                //cause the viewer to exit and shut down clean.
351        viewer->setDone(true);
352    }
353
354         // any option left unread are converted into errors to write out later.
355    arguments.reportRemainingOptionsAsUnrecognized();
356
357    // report any errors if they have occurred when parsing the program arguments.
358    if (arguments.errors())
359    {
360        arguments.writeErrorMessages(std::cout);
361        return false;
362    }
363        return true;
364}
365
366void visual_core::setupScenery()
367{
[194]368        // Parse Scenery from Configuration file
369        xmlDoc* tmpDoc;
370        xmlNode* sceneryNode = util::getSceneryXMLConfig(configFilename, tmpDoc);
371        parseScenery(sceneryNode);
372        if(sceneryNode)
373        {
374                xmlFreeDoc(tmpDoc); xmlCleanupParser();
375        }
[122]376
[273]377        osgTerrain::Terrain* terrain = util::findTopMostNodeOfType<osgTerrain::Terrain>(rootNode);
378    if (!terrain)
379    {
380        OSG_ALWAYS << "No TerrainNode found!" << std::endl;
381    }
382        else
383        {
[305]384                //OSG_ALWAYS << "BorderEqual activated" << std::endl;
385                //terrain->setEqualizeBoundaries(true);
[273]386        }
[194]387
[31]388        //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
389        //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
390        ///* using a huge cylinder to test position & orientation */
391        //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
392        //testObj->addUpdater( new object_updater(testObj) );
[235]393        //testObj->setTrackingId(2);
[31]394
[115]395        //osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );       // todo memleak
396        ////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
397        //testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
398        //testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
[216]399        ////testObj2->addUpdater( new object_updater(testObj2) );
[235]400        //testObj2->setTrackingId(3);
[31]401
[212]402        //osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );     // todo memleak
403        //testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
404        //testObj3->loadGeometry( "../models/saenger1.flt" );
[216]405        //testObj3->addUpdater( new object_updater(testObj3) );
[235]406        //testObj3->setTrackingId(4);
[31]407
[364]408        //osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );     // todo memleak
409        //testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
410        //testObj4->loadGeometry( "../models/saenger2.flt" );
411        //testObj4->addUpdater( new object_updater(testObj4) );
412        //testObj4->addLabel("testLabel", "Object4 :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
413        //testObj4->setTrackingId(2);
[31]414
[212]415        //osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );      // todo memleak
416        //testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
417        //testObj5->loadGeometry( "../models/saengerCombine.flt" );
418        ////testObj5->setScale( 2 );
[216]419        //testObj5->addUpdater( new object_updater(testObj5) );
[235]420        //testObj5->setTrackingId(6);
[31]421
[364]422        //manipulators->trackNode( testObj4 );
[31]423
424        // Load EDDF
425        //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
426        //if( !osgDB::fileExists(filename) )
427        //{
428        //      OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
429        //}
430        //// read model
431        //osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
432        //if (tmpModel.valid())
433        //      rootNode->addChild( tmpModel );
434       
435 
436        visual_draw2D::getInstance()->init( rootNode, viewer );
437        //osg::ref_ptr<visual_hud> hud = new visual_hud();
[87]438        hud = new visual_debug_hud();
[31]439        hud->init( viewer, rootNode );
440       
[122]441       
[31]442
443        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
444        //test->init( rootNode, viewer );
445
[69]446        //// Creating Testclasses
447        //osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
448        //osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
449        //osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
450        //test->setFrameID( 22 );
451        //test->setName("ugamoep");
452        //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
453        //testSlot->setVariableName(std::string("HalloName"));
454        //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
455        //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
456        //testSlot->setValue( 0.12345 );
457        //test->addExecuter( testEx );
458        //test->addSlot( testSlot );
[31]459
[69]460        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
[155]461
[31]462}
Note: See TracBrowser for help on using the repository browser.