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/ApplicationUsage>
|
||||
#include <osg/Timer>
|
||||
#include <osg/CoordinateSystemNode>
|
||||
#include <osg/Notify>
|
||||
#include <osg/io_utils>
|
||||
|
||||
@ -9,6 +10,7 @@
|
||||
#include <osgUtil/IntersectionVisitor>
|
||||
|
||||
#include <osgSim/LineOfSight>
|
||||
#include <osgSim/HeightAboveTerrain>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -31,9 +33,9 @@ int main(int argc, char **argv)
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
|
||||
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;
|
||||
return 0;
|
||||
@ -42,8 +44,10 @@ int main(int argc, char **argv)
|
||||
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;
|
||||
@ -57,11 +61,14 @@ int main(int argc, char **argv)
|
||||
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 = 50;
|
||||
unsigned int numColumns = 50;
|
||||
unsigned int numRows = 20;
|
||||
unsigned int numColumns = 20;
|
||||
|
||||
osgSim::LineOfSight los;
|
||||
|
||||
osgSim::HeightAboveTerrain hat;
|
||||
hat.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback());
|
||||
|
||||
for(unsigned int r=0; r<numRows; ++r)
|
||||
{
|
||||
for(unsigned int c=0; c<numColumns; ++c)
|
||||
@ -69,17 +76,20 @@ int main(int argc, char **argv)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
los.computeIntersections(root.get());
|
||||
std::cout<<"Computing LineOfSight"<<std::endl;
|
||||
|
||||
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;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
for(unsigned int i=0; i<los.getNumLOS(); i++)
|
||||
{
|
||||
const osgSim::LineOfSight::Intersections& intersections = los.getIntersections(i);
|
||||
@ -95,7 +105,14 @@ int main(int argc, char **argv)
|
||||
// now do a second traversal to test performance of cache.
|
||||
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();
|
||||
|
||||
@ -128,7 +145,7 @@ int main(int argc, char **argv)
|
||||
|
||||
|
||||
osgUtil::IntersectionVisitor intersectVisitor( intersectorGroup.get(), new MyReadCallback );
|
||||
root->accept(intersectVisitor);
|
||||
scene->accept(intersectVisitor);
|
||||
|
||||
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 );
|
||||
|
||||
root->accept(intersectVisitor);
|
||||
scene->accept(intersectVisitor);
|
||||
|
||||
osg::Timer_t endTick = osg::Timer::instance()->tick();
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
#include <osgUtil/IntersectionVisitor>
|
||||
|
||||
#include <osgSim/Export>
|
||||
// include so we can get access to the DatabaseCacheReadCallback
|
||||
#include <osgSim/LineOfSight>
|
||||
|
||||
namespace osgSim {
|
||||
|
||||
@ -25,8 +26,86 @@ class OSGSIM_EXPORT HeightAboveTerrain
|
||||
{
|
||||
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 :
|
||||
|
||||
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();
|
||||
|
||||
/** 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.*/
|
||||
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; }
|
||||
|
||||
/** 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);
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
|
||||
#include <osg/CoordinateSystemNode>
|
||||
#include <osgSim/HeightAboveTerrain>
|
||||
|
||||
#include <osg/Notify>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void LineOfSight::clearLOS()
|
||||
void LineOfSight::clear()
|
||||
{
|
||||
_LOSList.clear();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user