osg解析系列-对“地形”类场景子树进行射线求交、面求交,适用于大场景如数字地球等

note1: osgSim::LineOfSight、osgSim::HeightAboveTerrain均是用于计算与“地形”类场景子树进行射线求交的辅助类,
是对osgUtil::LineSegmentIntersector、osgUtil::IntersectorGroup的封装和应用。
note2: osgSim::ElevationSlice是用于计算与“地形”类场景子树进行面求交的辅助类, 是对osgUtil::PlaneIntersector的封装和应用
note3: 以上3个辅助类(helper class)应用在osg::PagedLOD子树上,可提升求交的计算效率和结果的精确性;应用在其他类型的子树时,
仅是对osgUtil::LineSegmentIntersector的封装,没有效率和精确性的提升。

// M23.12.W9.osgSim.IntersectionHelper.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include 
#include 

//osg
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

// osgviewer
#include 
#include 
// osgDB
#include 
#include 
#include 

// osgGA
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


//osgUtil
#include 

//osgManipulator
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

//osgsim
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 

//osglib
#ifdef _DEBUG
#pragma comment(lib,"OpenThreadsd.lib")
#pragma comment(lib,"osgd.lib")
#pragma comment(lib,"osgUtild.lib")
#pragma comment(lib,"osgDBd.lib")
#pragma comment(lib,"osgFXd.lib")
#pragma comment(lib,"osgGAd.lib")
#pragma comment(lib,"osgTextd.lib")
#pragma comment(lib,"osgViewerd.lib")

#pragma comment(lib,"osgShadowd.lib")
#pragma comment(lib,"osgManipulatord.lib")
#pragma comment(lib,"osgParticled.lib")
#pragma comment(lib,"osgSimd.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")
#pragma comment(lib,"osgManipulator.lib")
#pragma comment(lib,"osgSim.lib")
#endif // DEBUG

/*
note1: osgSim::LineOfSight、osgSim::HeightAboveTerrain均是用于计算与“地形”类场景子树进行射线求交的辅助类,
是对osgUtil::LineSegmentIntersector、osgUtil::IntersectorGroup的封装和应用。
note2: osgSim::ElevationSlice是用于计算与“地形”类场景子树进行面求交的辅助类, 是对osgUtil::PlaneIntersector的封装和应用
note3: 以上3个辅助类(helper class)应用在osg::PagedLOD子树上,可提升求交的计算效率和结果的精确性;应用在其他类型的子树时,
仅是对osgUtil::LineSegmentIntersector的封装,没有效率和精确性的提升。
*/

int main(int argc,char** argv)
{
	// use a ArgumentParser object to manage the program arguments
	osg::ArgumentParser Parser(&argc, argv);

	osg::ref_ptr<osg::Node> scene = osgDB::readRefNodeFiles(Parser);
	if (!scene)
	{
		std::cout << "No model loaded, please specify a valid model on the command line." << std::endl;
		return 0;
	}

	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::Vec3d deltaRow(0.0, 0.0, bs.radius()*0.5);
	osg::Vec3d deltaColumn(bs.radius()*0.5, 0.0, 0.0);

	osgSim::LineOfSight los;
	osgSim::HeightAboveTerrain hat;
	hat.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback());

	//生成多条射线
	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);
			los.addLOS(s, e);
			hat.addPoint(s);
		}
	}
	//利用osgSim::LineOfSight进行射线求交点,打印出交点坐标
	{
		std::cout << "Computing LineOfSight" << std::endl;

		osg::Timer_t startTick = osg::Timer::instance()->tick();

		los.computeIntersections(scene.get());

		osg::Timer_t endTick = osg::Timer::instance()->tick();

		std::cout << "Completed in " << osg::Timer::instance()->delta_s(startTick, endTick) << std::endl;

		for (unsigned int i = 0; i < los.getNumLOS(); i++)
		{
			const osgSim::LineOfSight::Intersections& intersections = los.getIntersections(i);
			for (osgSim::LineOfSight::Intersections::const_iterator itr = intersections.begin();
			itr != intersections.end();
				++itr)
			{
				std::cout << "  point " << *itr << std::endl;
			}
		}
	}
	//利用osgSim::HeightAboveTerrain进行射线求交点,打印出交点坐标及交点高程
	{
		// now do a second traversal to test performance of cache.
		osg::Timer_t startTick = osg::Timer::instance()->tick();

		std::cout << "Computing HeightAboveTerrain" << std::endl;

		hat.computeIntersections(scene.get());

		osg::Timer_t endTick = osg::Timer::instance()->tick();

		for (unsigned int i = 0; i < hat.getNumPoints(); i++)
		{
			std::cout << "  point = " << hat.getPoint(i) << " hat = " << hat.getHeightAboveTerrain(i) << std::endl;
		}
		std::cout << "Completed in " << osg::Timer::instance()->delta_s(startTick, endTick) << std::endl;
	}
	//利用osgSim::ElevationSlice进行面求交,打印出distance、点高程height
	{
		// now do a second traversal to test performance of cache.
		osg::Timer_t startTick = osg::Timer::instance()->tick();

		std::cout << "Computing ElevationSlice" << std::endl;
		osgSim::ElevationSlice es;
		es.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback());

		es.setStartPoint(bs.center() + osg::Vec3d(bs.radius(), 0.0, 0.0));
		es.setEndPoint(bs.center() + osg::Vec3d(0.0, 0.0, bs.radius()));

		es.computeIntersections(scene.get());

		osg::Timer_t endTick = osg::Timer::instance()->tick();

		std::cout << "Completed in " << osg::Timer::instance()->delta_s(startTick, endTick) << std::endl;

		typedef osgSim::ElevationSlice::DistanceHeightList DistanceHeightList;
		const DistanceHeightList& dhl = es.getDistanceHeightIntersections();
		std::cout << "Number of intersections =" << dhl.size() << std::endl;
		for (DistanceHeightList::const_iterator dhitr = dhl.begin();
		dhitr != dhl.end();
			++dhitr)
		{
			std::cout.precision(10);
			std::cout << "  " << dhitr->first << " " << dhitr->second << std::endl;
		}
	}

    return 0;
}


你可能感兴趣的:(c++,图形渲染)