From 4954262eb01decb22272e85f55355a81e9b38ca6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 10 Jan 2007 10:09:05 +0000 Subject: [PATCH] Added View::computeIntersection implementation for a node withing a scene graph. --- include/osgUtil/LineSegmentIntersector | 2 +- include/osgViewer/Scene | 18 +------- include/osgViewer/View | 9 +--- include/osgViewer/Viewer | 6 ++- src/osgUtil/LineSegmentIntersector.cpp | 2 +- src/osgViewer/Scene.cpp | 45 +------------------- src/osgViewer/View.cpp | 36 +++++++++++++++- src/osgViewer/Viewer.cpp | 57 +++++++++++--------------- 8 files changed, 69 insertions(+), 106 deletions(-) diff --git a/include/osgUtil/LineSegmentIntersector b/include/osgUtil/LineSegmentIntersector index 113bdaf9a..a617b00d2 100644 --- a/include/osgUtil/LineSegmentIntersector +++ b/include/osgUtil/LineSegmentIntersector @@ -33,7 +33,7 @@ class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector /** Convinience constructor for supporting picking in WINDOW, or PROJECTION coorindates * In WINDOW coordinates creates a start value of (x,y,0) and end value of (x,y,1). - * In PROJECTION coordinates (clip space cube) creates a start value of (x,y,1) and end value of (x,y,-1). + * In PROJECTION coordinates (clip space cube) creates a start value of (x,y,-1) and end value of (x,y,1). * In VIEW and MODEL coordinates creates a start value of (x,y,0) and end value of (x,y,1).*/ LineSegmentIntersector(CoordinateFrame cf, double x, double y); diff --git a/include/osgViewer/Scene b/include/osgViewer/Scene index dbbc43256..7279ad1e3 100644 --- a/include/osgViewer/Scene +++ b/include/osgViewer/Scene @@ -41,22 +41,12 @@ class OSGVIEWER_EXPORT Scene : public virtual osg::Referenced osg::FrameStamp* getFrameStamp() { return _frameStamp.get(); } - void setEventQueue(osgGA::EventQueue* eventQueue) { _eventQueue = eventQueue; } - osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); } - const osgGA::EventQueue* getEventQueue() const { return _eventQueue.get(); } - - typedef std::list< osg::ref_ptr > EventHandlers; - - void addEventHandler(osgGA::GUIEventHandler* eventHandler); - EventHandlers& getEventHandlers() { return _eventHandlers; } - const EventHandlers& getEventHandlers() const { return _eventHandlers; } - void setDatabasePager(osgDB::DatabasePager* dp); osgDB::DatabasePager* getDatabasePager() { return _databasePager.get(); } const osgDB::DatabasePager* getDatabasePager() const { return _databasePager.get(); } virtual void frameAdvance(); - virtual void frameEventTraversal(); + virtual void frameUpdateTraversal(); public: @@ -72,13 +62,7 @@ class OSGVIEWER_EXPORT Scene : public virtual osg::Referenced osg::ref_ptr _updateVisitor; - osg::ref_ptr _eventQueue; - osg::ref_ptr _eventVisitor; - osg::ref_ptr _databasePager; - - EventHandlers _eventHandlers; - }; diff --git a/include/osgViewer/View b/include/osgViewer/View index ec83db549..12d352d71 100644 --- a/include/osgViewer/View +++ b/include/osgViewer/View @@ -64,12 +64,8 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter * directly on to the computeIntersections method. */ bool computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); - /** Compute intersections between a ray through the specified master cameras window/eye coords and a specified node. - * Note, when a master cameras has slaves and no viewport itself its coordinate frame will be in clip space i.e. -1,-1 to 1,1, - * while if its has a viewport the coordintates will be relative to its viewport dimensions. - * Mouse events handled by the view will automatically be attached into the master camera window/clip coords so can be passed - * directly on to the computeIntersections method. */ - bool computeIntersections(float x,float y, osg::Node* node, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); + /** Compute intersections between a ray through the specified master cameras window/eye coords and a specified nodePath's subgraph. */ + bool computeIntersections(float x,float y, osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); virtual void requestRedraw(); @@ -91,7 +87,6 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter typedef std::map, osg::ref_ptr > CameraSceneViewMap; CameraSceneViewMap _cameraSceneViewMap; - }; } diff --git a/include/osgViewer/Viewer b/include/osgViewer/Viewer index d7a71ba8a..39de2d1c6 100644 --- a/include/osgViewer/Viewer +++ b/include/osgViewer/Viewer @@ -16,6 +16,7 @@ #include #include +#include namespace osgViewer { @@ -132,8 +133,9 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View unsigned int _numThreadsOnBarrier; - osg::observer_ptr _cameraWithFocus; - + osg::observer_ptr _cameraWithFocus; + + osg::ref_ptr _eventVisitor; }; diff --git a/src/osgUtil/LineSegmentIntersector.cpp b/src/osgUtil/LineSegmentIntersector.cpp index 37fb999cc..aa5c4cce2 100644 --- a/src/osgUtil/LineSegmentIntersector.cpp +++ b/src/osgUtil/LineSegmentIntersector.cpp @@ -220,7 +220,7 @@ LineSegmentIntersector::LineSegmentIntersector(CoordinateFrame cf, double x, dou switch(cf) { case WINDOW : _start.set(x,y,0.0); _end.set(x,y,1.0); break; - case PROJECTION : _start.set(x,y,1.0); _end.set(x,y,-1.0); break; + case PROJECTION : _start.set(x,y,-1.0); _end.set(x,y,1.0); break; case VIEW : _start.set(x,y,0.0); _end.set(x,y,1.0); break; case MODEL : _start.set(x,y,0.0); _end.set(x,y,1.0); break; } diff --git a/src/osgViewer/Scene.cpp b/src/osgViewer/Scene.cpp index 0382c909f..614b24d76 100644 --- a/src/osgViewer/Scene.cpp +++ b/src/osgViewer/Scene.cpp @@ -12,6 +12,7 @@ */ #include +#include using namespace osgViewer; @@ -64,11 +65,6 @@ void Scene::setDatabasePager(osgDB::DatabasePager* dp) _databasePager = dp; } -void Scene::addEventHandler(osgGA::GUIEventHandler*) -{ - osg::notify(osg::NOTICE)<<"Scene::addEventHandler() not implementated yet."<getReferenceTime(); @@ -79,45 +75,6 @@ void Scene::frameAdvance() // osg::notify(osg::NOTICE)<<"Frame rate = "<<1.0/(_frameStamp->getReferenceTime()-previousTime)<frame( _frameStamp->getReferenceTime() ); - - osgGA::EventQueue::Events events; - _eventQueue->takeEvents(events); - - if (_eventVisitor.valid()) - { - _eventVisitor->setTraversalNumber(_frameStamp->getFrameNumber()); - } - - for(osgGA::EventQueue::Events::iterator itr = events.begin(); - itr != events.end(); - ++itr) - { - osgGA::GUIEventAdapter* event = itr->get(); - - bool handled = false; - - if (_eventVisitor.valid() && getSceneData()) - { - _eventVisitor->reset(); - _eventVisitor->addEvent( event ); - - getSceneData()->accept(*_eventVisitor); - - if (_eventVisitor->getEventHandled()) handled = true; - } - - for(EventHandlers::iterator hitr = _eventHandlers.begin(); - hitr != _eventHandlers.end() && !handled; - ++hitr) - { -// handled = (*hitr)->handle( *event, *this, 0, 0); - } - } -} - void Scene::frameUpdateTraversal() { if (!getSceneData()) return; diff --git a/src/osgViewer/View.cpp b/src/osgViewer/View.cpp index f42b70646..7f52e6082 100644 --- a/src/osgViewer/View.cpp +++ b/src/osgViewer/View.cpp @@ -409,11 +409,43 @@ bool View::computeIntersections(float x,float y, osgUtil::LineSegmentIntersector } } -bool View::computeIntersections(float x,float y, osg::Node* node, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask) +bool View::computeIntersections(float x,float y, osg::NodePath& nodePath, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask) { if (!_camera.valid()) return false; osg::notify(osg::NOTICE)<<"View::computeIntersections(x,y,node,intersections) not implemented"<getViewMatrix() * _camera->getProjectionMatrix(); + + double zNear = -1.0; + double zFar = 1.0; + if (_camera->getViewport()) + { + matrix.postMult(_camera->getViewport()->computeWindowMatrix()); + zNear = 0.0; + zFar = 1.0; + } + + osg::Matrix inverse; + inverse.invert(matrix); + + osg::Vec3d startVertex = osg::Vec3d(x,y,zNear) * inverse; + osg::Vec3d endVertex = osg::Vec3d(x,y,zFar) * inverse; + + osgUtil::LineSegmentIntersector* picker = new osgUtil::LineSegmentIntersector(osgUtil::Intersector::MODEL, startVertex, endVertex); + + osgUtil::IntersectionVisitor iv(picker); + iv.setTraversalMask(traversalMask); + nodePath.back()->accept(iv); + + if (picker->containsIntersections()) + { + intersections = picker->getIntersections(); + return true; + } + else + { + intersections.clear(); + return false; + } } diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index d63dcbaed..a69b16057 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -31,6 +31,8 @@ Viewer::Viewer(): _threadingModel(ThreadPerContext), _numThreadsOnBarrier(0) { + _eventVisitor = new osgGA::EventVisitor; + _eventVisitor->setActionAdapter(this); } Viewer::~Viewer() @@ -723,37 +725,6 @@ void Viewer::eventTraversal() } } -#if 0 - // pointer coordinate transform - for(osgGA::EventQueue::Events::iterator itr = events.begin(); - itr != events.end(); - ++itr) - { - osgGA::GUIEventAdapter* event = itr->get(); - - if (getEventQueue()->getUseFixedMouseInputRange()) - { - event->setInputRange(eventState->getXmin(), eventState->getYmin(), eventState->getXmax(), eventState->getYmax()); - } - - switch(event->getEventType()) - { - case(osgGA::GUIEventAdapter::PUSH): - case(osgGA::GUIEventAdapter::RELEASE): - case(osgGA::GUIEventAdapter::DRAG): - case(osgGA::GUIEventAdapter::MOVE): - eventState->setX(event->getX()); - eventState->setY(event->getY()); - eventState->setButtonMask(event->getButtonMask()); - // osg::notify(osg::NOTICE)<<" mouse x = "<getX()<<" y="<getY()<getKey()<<"'"<getWindowX()<<"/"<getWindowY()<<" x "<getWindowWidth()<<"/"<getWindowHeight() << std::endl; break; case(osgGA::GUIEventAdapter::QUIT_APPLICATION): @@ -861,6 +832,28 @@ void Viewer::eventTraversal() } } + if (_eventVisitor.valid()) + { + _eventVisitor->setFrameStamp(_scene->getFrameStamp()); + _eventVisitor->setTraversalNumber(_scene->getFrameStamp()->getFrameNumber()); + + for(osgGA::EventQueue::Events::iterator itr = events.begin(); + itr != events.end(); + ++itr) + { + osgGA::GUIEventAdapter* event = itr->get(); + + bool handled = false; + + _eventVisitor->reset(); + _eventVisitor->addEvent( event ); + + getSceneData()->accept(*_eventVisitor); + + if (_eventVisitor->getEventHandled()) handled = true; + } + } + } void Viewer::updateTraversal()