/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer * * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * osgVisual requires for some proprietary modules a license from the correspondig manufacturer. * You have to aquire licenses for all used proprietary modules. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include using namespace osgVisual; visual_core::visual_core(osg::ArgumentParser& arguments_) : arguments(arguments_) { OSG_NOTIFY( osg::ALWAYS ) << "visual_core instantiated." << std::endl; // Setup pathes osgDB::Registry::instance()->getDataFilePathList().push_back( "D:\\DA\\osgVisual\\models" ); // Setup viewer viewer = new osgViewer::Viewer(arguments); // Setup coordinate system node rootNode = new osg::CoordinateSystemNode; rootNode->setEllipsoidModel(new osg::EllipsoidModel()); // Test memory leak (todo) //double* test = new double[1000]; #ifdef USE_SPACENAVIGATOR mouse = NULL; #endif //osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( 8 ); } visual_core::~visual_core(void) { // shut osgVisual down shutdown(); OSG_NOTIFY( osg::ALWAYS ) << "visual_core destroyed." << std::endl; } void visual_core::initialize() { OSG_NOTIFY( osg::ALWAYS ) << "Initialize visual_core..." << std::endl; // Add manipulators for user interaction addManipulators(); // Load terrain //loadTerrain(arguments); // Show model viewer->setSceneData( rootNode ); #ifdef USE_DISTORTION // Initialize distortion distortion = new visual_distortion( viewer, arguments ); distortion->initialize( rootNode, viewer->getCamera()->getClearColor() ); #endif #ifdef USE_SKY_SILVERLINING // Initialize sky sky = new visual_skySilverLining( viewer ); #ifdef USE_DISTORTION if ( distortion.valid() ) { OSG_NOTIFY( osg::ALWAYS ) << "Using sky with distortion." << std::endl; sky->init( distortion->getDistortedSceneGraph(), rootNode); } #else OSG_NOTIFY( osg::ALWAYS ) << "Using Sky without distortion." << std::endl; sky->init(NULL, rootNode); #endif #endif // Initialize DataIO interface visual_dataIO::getInstance()->init(viewer, arguments); loadTerrain(arguments); // All modules are initialized - now check arguments for any unused parameter. checkCommandlineArgumentsForFinalErrors(); // create the windows and run the threads. viewer->realize(); // setup scenery setupScenery(); // Run visual main loop mainLoop(); } void visual_core::mainLoop() { // run main loop while( !viewer->done() ) { // next frame please.... viewer->advance(); std::cout << "New frame----------------------------" << std::endl; /*double hat, hot, lat, lon, height; util::getWGS84ofCamera( viewer->getCamera(), rootNode, lat, lon, height); if (util::queryHeightOfTerrain( hot, rootNode, lat, lon) && util::queryHeightAboveTerrainInWGS84( hat, rootNode, lat, lon, height ) ) OSG_NOTIFY( osg::ALWAYS ) << "HOT is: " << hot << ", HAT is: " << hat << std::endl;*/ // perform all queued events viewer->eventTraversal(); // update the scene by traversing it with the the update visitor which will // call all node update callbacks and animations. viewer->updateTraversal(); // Render the Frame. viewer->renderingTraversals(); } // END WHILE } void visual_core::shutdown() { OSG_NOTIFY( osg::ALWAYS ) << "Shutdown visual_core..." << std::endl; // Unset scene data viewer->setSceneData( NULL ); #ifdef USE_SKY_SILVERLINING // Shutdown sky if( sky.valid() ) sky->shutdown(); #endif #ifdef USE_DISTORTION // Shutdown distortion if( distortion.valid() ) distortion->shutdown(); #endif // Shutdown dataIO visual_dataIO::getInstance()->shutdown(); #ifdef USE_SPACENAVIGATOR //Delete SpaceMouse driver if(mouse) { mouse->shutdown(); delete mouse; } #endif } bool visual_core::loadTerrain(osg::ArgumentParser& arguments_) { osg::ref_ptr model = osgDB::readNodeFiles(arguments_); if( model.valid() ) { rootNode->addChild( model.get() ); return true; } else { OSG_NOTIFY( osg::FATAL ) << "Load terrain: No data loaded" << std::endl; return false; } return false; } void visual_core::addManipulators() { // set up the camera manipulators. { osg::ref_ptr keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() ); keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() ); keyswitchManipulator->addMatrixManipulator( '3', "Terrain", new osgGA::TerrainManipulator() ); nt = new osgGA::NodeTrackerManipulator(); keyswitchManipulator->addMatrixManipulator( '4', "NodeTrackerManipulator", nt ); #ifdef USE_SPACENAVIGATOR // SpaceNavigator manipulator mouse = new SpaceMouse(); mouse->initialize(); mouseTrackerManip = new NodeTrackerSpaceMouse(mouse); mouseTrackerManip->setTrackerMode(NodeTrackerSpaceMouse::NODE_CENTER); mouseTrackerManip->setRotationMode(NodeTrackerSpaceMouse::ELEVATION_AZIM); mouseTrackerManip->setAutoComputeHomePosition( true ); keyswitchManipulator->addMatrixManipulator( '5', "Spacemouse Node Tracker", mouseTrackerManip ); keyswitchManipulator->addMatrixManipulator( '6', "Spacemouse Free (Airplane)", new FreeManipulator(mouse) ); #endif // objectMounted Manipulator for Camera control by Nodes objectMountedCameraManip = new objectMountedManipulator(); keyswitchManipulator->addMatrixManipulator( '7', "Object mounted Camera", objectMountedCameraManip ); // Animation path manipulator std::string pathfile; char keyForAnimationPath = '8'; while (arguments.read("-p",pathfile)) { osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile); if (apm || !apm->valid()) { unsigned int num = keyswitchManipulator->getNumMatrixManipulators(); keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm ); keyswitchManipulator->selectMatrixManipulator(num); ++keyForAnimationPath; } } viewer->setCameraManipulator( keyswitchManipulator.get() ); } // add the state manipulator viewer->addEventHandler( new osgGA::StateSetManipulator(rootNode->getOrCreateStateSet()) ); // add the thread model handler viewer->addEventHandler(new osgViewer::ThreadingHandler); // add the window size toggle handler viewer->addEventHandler(new osgViewer::WindowSizeHandler); // add the stats handler viewer->addEventHandler(new osgViewer::StatsHandler); // add the help handler viewer->addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage())); // add the record camera path handler viewer->addEventHandler(new osgViewer::RecordCameraPathHandler); // add the LOD Scale handler viewer->addEventHandler(new osgViewer::LODScaleHandler); // add the screen capture handler viewer->addEventHandler(new osgViewer::ScreenCaptureHandler); } bool visual_core::checkCommandlineArgumentsForFinalErrors() { // Setup Application Usage arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the new FSD visualization tool, written by Torben Dannhauer"); arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] Terrain_filename"); arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); // if user request help write it out to cout. if (arguments.read("-h") || arguments.read("--help")) { arguments.getApplicationUsage()->write(std::cout); //cause the viewer to exit and shut down clean. viewer->setDone(true); } // report any errors if they have occurred when parsing the program arguments. if (arguments.errors()) { arguments.writeErrorMessages(std::cout); //cause the viewer to exit and shut down clean. viewer->setDone(true); } // any option left unread are converted into errors to write out later. arguments.reportRemainingOptionsAsUnrecognized(); // report any errors if they have occurred when parsing the program arguments. if (arguments.errors()) { arguments.writeErrorMessages(std::cout); return false; } return true; } void visual_core::setupScenery() { //testObj = new visual_object( rootNode, "testStab", objectMountedCameraManip ); //testObj->setNewPosition( osg::DegreesToRadians(47.7123), osg::DegreesToRadians(12.84088), 600 ); ///* using a huge cylinder to test position & orientation */ //testObj->setGeometry( util::getDemoCylinder(5000.0, 20.0 ) ); //testObj->addUpdater( new object_updater(testObj) ); osg::ref_ptr testObj2 = new visual_object( rootNode, "cessna" ); //testObj2->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 ); testObj2->setNewPosition( osg::DegreesToRadians(50.8123), osg::DegreesToRadians(8.94088), 600 ); testObj2->loadGeometry( "../models/cessna.osg" ); testObj2->addUpdater( new object_updater(testObj2) ); osg::ref_ptr testObj3 = new visual_object( rootNode, "SAENGER1" ); testObj3->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 600 ); testObj3->loadGeometry( "../models/saenger1.flt" ); testObj3->addUpdater( new object_updater(testObj3) ); osg::ref_ptr testObj4 = new visual_object( rootNode, "SAENGER2" ); testObj4->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 650 ); testObj4->loadGeometry( "../models/saenger2.flt" ); testObj4->addUpdater( new object_updater(testObj4) ); testObj4->addLabel("testLabel", "LabelTest!!\nnächste Zeile :)",osg::Vec4(1.0f,0.25f,1.0f,1.0f)); osg::ref_ptr testObj5 = new visual_object( rootNode, "SAENGER" ); testObj5->setNewPosition( osg::DegreesToRadians(47.8123), osg::DegreesToRadians(12.94088), 550 ); testObj5->loadGeometry( "../models/saengerCombine.flt" ); //testObj5->setScale( 2 ); testObj5->addUpdater( new object_updater(testObj5) ); #ifdef USE_SPACENAVIGATOR // Manipulatoren auf dieses Objekt binden (Primärobjekt) if (objectMountedCameraManip.valid()) objectMountedCameraManip->setAttachedObject( testObj4 ); if (mouseTrackerManip.valid()) { mouseTrackerManip->setTrackNode( testObj4->getGeometry() ); mouseTrackerManip->setMinimumDistance( 100 ); } #endif osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER; osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM; nt->setTrackerMode(trackerMode); nt->setRotationMode(rotationMode); //nt->setAutoComputeHomePosition( true ); nt->setMinimumDistance( 100 ); nt->setTrackNode(testObj4->getGeometry()); //nt->computeHomePosition(); nt->setAutoComputeHomePosition( true ); nt->setDistance( 250 ); // Load EDDF //std::string filename = "D:\\DA\\EDDF_test\\eddf.ive"; //if( !osgDB::fileExists(filename) ) //{ // OSG_NOTIFY(osg::ALWAYS) << "Warning: EDDF Model not loaded. File '" << filename << "' does not exist. Skipping."; //} //// read model //osg::ref_ptr tmpModel = osgDB::readNodeFile( filename ); //if (tmpModel.valid()) // rootNode->addChild( tmpModel ); visual_draw2D::getInstance()->init( rootNode, viewer ); //osg::ref_ptr hud = new visual_hud(); osg::ref_ptr hud = new visual_debug_hud(); hud->init( viewer, rootNode ); //osg::ref_ptr test = new visual_draw3D(); //test->init( rootNode, viewer ); //// Creating Testclasses //osg::ref_ptr test = new osgVisual::dataIO_transportContainer(); //osg::ref_ptr testEx = new osgVisual::dataIO_executer(); //osg::ref_ptr testSlot = new osgVisual::dataIO_slot(); //test->setFrameID( 22 ); //test->setName("ugamoep"); //testEx->setexecuterID( osgVisual::dataIO_executer::IS_COLLISION ); //testSlot->setVariableName(std::string("HalloName")); //testSlot->setdataDirection( osgVisual::dataIO_slot::TO_OBJ ); //testSlot->setvarType( osgVisual::dataIO_slot::DOUBLE ); //testSlot->setValue( 0.12345 ); //test->addExecuter( testEx ); //test->addSlot( testSlot ); visual_dataIO::getInstance()->setSlotData("TestSlot1", osgVisual::dataIO_slot::TO_OBJ, 0.12345); //// Writing object to stream ////std::ofstream myOstream("test.txt" ); //std::stringstream myOstream; //std::string extension = "osgb"; //bool compressed = false; //osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(extension.c_str()); //if ( rw ) //{ // osgDB::ReaderWriter::WriteResult wr; // if (extension == "osgb") // { // if (compressed) // wr = rw->writeObject( *test, myOstream, new osgDB::Options("Compressor=zlib") ); // else // wr = rw->writeObject( *test, myOstream ); // } // if (extension == "osgt") // { // if (compressed) // wr = rw->writeObject( *test, myOstream, new osgDB::Options("Ascii Compressor=zlib") ); // else // wr = rw->writeObject( *test, myOstream, new osgDB::Options("Ascii") ); // } // if (extension == "osgx") // { // if (compressed) // wr = rw->writeObject( *test, myOstream, new osgDB::Options("XML Compressor=zlib") ); // else // wr = rw->writeObject( *test, myOstream, new osgDB::Options("XML") ); // } // if (!wr.success() ) OSG_NOTIFY( osg::WARN ) << "ERROR: Save failed: " << wr.message() << std::endl; //} //else // OSG_NOTIFY( osg::WARN ) << "error getting readerWriter for osgt" << std::endl; //// Size ermitteln. //std::stringbuf *pbuf; //pbuf = myOstream.rdbuf(); //OSG_NOTIFY( osg::WARN ) << "PBUF Bytes available: " << pbuf->in_avail() << std::endl; //OSG_NOTIFY( osg::ALWAYS ) << "STRING Bytes available: " << myOstream.str().length() << std::endl; //OSG_NOTIFY( osg::ALWAYS ) << "STRING content: " << myOstream.str() << std::endl; ////Reading Stream to node //if ( rw ) //{ // osgDB::ReaderWriter::ReadResult rr = rw->readObject( myOstream ); // osg::ref_ptr test2 = dynamic_cast(rr.takeObject()); // if (test2) // { // OSG_NOTIFY( osg::WARN ) << "TEST::FrameID is: " << test->getFrameID() << std::endl; // } // else // OSG_NOTIFY( osg::WARN ) << "Error converting stream to Node" << std::endl; //} }