#include #include #include #include #include using namespace osgProducer; class ViewerEventHandler::SnapImageDrawCallback : public Producer::Camera::Callback { public: SnapImageDrawCallback(const std::string& filename): _filename(filename), _snapImageOnNextFrame(false) { } void setSnapImageOnNextFrame(bool flag) { _snapImageOnNextFrame = flag; } bool getSnapImageOnNextFrame() const { return _snapImageOnNextFrame; } virtual void operator()( const Producer::Camera & camera) { if (!_snapImageOnNextFrame) return; int x,y; unsigned int width,height; camera.getProjectionRectangle(x,y,width,height); osg::ref_ptr image = new osg::Image; image->readPixels(x,y,width,height, GL_RGB,GL_UNSIGNED_BYTE); if (osgDB::writeImageFile(*image,_filename)) { osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl; } _snapImageOnNextFrame = false; } protected: std::string _filename; bool _snapImageOnNextFrame; }; class ViewerEventHandler::StatsAndHelpDrawCallback : public Producer::CameraGroup::StatsHandler, public Producer::Camera::Callback { public: StatsAndHelpDrawCallback(ViewerEventHandler* veh, unsigned int cameraNumber): _veh(veh), _cameraNumber(cameraNumber), _helpInitialized(false), _statsInitialized(false) { _fs.resize(20); _index = 0; _veh->getOsgCameraGroup()->setStatsHandler(this); _stateset = new osg::StateSet; _viewport = new osg::Viewport(0,0,1280,1024); _stateset->setAttribute(_viewport.get()); //createHelpText(); //createStatsText(); //_helpInitialized = false; } void setArraySize(unsigned int size) { _fs.resize(size); } unsigned int getArraySize() { return _fs.size(); } void operator() (const Producer::CameraGroup &cg ) { _index = (_index + 1) % _fs.size(); _fs[_index] = cg.getFrameStats(); } virtual void operator()( const Producer::Camera & camera); protected: ViewerEventHandler* _veh; unsigned int _cameraNumber; osg::ref_ptr _stateset; osg::ref_ptr _viewport; // help related methods and data void displayHelp(); void createHelpText(); typedef std::vector< osg::ref_ptr > TextList; bool _helpInitialized; TextList _descriptionList; TextList _optionList; TextList _explanationList; // stats related methods and data. void displayStats(); void createStatsText(); typedef std::vector CameraTimes; bool _statsInitialized; osg::ref_ptr _frameRateLabelText; osg::ref_ptr _frameRateCounterText; TextList _statsLabelList; osg::ref_ptr _updateTimeText; CameraTimes _cullTimes; TextList _cullTimeText; CameraTimes _drawTimes; TextList _drawTimeText; std::vector _fs; unsigned int _index; }; void ViewerEventHandler::StatsAndHelpDrawCallback::operator()( const Producer::Camera & camera) { if (_veh->getDisplayHelp()==false && _veh->getFrameStatsMode()==ViewerEventHandler::NO_STATS) return; int x,y; unsigned int width,height; camera.getProjectionRectangle(x,y,width,height); _viewport->setViewport(x,y,width,height); OsgSceneHandler* osh = _veh->getOsgCameraGroup()->getSceneHandlerList()[_cameraNumber].get(); osh->getState()->pushStateSet(_stateset.get()); if (_veh->getDisplayHelp()) displayHelp(); if (_veh->getFrameStatsMode()!=ViewerEventHandler::NO_STATS && camera.getInstrumentationMode()) { osh->getState()->apply(); displayStats(); } osh->getState()->popStateSet(); } void ViewerEventHandler::StatsAndHelpDrawCallback::displayHelp() { if (!_helpInitialized) createHelpText(); OsgSceneHandler* osh = _veh->getOsgCameraGroup()->getSceneHandlerList()[_cameraNumber].get(); // should possibly update _viewport... // Set up the Orthographic view glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glOrtho( 0.0, 1280.0, 0.0, 1024, -1.0, 1.0 ); glPushAttrib( GL_ENABLE_BIT ); glDisable( GL_LIGHTING ); glDisable( GL_DEPTH_TEST ); glEnable( GL_BLEND ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); for(TextList::iterator ditr=_descriptionList.begin(); ditr!=_descriptionList.end(); ++ditr) { (*ditr)->draw(*(osh->getState())); } for(TextList::iterator oitr=_optionList.begin(); oitr!=_optionList.end(); ++oitr) { (*oitr)->draw(*(osh->getState())); } for(TextList::iterator eitr=_explanationList.begin(); eitr!=_explanationList.end(); ++eitr) { (*eitr)->draw(*(osh->getState())); } glPopMatrix(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopAttrib(); } void ViewerEventHandler::StatsAndHelpDrawCallback::createHelpText() { OsgCameraGroup* ocg = _veh->getOsgCameraGroup(); if (ocg->getApplicationUsage()) { const osg::ApplicationUsage::UsageMap& um = ocg->getApplicationUsage()->getKeyboardMouseBindings(); float maxWidthOfDisplayRegion = 1200.0f; float bottomOfDescription = 1000.0f; osg::Vec3 posDescription(0.0f,bottomOfDescription,0.0f); osg::Vec4 colorDescription(1.0f,1.0f,0.0f,1.0f); float characterSize = 20.0f; if (!(ocg->getApplicationUsage()->getDescription()).empty()) { osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorDescription); text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(posDescription); text->setMaximumWidth(maxWidthOfDisplayRegion); text->setAlignment(osgText::Text::BASE_LINE); text->setText(ocg->getApplicationUsage()->getDescription()); bottomOfDescription = text->getBound().yMin()-characterSize*2.0f; _descriptionList.push_back(text); } osg::Vec3 posOption(0.0f,bottomOfDescription,0.0f); osg::Vec4 colorOption(1.0f,1.0f,0.0f,1.0f); float maxX = 0.0f; // create option strings. osg::ApplicationUsage::UsageMap::const_iterator citr; for(citr=um.begin(); citr!=um.end(); ++citr) { osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorOption); text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(posOption); text->setAlignment(osgText::Text::BASE_LINE); text->setText(citr->first); if (text->getBound().xMax()>maxX) maxX=text->getBound().xMax(); _optionList.push_back(text); } osg::Vec3 posExplanation(maxX+characterSize,bottomOfDescription,0.0f); osg::Vec4 colorExplanation(1.0f,1.0f,0.0f,1.0f); float maxWidth = maxWidthOfDisplayRegion-maxX; TextList::iterator oitr; TextList::iterator eitr; TextList::iterator ditr; for(citr=um.begin(), oitr=_optionList.begin(); citr!=um.end(); ++citr,++oitr) { osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorExplanation); text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(posExplanation); text->setMaximumWidth(maxWidth); text->setAlignment(osgText::Text::BASE_LINE); text->setText(citr->second); if (text->getBound().xMax()>maxX) maxX=text->getBound().xMax(); // fix the position of option text to be the same height as the examplanation. osg::Vec3 pos((*oitr)->getPosition()); (*oitr)->setPosition(osg::Vec3(pos.x(),posExplanation.y(),pos.z())); posExplanation.y() = text->getBound().yMin()-characterSize; _explanationList.push_back(text); } // compute the boundings of the all the text. osg::BoundingBox bb; for(ditr=_descriptionList.begin(); ditr!=_descriptionList.end(); ++ditr) { bb.expandBy((*ditr)->getBound()); } for(oitr=_optionList.begin(); oitr!=_optionList.end(); ++oitr) { bb.expandBy((*oitr)->getBound()); } for(eitr=_explanationList.begin(); eitr!=_explanationList.end(); ++eitr) { bb.expandBy((*eitr)->getBound()); } float totalWidth = bb.xMax()-bb.xMin(); float totalHeight = bb.yMax()-bb.yMin(); float widthMargin = (1280.0f-totalWidth)*0.5f; float heightMargin = (1024.0f-totalHeight)*0.5f; osg::Vec3 delta(widthMargin-bb.xMin(),heightMargin-bb.yMin(),0.0f); // shift the text to center it. for(ditr=_descriptionList.begin(); ditr!=_descriptionList.end(); ++ditr) { (*ditr)->setPosition((*ditr)->getPosition()+delta); } for(oitr=_optionList.begin(); oitr!=_optionList.end(); ++oitr) { (*oitr)->setPosition((*oitr)->getPosition()+delta); } for(eitr=_explanationList.begin(); eitr!=_explanationList.end(); ++eitr) { (*eitr)->setPosition((*eitr)->getPosition()+delta); } } _helpInitialized = true; } void ViewerEventHandler::StatsAndHelpDrawCallback::displayStats() { if (!_statsInitialized) createStatsText(); OsgSceneHandler* osh = _veh->getOsgCameraGroup()->getSceneHandlerList()[_cameraNumber].get(); // render the text if (_veh->getFrameStatsMode()>=ViewerEventHandler::FRAME_RATE) { // Set up the Orthographic view glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glOrtho( 0.0, 1280.0, 0.0, 1024, -1.0, 1.0 ); glPushAttrib( GL_ENABLE_BIT ); glDisable( GL_LIGHTING ); glDisable( GL_DEPTH_TEST ); glEnable( GL_BLEND ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); // update and draw the frame rate text. char tmpText[128]; _frameRateLabelText->draw(*(osh->getState())); if (_fs.size()>1) { unsigned int lindex = (_index + 1) % _fs.size(); double timeForFrames = (_fs[_index]._startOfFrame-_fs[lindex]._startOfFrame); double timePerFrame = timeForFrames/(double)(_fs.size()-1); sprintf(tmpText,"%4.2f",1.0/timePerFrame); _frameRateCounterText->setText(tmpText); } _frameRateCounterText->draw(*(osh->getState())); if (_veh->getFrameStatsMode()>=ViewerEventHandler::CAMERA_STATS) { TextList::iterator itr; for(itr=_statsLabelList.begin(); itr!=_statsLabelList.end(); ++itr) { (*itr)->draw(*(osh->getState())); } double updateTime = 0.0; std::fill(_cullTimes.begin(),_cullTimes.end(),0.0); std::fill(_drawTimes.begin(),_drawTimes.end(),0.0); for(unsigned int frame = 0; frame < _fs.size(); frame++ ) { Producer::CameraGroup::FrameStats fs = _fs[frame]; updateTime += (fs._endOfUpdate-fs._startOfUpdate); for(unsigned int i = 0; i < fs.getNumFrameTimeStampSets(); i++ ) { Producer::Camera::FrameTimeStampSet fts = fs.getFrameTimeStampSet(i); _cullTimes[i] += fts[Producer::Camera::EndCull]-fts[Producer::Camera::BeginCull]; _drawTimes[i] += fts[Producer::Camera::EndDraw]-fts[Producer::Camera::BeginDraw]; } } sprintf(tmpText,"%4.2f",1000.0*updateTime/(double)_fs.size()); _updateTimeText->setText(tmpText); _updateTimeText->draw(*(osh->getState())); CameraTimes::iterator titr; for(itr=_cullTimeText.begin(),titr = _cullTimes.begin(); itr!=_cullTimeText.end() && titr!=_cullTimes.end(); ++itr,++titr) { sprintf(tmpText,"%4.2f",1000.0*(*titr)/(double)_fs.size()); (*itr)->setText(tmpText); (*itr)->draw(*(osh->getState())); } for(itr=_drawTimeText.begin(),titr = _drawTimes.begin(); itr!=_drawTimeText.end() && titr!=_cullTimes.end(); ++itr,++titr) { sprintf(tmpText,"%4.2f",1000.0*(*titr)/(double)_fs.size()); (*itr)->setText(tmpText); (*itr)->draw(*(osh->getState())); } } glPopMatrix(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopAttrib(); } // render graphs if (_veh->getFrameStatsMode()>=ViewerEventHandler::CAMERA_STATS) { // Set up the Orthographic view glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glOrtho( -.025, .128, 600.0, -10.0, -1.0, 1.0 ); glPushAttrib( GL_ENABLE_BIT ); glDisable( GL_LIGHTING ); glDisable( GL_DEPTH_TEST ); glEnable( GL_BLEND ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); unsigned int lindex = (_index + 1) % _fs.size(); Producer::Camera::TimeStamp zero = _fs[lindex]._startOfFrame; unsigned int i; double x1=0.0, x2=0.0, y1=0.0, y2=0.0; for(unsigned int frame = 0; frame < _fs.size(); frame++ ) { Producer::CameraGroup::FrameStats fs = _fs[(lindex + frame) % _fs.size()]; y1 = 0.0; y2 = y1 + 10; x1 = fs._startOfUpdate - zero; x2 = fs._endOfUpdate - zero; glBegin( GL_QUADS ); // Draw Update length glColor4f( 0.0, 1.0, 0.0, 0.5 ); glVertex2d( x1, y1); glVertex2d( x2, y1); glVertex2d( x2, y2); glVertex2d( x1, y2); for( i = 0; i < fs.getNumFrameTimeStampSets(); i++ ) { Producer::Camera::FrameTimeStampSet fts = fs.getFrameTimeStampSet(i); y1 += 13.0; y2 = y1 + 10.0; x1 = fts[Producer::Camera::BeginCull] - zero; x2 = fts[Producer::Camera::EndCull] - zero; glColor4f( 0.0, 1.0, 1.0, 0.5 ); glVertex2d( x1, y1); glVertex2d( x2, y1); glVertex2d( x2, y2); glVertex2d( x1, y2); x1 = fts[Producer::Camera::BeginDraw] - zero; x2 = fts[Producer::Camera::EndDraw] - zero; glColor4f( 1.0, 1.0, 0.0, 0.5 ); glVertex2d( x1, y1); glVertex2d( x2, y1); glVertex2d( x2, y2); glVertex2d( x1, y2); } glEnd(); glBegin( GL_LINES ); glColor4f( 1, 1, 1, 0.5 ); glVertex2d( fs._startOfFrame - zero , 0.0 ); y1 = fs.getNumFrameTimeStampSets() * 13.0 + 10.0; glVertex2d( fs._startOfFrame - zero, y1 ); y1 = 12.5; for( i = 0; i < fs.getNumFrameTimeStampSets(); i++ ) { y2 = y1 + 11; Producer::Camera::FrameTimeStampSet fts = fs.getFrameTimeStampSet(i); Producer::Camera::TimeStamp vsync = fts[Producer::Camera::Vsync]; double x1 = vsync - zero; glColor4f( 1.0, 1.0, 0.0, 0.5 ); glVertex2d( x1, y1 ); glVertex2d( x1, y2 ); y1 += 13.0; } glEnd(); } glBegin( GL_LINES ); glColor4f( 1, 1, 1, 0.5 ); for( i = 0; i < 128; i++ ) { glVertex2d((GLdouble)i*.001, y1); if( !(i%10) ) glVertex2d((GLdouble)i*.001, y1 - 5.0); else if( !(i%5) ) glVertex2d((GLdouble)i*.001, y1 - 3.0); else glVertex2d((GLdouble)i*.001, y1 - 1.0); } glEnd(); glPopMatrix(); glMatrixMode( GL_PROJECTION ); glPopMatrix(); glMatrixMode( GL_MODELVIEW ); glPopAttrib(); } } void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText() { _statsInitialized = true; float characterSize = 20.0f; osg::Vec4 colorFR(1.0f,1.0f,1.0f,1.0f); osg::Vec4 colorUpdate( 0.0f,1.0f,0.0f,1.0f); osg::Vec4 colorCull( 0.0f,1.0f,1.0f,1.0f); osg::Vec4 colorDraw( 1.0f,1.0f,0.0f,1.0f); float leftPos = 10.0f; osg::Vec3 pos(leftPos,1000.0f,0.0f); _frameRateLabelText = new osgText::Text; _frameRateLabelText->setFont("fonts/arial.ttf"); _frameRateLabelText->setColor(colorFR); _frameRateLabelText->setCharacterSize(characterSize); _frameRateLabelText->setPosition(pos); _frameRateLabelText->setAlignment(osgText::Text::BASE_LINE); _frameRateLabelText->setText("Frame Rate: "); pos.x() = _frameRateLabelText->getBound().xMax(); _frameRateCounterText = new osgText::Text; _frameRateCounterText->setFont("fonts/arial.ttf"); _frameRateCounterText->setColor(colorFR); _frameRateCounterText->setCharacterSize(characterSize); _frameRateCounterText->setPosition(pos); _frameRateCounterText->setAlignment(osgText::Text::BASE_LINE); _frameRateCounterText->setText("0123456789."); pos.x() = leftPos; pos.y() -= characterSize; { osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorUpdate); text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(pos); text->setAlignment(osgText::Text::BASE_LINE); text->setText("Update: "); _statsLabelList.push_back(text); pos.x() = text->getBound().xMax(); _updateTimeText = new osgText::Text; _updateTimeText->setFont("fonts/arial.ttf"); _updateTimeText->setColor(colorUpdate); _updateTimeText->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); _updateTimeText->setCharacterSize(characterSize); _updateTimeText->setPosition(pos); _updateTimeText->setAlignment(osgText::Text::BASE_LINE); _updateTimeText->setText("0123456789."); } pos.x() = leftPos; pos.y() -= characterSize; _cullTimes.clear(); _drawTimes.clear(); OsgCameraGroup* ocg = _veh->getOsgCameraGroup(); Producer::CameraConfig* cfg = ocg->getCameraConfig(); for (unsigned int i=0;igetNumberOfCameras(); ++i ) { pos.x() = leftPos; osgText::Text* cullLabel = new osgText::Text; cullLabel->setFont("fonts/arial.ttf"); cullLabel->setColor(colorCull); cullLabel->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); cullLabel->setCharacterSize(characterSize); cullLabel->setPosition(pos); cullLabel->setAlignment(osgText::Text::BASE_LINE); cullLabel->setText("Cull: "); _statsLabelList.push_back(cullLabel); pos.x() = cullLabel->getBound().xMax(); osgText::Text* cullField = new osgText::Text; cullField->setFont("fonts/arial.ttf"); cullField->setColor(colorCull); cullField->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); cullField->setCharacterSize(characterSize); cullField->setPosition(pos); cullField->setAlignment(osgText::Text::BASE_LINE); cullField->setText("1000.00"); _cullTimes.push_back(0.0); _cullTimeText.push_back(cullField); pos.x() = cullField->getBound().xMax(); osgText::Text* drawLabel = new osgText::Text; drawLabel->setFont("fonts/arial.ttf"); drawLabel->setColor(colorDraw); drawLabel->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); drawLabel->setCharacterSize(characterSize); drawLabel->setPosition(pos); drawLabel->setAlignment(osgText::Text::BASE_LINE); drawLabel->setText("Draw: "); _statsLabelList.push_back(drawLabel); pos.x() = drawLabel->getBound().xMax(); osgText::Text* drawField = new osgText::Text; drawField->setFont("fonts/arial.ttf"); drawField->setColor(colorDraw); drawField->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); drawField->setCharacterSize(characterSize); drawField->setPosition(pos); drawField->setAlignment(osgText::Text::BASE_LINE); drawField->setText("1000.00"); _drawTimeText.push_back(drawField); _drawTimes.push_back(0.0); pos.y() -= characterSize; } } ViewerEventHandler::ViewerEventHandler(OsgCameraGroup* cg): _cg(cg), _writeNodeFileName("saved_model.osg"), _displayHelp(false), _frameStatsMode(NO_STATS), _firstTimeTogglingFullScreen(true) { Producer::CameraConfig* cfg = _cg->getCameraConfig(); Producer::Camera *cam = cfg->getCamera(0); _statsAndHelpDrawCallback = new StatsAndHelpDrawCallback(this,0); cam->addPostDrawCallback(_statsAndHelpDrawCallback); if (cfg->getNumberOfCameras()==1) { SnapImageDrawCallback* snapImageDrawCallback = new SnapImageDrawCallback("saved_image.rgb"); cam->addPostDrawCallback(snapImageDrawCallback); _snapImageDrawCallbackList.push_back(snapImageDrawCallback); } else { std::string basename("saved_image_"); std::string ext(".rgb"); for(unsigned int i=0;igetNumberOfCameras();++i) { std::string filename(basename); filename += ('0'+i); filename += ext; SnapImageDrawCallback* snapImageDrawCallback = new SnapImageDrawCallback(filename); cfg->getCamera(i)->addPostDrawCallback(snapImageDrawCallback); _snapImageDrawCallbackList.push_back(snapImageDrawCallback); } } } bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) { if(!_cg) return false; if(ea.getEventType()==osgGA::GUIEventAdapter::KEYDOWN) { switch( ea.getKey() ) { case 's' : { _frameStatsMode = (FrameStatsMode)((_frameStatsMode+1)%3); if (_frameStatsMode==NO_STATS) { _cg->setInstrumentationMode(false); } else { _cg->setInstrumentationMode(true); } return true; } case 'v' : { _cg->setBlockOnVsync(!_cg->getBlockOnVsync()); return true; } case 'f' : { Producer::CameraConfig* cfg = _cg->getCameraConfig(); for( unsigned int i = 0; i < cfg->getNumberOfCameras(); ++i ) { Producer::Camera *cam = cfg->getCamera(i); Producer::RenderSurface* rs = cam->getRenderSurface(); if (_firstTimeTogglingFullScreen && rs->isFullScreen()) { #ifndef WIN32 rs->useBorder(true); rs->setWindowRectangle(240,220,800,600); #else rs->fullScreen(false); rs->setWindowRectangle(240,220,800,600); #endif } else { rs->fullScreen(!rs->isFullScreen()); } } _firstTimeTogglingFullScreen = false; return true; } case 'o' : { osg::Node* node = _cg->getSceneData(); if (node) { if (osgDB::writeNodeFile(*node,_writeNodeFileName.c_str())) { std::cout<<"writen nodes to file "<<_writeNodeFileName<setSnapImageOnNextFrame(true); } return true; } case osgGA::GUIEventAdapter::KEY_Help : case 'h' : { setDisplayHelp(!getDisplayHelp()); return true; } case 'Z' : case 'z' : { osgProducer::Viewer* viewer = dynamic_cast(_cg); if (viewer) { if (viewer->getRecordingAnimationPath()) { // have already been recording so switch of recording. viewer->setRecordingAnimationPath(false); osg::notify(osg::NOTICE) << "To finished recording camera animation, press 'Z' to reply."<< std::endl; if (viewer->getAnimationPath()) { std::ofstream fout("saved_animation.path"); const osg::AnimationPath::TimeControlPointMap& tcpm = viewer->getAnimationPath()->getTimeControlPointMap(); for(osg::AnimationPath::TimeControlPointMap::const_iterator tcpmitr=tcpm.begin(); tcpmitr!=tcpm.end(); ++tcpmitr) { const osg::AnimationPath::ControlPoint& cp = tcpmitr->second; fout<first<<" "<setRecordingAnimationPath(true); viewer->setAnimationPath(new osg::AnimationPath()); viewer->getAnimationPath()->setLoopMode(osg::AnimationPath::LOOP); osg::notify(osg::NOTICE) << "Recording camera animation, press 'z' to finish recording."<< std::endl; } if (ea.getKey()=='Z') { osgGA::AnimationPathManipulator* apm = 0; unsigned int apmNo = 0; osgGA::KeySwitchCameraManipulator* kscm = viewer->getKeySwitchCameraManipulator(); if (kscm) { for(apmNo=0;apmNogetNumCameraManipualtors() && apm==0;++apmNo) { apm = dynamic_cast(kscm->getCameraManipulator(apmNo)); } } if (!apm) { apm = new osgGA::AnimationPathManipulator(); apmNo = viewer->addCameraManipulator(apm); } apm->setAnimationPath(viewer->getAnimationPath()); apm->home(ea,aa); viewer->selectCameraManipulator(apmNo); } break; } return true; } default: break; } } return false; } void ViewerEventHandler::accept(osgGA::GUIEventHandlerVisitor& gehv) { gehv.visit(*this); } void ViewerEventHandler::getUsage(osg::ApplicationUsage& usage) const { usage.addKeyboardMouseBinding("f","Toggle fullscreen"); usage.addKeyboardMouseBinding("h","Display help"); usage.addKeyboardMouseBinding("o","Write scene graph to \"saved_model.osg\""); usage.addKeyboardMouseBinding("O PrtSrn","Write camera images to \"saved_image*.rgb\""); usage.addKeyboardMouseBinding("s","Toggle intrumention"); usage.addKeyboardMouseBinding("v","Toggle block and vsync"); usage.addKeyboardMouseBinding("z","Start recording camera path."); usage.addKeyboardMouseBinding("Z","If recording camera path stop recording camera path, save to \"saved_animation.path\"\nThen start viewing from being on animation path"); }