/* -*-c++-*- osgVisual - Copyright (C) 2009-2011 Torben Dannhauer * * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * osgVisual requires for some proprietary modules a license from the correspondig manufacturer. * You have to aquire licenses for all used proprietary modules. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #ifndef OSGSIM_HEIGHTABOVETERRAIN #define OSGSIM_HEIGHTABOVETERRAIN 1 #include // include so we can get access to the DatabaseCacheReadCallback #include namespace osgSim { /** Helper class for setting up and acquiring height above terrain intersections with terrain. * By default assigns a osgSim::DatabaseCacheReadCallback that enables automatic loading * of external PagedLOD tiles to ensure that the highest level of detail is used in intersections. * This automatic loading of tiles is done by the intersection traversal that is done within * the computeIntersections(..) method, so can result in long intersection times when external * tiles have to be loaded. * The external loading of tiles can be disabled by removing the read callback, this is done by * calling the setDatabaseCacheReadCallback(DatabaseCacheReadCallback*) method with a value of 0.*/ class OSGSIM_EXPORT HeightAboveTerrain { public : HeightAboveTerrain(bool loadHighestLOD = true); /** 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 query 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; } /** Get the intersection height for a single height of terrain test. * Note, you must call computeIntersections(..) before you can query the HeightOfTerrain. * If no intersections are found then height returned will be the height of mean sea level. */ double getHeightOfTerrain(unsigned int i) const { return _HATList[i]._hot; } /** 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, osg::Node::NodeMask traversalMask=0xffffffff); /** Compute the vertical distance between the specified scene graph and a single HAT point. */ static double computeHeightAboveTerrain(osg::Node* scene, const osg::Vec3d& point, bool loadHighestLOD = true, osg::Node::NodeMask traversalMask=0xffffffff); /** Compute the vertical position of the scene at a single HOT point. */ static double computeHeightOfTerrain(osg::Node* scene, const osg::Vec3d& point, bool loadHighestLOD = true, osg::Node::NodeMask traversalMask=0xffffffff); /** 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 multiple 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(); } protected : struct HAT { HAT(const osg::Vec3d& point): _point(point), _hat(0.0), _hot(0.0) {} osg::Vec3d _point; double _hat; double _hot; }; typedef std::vector HATList; double _lowestHeight; HATList _HATList; osg::ref_ptr _dcrc; osgUtil::IntersectionVisitor _intersectionVisitor; }; } #endif