osg解析系列-[osgUtil::IntersectionVisitor]-场景求交示例 线段/射线/面/多面体 求交

// 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;
}


运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值