source: osgVisual/src/core/visual_core.cpp @ 160

Last change on this file since 160 was 156, checked in by Torben Dannhauer, 14 years ago
File size: 17.7 KB
RevLine 
[31]1/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 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
[86]17
[31]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;
[86]25}
[31]26
[86]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
[144]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
[86]45        // Configure osg to use KdTrees
46        osgDB::Registry::instance()->setBuildKdTreesHint(osgDB::ReaderWriter::Options::BUILD_KDTREES);
47
[31]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
[87]55        rootNode = new osg::CoordinateSystemNode;       // todo memleakf
[31]56        rootNode->setEllipsoidModel(new osg::EllipsoidModel());
57
58        // Test memory leak (todo)
[116]59        double* test = new double[1000];
[31]60
[55]61        #ifdef USE_SPACENAVIGATOR
62                mouse = NULL;
63        #endif
64
65        //osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( 8 );
[31]66
67        // Show model
68        viewer->setSceneData( rootNode );
69
[71]70        osg::Group* distortedSceneGraph = NULL;
[31]71#ifdef USE_DISTORTION
72        // Initialize distortion
[144]73        distortion = new visual_distortion( viewer, arguments, configFilename );
[151]74        distortedSceneGraph = distortion->initialize( rootNode, viewer->getCamera()->getClearColor() );
[31]75#endif
76
77#ifdef USE_SKY_SILVERLINING
78        // Initialize sky
[144]79        sky = new visual_skySilverLining( viewer, configFilename );
80        sky->init(distortedSceneGraph, rootNode);       // Without distortion: distortedSceneGraph=NULL
[31]81#endif
82
83        // Initialize DataIO interface
[144]84        visual_dataIO::getInstance()->init(viewer, arguments, configFilename);
[31]85
[144]86        // Add manipulators for user interaction - after dataIO to be able to skip it in slaves rendering machines.
[73]87        addManipulators();
88
[68]89        loadTerrain(arguments);
90
[31]91        // create the windows and run the threads.
92        viewer->realize();
93
[127]94        // parse Configuration file
95        parseConfigFile(arguments);
96
97        // All modules are initialized - now check arguments for any unused parameter.
98        checkCommandlineArgumentsForFinalErrors();
99
[31]100        // Run visual main loop
101        mainLoop();
102}
103
104void visual_core::mainLoop()
105{
[134]106        int framestoScenerySetup = 5;
[31]107        // run main loop
108        while( !viewer->done() )
109    {
[134]110                // setup scenery
111                if(framestoScenerySetup-- == 0)
112                        setupScenery();
113
[31]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       
[70]122                // perform all queued events
123                viewer->eventTraversal();
124
[31]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
[87]139        // Shutdown Dbug HUD
140        if(hud.valid())
141                hud->shutdown();
[31]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
[87]157        // Shutdown data
158        rootNode = NULL;
159
[31]160        // Shutdown dataIO
161        visual_dataIO::getInstance()->shutdown();
162
163       
164#ifdef USE_SPACENAVIGATOR
165        //Delete SpaceMouse driver
166        if(mouse)
167        {
168                mouse->shutdown();
169                delete mouse;
170        }
171#endif
[86]172
173        // Destroy osgViewer
174        viewer = NULL;
[31]175}
176
177bool visual_core::loadTerrain(osg::ArgumentParser& arguments_)
178{
179        osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments_);
180        if( model.valid() )
181        {
182        rootNode->addChild( model.get() );
183                return true;
184        }
185        else
186        {
[58]187        OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl;
[31]188        return false;
189    }   
190
191        return false;
192}
193
194void visual_core::addManipulators()
195{
[73]196        if(!visual_dataIO::getInstance()->isSlave()) // set up the camera manipulators if not slave.
[31]197    {
198        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
199
200        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
201        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
202        keyswitchManipulator->addMatrixManipulator( '3', "Terrain", new osgGA::TerrainManipulator() );
203                nt = new osgGA::NodeTrackerManipulator();
204                keyswitchManipulator->addMatrixManipulator( '4', "NodeTrackerManipulator", nt );
205               
206#ifdef USE_SPACENAVIGATOR
207                // SpaceNavigator manipulator
208                mouse = new SpaceMouse();
209                mouse->initialize();
210                mouseTrackerManip = new NodeTrackerSpaceMouse(mouse);
211                mouseTrackerManip->setTrackerMode(NodeTrackerSpaceMouse::NODE_CENTER);
212                mouseTrackerManip->setRotationMode(NodeTrackerSpaceMouse::ELEVATION_AZIM);
213                mouseTrackerManip->setAutoComputeHomePosition( true );
214                keyswitchManipulator->addMatrixManipulator( '5', "Spacemouse Node Tracker", mouseTrackerManip );
215                keyswitchManipulator->addMatrixManipulator( '6', "Spacemouse Free (Airplane)", new FreeManipulator(mouse) );
216#endif
217
218                // objectMounted Manipulator for Camera control by Nodes
219                objectMountedCameraManip = new objectMountedManipulator();
220                keyswitchManipulator->addMatrixManipulator( '7', "Object mounted Camera", objectMountedCameraManip );
221
222                // Animation path manipulator
223        std::string pathfile;
224        char keyForAnimationPath = '8';
225        while (arguments.read("-p",pathfile))
226        {
227            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
228            if (apm || !apm->valid()) 
229            {
230                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
231                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
232                keyswitchManipulator->selectMatrixManipulator(num);
233                ++keyForAnimationPath;
234            }
235        }
236
237        viewer->setCameraManipulator( keyswitchManipulator.get() );
[73]238    }   // If not Slave END
[31]239
240    // add the state manipulator
241    viewer->addEventHandler( new osgGA::StateSetManipulator(rootNode->getOrCreateStateSet()) );
242   
243    // add the thread model handler
244    viewer->addEventHandler(new osgViewer::ThreadingHandler);
245
246    // add the window size toggle handler
247    viewer->addEventHandler(new osgViewer::WindowSizeHandler);
248       
249    // add the stats handler
250    viewer->addEventHandler(new osgViewer::StatsHandler);
251
252    // add the help handler
253    viewer->addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
254
255    // add the record camera path handler
256    viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
257
258    // add the LOD Scale handler
259    viewer->addEventHandler(new osgViewer::LODScaleHandler);
260
261    // add the screen capture handler
262    viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
263}
264
[125]265void visual_core::parseConfigFile(osg::ArgumentParser& arguments_)
266{
[144]267        if( configFilename != "" )
[125]268        {
[144]269                xmlDoc *doc = NULL;
270                xmlNode *root_element = NULL;
271               
272                doc = xmlReadFile(configFilename.c_str(), NULL, 0);
273                if (doc == NULL)
[125]274                {
[144]275                        OSG_ALWAYS << "visual_core::parseConfigFile() - ERROR: could not parse osgVisual config file" << configFilename  << std::endl;
276                }
277                else
278                {
279                        //  Get the root element node
280                        root_element = xmlDocGetRootElement(doc);
[67]281
[144]282                        // Parse the XML document.
283                        checkXMLNode(root_element);
[125]284
[144]285                        // free the document
286                        xmlFreeDoc(doc);;
287                }
288                // Free the global variables that may have been allocated by the parser.
289                xmlCleanupParser();
[125]290
[144]291        }       // IF configfile exists
[125]292}
293
294void visual_core::checkXMLNode(xmlNode * a_node)
295{
[127]296  for (xmlNode *cur_node = a_node; cur_node; cur_node = cur_node->next)
297        {
298                std::string node_name=reinterpret_cast<const char*>(cur_node->name);
299                if(cur_node->type == XML_ELEMENT_NODE && node_name == "osgvisualconfiguration")
300                {
301                        OSG_DEBUG << "XML node osgvisualconfiguration found" << std::endl;
[144]302
[127]303                        // Iterate to the next nodes to configure modules and scenery.
304                        checkXMLNode(cur_node->children);               
305                }
[125]306
[127]307        if (cur_node->type == XML_ELEMENT_NODE && node_name == "module")
308                {
309                        OSG_DEBUG << "XML node module found" << std::endl;
310
311                        parseModule(cur_node);
312       
313            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
314                        //OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
315        }       // IF(module) END
316
317                if (cur_node->type == XML_ELEMENT_NODE && node_name == "scenery")
318                {
319                        OSG_DEBUG << "XML node scenery found" << std::endl;
320
321                        parseScenery(cur_node);
322       
323            //OSG_DEBUG << "node type=Element, name:" << cur_node->name << std::endl;
324                        //OSG_DEBUG << "Processing children at " << cur_node->children << std::endl;
325        }       // IF(scenery) END
326    }   // FOR END
[125]327}
328
[127]329void visual_core::parseModule(xmlNode * a_node)
330{
[128]331        OSG_ALWAYS << "parseModule()" << std::endl;
332
333// Extract infos
334        std::string name = "";
335        bool enabled = false;
336
337        xmlAttr  *attr = a_node->properties;
338        while ( attr ) 
339        { 
340                std::string attr_name=reinterpret_cast<const char*>(attr->name);
341                std::string attr_value=reinterpret_cast<const char*>(attr->children->content);
342                if( attr_name == "name" )
343                        name = reinterpret_cast<const char*>(attr->children->content);
344                if( attr_name == "enabled" && attr_value== "yes" )
345                        enabled = true;
346                if( attr_name == "enabled" && attr_value== "no" )
347                        enabled = false;
348
349                attr = attr->next; 
350        } 
[144]351        OSG_ALWAYS << "Module '" << name << "' found. Enabled = " << enabled << std::endl;
[128]352
[129]353        // Pass the nodes to the corresponding modules...
354        if(name == "core") this->config(a_node);
[127]355}
356
[125]357void visual_core::parseScenery(xmlNode * a_node)
358{
[128]359        OSG_ALWAYS << "parseScenery()" << std::endl;
[125]360}
361
[129]362void visual_core::config(xmlNode * a_node)
363{
364        // Currently no configuration options fpr the core module are available.
365}
366
[67]367bool visual_core::checkCommandlineArgumentsForFinalErrors()
[31]368{
369        // Setup Application Usage
370        arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
371        arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer");
372    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] Terrain_filename");
373        arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
374
375    // if user request help write it out to cout.
376    if (arguments.read("-h") || arguments.read("--help"))
377    {
378        arguments.getApplicationUsage()->write(std::cout);
379                //cause the viewer to exit and shut down clean.
380        viewer->setDone(true);
381    }
382
383    // report any errors if they have occurred when parsing the program arguments.
384    if (arguments.errors())
385    {
386        arguments.writeErrorMessages(std::cout);
387                //cause the viewer to exit and shut down clean.
388        viewer->setDone(true);
389    }
390
391         // any option left unread are converted into errors to write out later.
392    arguments.reportRemainingOptionsAsUnrecognized();
393
394    // report any errors if they have occurred when parsing the program arguments.
395    if (arguments.errors())
396    {
397        arguments.writeErrorMessages(std::cout);
398        return false;
399    }
400        return true;
401}
402
403void visual_core::setupScenery()
404{
[122]405
406        // Sky settings:       
[144]407        sky->setTime(15,30,00);
[122]408        sky->setVisibility(50000);
[144]409        sky->addWindVolume( 0.0, 15000.0, 25.0, 90.0 );
[122]410       
[136]411        //sky->addCloudLayer( 0, 20000, 20000, 600.0, 1000.0, 0.5, CUMULONIMBUS_CAPPILATUS );
[130]412        //sky->addCloudLayer( 1, 5000000, 5000000, 600.0, 7351.0, 0.2, CIRRUS_FIBRATUS );
[133]413        //sky->addCloudLayer( 2, 50000, 50000, 600.0, 7351.0, 0.2, CIRROCUMULUS );
[144]414        ///sky->addCloudLayer( 2, 100000, 100000, 600.0, 2351.0, 0.75, STRATUS );
415        sky->addCloudLayer( 3, 50000, 50000, 1300.0, 700.0, 0.07, CUMULUS_CONGESTUS );
416        //sky->addCloudLayer( 1, 100000, 100000, 3500.0, 2000.0, 0.50, STRATOCUMULUS );
[135]417
[143]418        //sky->setSlotPrecipitation( 1, 0.0, 0.0, 0.0, 25.0 );
[122]419
[143]420
[31]421        //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip );
422        //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 );
423        ///* using a huge cylinder to test position & orientation */
424        //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) );
425        //testObj->addUpdater( new object_updater(testObj) );
426
[115]427        //osg::ref_ptr<visual_object> testObj2 = new visual_object( rootNode, "neuschwanstein" );       // todo memleak
428        ////testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
429        //testObj2->setNewPosition( osg::DegreesToRadians(47.557523564234), osg::DegreesToRadians(10.749646398595), 950 );
430        //testObj2->loadGeometry( "../models/neuschwanstein.osgb" );
431        ////testObj2->addUpdater( new object_updater(testObj2) );       // todo memleak
[31]432
[87]433        osg::ref_ptr<visual_object> testObj3 = new visual_object( rootNode, "SAENGER1" );       // todo memleak
[31]434        testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 );
435        testObj3->loadGeometry( "../models/saenger1.flt" );
[87]436        testObj3->addUpdater( new object_updater(testObj3) );   // todo memleak
[31]437       
438
[87]439        osg::ref_ptr<visual_object> testObj4 = new visual_object( rootNode, "SAENGER2" );       // todo memleak
[31]440        testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 );
441        testObj4->loadGeometry( "../models/saenger2.flt" );
[87]442        testObj4->addUpdater( new object_updater(testObj4) );   // todo memleak
[31]443        testObj4->addLabel("testLabel", "LabelTest!!\nnächste Zeile :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f));
444
[87]445        osg::ref_ptr<visual_object> testObj5 = new visual_object( rootNode, "SAENGER" );        // todo memleak
[31]446        testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 );
447        testObj5->loadGeometry( "../models/saengerCombine.flt" );
448        //testObj5->setScale( 2 );
[87]449        testObj5->addUpdater( new object_updater(testObj5) );   // todo memleak
[31]450
451#ifdef USE_SPACENAVIGATOR
452        // Manipulatoren auf dieses Objekt binden (Primärobjekt)
453        if (objectMountedCameraManip.valid())
[115]454                objectMountedCameraManip->setAttachedObject( testObj4 );
[31]455        if (mouseTrackerManip.valid())
456        {
[115]457                mouseTrackerManip->setTrackNode( testObj4->getGeometry() );
[31]458                mouseTrackerManip->setMinimumDistance( 100 );
459        }
460#endif
461
[73]462        if(nt.valid())
463        {
464                osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
465                osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
466                nt->setTrackerMode(trackerMode);
467                nt->setRotationMode(rotationMode);
468                //nt->setAutoComputeHomePosition( true );
469                nt->setMinimumDistance( 100 );
470                nt->setTrackNode(testObj4->getGeometry());
471                //nt->computeHomePosition();
472                nt->setAutoComputeHomePosition( true );
473                nt->setDistance( 250 );
474        }
[31]475
476
477        // Load EDDF
478        //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive";
479        //if( !osgDB::fileExists(filename) )
480        //{
481        //      OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping.";
482        //}
483        //// read model
484        //osg::ref_ptr<osg::Node> tmpModel = osgDB::readNodeFile( filename );
485        //if (tmpModel.valid())
486        //      rootNode->addChild( tmpModel );
487       
488 
489        visual_draw2D::getInstance()->init( rootNode, viewer );
490        //osg::ref_ptr<visual_hud> hud = new visual_hud();
[87]491        hud = new visual_debug_hud();
[31]492        hud->init( viewer, rootNode );
493       
[122]494       
[31]495
496        //osg::ref_ptr<visual_draw3D> test = new visual_draw3D();
497        //test->init( rootNode, viewer );
498
[69]499        //// Creating Testclasses
500        //osg::ref_ptr<osgVisual::dataIO_transportContainer> test = new osgVisual::dataIO_transportContainer();
501        //osg::ref_ptr<osgVisual::dataIO_executer> testEx = new osgVisual::dataIO_executer();
502        //osg::ref_ptr<osgVisual::dataIO_slot> testSlot = new osgVisual::dataIO_slot();
503        //test->setFrameID( 22 );
504        //test->setName("ugamoep");
505        //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION );
506        //testSlot->setVariableName(std::string("HalloName"));
507        //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ );
508        //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE );
509        //testSlot->setValue( 0.12345 );
510        //test->addExecuter( testEx );
511        //test->addSlot( testSlot );
[31]512
[69]513        visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345);
[155]514
[31]515}
Note: See TracBrowser for help on using the repository browser.