[osg-users] Visibility of Vertices

Robert Osfield robert.osfield at gmail.com
Sat Jul 9 01:30:17 PDT 2016


Hi Daniel,

There isn't a perfect solution for what you are after as points are
how "large" points are can be an poorly controlled property.  It's
perfect legal to have a point be inifinitely small so that it's not
likely that two points will ever be in front of each other.  Only if
you start to assign a size to points does it become practical to doing
tests against which points may be in front of each other.

The osg::PolytopeIntersector doesn't know anything about the possible
size of points so can't make any decision about what might be in front
of another.  To implement a form of infront/behind test for points
you'll need t come up with a way of mapping a size to the points.
That size could be in screen space or object space, which is
appropriate for your usage is entirely down to the needs of your app.
 You'll then need to work out a means for projecting the points into a
form of cyclinder or polytope to do the collision test and then do the
tests.  The OSG doesn't have anything off the shelf that implements
this so it's down to you.

Robert.





On 8 July 2016 at 16:04, Daniel Neos <daniel.rd at hotmail.de> wrote:
> Hi,
>
> 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:
>
> Code:
>
> 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)
> {
>     try
>     {
>         intersector = new osgUtil::PolytopeIntersector(
>             osgUtil::Intersector::PROJECTION,
>             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
>     intersector->setDimensionMask(osgUtil::PolytopeIntersector::DimZero);
>     // nearest intersection
>     intersector->setIntersectionLimit(osgUtil::Intersector::NO_LIMIT);
>     osgUtil::IntersectionVisitor iv(intersector);
>     viewer->getCamera()->accept(iv);
>
>     // 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;
>             numIntersection++;
>             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]);
>     }
>     else
>     {
>         float NaN = std::numeric_limits<float>::quiet_NaN();
>         m_point.set(NaN, NaN, NaN);
>     }
>     return true;
> }
>
>
>
>
>
>
>
>
> Thank you!
>
> Cheers,
> Daniel[/code]
>
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=68065#68065
>
>
>
>
>
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org



More information about the osg-users mailing list