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

237 lines
9.1 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.
*
* 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 <http://www.gnu.org/licenses/>
*/
#ifndef OSGEARTH_OVERLAY_DECORATOR
#define OSGEARTH_OVERLAY_DECORATOR
#include <osgEarth/Common>
#include <osgEarth/Threading>
#include <osgEarth/TerrainEngineNode>
#include <osg/Camera>
#include <osg/CoordinateSystemNode>
#include <osg/TexGenNode>
#include <osg/Uniform>
#include <osgUtil/CullVisitor>
#include <osgShadow/ConvexPolyhedron>
namespace osgEarth
{
class TerrainEngineNode;
}
namespace osgEarth { namespace Util
{
class OverlayDecorator;
class OverlayTechnique;
/**
* Overlays geometry onto the terrain using various techniques.
*/
class OSGEARTH_EXPORT OverlayDecorator : public osg::Group
{
public:
OverlayDecorator();
/**
* Adds a new overlay technique to the decorator.
*/
void addTechnique( OverlayTechnique* technique );
/**
* Gets the group for nodes that are to be overlaid with
* the specified Technique.
*/
template<typename T>
osg::Group* getGroup() {
for(unsigned i=0; i<_techniques.size(); ++i ) {
if ( dynamic_cast<T*>(_techniques[i].get()) )
return _overlayGroups[i].get();
}
return 0L;
}
/**
* The traversal mask to use when traversing the overlay groups.
*/
void setOverlayGraphTraversalMask( unsigned mask );
/**
* Sets the maximum horizon distance to enforce when calculating
* the draping extents. Constraining the distance will mean that you won't
* see draped geometry past a certain point, but you will potentially get
* higher quality for the geometry you do see (with fewer aliasing artifacts).
*/
double getMaxHorizonDistance() const;
void setMaxHorizonDistance( double horizonDistance );
/**
* Maximum height (above and below) the terrain MSL/ellipsoid at which
* to drape geometry. Geometry above the max or below the -max will not
* appear. This is only important to maintain Z buffering precision in the
* draped geometry; however, it is usually a better idea to draw draped
* geometry without blending or z-testing anyway.
* Default is 500,000 meters.
*/
void setMaximumHeight(double value) { _maxHeight = value; }
double getMaximumHeight() const { return _maxHeight; }
/**
* Initializes the decorator with a terrain engine
*/
void setTerrainEngine(TerrainEngineNode*);
public: // osg::Node
void traverse( osg::NodeVisitor& nv );
public: // osg::Object
void resizeGLObjectBuffers(unsigned maxSize);
void releaseGLObjects(osg::State* state) const;
public: // NotiferGroup listener interface
void onGroupChanged(osg::Group* group);
protected:
virtual ~OverlayDecorator() { }
public:
// RTT camera parameters for an overlay technique. There will be
// one of these per technique, per view.
struct TechRTTParams
{
osg::Camera* _mainCamera; // Camera to which this per-view data is attached
osg::ref_ptr<osg::Camera> _rttCamera; // RTT camera.
osg::Matrixd _rttViewMatrix; // View matrix of RTT camera
osg::Matrixd _rttProjMatrix; // Projection matrix of RTT camera
osg::Group* _group; // contains the overlay graphics
osg::StateSet* _terrainStateSet; // same object as in PerViewData (shared across techniques)
osg::ref_ptr<osg::Object> _techniqueData; // technique sets this if needed
const double* _horizonDistance; // points to the PVD horizon distance
TerrainResources* _terrainResources; // for accessing image units
osg::Vec3d _eyeWorld; // eyepoint in world coords
osgShadow::ConvexPolyhedron _visibleFrustumPH; // polyhedron representing the frustum
osg::ref_ptr<osg::Uniform> _rttToPrimaryMatrixUniform; // xform from RTT cam to primary cam
};
// One of these per view (camera). The terrain state set
// if Shared almong all the techniques under a view.
struct PerViewData
{
osg::Camera* _camera; // Camera to which this per-view data is attached
std::vector<TechRTTParams> _techParams; // Pre-view data for each technique
osg::ref_ptr<osg::StateSet> _sharedTerrainStateSet; // shared state set to apply to the terrain traversal
double _sharedHorizonDistance; // horizon distnace (not used?)
osg::Matrix _prevViewMatrix; // last frame's view matrix
};
private:
optional<int> _explicitTextureUnit;
optional<int> _textureUnit;
optional<int> _textureSize;
bool _isGeocentric;
unsigned _rttTraversalMask;
double _maxHeight;
double _maxHorizonDistance;
unsigned _totalOverlayChildren;
osg::ref_ptr<const SpatialReference> _srs;
Ellipsoid _ellipsoid;
osg::observer_ptr<TerrainEngineNode> _engine;
// Mapping of each RTT camera params vector to a Camera (per view data)
using PerViewDataMap = std::unordered_map<osg::Camera*, PerViewData>;
PerViewDataMap _perViewData;
mutable Threading::ReadWriteMutex _perViewDataMutex;
typedef std::vector< osg::ref_ptr<OverlayTechnique> > Techniques;
Techniques _techniques;
Techniques _unsupportedTechniques;
typedef std::vector< osg::ref_ptr<osg::Group> > Groups;
Groups _overlayGroups;
private:
void cullTerrainAndCalculateRTTParams( osgUtil::CullVisitor* cv, PerViewData& pvd );
void initializePerViewData( PerViewData&, osg::Camera* );
PerViewData& getPerViewData( osg::Camera* key );
public:
// marker class for DrapeableNode support.
struct InternalNodeVisitor : public osg::NodeVisitor {
InternalNodeVisitor(const osg::NodeVisitor::TraversalMode& mode =osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) :
osg::NodeVisitor(mode) { }
};
//debugging:
void requestDump() { _dumpRequested = true; }
osg::Node* getDump() { osg::Node* r = _dump.release(); _dump = 0L; return r; }
osg::ref_ptr<osg::Node> _dump;
bool _dumpRequested;
};
/**
* Abstract interface for an overlay technique implementation
*/
class OverlayTechnique : public osg::Referenced
{
protected:
bool _supported;
OverlayTechnique() : _supported(true) { }
virtual ~OverlayTechnique() { }
public:
virtual bool supported() { return _supported; }
virtual bool constrainOrthoZ() const { return false; }
virtual bool hasData(
OverlayDecorator::TechRTTParams& params) const { return true; }
virtual const osg::BoundingSphere& getBound(
OverlayDecorator::TechRTTParams& params) const { return params._group->getBound(); }
virtual bool optimizeToVisibleBound() const { return false; }
virtual void onInstall( TerrainEngineNode* engine ) { }
virtual void onUninstall( TerrainEngineNode* engine ) { }
virtual void reestablish( TerrainEngineNode* engine ) { }
virtual void preCullTerrain(
OverlayDecorator::TechRTTParams& params,
osgUtil::CullVisitor* cv ) { }
virtual void cullOverlayGroup(
OverlayDecorator::TechRTTParams& params,
osgUtil::CullVisitor* cv ) { }
virtual void resizeGLObjectBuffers(unsigned maxSize) { }
virtual void releaseGLObjects(osg::State* state) const { }
};
} } // namespace osgEarth
#endif //OSGEARTH_OVERLAY_DECORATOR