/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2020 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see
*/
#ifndef OSGEARTHUTIL_LINEAR_LINE_OF_SIGHT
#define OSGEARTHUTIL_LINEAR_LINE_OF_SIGHT
#include
#include
#include
#include
#include
#include
namespace osgEarth { namespace Contrib
{
/**
* A Node that can be used to display point to point line of sight calculations
*/
class OSGEARTH_EXPORT LinearLineOfSightNode: public LineOfSightNode, public MapNodeObserver
{
public:
/**
*Constructs and new LinearLineOfSightNode
*@param mapNode
* The MapNode that this LinearLineOfSightNode will be operating on
*/
LinearLineOfSightNode( osgEarth::MapNode* mapNode );
virtual ~LinearLineOfSightNode();
/**
*Constructs and new LinearLineOfSightNode
*@param mapNode
* The MapNode that this LinearLineOfSightNode will be operating on
*@param start
* The start point
*@param end
* The end point
*/
LinearLineOfSightNode(
osgEarth::MapNode* mapNode,
const GeoPoint& start,
const GeoPoint& end );
/**
* Get the start point
*/
//const osg::Vec3d& getStart() const;
const GeoPoint& getStart() const;
/**
* Gets the start point in world coordinates
*/
const osg::Vec3d& getStartWorld() const;
/**
* Set the start point. The point should be in the Map's coordinate system. So if you're dealing with a geocentric map
* the location should be in the form lon, lat, elevation
*/
void setStart(const GeoPoint& start);
/**
* Get the end point
*/
const GeoPoint& getEnd() const;
/**
* Gets the end point in world coordinates
*/
const osg::Vec3d& getEndWorld() const;
/**
* Set the end point. The point should be in the Map's coordinate system. So if you're dealing with a geocentric map
* the location should be in the form lon, lat, elevation
*/
void setEnd(const GeoPoint& end);
/**
* Gets the hit point. Only valid is getHasLOS is false.
*/
const GeoPoint& getHit() const;
/**
* Gets the hit point in world coordinates
*/
const osg::Vec3d& getHitWorld() const;
/**
* Gets whether not this calculation has line of sight.
*/
bool getHasLOS() const;
/**
* Set the good color
*/
void setGoodColor( const osg::Vec4f &color );
/**
* Gets the good color
*/
const osg::Vec4f& getGoodColor() const;
/**
* Sets the bad color
*/
void setBadColor( const osg::Vec4f &color );
/**
* Gets the bad color
*/
const osg::Vec4f& getBadColor() const;
/**
* Gets the display mode
*/
LineOfSight::DisplayMode getDisplayMode() const;
/**
* Sets the display mode
*/
void setDisplayMode( LineOfSight::DisplayMode displayMode );
/**
* Called when the underlying terrain has changed.
*/
void terrainChanged( const osgEarth::TileKey& tileKey, osg::Node* terrain );
void addChangedCallback( LOSChangedCallback* callback );
void removeChangedCallback( LOSChangedCallback* callback );
bool getTerrainOnly() const;
void setTerrainOnly( bool terrainOnly );
public: // MapNodeObserver
/**
* Gets the MapNode that this LineOfSightNode is operating on.
*/
virtual osgEarth::MapNode* getMapNode() { return _mapNode.get(); }
virtual void setMapNode( osgEarth::MapNode* mapNode );
private:
osg::Node* getNode();
void compute(osg::Node* node, bool backgroundThread = false);
void draw(bool backgroundThread = false);
void subscribeToTerrain();
osg::observer_ptr< osgEarth::MapNode > _mapNode;
bool _hasLOS;
LineOfSight::DisplayMode _displayMode;
osg::Vec4 _goodColor;
osg::Vec4 _badColor;
GeoPoint _hit;
GeoPoint _start;
GeoPoint _end;
osg::Vec3d _startWorld;
osg::Vec3d _endWorld;
osg::Vec3d _hitWorld;
LOSChangedCallbackList _changedCallbacks;
osg::ref_ptr < osgEarth::TerrainCallback > _terrainChangedCallback;
bool _clearNeeded;
bool _terrainOnly;
};
/**********************************************************************/
/**
* An update callback that allows you to attach a LineOfSightNode to two moving nodes.
* The update callback will update the start and end points of the LineOfSight calcuation to
* follow the nodes.
*
* Example:
* LineOfSightNode* los = new LineOfSightNode(myMapNode);
* los->setUpdateCallback( new LineOfSightTether( startNode, endNode ) );
*/
class OSGEARTH_EXPORT LineOfSightTether : public osg::NodeCallback
{
public:
LineOfSightTether(osg::Node* startNode, osg::Node* endNode);
/** dtor */
virtual ~LineOfSightTether() { }
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
osg::Node* startNode() { return _startNode.get(); }
osg::Node* endNode() { return _endNode.get(); }
private:
osg::ref_ptr< osg::Node > _startNode;
osg::ref_ptr< osg::Node > _endNode;
};
/**********************************************************************/
/**
* An editor node that allows you to move the start and end points
* of the LineOfSightNode
*/
class OSGEARTH_EXPORT LinearLineOfSightEditor : public osg::Group
{
public:
/**
* Create a new LineOfSightEditor
* @param los
* The LineOfSightNode to edit
*/
LinearLineOfSightEditor(LinearLineOfSightNode* los);
virtual ~LinearLineOfSightEditor();
/**
*Updates the position of the draggers to represent the actual location of the LineOfSightNode.
*This should be called if the los is changed outside of the editor and would probably benefit
*from the LineOfSightNode having a callback that notifies listeners that the start/end points have changed.
*/
void updateDraggers();
private:
osg::ref_ptr< LinearLineOfSightNode > _los;
osgEarth::Dragger* _startDragger;
osgEarth::Dragger* _endDragger;
osg::ref_ptr< LOSChangedCallback > _callback;
};
} }
#endif // OSGEARTHUTIL_LINEAR_LINE_OF_SIGHT