/* -*-c++-*- */ /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph * Copyright 2015 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ #ifndef OSGEARTH_INTERSECTION_PICKER_H #define OSGEARTH_INTERSECTION_PICKER_H #include <osgEarth/Common> #include <osgEarth/ObjectIndex> #include <osgEarth/PrimitiveIntersector> #include <osgViewer/View> #include <osgEarthFeatures/Feature> namespace osgEarth { /** * Utility for picking objects from the scene. */ class OSGEARTH_EXPORT IntersectionPicker { public: typedef osgEarth::PrimitiveIntersector::Intersection Hit; typedef osgEarth::PrimitiveIntersector::Intersections Hits; enum Limit { NO_LIMIT, LIMIT_ONE_PER_DRAWABLE, LIMIT_ONE, LIMIT_NEAREST }; public: /** * Constructs a picker that will pick data from the given view, * and restrict its search to the given graph. * * @param view View under which to pick * @param graph Subgraph within which to restrict the pick * @param traversalMask Node mask to apply to the pick visitor * @param buffer Pick buffer around the click (pixels) */ IntersectionPicker( osgViewer::View* view, osg::Node* graph =0L, unsigned traversalMask =~0, float buffer =5.0f, Limit limit =LIMIT_NEAREST); /** dtor */ virtual ~IntersectionPicker() { } /** * Sets the node mask to apply to the pick visitor. This lets you * limit the subgraph that the picker searches. */ void setTraversalMask(unsigned mask); /** * Sets the search buffer around the mouse. */ void setBuffer(float buffer); /** * Sets the hit limit mode. */ void setLimit(const Limit& limit); /** * Picks geometry under the specified viewport coordinates. The results * are stores in "results". You can typically get the mouseX and mouseY * from osgGA::GUIEventAdapter getX() and getY(). */ bool pick( float mouseX, float mouseY, Hits& results ) const; /** * Finds and returns the lowest node of type "T" in a hit, or 0L if no such * node exists. */ template<typename T> T* getNode( const Hit& hit ) const { for( osg::NodePath::const_reverse_iterator i = hit.nodePath.rbegin(); i != hit.nodePath.rend(); ++i ) { T* node = dynamic_cast<T*>(*i); if ( node ) return node; } return 0L; } /** * Given a set of pick results, extract the object IDs within. * Results true is the output connection is populated. */ bool getObjectIDs(const Hits& results, std::set<ObjectID>& out_objectIDs) const; protected: osgViewer::View* _view; osg::ref_ptr<osg::Node> _root; osg::NodePath _path; unsigned _travMask; float _buffer; Limit _limit; }; } #endif // OSGEARTH_INTERSECTION_PICKER_H