From 904aceec2279c39205741309ef7c72839f3d7c92 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 16 Apr 2003 14:17:49 +0000 Subject: [PATCH] Added convinence methods to osgProducer::Viewer: /** compute, from normalized mouse coords, for sepecified Camera, the pixel coords relative to that Camera's RenderSurface.*/ bool computePixelCoords(float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y); /** compute, from normalized mouse coords, for sepecified Camera, the near and far points in worlds coords.*/ bool computeNearFar(float x,float y,unsigned int cameraNum,osg::Vec3& near, osg::Vec3& far); /** compute, from normalized mouse coords, for sepecified Camera, intersections with the scene.*/ bool computeIntersections(float x,float y,unsigned int cameraNum,osgUtil::IntersectVisitor::HitList& hits); /** compute, from normalized mouse coords, for all Cameras, intersections with the scene.*/ bool computeIntersections(float x,float y,osgUtil::IntersectVisitor::HitList& hits); --- examples/osgpick/osgpick.cpp | 143 ++++--------------------- include/osgProducer/Viewer | 21 +++- runexamples.bat | 3 + src/osgProducer/Viewer.cpp | 111 +++++++++++++++++++ src/osgProducer/ViewerEventHandler.cpp | 13 ++- src/osgUtil/PickVisitor.cpp | 3 +- 6 files changed, 160 insertions(+), 134 deletions(-) diff --git a/examples/osgpick/osgpick.cpp b/examples/osgpick/osgpick.cpp index f7cb931c8..2ef52cc1f 100644 --- a/examples/osgpick/osgpick.cpp +++ b/examples/osgpick/osgpick.cpp @@ -28,41 +28,6 @@ #include -#include - - - -static Producer::CameraConfig *BuildConfig(void) -{ - Producer::RenderSurface *rs1 = new Producer::RenderSurface; - rs1->setScreenNum(0); - //rs1->useBorder(false); - rs1->setWindowRect(0,0,640,480); - Producer::Camera *camera1 = new Producer::Camera; - camera1->setRenderSurface(rs1); - camera1->setOffset( 1.0, 0.0 ); - - Producer::RenderSurface *rs2 = new Producer::RenderSurface; - rs2->setScreenNum(0); - //rs2->useBorder(false); - rs2->setWindowRect(640,0,640,480); - Producer::Camera *camera2 = new Producer::Camera; - camera2->setRenderSurface(rs2); - camera2->setOffset( -1.0, 0.0 ); - - Producer::InputArea *ia = new Producer::InputArea; - ia->addInputRectangle( rs1, Producer::InputRectangle(0.0,0.5,0.0,1.0)); - ia->addInputRectangle( rs2, Producer::InputRectangle(0.5,1.0,0.0,1.0)); -// ia->addInputRectangle( rs1, Producer::InputRectangle(-1.0,0.0,-1.0,1.0)); -// ia->addInputRectangle( rs2, Producer::InputRectangle(0.0,1.0,-1.0,1.0)); - - - Producer::CameraConfig *cfg = new Producer::CameraConfig; - cfg->addCamera("Camera 1",camera1); - cfg->addCamera("Camera 2", camera2); - cfg->setInputArea(ia); - return cfg; -} // class to handle events with a pick class PickHandler : public osgGA::GUIEventHandler { @@ -106,104 +71,33 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte void PickHandler::pick(const osgGA::GUIEventAdapter& ea) { - // OK here is the interesting bit - How To Pick a Geode - // including geodes in a HUD under a Projection Matrix - osg::Node *scene=_viewer->getSceneData();//main node of the scene. - if (scene) + osgUtil::IntersectVisitor::HitList hlist; + + std::string gdlist=""; + if (_viewer->computeIntersections(ea.getX(),ea.getY(),hlist)) { - float x=ea.getX(); - float y=ea.getY(); - - - Producer::KeyboardMouse* km = _viewer->getKeyboardMouse(); - - - std::string gdlist=""; - - for(unsigned int i=0;i<_viewer->getNumberOfCameras();++i) + for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin(); + hitr!=hlist.end(); + ++hitr) { - Producer::Camera* cmm=_viewer->getCamera(i); - Producer::RenderSurface* rs = cmm->getRenderSurface(); - - //std::cout << "checking camara "<computePixelCoords(x,y,rs,pixel_x,pixel_y)) + //osg::Vec3 ip = hitr->getLocalIntersectPoint(); + //osg::Vec3 in = hitr->getLocalIntersectNormal(); + osg::Geode* geode = hitr->_geode.get(); + // the geodes are identified by name. + if (geode) { - //std::cout << " compute pixel coords "<getProjectionRect( pr_wx, pr_wy, pr_width, pr_height ); - - int rs_wx, rs_wy; - unsigned int rs_width, rs_height; - rs->getWindowRect( rs_wx, rs_wy, rs_width, rs_height ); - - pr_wx += rs_wx; - pr_wy += rs_wy; - - //std::cout << " wx = "<(cmm->getSceneHandler()); - osg::Matrix vum; - if (sh!=0 && sh->getModelViewMatrix()!=0 && sh->getProjectionMatrix()!=0) + if (!geode->getName().empty()) { - vum.set((*(sh->getModelViewMatrix())) * - (*(sh->getProjectionMatrix()))); + gdlist=gdlist+" "+geode->getName(); } else { - vum.set(osg::Matrix(cmm->getViewMatrix()) * - osg::Matrix(cmm->getProjectionMatrix())/* * - osg::Matrix::translate(1.0f,1.0f,1.0f) * - osg::Matrix::scale(0.5f,0.5f,0.5f)*/); + gdlist=gdlist+" geode"; } - - osgUtil::PickVisitor iv; - osgUtil::IntersectVisitor::HitList& hlist=iv.getHits(scene, vum, rx,ry); - if (iv.hits()) - { - for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin(); - hitr!=hlist.end(); - ++hitr) - { - //osg::Vec3 ip = hitr->getLocalIntersectPoint(); - //osg::Vec3 in = hitr->getLocalIntersectNormal(); - osg::Geode* geode = hitr->_geode.get(); - // the geodes are identified by name. - if (geode) - { - if (!geode->getName().empty()) - { - gdlist=gdlist+" "+geode->getName(); - } - else - { - gdlist=gdlist+" geode"; - } - } - } - } - } + } } - - setLabel(gdlist); } + setLabel(gdlist); } osg::Node* createHUD(osgText::Text* updateText) @@ -311,8 +205,7 @@ int main( int argc, char **argv ) // construct the viewer. - //osgProducer::Viewer viewer(arguments); - osgProducer::Viewer viewer(BuildConfig()); + osgProducer::Viewer viewer(arguments); // set up the value with sensible default event handlers. viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); diff --git a/include/osgProducer/Viewer b/include/osgProducer/Viewer index 03a8a89cf..8fbb03eb5 100644 --- a/include/osgProducer/Viewer +++ b/include/osgProducer/Viewer @@ -20,6 +20,8 @@ #include #include +#include + #include #include #include @@ -92,14 +94,27 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction virtual void requestContinuousUpdate(bool) {} virtual void requestWarpPointer(float x,float y); - Producer::KeyboardMouse* getKeyboardMouse() { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); } - const Producer::KeyboardMouse* getKeyboardMouse() const { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); } + /** compute, from normalized mouse coords, for sepecified Camera, the pixel coords relative to that Camera's RenderSurface.*/ + bool computePixelCoords(float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y); + + /** compute, from normalized mouse coords, for sepecified Camera, the near and far points in worlds coords.*/ + bool computeNearFar(float x,float y,unsigned int cameraNum,osg::Vec3& near, osg::Vec3& far); - KeyboardMouseCallback* getKeyboardMouseCallback() { return _kbmcb; } + /** compute, from normalized mouse coords, for sepecified Camera, intersections with the scene.*/ + bool computeIntersections(float x,float y,unsigned int cameraNum,osgUtil::IntersectVisitor::HitList& hits); + /** compute, from normalized mouse coords, for all Cameras, intersections with the scene.*/ + bool computeIntersections(float x,float y,osgUtil::IntersectVisitor::HitList& hits); + + + Producer::KeyboardMouse* getKeyboardMouse() { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); } + const Producer::KeyboardMouse* getKeyboardMouse() const { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); } + + KeyboardMouseCallback* getKeyboardMouseCallback() { return _kbmcb; } const KeyboardMouseCallback* getKeyboardMouseCallback() const { return _kbmcb; } + typedef std::list< osg::ref_ptr > EventHandlerList; EventHandlerList& getEventHandlerList() { return _eventHandlerList; } diff --git a/runexamples.bat b/runexamples.bat index a189d472f..336db080b 100644 --- a/runexamples.bat +++ b/runexamples.bat @@ -10,6 +10,9 @@ osgviewer cow.osg echo osgkeyboard osgkeyboard +echo osgpick fountain.osg +osgpick fountain.osg + echo osgwindows glider.osg osgwindows glider.osg diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index b56ce2721..b47c83174 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -2,6 +2,7 @@ #include #include +#include #include @@ -299,6 +300,116 @@ void Viewer::frame() OsgCameraGroup::frame(); } +bool Viewer::computePixelCoords(float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y) +{ + Producer::KeyboardMouse* km = getKeyboardMouse(); + if (!km) return false; + + if (cameraNum>=getNumberOfCameras()) return false; + + Producer::Camera* camera=getCamera(cameraNum); + Producer::RenderSurface* rs = camera->getRenderSurface(); + + //std::cout << "checking camara "<computePixelCoords(x,y,rs,pixel_x,pixel_y)) + { + //std::cout << " compute pixel coords "<getProjectionRect( pr_wx, pr_wy, pr_width, pr_height ); + + int rs_wx, rs_wy; + unsigned int rs_width, rs_height; + rs->getWindowRect( rs_wx, rs_wy, rs_width, rs_height ); + + pixel_x -= (float)rs_wx; + pixel_y -= (float)rs_wy; + + //std::cout << " wx = "<(camera->getSceneHandler()); + osg::Matrix vum; + if (sh!=0 && sh->getModelViewMatrix()!=0 && sh->getProjectionMatrix()!=0) + { + vum.set((*(sh->getModelViewMatrix())) * + (*(sh->getProjectionMatrix()))); + } + else + { + vum.set(osg::Matrix(camera->getViewMatrix()) * + osg::Matrix(camera->getProjectionMatrix())); + } + + osgUtil::PickVisitor iv; + + osgUtil::IntersectVisitor::HitList localHits; + localHits = iv.getHits(getSceneData(), vum, rx,ry); + + if (localHits.empty()) return false; + + hits.insert(hits.begin(),localHits.begin(),localHits.end()); + + return true; + } + return false; +} + +bool Viewer::computeIntersections(float x,float y,osgUtil::IntersectVisitor::HitList& hits) +{ + bool hitFound = false; + osgUtil::IntersectVisitor::HitList hlist; + for(unsigned int i=0;ireadPixels(x,y,width,height, GL_RGB,GL_UNSIGNED_BYTE); - osgDB::writeImageFile(*image,_filename); - - osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl; + if (osgDB::writeImageFile(*image,_filename)) + { + osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl; + } _snapImageOnNextFrame = false; } @@ -802,8 +803,10 @@ bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActio osg::Node* node = _cg->getSceneData(); if (node) { - std::cout<<"writing file "<<_writeNodeFileName<