// M23.11.W5.LineSegmentIntersector.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
//osg
#include <osg/Texture2D>
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osg/Geometry>
#include <osg/Material>
#include <osg/PolygonMode>
#include <osg/PolygonOffset>
#include <osg/OccluderNode>
#include <osg/LineWidth>
#include <osg/io_utils>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgGA/AnimationPathManipulator>
//osgUtil
#include <osgUtil/SmoothingVisitor>
#include <osgUtil/Optimizer>
#include <osgUtil/PrintVisitor>
#include <osgUtil/IntersectionVisitor>
#include <osgUtil/LineSegmentIntersector>
//osglib
#ifdef DEBUG
#pragma comment(lib,"OpenThreads_d.lib")
#pragma comment(lib,"osg_d.lib")
#pragma comment(lib,"osgDB_d.lib")
#pragma comment(lib,"osgFX_d.lib")
#pragma comment(lib,"osgGA_d.lib")
#pragma comment(lib,"osgUtil_d.lib")
#pragma comment(lib,"osgViewer_d.lib")
#pragma comment(lib,"osgShadow_d.lib")
#else
#pragma comment(lib,"OpenThreads.lib")
#pragma comment(lib,"osg.lib")
#pragma comment(lib,"osgDB.lib")
#pragma comment(lib,"osgFX.lib")
#pragma comment(lib,"osgGA.lib")
#pragma comment(lib,"osgUtil.lib")
#pragma comment(lib,"osgViewer.lib")
#pragma comment(lib,"osgShadow.lib")
#endif // DEBUG
struct MyReadCallback : public osgUtil::IntersectionVisitor::ReadCallback
{
virtual osg::ref_ptr<osg::Node> readNodeFile(const std::string& filename)
{
return osgDB::readRefNodeFile(filename);
}
};
int main(int argc, char **argv)
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc, argv);
osg::ref_ptr<osg::Node> scene = osgDB::readRefNodeFiles(arguments);
if (!scene)
{
std::cout << "No model loaded, please specify a valid model on the command line." << std::endl;
return 0;
}
std::cout << "Intersection " << std::endl;
osg::Timer_t startTick = osg::Timer::instance()->tick();
osg::BoundingSphere bs = scene->getBound();
osg::Vec3d start = bs.center() + osg::Vec3d(0.0, bs.radius(), 0.0);
osg::Vec3d end = bs.center() - osg::Vec3d(0.0, bs.radius(), 0.0);
osg::ref_ptr<osgUtil::IntersectorGroup> intersectorGroup = new osgUtil::IntersectorGroup();
// ture=多条求交线段;false=一条线段求交
bool useIntersectorGroup = false;
if (useIntersectorGroup)
{//多条求交线段
osg::Vec3d deltaRow(0.0, 0.0, bs.radius()*0.01);
osg::Vec3d deltaColumn(bs.radius()*0.01, 0.0, 0.0);
unsigned int numRows = 2;
unsigned int numColumns = 2;
for (unsigned int r = 0; r < numRows; ++r)
{
for (unsigned int c = 0; c < numColumns; ++c)
{
osg::Vec3d s = start + deltaColumn * double(c) + deltaRow * double(r);
osg::Vec3d e = end + deltaColumn * double(c) + deltaRow * double(r);
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(s, e);
intersectorGroup->addIntersector(intersector.get());
}
}
}
else
{//一条线段求交
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(start, end);
intersectorGroup->addIntersector(intersector.get());
}
//如果 射线求交
//osg::ref_ptr<osgUtil::RayIntersector> ray = new osgUtil::RayIntersector(args...);
//intersectorGroup->addIntersector(ray.get());
//如果 面求交
//osg::ref_ptr<osgUtil::PlaneIntersector> plane = new osgUtil::PlaneIntersector(args...);
//intersectorGroup->addIntersector(plane.get());
//如果 多面体求交
//osg::ref_ptr<osgUtil::PolytopeIntersector> polytope = new osgUtil::PolytopeIntersector(args...);
//intersectorGroup->addIntersector(polytope.get());
//遍历整个节点树(也可以是某个子树或几何体节点)
osgUtil::IntersectionVisitor intersectVisitor(intersectorGroup.get(), new MyReadCallback);
scene->accept(intersectVisitor);
osg::Timer_t endTick = osg::Timer::instance()->tick();
std::cout << "Completed in " << osg::Timer::instance()->delta_s(startTick, endTick) << std::endl;
if (intersectorGroup->containsIntersections())
{//有交点
std::cout << "Found intersections " << std::endl;
osgUtil::IntersectorGroup::Intersectors& intersectors = intersectorGroup->getIntersectors();
for (osgUtil::IntersectorGroup::Intersectors::iterator intersector_itr = intersectors.begin();
intersector_itr != intersectors.end();
++intersector_itr)
{
osgUtil::LineSegmentIntersector* lsi = dynamic_cast<osgUtil::LineSegmentIntersector*>(intersector_itr->get());
if (lsi)
{
osgUtil::LineSegmentIntersector::Intersections& intersections = lsi->getIntersections();
for (osgUtil::LineSegmentIntersector::Intersections::iterator itr = intersections.begin();
itr != intersections.end();
++itr)
{
const osgUtil::LineSegmentIntersector::Intersection& intersection = *itr;
std::cout << " ratio " << intersection.ratio << std::endl;
//注意添加 #include <osg/io_utils> ,否则无法直接打印点坐标
std::cout << " point " << intersection.localIntersectionPoint << std::endl;
std::cout << " normal " << intersection.localIntersectionNormal << std::endl;
std::cout << " indices " << intersection.indexList.size() << std::endl;
std::cout << " primitiveIndex " << intersection.primitiveIndex << std::endl;
std::cout << std::endl;
}
}
}
}
else
{//无交点
std::cout << "contains noting" << std::endl;
}
return 0;
}
运行结果: