void addDeviceTo(osgViewer::Viewer& viewer, const std::string& device_name) { osg::ref_ptr<osgGA::Device> dev = osgDB::readFile<osgGA::Device>(device_name); if (dev.valid()) { OSG_INFO << "Adding Device : " << device_name << std::endl; viewer.addDevice(dev.get()); if (dev->getCapabilities() & osgGA::Device::SEND_EVENTS) viewer.getEventHandlers().push_front(new ForwardToDeviceEventHandler(dev.get())); } else { OSG_WARN << "could not open device: " << device_name << std::endl; } }
void LevelUpdater::operator()(osg::Node *node, osg::NodeVisitor *nv) { double currentStepTime = viewer.getFrameStamp()->getSimulationTime(); // compensate error arising from the osg::Viewer resetting its SimulationTime if(currentStepTime - _previousStepTime < 0.0f) { Player::getInstance()->resetPosition(); ((LazyCameraManipulator *)viewer.getCameraManipulator())->resetCamera(); _previousStepTime = currentStepTime - 0.5; } int numSimulationSubSteps = _level->getPhysicsWorld()->stepSimulation(currentStepTime - _previousStepTime, (int)((currentStepTime - _previousStepTime) * 60.0f) + 1); ((LazyCameraManipulator *)viewer.getCameraManipulator())->setNumSimulationSubSteps(numSimulationSubSteps); _previousStepTime = currentStepTime; // player dies when falling too low { btVector3 position = Player::getInstance()->getController()->getGhostObject()->getWorldTransform().getOrigin(); int yBucketIndex = (int)(position.y() / 20.0f); if(yBucketIndex >= _level->getDeadlyAltitudes().size()) yBucketIndex = _level->getDeadlyAltitudes().size() - 1; float minimum = min(_level->getDeadlyAltitudes()[yBucketIndex], (_level->getDeadlyAltitudes())[yBucketIndex + 1]); if(position.z() < (minimum - 5.0f)) _level->playerDied(); } // fade out when level is finished osg::Vec4 constantBlendColor = _blendColor->getConstantColor(); float alpha = constantBlendColor.a(); // player reached finish { osg::Vec3 position = Player::getInstance()->getPosition(); std::vector<osg::Vec3> finishs = _level->getFinishs(); for(size_t i = 0; i < finishs.size(); i++) { float maxDistance = 1.0f; osg::Vec3 diff = position - finishs[i]; if(diff.x() < maxDistance && diff.x() > -maxDistance && diff.y() < maxDistance * 3.0f && diff.y() > -maxDistance && diff.z() < maxDistance && diff.z() > -maxDistance) { if(alpha == 1.0f) { alpha -= 0.01f; _level->getHeadUpDisplay()->stopTimer(); viewer.getEventHandlers().remove(_level->getKeyboardHandler()); ((LazyCameraManipulator *)viewer.getCameraManipulator())->fadeOut(); Player::getInstance()->getPlayerState()->setRequestAccelerate(false); Player::getInstance()->getPlayerState()->setRequestDecelerate(true); } } } if(alpha < 1.0f) { alpha -= 0.01f; if(alpha <= 0.0f) { alpha = 0.0f; _level->setReachedFinish(true); } constantBlendColor[3] = alpha; _blendColor->setConstantColor(constantBlendColor); } } traverse(node, nv); }
int main( int argc, char **argv ) { int windowWidth, windowHeight; std::string osgEarthFileName = "D:/Dev/csp/csp/examples/cspEarth/data/srtm.earth"; // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // Allow a debugger to be attached before the interesting parts start if (arguments.read("-p")) { std::cout << "Attach debugger and press a key..." << std::endl; std::getchar(); } // if an .earth file definition was specified, use this one instead of the default arguments.read("-file", osgEarthFileName); // get screen size arguments.read("-window", windowWidth, windowHeight); // ===================================================================== // SETUP // Make it possible for this application to locate images bound // to textures. std::string search_path = ";"; csp::ospath::addpath(search_path, "./data/images/"); csp::ospath::addpath(search_path, "./data/models/"); csp::ObjectModel::setDataFilePathList(search_path); // Set paths for shader files. Shader::instance()->setShaderPath("./data/shaders/"); // ===================================================================== // Manual creation of a object model. Ref<ObjectModel> my_model = new ObjectModel(); // An external is used to handle the path to the scene graph file. // It is also ensuring that paths is handled independent on operating // system. External modelPath; modelPath.setSource("industry/refinery_column01/refinery_column01.osg"); my_model->setModelPath(modelPath); my_model->setSmooth(true); // Load the model from disc. This will also apply needed shaders. // smoothing and more things. my_model->loadModel(); // read osgEarth config file and create the globe std::cout << "reading osgEarth config file: " << osgEarthFileName << std::endl; osg::ref_ptr<osg::Node> globe = osgDB::readNodeFile(osgEarthFileName); osg::ref_ptr<osg::Node> topNode = new osg::Node; osg::Group* group = new osg::Group; group->setName("root group"); // ===================================================================== // construct the viewer viewer.addEventHandler(new osgViewer::StatsHandler); viewer.addEventHandler(new osgViewer::HelpHandler); viewer.addEventHandler(new osgViewer::WindowSizeHandler); viewer.addEventHandler(new osgViewer::ScreenCaptureHandler); // modify the key mapping of an osg default event handler // this is just to demonstrate the principle, no real use case behind it... osgViewer::View::EventHandlers eventHandlers = viewer.getEventHandlers(); // iterate through the viewer's event handlers and modify their default behavior for (osgViewer::View::EventHandlers::iterator it = eventHandlers.begin(); it != eventHandlers.end(); ++it) { // EventHandlers is a list of osgGA::GUIEventHandlers, so RTTI is used to find out the derived class if(osgViewer::WindowSizeHandler *winSizeHandler = dynamic_cast<osgViewer::WindowSizeHandler *>(it->get())) { winSizeHandler->setKeyEventToggleFullscreen(osgGA::GUIEventAdapter::KEY_F2); } } // Create overlay data osg::ref_ptr<osg::Geode> statsGeometry = createStatsGeometry(); group->addChild( statsGeometry ); // add the osgEarth globe to the scene group->addChild( globe.get() ); group->addChild( my_model->getModel().get() ); //viewer.setSceneData(my_model->getModel().get()); viewer.setSceneData( group ); //viewer.setSceneData(globe.get()); // create camera and context setupCameraAndContext( viewer, windowWidth, windowHeight ); // the overlay geometry is added to an individual camera // QUESTION: But why isn't it rendered by the primary cam?!? statsCamera->addChild( statsGeometry ); //viewer.setCameraManipulator(new osgGA::FlightManipulator); osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode(globe); manip = new osgEarthUtil::EarthManipulator(); manip->setNode(globe); if ( mapNode->getMap()->isGeocentric() ) { manip->setHomeViewpoint( osgEarthUtil::Viewpoint( osg::Vec3d( -90, 0, 0 ), 0.0, -90.0, 5e7 ) ); } manip->getSettings()->bindMouseDoubleClick( osgEarthUtil::EarthManipulator::ACTION_GOTO, osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON ); viewer.setCameraManipulator(manip); viewer.addEventHandler(new inputHandler()); // run the viewers frame loop viewer.realize(); // main loop (note, window toolkits which take control over the main loop will require // a window redraw callback containing the code below.) while(!viewer.done()) { viewer.frame(); } }