/* -*-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 OSGEARTH_MAPNODE_H #define OSGEARTH_MAPNODE_H 1 #include #include #include #include namespace osg { class View; } namespace osgEarth { class Registry; } namespace osgEarth { class Terrain; class TerrainEngineNode; class SpatialReference; class DrapableNode; class ClampableNode; namespace Util { class DrapingManager; class ClampingManager; class DrapingTechnique; class ClampingTechnique; } /** * OSG Node that forms the root of an osgEarth map. * This node is a "view" component that renders data from a "Map" data model. */ class OSGEARTH_EXPORT MapNode : public osg::Group { public: // serialization data class OSGEARTH_EXPORT Options : public ConfigOptions { public: META_ConfigOptions(osgEarth, Options, ConfigOptions); OE_OPTION(int, drapingRenderBinNumber, 1); OE_OPTION(bool, enableLighting, true); OE_OPTION(bool, overlayBlending, true); OE_OPTION(bool, overlayMipMapping, false); OE_OPTION(bool, useCascadeDraping, false); OE_OPTION(float, overlayResolutionRatio, 3.0f); OE_OPTION(float, screenSpaceError, 25.0f); OE_OPTION(unsigned, overlayTextureSize, 4096); OE_OPTION(std::string, overlayBlendingSource, "alpha"); OE_OPTION(TerrainOptions, terrain); OE_OPTION(ProxySettings, proxySettings); virtual Config getConfig() const; private: void fromConfig(const Config& conf); }; public: // static loaders //! Loads a MapNode form a ".earth" file in the arguemnts list static MapNode* load(class osg::ArgumentParser& arguments); //! Loads a MapNode from a ".earth" file in the arguments list static MapNode* load( class osg::ArgumentParser& arguments, const Options& options); public: // constructors //! Creates an empty map node (with a default empty Map). MapNode(); //! Creates an empty map node with some intialization options MapNode(const Options& options); //! Creates a map node that will render the given Map. MapNode(Map* map); //! Creates a map node that will render the given Map. MapNode(Map* map, const Options& options); public: //! Map this node is rendering. Map* getMap(); const Map* getMap() const; //! Screen-space error for geometry level of detail void setScreenSpaceError(float sse); float getScreenSpaceError() const; //! Whether to allow lighting when present void setEnableLighting(const bool& value); const bool& getEnableLighting() const; //! Access to the terrain-specific options API. TerrainOptionsAPI getTerrainOptions(); //! Spatial Reference System of the underlying map. const SpatialReference* getMapSRS() const; //! API for for querying the in-memory terrain scene graph directly. Terrain* getTerrain(); const Terrain* getTerrain() const; /** * Finds the topmost Map node in the specified scene graph, or returns NULL if * no Map node exists in the graph. * * @param graph * Node graph in which to search for a MapNode * @param travMask * Traversal mask to apply while searching */ static MapNode* findMapNode(osg::Node* graph, unsigned travMask = ~0); static MapNode* get(osg::Node* graph, unsigned travMask = ~0) { return findMapNode(graph, travMask); } static MapNode* get(osg::ref_ptr& graph, unsigned travMask = ~0) { return findMapNode(graph.get(), travMask); } /** * Returns true if the realized terrain model is geocentric, false if * it is flat/projected. */ bool isGeocentric() const; /** * Accesses the group node that contains all the nodes added by Layers. */ osg::Group* getLayerNodeGroup() const; /** * Gets the underlying terrain engine that renders the terrain surface of the map. */ TerrainEngine* getTerrainEngine() const; /** * Gets the Config object serializing external data. External data is information * that osgEarth itself does not control, but that an app can include in the * MapNode for the purposes of including it in a .earth file. */ Config& externalConfig() { return _externalConf; } const Config& externalConfig() const { return _externalConf; } /** * Adds an Extension and calls its startup method with this MapNode. */ void addExtension(Extension* extension, const osgDB::Options* options =0L); /** * Removes an extension, and calls its shutdown method with this MapNode. */ void removeExtension(Extension* extension); /** * Removes all extensions, calling each one's shutdown method this this MapNode. */ void clearExtensions(); /** * Access the extensions vector. */ const std::vector< osg::ref_ptr >& getExtensions() const { return _extensions; } /** * Find an extension by type and return it. */ template T* getExtension() const { for(std::vector< osg::ref_ptr >::const_iterator i = _extensions.begin(); i != _extensions.end(); ++i) { T* e = dynamic_cast(i->get()); if ( e ) return e; } return 0L; } //! Opens all layers that are not already open. void openMapLayers(); //! Serializes the MapNode into a Config object Config getConfig() const; //! Opens the map (installs a terrain engine and initializes all the layers) bool open(); //! Returns the map coordinates under the provided mouse (window) coordinates. //! @param view View in which to do the query //! @param mx, my Mouse coordinates //! @param out_point Outputs the point under the mouse (when returning true) //! @return true upon success, false upon failure bool getGeoPointUnderMouse( osg::View* view, float mx, float my, GeoPoint& out_point) const; //! Returns the map coordinates under the provided mouse (window) coordinates. //! @param view View in which to do the query //! @param mx, my Mouse coordinates //! @return Outputs the point under the mouse GeoPoint getGeoPointUnderMouse( osg::View* view, float mx, float my) const; public: // osg::Object const char* libraryName() const override { return "osgEarth"; } const char* className() const override { return "MapNode"; } public: //override osg::Node osg::BoundingSphere computeBound() const override; void traverse(class osg::NodeVisitor& nv) override; void resizeGLObjectBuffers(unsigned maxSize) override; void releaseGLObjects(osg::State* state) const override; protected: virtual ~MapNode(); private: osg::ref_ptr _map; osg::Group* _layerNodes; unsigned _lastNumBlacklistedFilenames; Config _externalConf; osg::Group* _terrainGroup; std::shared_ptr _drapingManager; ClampingManager* _clampingManager; std::atomic _readyForUpdate; // yes, this must be a ref_ptr so observers can point to it // in setMap(). osg::ref_ptr _terrainEngine; std::vector< osg::ref_ptr > _extensions; bool _isOpen; public: // MapCallback proxy void onLayerAdded(Layer* layer, unsigned index); void onLayerRemoved(Layer* layer, unsigned index); void onLayerMoved(Layer* layer, unsigned oldIndex, unsigned newIndex); private: osg::ref_ptr< MapCallback > _mapCallback; osg::ref_ptr _sseU; void init(); //std::shared_ptr& getDrapingManager(); friend class DrapingTechnique; friend class DrapeableNode; ClampingManager* getClampingManager(); friend class ClampingTechnique; friend class ClampableNode; private: Options _optionsConcrete; Options& options() { return _optionsConcrete; } public: const Options& options() const { return _optionsConcrete; } }; } // namespace osgEarth #endif // OSGEARTH_MAPNODE_H