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

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