Simple object picking with OpenSceneGraph
Tags: programming, projects, software
As an extension to my previous post on rectangular selections with Qt and OpenScenegraph, I just updated the example project with a very simple pick handler. A pick handler is a simple event handler that permits picking, i.e. selecting objects in a scene.
Doing it manually
The basic implementation is straightforward. We first inherit from the
base class osgGA::GUIEventHandler
and provide our own implementation
of the handle()
function. In this function, we use a line segment
intersector class to determine intersections within the window:
bool PickHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
{
if( ea.getEventType() != osgGA::GUIEventAdapter::RELEASE &&
ea.getButton() != osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
{
return false;
}
osgViewer::View* viewer = dynamic_cast<osgViewer::View*>( &aa );
if( viewer )
{
osgUtil::LineSegmentIntersector* intersector
= new osgUtil::LineSegmentIntersector( osgUtil::Intersector::WINDOW, ea.getX(), ea.getY() );
osgUtil::IntersectionVisitor iv( intersector );
osg::Camera* camera = viewer->getCamera();
if( !camera )
return false;
camera->accept( iv );
if( !intersector->containsIntersections() )
return false;
auto intersections = intersector->getIntersections();
std::cout << "Got " << intersections.size() << " intersections:\n";
for( auto&& intersection : intersections )
std::cout << " - Local intersection point = " << intersection.localIntersectionPoint << "\n";
}
return true;
}
The localIntersectionPoint
variable contains the intersection point in
local coordinates. It is also possible to obtain the intersection point
in world coordinates by calling the getWorldIntersectPoint()
function of the intersection.
A shortcut
Instead of setting up our own line segment intersector, we could also
call the osgViewer::View::computeIntersections
of our view. This
involves a dynamic cast in the handle
function. The way outlined above
is for instructive purposes only.
Code
As always, the code is available in a git repository.