Implemented HeightAboveTerrain and added usage into osgintersection
This commit is contained in:
parent
e9b501002c
commit
a253e17d3e
@ -1,6 +1,7 @@
|
|||||||
#include <osg/ArgumentParser>
|
#include <osg/ArgumentParser>
|
||||||
#include <osg/ApplicationUsage>
|
#include <osg/ApplicationUsage>
|
||||||
#include <osg/Timer>
|
#include <osg/Timer>
|
||||||
|
#include <osg/CoordinateSystemNode>
|
||||||
#include <osg/Notify>
|
#include <osg/Notify>
|
||||||
#include <osg/io_utils>
|
#include <osg/io_utils>
|
||||||
|
|
||||||
@ -9,6 +10,7 @@
|
|||||||
#include <osgUtil/IntersectionVisitor>
|
#include <osgUtil/IntersectionVisitor>
|
||||||
|
|
||||||
#include <osgSim/LineOfSight>
|
#include <osgSim/LineOfSight>
|
||||||
|
#include <osgSim/HeightAboveTerrain>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -31,9 +33,9 @@ int main(int argc, char **argv)
|
|||||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
|
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
|
||||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
||||||
|
|
||||||
osg::ref_ptr<osg::Node> root = osgDB::readNodeFiles(arguments);
|
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFiles(arguments);
|
||||||
|
|
||||||
if (!root)
|
if (!scene)
|
||||||
{
|
{
|
||||||
std::cout<<"No model loaded, please specify a valid model on the command line."<<std::endl;
|
std::cout<<"No model loaded, please specify a valid model on the command line."<<std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
@ -42,8 +44,10 @@ int main(int argc, char **argv)
|
|||||||
std::cout<<"Intersection "<<std::endl;
|
std::cout<<"Intersection "<<std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(scene.get());
|
||||||
|
osg::EllipsoidModel* em = csn ? csn->getEllipsoidModel() : 0;
|
||||||
|
|
||||||
osg::BoundingSphere bs = root->getBound();
|
osg::BoundingSphere bs = scene->getBound();
|
||||||
|
|
||||||
|
|
||||||
bool useIntersectorGroup = true;
|
bool useIntersectorGroup = true;
|
||||||
@ -57,10 +61,13 @@ int main(int argc, char **argv)
|
|||||||
osg::Vec3d end = 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 deltaRow( 0.0, 0.0, bs.radius()*0.01);
|
||||||
osg::Vec3d deltaColumn( bs.radius()*0.01, 0.0, 0.0);
|
osg::Vec3d deltaColumn( bs.radius()*0.01, 0.0, 0.0);
|
||||||
unsigned int numRows = 50;
|
unsigned int numRows = 20;
|
||||||
unsigned int numColumns = 50;
|
unsigned int numColumns = 20;
|
||||||
|
|
||||||
osgSim::LineOfSight los;
|
osgSim::LineOfSight los;
|
||||||
|
|
||||||
|
osgSim::HeightAboveTerrain hat;
|
||||||
|
hat.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback());
|
||||||
|
|
||||||
for(unsigned int r=0; r<numRows; ++r)
|
for(unsigned int r=0; r<numRows; ++r)
|
||||||
{
|
{
|
||||||
@ -69,17 +76,20 @@ int main(int argc, char **argv)
|
|||||||
osg::Vec3d s = start + deltaColumn * double(c) + deltaRow * double(r);
|
osg::Vec3d s = start + deltaColumn * double(c) + deltaRow * double(r);
|
||||||
osg::Vec3d e = end + deltaColumn * double(c) + deltaRow * double(r);
|
osg::Vec3d e = end + deltaColumn * double(c) + deltaRow * double(r);
|
||||||
los.addLOS(s,e);
|
los.addLOS(s,e);
|
||||||
|
hat.addPoint(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
los.computeIntersections(root.get());
|
std::cout<<"Computing LineOfSight"<<std::endl;
|
||||||
|
|
||||||
|
los.computeIntersections(scene.get());
|
||||||
|
|
||||||
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
||||||
|
|
||||||
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
|
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
for(unsigned int i=0; i<los.getNumLOS(); i++)
|
for(unsigned int i=0; i<los.getNumLOS(); i++)
|
||||||
{
|
{
|
||||||
const osgSim::LineOfSight::Intersections& intersections = los.getIntersections(i);
|
const osgSim::LineOfSight::Intersections& intersections = los.getIntersections(i);
|
||||||
@ -95,8 +105,15 @@ int main(int argc, char **argv)
|
|||||||
// now do a second traversal to test performance of cache.
|
// now do a second traversal to test performance of cache.
|
||||||
startTick = osg::Timer::instance()->tick();
|
startTick = osg::Timer::instance()->tick();
|
||||||
|
|
||||||
los.computeIntersections(root.get());
|
std::cout<<"Computing HeightAboveTerrain"<<std::endl;
|
||||||
|
|
||||||
|
hat.computeIntersections(scene.get());
|
||||||
|
|
||||||
|
for(unsigned int i=0; i<hat.getNumPoints(); i++)
|
||||||
|
{
|
||||||
|
std::cout<<" point = "<<hat.getPoint(i)<<" hat = "<<hat.getHeightAboveTerrain(i)<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
endTick = osg::Timer::instance()->tick();
|
endTick = osg::Timer::instance()->tick();
|
||||||
|
|
||||||
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
|
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
|
||||||
@ -128,7 +145,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
|
|
||||||
osgUtil::IntersectionVisitor intersectVisitor( intersectorGroup.get(), new MyReadCallback );
|
osgUtil::IntersectionVisitor intersectVisitor( intersectorGroup.get(), new MyReadCallback );
|
||||||
root->accept(intersectVisitor);
|
scene->accept(intersectVisitor);
|
||||||
|
|
||||||
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
||||||
|
|
||||||
@ -181,7 +198,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
osgUtil::IntersectionVisitor intersectVisitor( intersector.get(), new MyReadCallback );
|
osgUtil::IntersectionVisitor intersectVisitor( intersector.get(), new MyReadCallback );
|
||||||
|
|
||||||
root->accept(intersectVisitor);
|
scene->accept(intersectVisitor);
|
||||||
|
|
||||||
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
#include <osgUtil/IntersectionVisitor>
|
#include <osgUtil/IntersectionVisitor>
|
||||||
|
|
||||||
#include <osgSim/Export>
|
// include so we can get access to the DatabaseCacheReadCallback
|
||||||
|
#include <osgSim/LineOfSight>
|
||||||
|
|
||||||
namespace osgSim {
|
namespace osgSim {
|
||||||
|
|
||||||
@ -25,7 +26,85 @@ class OSGSIM_EXPORT HeightAboveTerrain
|
|||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
||||||
|
|
||||||
|
HeightAboveTerrain();
|
||||||
|
|
||||||
|
|
||||||
|
/** Clear the internal HAT List so it contains no height above terrain tests.*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/** Add a height above terrain test point in the CoordinateFrame.*/
|
||||||
|
unsigned int addPoint(const osg::Vec3d& point);
|
||||||
|
|
||||||
|
/** Get the number of height above terrain tests.*/
|
||||||
|
unsigned int getNumPoints() const { return _HATList.size(); }
|
||||||
|
|
||||||
|
/** Set the source point of single height above terrain test.*/
|
||||||
|
void setPoint(unsigned int i, const osg::Vec3d& point) { _HATList[i]._point = point; }
|
||||||
|
|
||||||
|
/** Get the source point of single height above terrain test.*/
|
||||||
|
const osg::Vec3d& getPoint(unsigned int i) const { return _HATList[i]._point; }
|
||||||
|
|
||||||
|
/** Get the intersection height for a single height above terrain test.
|
||||||
|
* Note, you must call computeIntersections(..) before you can querry the HeightAboveTerrain.
|
||||||
|
* If no intersections are found then height returned will be the height above mean sea level. */
|
||||||
|
double getHeightAboveTerrain(unsigned int i) const { return _HATList[i]._hat; }
|
||||||
|
|
||||||
|
/** Set the lowest height that the should be tested for.
|
||||||
|
* Defaults to -1000, i.e. 1000m below mean sea level. */
|
||||||
|
void setLowestHeight(double lowestHeight) { _lowestHeight = lowestHeight; }
|
||||||
|
|
||||||
|
/** Get the lowest height that the should be tested for.*/
|
||||||
|
double getLowestHeight() const { return _lowestHeight; }
|
||||||
|
|
||||||
|
/** Compute the HAT intersections with the specified scene graph.
|
||||||
|
* The results are all stored in the form of a single height above terrain value per HAT test.
|
||||||
|
* Note, if the topmost node is a CoordinateSystemNode then the input points are assumed to be geocentric,
|
||||||
|
* with the up vector defined by the EllipsoidModel attached to the CoordinateSystemNode.
|
||||||
|
* If the topmost node is not a CoordinateSystemNode then a local coordinates frame is assumed, with a local up vector. */
|
||||||
|
void computeIntersections(osg::Node* scene);
|
||||||
|
|
||||||
|
/** Compute the vertical distance between the specified scene graph and a single HAT point. .*/
|
||||||
|
static double computeHeightAboveTerrain(osg::Node* scene, const osg::Vec3d& point);
|
||||||
|
|
||||||
|
|
||||||
|
/** Clear the database cache.*/
|
||||||
|
void clearDatabaseCache() { if (_dcrc.valid()) _dcrc->clearDatabaseCache(); }
|
||||||
|
|
||||||
|
/** Set the ReadCallback that does the reading of external PagedLOD models, and caching of loaded subgraphs.
|
||||||
|
* Note, if you have mulitple LineOfSight or HeightAboveTerrain objects in use at one time then you should share a single
|
||||||
|
* DatabaseCacheReadCallback between all of them. */
|
||||||
|
void setDatabaseCacheReadCallback(DatabaseCacheReadCallback* dcrc);
|
||||||
|
|
||||||
|
/** Get the ReadCallback that does the reading of external PagedLOD models, and caching of loaded subgraphs.*/
|
||||||
|
DatabaseCacheReadCallback* getDatabaseCacheReadCallback() { return _dcrc.get(); }
|
||||||
|
|
||||||
|
/** Get the IntersectionVistor that does the intersection traversal over the scene.
|
||||||
|
* Note, if you want to customized the traversal then you can use the IntersectionVisitor's method to alter its behavior. */
|
||||||
|
osgUtil::IntersectionVisitor& getIntersectionVisitor() { return _intersectionVisitor; }
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
|
|
||||||
|
struct HAT
|
||||||
|
{
|
||||||
|
HAT(const osg::Vec3d& point):
|
||||||
|
_point(point),
|
||||||
|
_hat(0.0) {}
|
||||||
|
|
||||||
|
osg::Vec3d _point;
|
||||||
|
double _hat;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<HAT> HATList;
|
||||||
|
|
||||||
|
|
||||||
|
double _lowestHeight;
|
||||||
|
HATList _HATList;
|
||||||
|
|
||||||
|
|
||||||
|
osg::ref_ptr<DatabaseCacheReadCallback> _dcrc;
|
||||||
|
osgUtil::IntersectionVisitor _intersectionVisitor;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ class OSGSIM_EXPORT LineOfSight
|
|||||||
LineOfSight();
|
LineOfSight();
|
||||||
|
|
||||||
/** Clear the internal LOS List so it contains no line of sight tests.*/
|
/** Clear the internal LOS List so it contains no line of sight tests.*/
|
||||||
void clearLOS();
|
void clear();
|
||||||
|
|
||||||
/** Add a line of sight test, consisting of start and end point. Returns the index number of the newly adding LOS test.*/
|
/** Add a line of sight test, consisting of start and end point. Returns the index number of the newly adding LOS test.*/
|
||||||
unsigned int addLOS(const osg::Vec3d& start, const osg::Vec3d& end);
|
unsigned int addLOS(const osg::Vec3d& start, const osg::Vec3d& end);
|
||||||
@ -78,7 +78,7 @@ class OSGSIM_EXPORT LineOfSight
|
|||||||
const Intersections& getIntersections(unsigned int i) const { return _LOSList[i]._intersections; }
|
const Intersections& getIntersections(unsigned int i) const { return _LOSList[i]._intersections; }
|
||||||
|
|
||||||
/** Compute the LOS intersections with the specified scene graph.
|
/** Compute the LOS intersections with the specified scene graph.
|
||||||
* The results are all stored in the form of IntersectionList, one per LOS test.*/
|
* The results are all stored in the form of Intersections list, one per LOS test.*/
|
||||||
void computeIntersections(osg::Node* scene);
|
void computeIntersections(osg::Node* scene);
|
||||||
|
|
||||||
/** Compute the intersection between the specified scene graph and a single LOS start,end pair. Returns an IntersectionList, of all the points intersected.*/
|
/** Compute the intersection between the specified scene graph and a single LOS start,end pair. Returns an IntersectionList, of all the points intersected.*/
|
||||||
|
@ -11,6 +11,111 @@
|
|||||||
* OpenSceneGraph Public License for more details.
|
* OpenSceneGraph Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <osg/CoordinateSystemNode>
|
||||||
#include <osgSim/HeightAboveTerrain>
|
#include <osgSim/HeightAboveTerrain>
|
||||||
|
|
||||||
|
#include <osg/Notify>
|
||||||
|
|
||||||
using namespace osgSim;
|
using namespace osgSim;
|
||||||
|
|
||||||
|
HeightAboveTerrain::HeightAboveTerrain()
|
||||||
|
{
|
||||||
|
_lowestHeight = -1000.0;
|
||||||
|
|
||||||
|
setDatabaseCacheReadCallback(new DatabaseCacheReadCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeightAboveTerrain::clear()
|
||||||
|
{
|
||||||
|
_HATList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int HeightAboveTerrain::addPoint(const osg::Vec3d& point)
|
||||||
|
{
|
||||||
|
unsigned int index = _HATList.size();
|
||||||
|
_HATList.push_back(HAT(point));
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeightAboveTerrain::computeIntersections(osg::Node* scene)
|
||||||
|
{
|
||||||
|
osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(scene);
|
||||||
|
osg::EllipsoidModel* em = csn ? csn->getEllipsoidModel() : 0;
|
||||||
|
|
||||||
|
osg::ref_ptr<osgUtil::IntersectorGroup> intersectorGroup = new osgUtil::IntersectorGroup();
|
||||||
|
|
||||||
|
for(HATList::iterator itr = _HATList.begin();
|
||||||
|
itr != _HATList.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
if (em)
|
||||||
|
{
|
||||||
|
|
||||||
|
osg::Vec3d start = itr->_point;
|
||||||
|
osg::Vec3d upVector = em->computeLocalUpVector(start.x(), start.y(), start.z());
|
||||||
|
|
||||||
|
double latitude, longitude, height;
|
||||||
|
em->convertXYZToLatLongHeight(start.x(), start.y(), start.z(), latitude, longitude, height);
|
||||||
|
osg::Vec3d end = start - upVector * (height - _lowestHeight);
|
||||||
|
|
||||||
|
itr->_hat = height;
|
||||||
|
|
||||||
|
osg::notify(osg::NOTICE)<<"lat = "<<latitude<<" longitude = "<<longitude<<" height = "<<height<<std::endl;
|
||||||
|
|
||||||
|
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(start, end);
|
||||||
|
intersectorGroup->addIntersector( intersector.get() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
osg::Vec3d start = itr->_point;
|
||||||
|
osg::Vec3d upVector (0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
double height = start.z();
|
||||||
|
osg::Vec3d end = start - upVector * (height - _lowestHeight);
|
||||||
|
|
||||||
|
itr->_hat = height;
|
||||||
|
|
||||||
|
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector( start, end);
|
||||||
|
intersectorGroup->addIntersector( intersector.get() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_intersectionVisitor.reset();
|
||||||
|
_intersectionVisitor.setIntersector( intersectorGroup.get() );
|
||||||
|
|
||||||
|
scene->accept(_intersectionVisitor);
|
||||||
|
|
||||||
|
unsigned int index = 0;
|
||||||
|
osgUtil::IntersectorGroup::Intersectors& intersectors = intersectorGroup->getIntersectors();
|
||||||
|
for(osgUtil::IntersectorGroup::Intersectors::iterator intersector_itr = intersectors.begin();
|
||||||
|
intersector_itr != intersectors.end();
|
||||||
|
++intersector_itr, ++index)
|
||||||
|
{
|
||||||
|
osgUtil::LineSegmentIntersector* lsi = dynamic_cast<osgUtil::LineSegmentIntersector*>(intersector_itr->get());
|
||||||
|
if (lsi)
|
||||||
|
{
|
||||||
|
osgUtil::LineSegmentIntersector::Intersections& intersections = lsi->getIntersections();
|
||||||
|
if (!intersections.empty())
|
||||||
|
{
|
||||||
|
const osgUtil::LineSegmentIntersector::Intersection& intersection = *intersections.begin();
|
||||||
|
osg::Vec3d intersectionPoint = intersection.localIntersectionPoint * (*intersection.matrix);
|
||||||
|
_HATList[index]._hat = (_HATList[index]._point - intersectionPoint).length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
double HeightAboveTerrain::computeHeightAboveTerrain(osg::Node* scene, const osg::Vec3d& point)
|
||||||
|
{
|
||||||
|
HeightAboveTerrain hat;
|
||||||
|
unsigned int index = hat.addPoint(point);
|
||||||
|
hat.computeIntersections(scene);
|
||||||
|
return hat.getHeightAboveTerrain(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeightAboveTerrain::setDatabaseCacheReadCallback(DatabaseCacheReadCallback* dcrc)
|
||||||
|
{
|
||||||
|
_dcrc = dcrc;
|
||||||
|
_intersectionVisitor.setReadCallback(dcrc);
|
||||||
|
}
|
||||||
|
@ -92,7 +92,7 @@ LineOfSight::LineOfSight()
|
|||||||
setDatabaseCacheReadCallback(new DatabaseCacheReadCallback);
|
setDatabaseCacheReadCallback(new DatabaseCacheReadCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LineOfSight::clearLOS()
|
void LineOfSight::clear()
|
||||||
{
|
{
|
||||||
_LOSList.clear();
|
_LOSList.clear();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user