Performance tests on big models did not indicate any performance penalty in using doubles over floats, so the move to doubles should mainly impact precision improvements for whole earth databases. Also made improvements to osgUtil::PlaneIntersector and osgSim::ElevationSlice classes
250 lines
9.4 KiB
C++
250 lines
9.4 KiB
C++
#include <osg/ArgumentParser>
|
|
#include <osg/ApplicationUsage>
|
|
#include <osg/Timer>
|
|
#include <osg/CoordinateSystemNode>
|
|
#include <osg/Notify>
|
|
#include <osg/io_utils>
|
|
|
|
#include <osgDB/ReadFile>
|
|
|
|
#include <osgUtil/IntersectionVisitor>
|
|
|
|
#include <osgSim/LineOfSight>
|
|
#include <osgSim/HeightAboveTerrain>
|
|
#include <osgSim/ElevationSlice>
|
|
|
|
#include <iostream>
|
|
|
|
struct MyReadCallback : public osgUtil::IntersectionVisitor::ReadCallback
|
|
{
|
|
virtual osg::Node* readNodeFile(const std::string& filename)
|
|
{
|
|
return osgDB::readNodeFile(filename);
|
|
}
|
|
};
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
// use an ArgumentParser object to manage the program arguments.
|
|
osg::ArgumentParser arguments(&argc,argv);
|
|
|
|
// set up the usage document, in case we need to print out how to use this program.
|
|
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of node tracker.");
|
|
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
|
|
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
|
|
|
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(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::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(scene.get());
|
|
osg::EllipsoidModel* em = csn ? csn->getEllipsoidModel() : 0;
|
|
|
|
osg::BoundingSphere bs = scene->getBound();
|
|
|
|
|
|
bool useIntersectorGroup = true;
|
|
bool useLineOfSight = true;
|
|
|
|
if (useLineOfSight)
|
|
{
|
|
|
|
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.01);
|
|
osg::Vec3d deltaColumn( bs.radius()*0.01, 0.0, 0.0);
|
|
unsigned int numRows = 20;
|
|
unsigned int numColumns = 20;
|
|
|
|
osgSim::LineOfSight los;
|
|
|
|
#if 0
|
|
osgSim::HeightAboveTerrain hat;
|
|
hat.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback());
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
// 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;
|
|
}
|
|
#endif
|
|
|
|
{
|
|
// 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,bs.radius(),0.0) );
|
|
|
|
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;
|
|
}
|
|
}
|
|
else if (useIntersectorGroup)
|
|
{
|
|
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
|
|
|
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.01);
|
|
osg::Vec3d deltaColumn( bs.radius()*0.01, 0.0, 0.0);
|
|
unsigned int numRows = 20;
|
|
unsigned int numColumns = 20;
|
|
|
|
osg::ref_ptr<osgUtil::IntersectorGroup> intersectorGroup = new osgUtil::IntersectorGroup();
|
|
|
|
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() );
|
|
}
|
|
}
|
|
|
|
|
|
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;
|
|
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
|
|
{
|
|
osg::Timer_t startTick = osg::Timer::instance()->tick();
|
|
|
|
#if 1
|
|
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);
|
|
#else
|
|
osg::Vec3d start = bs.center() + osg::Vec3d(0.0,0.0, bs.radius());
|
|
osg::Vec3d end = bs.center() - osg::Vec3d(0.0, 0.0, bs.radius());
|
|
#endif
|
|
|
|
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(start, end);
|
|
|
|
osgUtil::IntersectionVisitor intersectVisitor( intersector.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 ( intersector->containsIntersections() )
|
|
{
|
|
osgUtil::LineSegmentIntersector::Intersections& intersections = intersector->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;
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|