[osg-users] Visibility of Vertices

Daniel Neos daniel.rd at hotmail.de
Fri Jul 8 08:04:19 PDT 2016


is there an easy way to determine whether a single vertex is visible or not, i.e. no other object is blocking the line of sight?

My problem is that my geometry does not consist of solid objects or planes, just a lot of single vertices.

I want to be enable to pick a point reliably by a mouseclick. My approach is to use the polytopeintersector, then mapping all points that have been caught by the intersector into screen-coordinates and comparing them with the screen-coordinates of my mouseclick.

This works very well until my camera is set such that multiple vertices seems to be "in line", so that a point in the background gets accidentally picked.
I could exclude those points if I am able to tell that those points are occluded by the points in the foreground. I could imagine that this is rather simple with solid objects, but how can I achieve this in my setup?

Any help would by appreciated.

Here is the code which handles the pointpicking so far:


osg::Vec2d worldToScreenNormalized(const osg::Vec3d& worldPosition, const osg::Camera* pCamera, const osgGA::GUIEventAdapter& ea)
    osg::Vec2d screenPosition;

    if (pCamera != nullptr)
        osg::Matrixd MVPW = pCamera->getViewMatrix() * pCamera->getProjectionMatrix() * pCamera->getViewport()->computeWindowMatrix();
        osg::Vec4d screenPosition4d = osg::Vec4d(worldPosition, 1.0) * MVPW;
        screenPosition4d = screenPosition4d / screenPosition4d.w();
        screenPosition4d.y() = pCamera->getViewport()->height() - screenPosition4d.y();
        screenPosition.set(screenPosition4d.x(), screenPosition4d.y());
        screenPosition.set(2.0f*(screenPosition.x() - ea.getXmin()) / (ea.getXmax()- ea.getXmin()) - 1.0f,
            -(2.0f*(screenPosition.y() - ea.getYmin()) / (ea.getYmax() - ea.getYmin()) - 1.0f));

    return screenPosition;

bool PickHandler::getPickedPoint(const osgGA::GUIEventAdapter& ea, float buffer,
    osgViewer::View* viewer)
        intersector = new osgUtil::PolytopeIntersector(
            ea.getXnormalized() - buffer, ea.getYnormalized() - buffer, ea.getXnormalized() + buffer, ea.getYnormalized() + buffer);
    catch (const std::bad_alloc&)
        return false;

    const osg::Vec2d clickedNormalizedScreencoord(ea.getXnormalized(), ea.getYnormalized());
    // DimZero = check only for points
    // nearest intersection
    osgUtil::IntersectionVisitor iv(intersector);

    // check if intersector has got intersections and chooses the first one, else set NaN
    if (intersector->containsIntersections())
        osgUtil::PolytopeIntersector::Intersection intersection
            = *(intersector->getIntersections().begin());

        osg::Vec3f pickedPoint;

        float distance = 1E10;
        unsigned int numIntersection=0;
        osg::Vec3f sum;
        for (auto it = intersector->getIntersections().begin(); it != intersector->getIntersections().end(); it++)
            unsigned int numIntersections = it->numIntersectionPoints;
            for (size_t i = 0; i < numIntersections; ++i)
                osg::Vec2d screen = worldToScreenNormalized(it->intersectionPoints[i], viewer->getCamera(),ea);
                if ((screen - clickedNormalizedScreencoord).length2() < distance )
                    distance = (screen - clickedNormalizedScreencoord).length2();
                    pickedPoint = it->intersectionPoints[i];

        if (pickedPoint.isNaN())
            return false;
        m_point.set(pickedPoint[0], pickedPoint[1], pickedPoint[2]);
        float NaN = std::numeric_limits<float>::quiet_NaN();
        m_point.set(NaN, NaN, NaN);
    return true;

Thank you!


Read this topic online here:

More information about the osg-users mailing list