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

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