DYT/Tool/OpenSceneGraph-3.6.5/include/osgEarth/Terrain

313 lines
9.8 KiB
Plaintext
Raw Permalink Normal View History

2024-12-24 23:49:36 +00:00
/* -*-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.
*
* This program 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
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef OSGEARTH_TERRAIN_H
#define OSGEARTH_TERRAIN_H 1
#include <osgEarth/Common>
#include <osgEarth/TileKey>
#include <osgEarth/Threading>
#include <osg/OperationThread>
#include <osg/View>
namespace osgEarth
{
class Terrain;
class TerrainTile;
class SpatialReference;
/**
* This object is passed to terrain callbacks to provide context information
* and a feedback interface to terrain callback consumers.
*/
class TerrainCallbackContext
{
public:
const Terrain* getTerrain() const { return _terrain; }
/** Indicate that the callback should be removed immediately */
void remove() { _remove = true; }
/** whether the user called remove(). */
bool markedForRemoval() const { return _remove; }
public:
TerrainCallbackContext(Terrain* terrain)
: _remove(false), _terrain(terrain) { }
/** dtor */
virtual ~TerrainCallbackContext() { }
protected:
bool _remove;
Terrain* _terrain;
friend class Terrain;
};
/**
* Callback that you can register with the Terrain in order to receive
* update messaged about the terrain scene graph.
*/
class TerrainCallback : public osg::Referenced
{
public:
/**
* A tile was added to the terrain graph.
* @param key
* Tile key of the new tile, including the geographic extents
* @param graph
* Scene graph that can be used to intersect the tile (though it
* may include more than just the new tile)
* @param context
* Contextual information about the callback
*/
virtual void onTileUpdate(
const TileKey& key,
osg::Node* graph,
TerrainCallbackContext& context)
{
// back compat only
onTileAdded(key, graph, context);
}
/** dtor */
virtual ~TerrainCallback() { }
public: // deprecated - exists for backwards compatibilty only
virtual void onTileAdded(
const TileKey& key,
osg::Node* graph,
TerrainCallbackContext& context) { }
};
/**
* Convenience adapter for hooking a callback into a class. The
* class must be derived from osg::Referenced. When the class
* destructs, the callback will automatically remove itself from
* the Terrain object.
*/
template<typename T>
class TerrainCallbackAdapter : public TerrainCallback
{
public:
TerrainCallbackAdapter(T* t) : _t(t) { }
void onTileUpdate(const TileKey& key,
osg::Node* tile,
TerrainCallbackContext& context)
{
osg::ref_ptr<T> t;
if (_t.lock(t))
t->onTileUpdate(key, tile, context);
else
context.remove();
}
protected:
virtual ~TerrainCallbackAdapter() { }
osg::observer_ptr<T> _t;
};
/**
* Interface for an object that can resolve the terrain elevation
* at a given map location.
*/
class /*interface-only*/ TerrainResolver
{
public:
virtual bool getHeight(
const SpatialReference* srs,
double x,
double y,
double* out_heightAboveMSL,
double* out_heightAboveEllipsoid =0L) const =0;
virtual bool getHeight(
osg::Node* patch,
const SpatialReference* srs,
double x,
double y,
double* out_heightAboveMSL,
double* out_heightAboveEllipsoid =0L) const =0;
/** dtor */
virtual ~TerrainResolver() { }
};
// backwards compatibility
typedef TerrainResolver TerrainHeightProvider;
/**
* Services for interacting with the live terrain graph. This differs from
* the Map model; Map represents the parametric data backing the terrain,
* while Terrain represents the actual geometry in memory.
*
* All returned map coordinate values are in the units conveyed in the
* spatial reference at getSRS().
*/
class OSGEARTH_EXPORT Terrain : public osg::Referenced, public TerrainResolver
{
public:
/**
* Gets the profile of the map with which this terrain is associated.
*/
const Profile* getProfile() const { return _profile.get(); }
/**
* Gets the spatial reference of the map with which this terrain is
* associated.
*/
const SpatialReference* getSRS() const { return _profile->getSRS(); }
/**
* Returns the world coordinates under the mouse.
* @param view
* View in which to do the query
* @param mx, my
* Mouse coordinates
* @param out_coords
* Stores the world coordinates under the mouse (when returning true)
*/
bool getWorldCoordsUnderMouse(
osg::View* view,
float mx,
float my,
osg::Vec3d& out_world) const;
//! Terrain Tile node under the mouse
TerrainTile* getTerrainTileUnderMouse(
osg::View* view,
float mx,
float my) const;
public: // TerrainResolver interface
/**
* Intersects the terrain at the location x, y and returns the height data.
*
* @param srs
* Spatial reference system of (x,y) coordinates
* @param x, y
* Coordinates at which to query the height
* @param out_heightAboveMSL
* The resulting relative height goes here. The height is relative to MSL
* (mean sea level) as expressed by the map's vertical datum.
* @param out_heightAboveEllipsoid
* The resulting geodetic height goes here. The height is relative to the
* geodetic ellipsoid expressed by the map's SRS.
*/
bool getHeight(
const SpatialReference* srs,
double x,
double y,
double* out_heightAboveMSL,
double* out_heightAboveEllipsoid =0L) const;
/**
* Save as above, but specify a subgraph patch.
*/
bool getHeight(
osg::Node* patch,
const SpatialReference* srs,
double x,
double y,
double* out_heightAboveMSL,
double* out_heightAboveEllipsoid =0L) const;
public:
/**
* Adds a terrain callback.
*
* @param callback
* Terrain callback to add. This will get called whenever tile data changes in
* the active terrain graph
*/
void addTerrainCallback(TerrainCallback* callback);
/**
* Removes a terrain callback.
*/
void removeTerrainCallback(TerrainCallback* callback );
public:
/**
* Accept a node visitor on the terrain's scene graph.
*/
void accept( osg::NodeVisitor& nv );
// access the raw terrain graph
osg::Node* getGraph() const { return _graph.get(); }
// queues the onTileUpdate callback (internal)
void notifyTileUpdate( const TileKey& key, osg::Node* tile );
// queues the onTileRemoved callback (internal)
void notifyTilesRemoved(const std::vector<TileKey>& keys);
// internal
void notifyMapElevationChanged();
/** dtor */
virtual ~Terrain() { }
private:
//! Construct the Terrain graph interface
Terrain(osg::Node* graph, const Profile* profile);
/** update traversal. */
void update();
friend class TerrainEngineNode;
typedef std::list< osg::ref_ptr<TerrainCallback> > CallbackList;
CallbackList _callbacks;
Threading::ReadWriteMutex _callbacksMutex;
std::atomic_int _callbacksSize; // separate size tracker for MT size check w/o a lock
osg::ref_ptr<const Profile> _profile;
osg::observer_ptr<osg::Node> _graph;
osg::ref_ptr<osg::OperationQueue> _updateQueue;
void fireMapElevationChanged();
void fireTileUpdate( const TileKey& key, osg::Node* tile );
void fireTilesRemoved(const std::vector<TileKey>& keys);
struct onTileUpdateOperation : public osg::Operation {
osg::observer_ptr<Terrain> _terrain;
TileKey _key;
osg::observer_ptr<osg::Node> _node;
unsigned _count;
onTileUpdateOperation(const TileKey& key, osg::Node* node, Terrain* terrain);
void operator()(osg::Object*);
int _delay;
};
};
}
#endif // OSGEARTH_COMPOSITING_H