Moved PickVistor into osgUtil

This commit is contained in:
Robert Osfield
2005-12-07 10:25:50 +00:00
parent 2d14519946
commit 99be2cdb7f
4 changed files with 103 additions and 83 deletions

View File

@@ -202,6 +202,29 @@ class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor
osg::Vec3 _pseudoEyePoint;
};
/** Picking intersection visitor specialises the IntersectVistor to allow more convinient handling of mouse picking.*/
class OSGUTIL_EXPORT PickVisitor : public osgUtil::IntersectVisitor
{
public:
PickVisitor(const osg::Viewport* viewport, const osg::Matrixd& proj, const osg::Matrixd& view, float mx, float my);
void runNestedPickVisitor(osg::Node& node, const osg::Viewport* viewport, const osg::Matrix& proj, const osg::Matrix& view, float mx, float my);
void apply(osg::Projection& projection);
void apply(osg::CameraNode& camera);
protected:
float _mx;
float _my;
osg::ref_ptr<const osg::Viewport> _lastViewport;
osg::Matrixd _lastProjectionMatrix;
osg::Matrixd _lastViewMatrix;
};
}
#endif

View File

@@ -30,87 +30,6 @@ using namespace osg;
#define SINGLE_THREAD_KEYBOARDMOUSE
#endif
//////////////////////////////////////////////////////////////////////////////
//
// Picking intersection visitor.
//
class PickVisitor : public osgUtil::IntersectVisitor
{
public:
PickVisitor(const osg::Viewport* viewport, const osg::Matrixd& proj, const osg::Matrixd& view, float mx, float my):
_mx(mx),
_my(my),
_lastViewport(viewport),
_lastProjectionMatrix(proj),
_lastViewMatrix(view)
{
if (viewport &&
mx >= static_cast<float>(viewport->x()) &&
my >= static_cast<float>(viewport->y()) &&
mx < static_cast<float>(viewport->x()+viewport->width()) &&
my < static_cast<float>(viewport->y()+viewport->height()))
{
// mouse pointer intersect viewport so we can proceed to set up a line segment
osg::Matrix MVPW = view * proj * viewport->computeWindowMatrix();
osg::Matrixd inverseMVPW;
inverseMVPW.invert(MVPW);
osg::Vec3 nearPoint = osg::Vec3(mx,my,0.0f) * inverseMVPW;
osg::Vec3 farPoint = osg::Vec3(mx,my,1.0f) * inverseMVPW;
osg::LineSegment* lineSegment = new osg::LineSegment;
lineSegment->set(nearPoint, farPoint);
addLineSegment(lineSegment);
}
}
void runNestedPickVisitor(osg::Node& node, const osg::Viewport* viewport, const osg::Matrix& proj, const osg::Matrix& view, float mx, float my)
{
PickVisitor newPickVisitor( viewport, proj, view, _mx, _my );
newPickVisitor.setTraversalMask(getTraversalMask());
// the new pickvisitor over the nodes children.
node.traverse( newPickVisitor );
for(LineSegmentHitListMap::iterator itr = newPickVisitor._segHitList.begin();
itr != newPickVisitor._segHitList.end();
++itr)
{
_segHitList.insert(*itr);
}
}
void apply(osg::Projection& projection)
{
runNestedPickVisitor( projection,
_lastViewport.get(),
projection.getMatrix(),
_lastViewMatrix,
_mx, _my );
}
void apply(osg::CameraNode& camera)
{
runNestedPickVisitor( camera,
camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
camera.getProjectionMatrix(),
camera.getViewMatrix(),
_mx, _my );
}
float _mx;
float _my;
osg::ref_ptr<const osg::Viewport> _lastViewport;
osg::Matrixd _lastProjectionMatrix;
osg::Matrixd _lastViewMatrix;
};
class CollectedCoordinateSystemNodesVisitor : public osg::NodeVisitor
{
@@ -847,13 +766,13 @@ bool Viewer::computeIntersections(float x,float y,unsigned int cameraNum,osg::No
node = node->getParent(0);
PickVisitor pick(viewport, proj, view, pixel_x, pixel_y);
osgUtil::PickVisitor pick(viewport, proj, view, pixel_x, pixel_y);
pick.setTraversalMask(traversalMask);
node->accept(pick);
// copy all the hits across to the external hits list
for(osgUtil::IntersectVisitor::LineSegmentHitListMap::iterator itr = pick.getSegHitList().begin();
for(osgUtil::PickVisitor::LineSegmentHitListMap::iterator itr = pick.getSegHitList().begin();
itr != pick.getSegHitList().end();
++itr)
{

View File

@@ -18,6 +18,8 @@
#include <osg/Notify>
#include <osg/TriangleFunctor>
#include <osg/Geometry>
#include <osg/Projection>
#include <osg/CameraNode>
#include <osg/io_utils>
#include <float.h>
@@ -661,3 +663,67 @@ void IntersectVisitor::apply(LOD& node)
{
apply((Group&)node);
}
PickVisitor::PickVisitor(const osg::Viewport* viewport, const osg::Matrixd& proj, const osg::Matrixd& view, float mx, float my):
_mx(mx),
_my(my),
_lastViewport(viewport),
_lastProjectionMatrix(proj),
_lastViewMatrix(view)
{
if (viewport &&
mx >= static_cast<float>(viewport->x()) &&
my >= static_cast<float>(viewport->y()) &&
mx < static_cast<float>(viewport->x()+viewport->width()) &&
my < static_cast<float>(viewport->y()+viewport->height()))
{
// mouse pointer intersect viewport so we can proceed to set up a line segment
osg::Matrix MVPW = view * proj * viewport->computeWindowMatrix();
osg::Matrixd inverseMVPW;
inverseMVPW.invert(MVPW);
osg::Vec3 nearPoint = osg::Vec3(mx,my,0.0f) * inverseMVPW;
osg::Vec3 farPoint = osg::Vec3(mx,my,1.0f) * inverseMVPW;
osg::LineSegment* lineSegment = new osg::LineSegment;
lineSegment->set(nearPoint, farPoint);
addLineSegment(lineSegment);
}
}
void PickVisitor::runNestedPickVisitor(osg::Node& node, const osg::Viewport* viewport, const osg::Matrix& proj, const osg::Matrix& view, float mx, float my)
{
PickVisitor newPickVisitor( viewport, proj, view, mx, my );
newPickVisitor.setTraversalMask(getTraversalMask());
// the new pickvisitor over the nodes children.
node.traverse( newPickVisitor );
for(LineSegmentHitListMap::iterator itr = newPickVisitor._segHitList.begin();
itr != newPickVisitor._segHitList.end();
++itr)
{
_segHitList.insert(*itr);
}
}
void PickVisitor::apply(osg::Projection& projection)
{
runNestedPickVisitor( projection,
_lastViewport.get(),
projection.getMatrix(),
_lastViewMatrix,
_mx, _my );
}
void PickVisitor::apply(osg::CameraNode& camera)
{
runNestedPickVisitor( camera,
camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
camera.getProjectionMatrix(),
camera.getViewMatrix(),
_mx, _my );
}

View File

@@ -10,16 +10,20 @@
#include <osgIntrospection/Attributes>
#include <osg/Billboard>
#include <osg/CameraNode>
#include <osg/Drawable>
#include <osg/Geode>
#include <osg/Group>
#include <osg/LOD>
#include <osg/LineSegment>
#include <osg/Matrix>
#include <osg/Matrixd>
#include <osg/Node>
#include <osg/Projection>
#include <osg/Switch>
#include <osg/Transform>
#include <osg/Vec3>
#include <osg/Viewport>
#include <osgUtil/IntersectVisitor>
// Must undefine IN and OUT macros defined in Windows headers
@@ -103,6 +107,14 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::IntersectVisitor)
I_ReadOnlyProperty(osgUtil::IntersectVisitor::LineSegmentHitListMap &, SegHitList);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgUtil::PickVisitor)
I_BaseType(osgUtil::IntersectVisitor);
I_Constructor5(IN, const osg::Viewport *, viewport, IN, const osg::Matrixd &, proj, IN, const osg::Matrixd &, view, IN, float, mx, IN, float, my);
I_Method6(void, runNestedPickVisitor, IN, osg::Node &, node, IN, const osg::Viewport *, viewport, IN, const osg::Matrix &, proj, IN, const osg::Matrix &, view, IN, float, mx, IN, float, my);
I_Method1(void, apply, IN, osg::Projection &, projection);
I_Method1(void, apply, IN, osg::CameraNode &, camera);
END_REFLECTOR
STD_MAP_REFLECTOR(std::map< const osg::LineSegment * COMMA osgUtil::IntersectVisitor::HitList >);
STD_VECTOR_REFLECTOR(std::vector< int >);