osgUtil.IntersectionVisitor类是OpenSceneGraph中的一个实用性访问器,用于计算场景图中对撞机和可计算物体之间的相交信息。此访问者可以遍历场景图中的任何节点和三维几何体,以计算它们之间的相交信息。
class IntersectionVisitor : public osg::NodeVisitor;
IntersectionVisitor();
创建一个空的IntersectionVisitor对象。
IntersectionVisitor(const IntersectionVisitor& iv, osg::CopyOp copyop = osg::CopyOp::SHALLOW_COPY);
创建一个IntersectionVisitor对象的副本,并根据需要执行深复制或浅复制。
enum IntersectionVisitor::IntersectionMode {
INTERSECT_EACH_SEGMENT,
INTERSECT_EACH_PRIMITIVE,
};
这是一个枚举类型,用于指定IntersectionVisitor到达场景图节点时如何处理相交点。它有两个可能的值:
void setIntersectionMode(IntersectionMode mode);
设置IntersectionVisitor的相交模式。
IntersectionMode getIntersectionMode() const;
获取IntersectionVisitor的相交模式。
void setIntersectionLimit(unsigned int limit);
设置IntersectionVisitor的相交限制。如果设置,则在达到给定数量的相交点后,访问者将停止遍历场景图并返回相交信息。
unsigned int getIntersectionLimit() const;
获取IntersectionVisitor的相交限制。
void apply(osg::Node& node) override;
为一个节点应用IntersectionVisitor。如果IntersectionMode被设置为INTERSECT_EACH_PRIMITIVE,此函数将为每个三角形、线段和点调用回调函数。
void apply(osg::Geode& geode) override;
为一个几何图形应用IntersectionVisitor。如果IntersectionMode被设置为INTERSECT_EACH_PRIMITIVE,此函数将为每个面、线和点调用回调函数。
void apply(osg::Transform& transform) override;
为一个变换应用IntersectionVisitor。这个函数会遍历变换节点下的子节点,但是会将变换用于相交测试。
void apply(osg::Drawable& drawable) override;
为一个Drawable应用IntersectionVisitor。如果IntersectionMode被设置为INTERSECT_EACH_PRIMITIVE,此函数将为几何体的每个面、线和点调用回调函数。
void setEnterCallback(IntersectionVisitor::IntersectionVisitorCallback* cb);
设置IntersectionVisitor进入节点或三维几何体时的回调函数。
IntersectionVisitor::IntersectionVisitorCallback* getEnterCallback() const;
获取IntersectionVisitor进入节点或三维几何体时的回调函数。
void setLeaveCallback(IntersectionVisitor::IntersectionVisitorCallback* cb);
设置IntersectionVisitor离开节点或三维几何体时的回调函数。
IntersectionVisitor::IntersectionVisitorCallback* getLeaveCallback() const;
获取IntersectionVisitor离开节点或三维几何体时的回调函数。
osgUtil::Intersector* getIntersector();
获取IntersectionVisitor中与之关联的osgUtil::Intersector对象。
const osgUtil::Intersector* getIntersector() const;
获取IntersectionVisitor中与之关联的osgUtil::Intersector对象。
typedef std::vector<osgUtil::Intersector::Intersection> Intersections;
定义了一个存储相交信息的向量。
const Intersections& getIntersections() const;
获取所有相交信息。
void reset();
重置IntersectionVisitor中的相交信息。
以下示例演示了如何使用osgUtil::IntersectionVisitor计算场景图中每个几何体与对撞机之间的距离。
#include <osg/Node>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osgViewer/Viewer>
#include <osgUtil/IntersectionVisitor>
#include <osgUtil/LineSegmentIntersector>
class PickHandler : public osgGA::GUIEventHandler
{
public:
PickHandler(osg::Node* scene) : _scene(scene) {}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE &&
ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
if (view)
{
osg::NodePath nodePath;
osg::Vec3 clickPosition = osg::Vec3(ea.getX(), ea.getY(), 0);
if (view->computeIntersections(clickPosition.x(), clickPosition.y(), nodePath))
{
osg::Geode* geode = dynamic_cast<osg::Geode*>(nodePath.back());
if (geode)
{
osg::Vec3 worldClickPosition = clickPosition * osg::computeLocalToWorld(nodePath);
osgUtil::LineSegmentIntersector* intersectionVisitor =
new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW,
worldClickPosition - osg::Vec3(0, 0, 1000),
worldClickPosition + osg::Vec3(0, 0, 1000));
osgUtil::IntersectionVisitor iv(intersectionVisitor);
geode->accept(iv);
const osgUtil::LineSegmentIntersector::Intersections& hits = intersectionVisitor->getIntersections();
if (!hits.empty())
std::cout << "Distance: " << hits.front().distance << std::endl;
else
std::cout << "No hits" << std::endl;
return true;
}
}
}
}
return false;
}
private:
osg::ref_ptr<osg::Node> _scene;
};
int main(int argc, char** argv)
{
osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(osg::Vec3(0, 0, 0), 1.0f);
osg::ref_ptr<osg::ShapeDrawable> shapeDrawable = new osg::ShapeDrawable(sphere.get());
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
geode->addDrawable(shapeDrawable.get());
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
root->addChild(geode.get());
viewer->setSceneData(root.get());
viewer->addEventHandler(new PickHandler(root.get()));
return viewer->run();
}
这将在单击几何实体时计算从鼠标点击位置到几何实体的距离。