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 <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 <osg/CullFace>
#include <osg/Stencil>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osg/CoordinateSystemNode>
// osgviewer
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
// osgDB
#include <osgDB/FileUtils>
#include <osgDB/fstream>
#include <osgDB/ReadFile>
// osgGA
#include <osgGA/NodeTrackerManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>
//osgUtil
#include <osgUtil/Optimizer>
//osgManipulator
#include <osgManipulator/TabBoxDragger>
#include <osgManipulator/TabBoxTrackballDragger>
#include <osgManipulator/TabPlaneDragger>
#include <osgManipulator/TabPlaneTrackballDragger>
#include <osgManipulator/Scale1DDragger>
#include <osgManipulator/Scale2DDragger>
#include <osgManipulator/TrackballDragger>
#include <osgManipulator/Translate1DDragger>
#include <osgManipulator/Translate2DDragger>
#include <osgManipulator/TranslateAxisDragger>
#include <osgManipulator/TranslatePlaneDragger>
#include <osgManipulator/RotateCylinderDragger>
#include <osgManipulator/AntiSquish>
//osgsim
#include <osgSim/OverlayNode>
#include <osgSim/SphereSegment>
#include <osgSim/Impostor>
#include <osgSim/InsertImpostorsVisitor>
#include <osgSim/LightPointNode>
#include <osgSim/LineOfSight>
#include <osgSim/HeightAboveTerrain>
#include <osgSim/ElevationSlice>
//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;
}