/* -*-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 */ #ifndef OSGEARTH_GEOMETRY_CLAMPER #define OSGEARTH_GEOMETRY_CLAMPER 1 #include #include #include #include #include #include namespace osgEarth { namespace Util { /** * Utility that takes existing OSG geometry and modifies it so that * it "conforms" with a terrain patch. */ class OSGEARTH_EXPORT GeometryClamper : public osg::NodeVisitor { public: class GeometryData { osg::ref_ptr _verts; osg::ref_ptr _altitudes; friend class GeometryClamper; }; using LocalData = std::unordered_map; public: //! Construct a geometry clamper, passing in a data structure managed //! by the caller. GeometryClamper(LocalData& data); virtual ~GeometryClamper() { } //! Terrain graph the clamper should use to sample in-memory terrain void setTerrainPatch(osg::Node* node) { _terrainPatch = node; } osg::Node* getTerrainPatch() const { return _terrainPatch.get(); } //! SRS of the terrain model in memory void setTerrainSRS(const SpatialReference* srs) { _terrainSRS = srs; } const SpatialReference* getTerrainSRS() const { return _terrainSRS.get(); } //! Whether to incorporate (add) the original vertex's altitude to the result //! of the clamping operation. Default=true. If false, the vert's height information //! is ignored. void setUseVertexZ(bool value) { _useVertexZ = value; } bool getUseVertexZ() const { return _useVertexZ; } void setScale(float scale) { _scale = scale; } float getScale() const { return _scale; } void setOffset(float offset) { _offset = offset; } float getOffset() const { return _offset; } //! Whether to revert a previous clamping operation (default=false) void setRevert(bool value) { _revert = value; } public: // osg::NodeVisitor void apply( osg::Drawable& ); void apply( osg::Transform& ); protected: LocalData& _localData; osg::ref_ptr _terrainPatch; osg::ref_ptr _terrainSRS; bool _useVertexZ; bool _revert; float _scale; float _offset; osg::fast_back_stack _matrixStack; osg::ref_ptr _lsi; }; class GeometryClamperCallback : public osgEarth::TerrainCallback { public: GeometryClamperCallback(); virtual ~GeometryClamperCallback() { } /** Access to configure the underlying clamper */ GeometryClamper& getClamper() { return _clamper; } const GeometryClamper& getClamper() const { return _clamper; } public: // TerrainCallback virtual void onTileUpdate( const TileKey& key, osg::Node* tile, TerrainCallbackContext& context); protected: GeometryClamper _clamper; }; } } #endif // OSGEARTH_GEOMETRY_CLAMPER