[Git][debian-gis-team/osgearth][upstream] New upstream version 2.10.2+dfsg

Bas Couwenberg gitlab at salsa.debian.org
Fri Jul 12 07:57:21 BST 2019



Bas Couwenberg pushed to branch upstream at Debian GIS Project / osgearth


Commits:
a258c9f1 by Bas Couwenberg at 2019-07-12T04:56:14Z
New upstream version 2.10.2+dfsg
- - - - -


24 changed files:

- CMakeLists.txt
- + CMakeModules/FindWEBP.cmake
- docs/source/about.rst
- docs/source/faq.rst
- src/osgEarth/CascadeDrapingDecorator.cpp
- src/osgEarth/Config.cpp
- src/osgEarth/LayerShader
- src/osgEarth/Version
- src/osgEarthDrivers/CMakeLists.txt
- src/osgEarthDrivers/engine_rex/GeometryPool.cpp
- src/osgEarthDrivers/engine_rex/RexTerrainEngineNode.cpp
- src/osgEarthDrivers/engine_rex/RexTerrainEngineOptions
- src/osgEarthDrivers/engine_rex/SelectionInfo
- src/osgEarthDrivers/engine_rex/SelectionInfo.cpp
- src/osgEarthDrivers/engine_rex/SurfaceNode.cpp
- src/osgEarthDrivers/engine_rex/TileDrawable
- src/osgEarthDrivers/engine_rex/TileNode
- src/osgEarthDrivers/engine_rex/TileNode.cpp
- src/osgEarthDrivers/gltf/GLTFReader.h
- src/osgEarthDrivers/sky_simple/SimpleSkyExtension.cpp
- + src/osgEarthDrivers/webp/CMakeLists.txt
- + src/osgEarthDrivers/webp/ReaderWriterWebP.cpp
- src/osgEarthUtil/GeodeticGraticule.cpp
- src/osgEarthUtil/MGRSGraticule.cpp


Changes:

=====================================
CMakeLists.txt
=====================================
@@ -27,7 +27,7 @@ PROJECT(OSGEARTH)
 
 SET(OSGEARTH_MAJOR_VERSION 2)
 SET(OSGEARTH_MINOR_VERSION 10)
-SET(OSGEARTH_PATCH_VERSION 1)
+SET(OSGEARTH_PATCH_VERSION 2)
 SET(OSGEARTH_SOVERSION     0)
 
 SET(OSGEARTH_PLUGIN_PREFIX "")


=====================================
CMakeModules/FindWEBP.cmake
=====================================
@@ -0,0 +1,29 @@
+include(SelectLibraryConfigurations)
+include(FindPackageHandleStandardArgs)
+
+find_path(WEBP_INCLUDE_DIR "webp/decode.h"
+ 	      PATH_SUFFIXES include
+          )
+          
+find_library(WEBP_LIBRARY_RELEASE NAMES webp libwebp_a libwebp
+             HINTS "${WEBP_DIR}"
+             PATH_SUFFIXES "${PATH_SUFFIXES}" ${LIBRARY_PATH_SUFFIXES}
+			)
+
+
+find_library(WEBP_LIBRARY_DEBUG NAMES webp_debug libwebp libwebp_a libwebp
+             HINTS "${WEBP_DIR}"
+             PATH_SUFFIXES "${PATH_SUFFIXES}" ${LIBRARY_PATH_SUFFIXES} 
+			)
+
+select_library_configurations(WEBP)
+
+find_package_handle_standard_args(WEBP DEFAULT_MSG
+                                  WEBP_INCLUDE_DIR)
+
+mark_as_advanced(WEBP_INCLUDE_DIR)
+
+set( WEBP_FOUND "NO" )
+if( WEBP_LIBRARY AND WEBP_INCLUDE_DIR )
+    set( WEBP_FOUND "YES" )
+endif()
\ No newline at end of file


=====================================
docs/source/about.rst
=====================================
@@ -129,7 +129,7 @@ Maintainers
 .. _ at pelicanmapping:  https://twitter.com/pelicanmapping
 .. _Google+ Page:     https://plus.google.com/b/104014917856468748129/104014917856468748129/posts
 
-.. _support forum:    http://forum.osgearth.osg
+.. _support forum:    http://forum.osgearth.org
 .. _OSG Mailing List: http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
 .. _OSG Forum:        http://forum.openscenegraph.org
 .. _Contact us:       http://pelicanmapping.com/?page_id=2


=====================================
docs/source/faq.rst
=====================================
@@ -56,7 +56,7 @@ Lines or Annotations (FeatureNode, etc.) are not rendering. Why?
 
     Lines render using a shader that requires some initial state to be set.
     You can apply this state to your top-level camera (or anywhere else 
-    above the geometry) like so:
+    above the geometry) like so::
     
         #include <osgEarth/GLUtils>
         ...
@@ -87,90 +87,6 @@ Lines or Annotations (FeatureNode, etc.) are not rendering. Why?
     not place your annotations as descendants of the MapNode.
 
 
-How do make the terrain transparent?
-....................................
-
-    By default, the globe will be opaque white when there are no image layers, or when all the image
-    layers have their opacities set to zero. To make the underlying globe transparent, set the 
-    base color of the terrain to a transparent color like so::
-
-        <map>
-            <options>
-                <terrain color="#ffffff00" ...
-
-    In code, this option is found in the ``RexTerrainEngineOptions`` class::
-    
-        #include <osgEarthDrivers/engine_mp/RexTerrainEngineOptions>
-        using namespace osgEarth::Drivers::RexTerrainEngine;
-        ...
-        RexTerrainEngineOptions options;
-        options.color() = osg::Vec4(1,1,1,0);
-
-
-How do I set the resolution of terrain tiles?
-.............................................
-
-    Each tile is a grid of vertices. The number of vertices can vary depending on source data
-    and settings. By default (when you have no elevation data) it is an 17x17 grid, tessellated
-    into triangles.
-    
-    You can expressly set the terrain's tile size by using the Map options.
-    osgEarth will then resample all elevation data to the size you specify.
-    You will get best results from a tile size that is a power of 2 plus 1::
-
-        <map>
-            <options>
-                <terrain>
-                    <tile_size>9</tile_size> 
-                    ...
-
-
-----
-
-Other Terrain Formats
----------------------
-
-Does osgEarth work with VirtualPlanetBuilder?
-.............................................
-
-	VirtualPlanetBuilder_ (VPB) is a command-line terrain generation tool. Before osgEarth
-	came along, VPB	was probably the most-used open source tool for building terrains for
-	OSG appliations. We	mention is here because many people ask questions about loading 
-	VPB models or transitioning from VPB to osgEarth.
-	
-	osgEarth differs from VPB in that:
-	
-	* VPB builds static terrain models and saves them to disk. osgEarth generates terrain on
-	  demand as your application runs; you do not (and cannot) save a model to disk.
-	* Changing a VPB terrain generally requires that you rebuild the model. osgEarth does not
-	  require a preprocessing step since it builds the terrain at run time.
-	* osgEarth and VPB both use *GDAL* to read many types of imagery and elevation data from
-	  the local file system. osgEarth also supports network-based data sources through its
-	  plug-in framework.
-
-	osgEarth has a *VPB driver* for "scraping" elevation and imagery tiles from a VPB model.
-    Confiugration of this driver is quite tricky and requires you to understand the details
-    of how VPB models are organized. You're on your own.
-	
-	**Please Note** that this driver only exists as a **last resort** for people that have a VPB
-	model but no longer have access to the source data from which it was built. If at all
-	possible you should feed your source data directly into osgEarth instead of using the VPB
-	driver.
-
-
-Can osgEarth load TerraPage or MetaFlight?
-..........................................
-
-	osgEarth cannot load TerraPage (TXP) or MetaFlight. However, osgEarth does have a
-	"bring your own terrain" plugin that allows you to load an external model and use it as your
-	terrain. The caveat is that since osgEarth doesn't know anything about your terrain model, you
-	will not be able to use some of the features of osgEarth (like being able to add or remove layers).
-	
-	For usage formation, please refer to the ``byo.earth`` example in the repo.
-
-.. _VirtualPlanetBuilder:	http://www.openscenegraph.com/index.php/documentation/tools/virtual-planet-builder
-
-
 ----
 
 Community and Support


=====================================
src/osgEarth/CascadeDrapingDecorator.cpp
=====================================
@@ -939,7 +939,8 @@ CascadeDrapingDecorator::CameraLocal::traverse(osgUtil::CullVisitor* cv, Cascade
     // Create a view matrix that looks straight down at the horizon plane form the eyepoint.
     // This will be our view matrix for all RTT draping cameras.
     osg::Matrix rttView;
-    osg::Vec3d rttLook = -horizonPlane.getNormal();
+    osg::Vec3d rttLook = -ellipsoid->computeLocalUpVector(camEye.x(), camEye.y(), camEye.z());
+    rttLook.normalize();
     osg::Vec3d camLeft = camUp ^ camLook;
     osg::Vec3d rttUp = rttLook ^ camLeft;
     rttView.makeLookAt(camEye, camEye + rttLook, rttUp);


=====================================
src/osgEarth/Config.cpp
=====================================
@@ -135,6 +135,10 @@ Config::merge( const Config& rhs )
     // add in the new values.
     for( ConfigSet::const_iterator c = rhs._children.begin(); c != rhs._children.end(); ++c )
         add( *c );
+    
+    // merge ref map
+    for( RefMap::const_iterator c = rhs._refMap.begin(); c != rhs._refMap.end(); ++c )
+        _refMap[c->first] = c->second;
 }
 
 const Config*


=====================================
src/osgEarth/LayerShader
=====================================
@@ -36,7 +36,7 @@ namespace osgEarth
 
     //! Serializable shader that supports samplers and uniforms
     //! in an earth file.
-    class ShaderOptions : public ConfigOptions
+    class OSGEARTH_EXPORT ShaderOptions : public ConfigOptions
     {
     public:
         META_ConfigOptions(osgEarth, ShaderOptions, ConfigOptions);


=====================================
src/osgEarth/Version
=====================================
@@ -29,7 +29,7 @@ extern "C" {
 
 #define OSGEARTH_MAJOR_VERSION    2
 #define OSGEARTH_MINOR_VERSION    10
-#define OSGEARTH_PATCH_VERSION    1
+#define OSGEARTH_PATCH_VERSION    2
 #define OSGEARTH_SOVERSION        0
 #define OSGEARTH_RC_VERSION       0
 #define OSGEARTH_DEVEL_VERSION    0    // 0 = release; >0 = interim devel version


=====================================
src/osgEarthDrivers/CMakeLists.txt
=====================================
@@ -79,6 +79,7 @@ add_subdirectory(vdatum_egm96)
 add_subdirectory(viewpoints)
 add_subdirectory(vpb)
 add_subdirectory(wcs)
+add_subdirectory(webp)
 add_subdirectory(wms)
 add_subdirectory(xyz)
 


=====================================
src/osgEarthDrivers/engine_rex/GeometryPool.cpp
=====================================
@@ -178,7 +178,7 @@ namespace
     texCoords->push_back( (*texCoords)[INDEX] ); \
     texCoords->back().z() = (float)((int)texCoords->back().z() | VERTEX_MARKER_SKIRT); \
     if ( neighbors ) neighbors->push_back( (*neighbors)[INDEX] - ((*normals)[INDEX])*(HEIGHT) ); \
-    if ( neighborNormals ) neighborNormals->push_back( (*neighborNormals)[INDEX] - ((*neighborNormals)[INDEX])*(HEIGHT) ); \
+    if ( neighborNormals ) neighborNormals->push_back( (*neighborNormals)[INDEX] ); \
 }
 
 #define addSkirtTriangles(INDEX0, INDEX1) \


=====================================
src/osgEarthDrivers/engine_rex/RexTerrainEngineNode.cpp
=====================================
@@ -368,7 +368,8 @@ RexTerrainEngineNode::setMap(const Map* map, const TerrainOptions& options)
         0u, // always zero, not the terrain options firstLOD
         osg::minimum( _terrainOptions.maxLOD().get(), maxLOD ),
         map->getProfile(),
-        _terrainOptions.minTileRangeFactor().get() );
+        _terrainOptions.minTileRangeFactor().get(),
+        _terrainOptions.adaptivePolarRangeFactor().get() );
 
     // set up the initial graph
     refresh();


=====================================
src/osgEarthDrivers/engine_rex/RexTerrainEngineOptions
=====================================
@@ -45,7 +45,8 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
             _morphTerrain           ( true ),
             _morphImagery           ( true ),
             _mergesPerFrame         ( 20 ),
-            _expirationRange        ( 0 )
+            _expirationRange        ( 0 ),
+            _adaptivePolarRangeFactor( true )
         {
             setDriver( "rex" );
             fromConfig( _conf );
@@ -108,6 +109,14 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
         optional<int>& mergesPerFrame() { return _mergesPerFrame; }
         const optional<int>& mergesPerFrame() const { return _mergesPerFrame; }
 
+        /**
+         * Whether to automatically adjust(reduce) the minTileRangeFactor with increase in
+         * latitude. This prevents overtessellation in the polar regions. Only works with
+         * a geocentric map. Defaults to true.
+         */
+        optional<bool>& adaptivePolarRangeFactor() { return _adaptivePolarRangeFactor; }
+        const optional<bool>& adaptivePolarRangeFactor() const { return _adaptivePolarRangeFactor; }
+
         /** Options for specific LODs */
         std::vector<LODOptions>& lods() { return _lods; }
         const std::vector<LODOptions>& lods() const { return _lods; }
@@ -125,6 +134,7 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
             conf.set( "morph_terrain", _morphTerrain );
             conf.set( "morph_imagery", _morphImagery );
             conf.set( "merges_per_frame", _mergesPerFrame );
+            conf.set( "adaptive_polar_range_factor", _adaptivePolarRangeFactor);
 
             if (!_lods.empty()) {
                 Config lodsConf("lods");
@@ -159,6 +169,7 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
             conf.get( "morph_terrain", _morphTerrain );
             conf.get( "morph_imagery", _morphImagery );
             conf.get( "merges_per_frame", _mergesPerFrame );
+            conf.get( "adaptive_polar_range_factor", _adaptivePolarRangeFactor);
 
             const Config* lods = conf.child_ptr("lods");
             if (lods) {
@@ -185,6 +196,7 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
         optional<bool>     _morphTerrain;
         optional<bool>     _morphImagery;
         optional<int>      _mergesPerFrame;
+        optional<bool>     _adaptivePolarRangeFactor;
         std::vector<LODOptions> _lods;
     };
 


=====================================
src/osgEarthDrivers/engine_rex/SelectionInfo
=====================================
@@ -40,13 +40,14 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
             double _visibilityRange;
             double _morphStart;
             double _morphEnd;
+            unsigned _minValidTY, _maxValidTY;
         };
 
     public:
         SelectionInfo() : _firstLOD(0) { }
 
         //! Initialize the selection into LODs
-        void initialize(unsigned firstLod, unsigned maxLod, const Profile* profile, double mtrf);
+        void initialize(unsigned firstLod, unsigned maxLod, const Profile* profile, double mtrf, bool restrictPolarSubdivision);
 
         //! Number of LODs
         unsigned getNumLODs(void) const { return _lods.size(); }
@@ -54,6 +55,12 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
         //! Visibility and morphing information for a specific LOD
         const LOD& getLOD(unsigned lod) const;
 
+        //! Fetch the effective visibility range and morphing range for a key
+        void get(const TileKey& key, float& out_range, float& out_startMorphRange, float& out_endMorphRange) const;
+
+        //! Get just the visibility range for a TileKey.
+        float getRange(const TileKey& key) const;
+
     private:
         std::vector<LOD>    _lods;
         unsigned            _firstLOD;


=====================================
src/osgEarthDrivers/engine_rex/SelectionInfo.cpp
=====================================
@@ -41,7 +41,7 @@ SelectionInfo::getLOD(unsigned lod) const
 }
 
 void
-SelectionInfo::initialize(unsigned firstLod, unsigned maxLod, const Profile* profile, double mtrf)
+SelectionInfo::initialize(unsigned firstLod, unsigned maxLod, const Profile* profile, double mtrf, bool restrictPolarSubdivision)
 {
     if (getNumLODs() > 0)
     {
@@ -57,29 +57,104 @@ SelectionInfo::initialize(unsigned firstLod, unsigned maxLod, const Profile* pro
 
     _firstLOD = firstLod;
 
-    double fLodNear = 0;
-    float fRatio = 1.0;
-
     unsigned numLods = maxLod + 1u;
 
     _lods.resize(numLods);
 
     for (unsigned lod = 0; lod <= maxLod; ++lod)
     {
-        TileKey key(lod, 0, 0, profile);
+        unsigned tx, ty;
+        profile->getNumTiles(lod, tx, ty);
+        TileKey key(lod, tx/2, ty/2, profile);
         GeoExtent e = key.getExtent();
         GeoCircle c = e.computeBoundingGeoCircle();
         double range = c.getRadius() * mtrf * 2.0;
-
         _lods[lod]._visibilityRange = range;
+        _lods[lod]._minValidTY = 0;
+        _lods[lod]._maxValidTY = INT32_MAX;
     }
     
-    double lodNear = 0;
-    double prevPos = lodNear;
-    for (int i=(int)(numLods-1); i>=0; --i)
+    double metersPerEquatorialDegree = (profile->getSRS()->getEllipsoid()->getRadiusEquator() * 2.0 * osg::PI) / 360.0;
+
+    double prevPos = 0.0;
+
+    for (int lod=(int)(numLods-1); lod>=0; --lod)
+    {
+        double span = _lods[lod]._visibilityRange - prevPos;
+
+        _lods[lod]._morphEnd   = _lods[lod]._visibilityRange;
+        _lods[lod]._morphStart = prevPos + span*_morphStartRatio;
+        //prevPos = _lods[i]._morphStart; // original value
+        prevPos = _lods[lod]._morphEnd;
+
+        // Calc the maximum valid TY (to avoid over-subdivision at the poles)
+        // In a geographic map, this will effectively limit the maximum LOD
+        // progressively starting at about +/- 72 degrees latitude.
+        unsigned startLOD = 6;
+        if (restrictPolarSubdivision && lod >= startLOD && profile->getSRS()->isGeographic())
+        {            
+            const double startAR = 0.1; // minimum allowable aspect ratio at startLOD
+            const double endAR = 0.4;   // minimum allowable aspect ratio at maxLOD
+            double lodT = (double)(lod-startLOD)/(double)(numLods-1);
+            double minAR = startAR + (endAR-startAR)*lodT;
+
+            unsigned tx, ty;
+            profile->getNumTiles(lod, tx, ty);
+            for(int y=ty/2; y>=0; --y)
+            {
+                TileKey k(lod, 0, y, profile);
+                const GeoExtent& e = k.getExtent();
+                double lat = 0.5*(e.yMax()+e.yMin());
+                double width = e.width() * metersPerEquatorialDegree * cos(osg::DegreesToRadians(lat));
+                double height = e.height() * metersPerEquatorialDegree;
+                if (width/height < minAR)
+                {
+                    _lods[lod]._minValidTY = osg::minimum(y+1, (int)(ty-1));
+                    _lods[lod]._maxValidTY = (ty-1)-_lods[lod]._minValidTY;
+                    OE_DEBUG << "LOD " << lod 
+                        << " TY=" << ty
+                        << " minAR=" << minAR
+                        << " minTY=" << _lods[lod]._minValidTY
+                        << " maxTY=" << _lods[lod]._maxValidTY
+                        << " (+/-" << lat << " deg)"
+                        << std::endl;
+                    break;
+                }
+            }
+        }
+    }
+}
+
+void
+SelectionInfo::get(const TileKey& key, 
+                   float& out_range,
+                   float& out_startMorphRange,
+                   float& out_endMorphRange) const
+{
+    out_range = 0.0f;
+    out_startMorphRange = 0.0f;
+    out_endMorphRange = 0.0f;
+
+    if (key.getLOD() < _lods.size())
+    {
+        const LOD& lod = _lods[key.getLOD()];
+
+        if (key.getTileY() >= lod._minValidTY && key.getTileY() <= lod._maxValidTY)
+        {
+            out_range = lod._visibilityRange;
+            out_startMorphRange = lod._morphStart;
+            out_endMorphRange = lod._morphEnd;
+        }
+    }
+}
+
+float
+SelectionInfo::getRange(const TileKey& key) const
+{
+    const LOD& lod = _lods[key.getLOD()];
+    if (key.getTileY() >= lod._minValidTY && key.getTileY() <= lod._maxValidTY)
     {
-        _lods[i]._morphEnd   = _lods[i]._visibilityRange;
-        _lods[i]._morphStart = prevPos + (_lods[i]._morphEnd - prevPos) * _morphStartRatio;
-        prevPos = _lods[i]._morphStart;
+        return lod._visibilityRange;
     }
+    return 0.0f;
 }


=====================================
src/osgEarthDrivers/engine_rex/SurfaceNode.cpp
=====================================
@@ -242,8 +242,12 @@ SurfaceNode::computeBound() const
 
 float
 SurfaceNode::getPixelSizeOnScreen(osg::CullStack* cull) const
-{
-    return cull->clampedPixelSize(getMatrix().getTrans(), _drawable->getRadius()) / cull->getLODScale();
+{     
+    // By using the width, the "apparent" pixel size will decrease as we
+    // near the poles.
+    double R = _drawable->getWidth()*0.5;
+    //double R = _drawable->getRadius() / 1.4142;
+    return cull->clampedPixelSize(getMatrix().getTrans(), R) / cull->getLODScale();
 }
 
 void


=====================================
src/osgEarthDrivers/engine_rex/TileDrawable
=====================================
@@ -101,6 +101,8 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
 
         float getRadius() const { return _bboxRadius; }
 
+        float getWidth() const { return getBoundingBox().xMax() - getBoundingBox().xMin(); }
+
     public: // osg::Drawable overrides
 
         // These methods defer functors (like stats collection) to the underlying


=====================================
src/osgEarthDrivers/engine_rex/TileNode
=====================================
@@ -153,6 +153,7 @@ namespace osgEarth { namespace Drivers { namespace RexTerrainEngine
         bool                               _empty;
         bool                               _isRootTile;
         bool                               _imageUpdatesActive;
+        TileKey                            _subdivideTestKey;
 
         osg::observer_ptr<TileNode> _eastNeighbor;
         osg::observer_ptr<TileNode> _southNeighbor;


=====================================
src/osgEarthDrivers/engine_rex/TileNode.cpp
=====================================
@@ -159,11 +159,17 @@ TileNode::create(const TileKey& key, TileNode* parent, EngineContext* context)
         -1.0f);
 
     // initialize all the per-tile uniforms the shaders will need:
-    float start = (float)context->getSelectionInfo().getLOD(_key.getLOD())._morphStart;
-    float end   = (float)context->getSelectionInfo().getLOD(_key.getLOD())._morphEnd;
-    float one_by_end_minus_start = end - start;
-    one_by_end_minus_start = 1.0f/one_by_end_minus_start;
-    _morphConstants.set( end * one_by_end_minus_start, one_by_end_minus_start );
+    float range, morphStart, morphEnd;
+    context->getSelectionInfo().get(_key, range, morphStart, morphEnd);
+
+    float one_over_end_minus_start = 1.0f/(morphEnd - morphStart);
+    _morphConstants.set(morphEnd * one_over_end_minus_start, one_over_end_minus_start);
+
+    // Make a tilekey to use for testing whether to subdivide.
+    if (_key.getTileY() <= th/2)
+        _subdivideTestKey = _key.createChildKey(0);
+    else
+        _subdivideTestKey = _key.createChildKey(3);
 
     // Initialize the data model by copying the parent's rendering data
     // and scale/biasing the matrices.
@@ -367,7 +373,7 @@ TileNode::shouldSubDivide(TerrainCuller* culler, const SelectionInfo& selectionI
         // In DISTANCE-TO-EYE mode, use the visibility ranges precomputed in the SelectionInfo.
         else
         {
-            float range = selectionInfo.getLOD(currLOD+1)._visibilityRange;
+            float range = context->getSelectionInfo().getRange(_subdivideTestKey);
 #if 1
             // slightly slower than the alternate block below, but supports a user overriding
             // CullVisitor::getDistanceToViewPoint -gw
@@ -375,7 +381,7 @@ TileNode::shouldSubDivide(TerrainCuller* culler, const SelectionInfo& selectionI
 #else
             return _surface->anyChildBoxIntersectsSphere(
                 culler->getViewPointLocal(), 
-                range*range/culler->getLODScale());
+                range*range / culler->getLODScale());
 #endif
         }
     }                 


=====================================
src/osgEarthDrivers/gltf/GLTFReader.h
=====================================
@@ -28,6 +28,7 @@
 #include <osg/Texture2D>
 #include <osgDB/FileNameUtils>
 #include <osgDB/ReaderWriter>
+#include <osgUtil/Optimizer>
 #include <osgEarth/Notify>
 
 #undef LC
@@ -64,9 +65,7 @@ public:
 
     osg::Node* makeNodeFromModel(const tinygltf::Model &model) const
     {
-        // Rotate y-up to z-up
-        osg::MatrixTransform* transform = new osg::MatrixTransform;
-        transform->setMatrix(osg::Matrixd::rotate(osg::Vec3d(0.0, 1.0, 0.0), osg::Vec3d(0.0, 0.0, 1.0)));
+        osg::Group* group = new osg::Group();
 
         for (unsigned int i = 0; i < model.scenes.size(); i++)
         {
@@ -76,12 +75,11 @@ public:
                 osg::Node* node = createNode(model, model.nodes[scene.nodes[j]]);
                 if (node)
                 {
-                    transform->addChild(node);
+                    group->addChild(node);
                 }
             }
         }
-
-        return transform;
+        return group;
     }
 
     osg::Node* createNode(const tinygltf::Model &model, const tinygltf::Node& node) const
@@ -141,6 +139,9 @@ public:
         std::vector< osg::ref_ptr< osg::Array > > arrays;
         extractArrays(model, arrays);
 
+        // Transforms verts and normals from Y-UP (GLTF spec) to Z-UP (OSG)
+        const osg::Matrixd YUP2ZUP(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1);
+
         OE_DEBUG << "Drawing " << mesh.primitives.size() << " primitives in mesh" << std::endl;
 
         for (size_t i = 0; i < mesh.primitives.size(); i++) {
@@ -259,11 +260,21 @@ public:
                 if (it->first.compare("POSITION") == 0)
                 {
                     geom->setVertexArray(arrays[it->second]);
+
+                    // convert Y-UP to Z-UP
+                    osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>(geom->getVertexArray());
+                    for(unsigned i=0; i<verts->size(); ++i)
+                        (*verts)[i] = (*verts)[i] * YUP2ZUP;
                 }
 
                 else if (it->first.compare("NORMAL") == 0)
                 {
                     geom->setNormalArray(arrays[it->second]);
+
+                    // convert Y-UP to Z-UP
+                    osg::Vec3Array* normals = dynamic_cast<osg::Vec3Array*>(geom->getNormalArray());
+                    for (unsigned i = 0; i < normals->size(); ++i)
+                        (*normals)[i] = osg::Matrixd::transform3x3((*normals)[i], YUP2ZUP);
                 }
                 else if (it->first.compare("TEXCOORD_0") == 0)
                 {


=====================================
src/osgEarthDrivers/sky_simple/SimpleSkyExtension.cpp
=====================================
@@ -40,7 +40,7 @@ namespace osgEarth { namespace SimpleSky
                                public SkyNodeFactory
     {
     public:
-        META_OE_Extension(osgEarth, SimpleSkyExtension, simple_sky);
+        META_OE_Extension(osgEarth, SimpleSkyExtension, sky_simple);
 
         // CTORs
         SimpleSkyExtension() { }


=====================================
src/osgEarthDrivers/webp/CMakeLists.txt
=====================================
@@ -0,0 +1,15 @@
+IF(WEBP_FOUND)
+
+find_package(WEBP REQUIRED)
+
+SET(TARGET_SRC
+	ReaderWriterWebP.cpp
+)
+
+INCLUDE_DIRECTORIES( ${WEBP_INCLUDE_DIR} )
+
+SET(TARGET_COMMON_LIBRARIES ${TARGET_COMMON_LIBRARIES} ${WEBP_LIBRARY})
+
+SETUP_PLUGIN(webp)
+
+ENDIF(WEBP_FOUND)
\ No newline at end of file


=====================================
src/osgEarthDrivers/webp/ReaderWriterWebP.cpp
=====================================
@@ -0,0 +1,342 @@
+/* -*-c++-*- */
+/* osgEarth - Geospatial SDK for OpenSceneGraph
+ * Copyright 2019 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/>
+ */
+
+#include <osg/Image>
+#include <osg/Notify>
+
+#include <osg/Geode>
+
+#include <osg/GL>
+
+#include <osgDB/FileNameUtils>
+#include <osgDB/FileUtils>
+#include <osgDB/Registry>
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <stdio.h>
+#include <stdlib.h>
+#include <iomanip>
+
+#include "webp/encode.h"
+#include "webp/decode.h"
+
+#if TARGET_OS_IPHONE
+#include "strings.h"
+#define stricmp strcasecmp
+#endif
+
+using namespace osg;
+
+class ReaderWriterWebP : public osgDB::ReaderWriter
+{
+public:
+  ReaderWriterWebP()
+  {
+    supportsExtension("webp", "WebP image format");
+  }
+
+  ~ReaderWriterWebP()
+  {
+  }
+
+  virtual const char *className() const { return "Google WebP Image Reader/Writer"; }
+
+  virtual ReadResult readObject(const std::string &file, const osgDB::ReaderWriter::Options *options) const
+  {
+    return readImage(file, options);
+  }
+
+  virtual ReadResult readObject(std::istream &fin, const Options *options) const
+  {
+    return readImage(fin, options);
+  }
+
+  virtual ReadResult readImage(const std::string &file, const osgDB::ReaderWriter::Options *options) const
+  {
+    std::string ext = osgDB::getFileExtension(file);
+    if (!acceptsExtension(ext))
+      return ReadResult::FILE_NOT_HANDLED;
+
+    std::string fileName = osgDB::findDataFile(file, options);
+    if (fileName.empty())
+      return ReadResult::FILE_NOT_FOUND;
+
+    osgDB::ifstream f(file.c_str(), std::ios_base::in | std::ios_base::binary);
+    if (!f)
+      return ReadResult::FILE_NOT_HANDLED;
+
+    ReadResult rr = readImage(f, options);
+
+    if (rr.validImage())
+      rr.getImage()->setFileName(file);
+    return rr;
+  }
+
+  virtual ReadResult readImage(std::istream &fin, const Options *options) const
+  {
+    Image *image = NULL;
+    unsigned long size_of_vp8_image_data = 0;
+    char *vp8_buffer = NULL;
+
+    fin.seekg(0, std::ios::end);
+    size_t stream_size = fin.tellg();
+    fin.seekg(0, std::ios::beg);
+
+    if (stream_size > 0)
+    {
+
+      size_of_vp8_image_data = stream_size;
+      vp8_buffer = new char[stream_size];
+
+      int version = WebPGetEncoderVersion();
+      size_of_vp8_image_data = fin.read(vp8_buffer, size_of_vp8_image_data).gcount();
+
+      WebPDecoderConfig config;
+      WebPInitDecoderConfig(&config);
+      int status = WebPGetFeatures((const uint8_t *)vp8_buffer, (uint32_t)size_of_vp8_image_data, &config.input);
+      if (status == VP8_STATUS_OK)
+      {
+
+        unsigned int pixelFormat;
+        unsigned int dataType = GL_UNSIGNED_BYTE;
+
+        if (config.input.has_alpha)
+        {
+          pixelFormat = GL_RGBA;
+          config.output.colorspace = MODE_RGBA;
+        }
+        else
+        {
+          /*
+            BUG of AMD driver: http://devgurus.amd.com/message/1302663
+            pixelFormat = GL_RGB;
+            config.output.colorspace = MODE_RGB;
+            */
+          pixelFormat = GL_RGBA;
+          config.output.colorspace = MODE_RGBA;
+        }
+        int internalFormat = pixelFormat;
+        int r = 1;
+
+        image = new Image();
+        image->allocateImage(config.input.width, config.input.height, 1, pixelFormat, dataType);
+
+        config.output.u.RGBA.rgba = (uint8_t *)image->data();
+        config.output.u.RGBA.stride = image->getRowSizeInBytes();
+        config.output.u.RGBA.size = image->getImageSizeInBytes();
+
+        config.options.no_fancy_upsampling = 1;
+
+        config.output.is_external_memory = 1;
+
+        status = WebPDecode((const uint8_t *)vp8_buffer, (uint32_t)size_of_vp8_image_data, &config);
+      }
+      delete[] vp8_buffer;
+    }
+    else
+    {
+      OSG_NOTICE << "read webp image: stream size is zero" << std::endl;
+    }
+
+    return image;
+  }
+
+  virtual WriteResult writeObject(const osg::Object &object, const std::string &file, const osgDB::ReaderWriter::Options *options) const
+  {
+    const osg::Image *image = dynamic_cast<const osg::Image *>(&object);
+    if (!image)
+      return WriteResult::FILE_NOT_HANDLED;
+
+    return writeImage(*image, file, options);
+  }
+
+  virtual WriteResult writeObject(const osg::Object &object, std::ostream &fout, const Options *options) const
+  {
+    const osg::Image *image = dynamic_cast<const osg::Image *>(&object);
+    if (!image)
+      return WriteResult::FILE_NOT_HANDLED;
+
+    return writeImage(*image, fout, options);
+  }
+
+  virtual WriteResult writeImage(const osg::Image &img, const std::string &fileName, const osgDB::ReaderWriter::Options *options) const
+  {
+    std::string ext = osgDB::getFileExtension(fileName);
+    if (!acceptsExtension(ext))
+      return WriteResult::FILE_NOT_HANDLED;
+
+    int internalFormat = osg::Image::computeNumComponents(img.getPixelFormat());
+
+    osgDB::ofstream f(fileName.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
+    if (!f)
+      return WriteResult::ERROR_IN_WRITING_FILE;
+
+    return writeImage(img, f, options);
+  }
+
+  static int ostream_writer(const uint8_t *data, size_t data_size,
+                            const WebPPicture *const pic)
+  {
+
+    std::ostream *const out = (std::ostream *)pic->custom_ptr;
+    return data_size ? (int)out->write((const char *)data, data_size).tellp() : 1;
+  }
+
+  WriteResult writeImage(const osg::Image &img, std::ostream &fout, const Options *options) const
+  {
+    int internalFormat = osg::Image::computeNumComponents(img.getPixelFormat());
+
+    WebPConfig config;
+    config.quality = 75;
+    config.method = 2;
+
+    if (options)
+    {
+      std::istringstream iss(options->getOptionString());
+      std::string opt;
+      while (iss >> opt)
+      {
+        if (strcmp(opt.c_str(), "lossless") == 0)
+        {
+          config.lossless = 1;
+          config.quality = 100;
+        }
+        else if (strcmp(opt.c_str(), "hint") == 0)
+        {
+          std::string v;
+          iss >> v;
+          if (strcmp(v.c_str(), "picture") == 0)
+          {
+            config.image_hint = WEBP_HINT_PICTURE;
+          }
+          else if (strcmp(v.c_str(), "photo") == 0)
+          {
+            config.image_hint = WEBP_HINT_PHOTO;
+          }
+          else if (strcmp(v.c_str(), "graph") == 0)
+          {
+            config.image_hint = WEBP_HINT_GRAPH;
+          }
+        }
+        else if (strcmp(opt.c_str(), "quality") == 0)
+        {
+          float v;
+          iss >> v;
+          if (v >= 0.0 && v <= 100.0)
+          {
+            config.quality = v;
+          }
+        }
+        else if (strcmp(opt.c_str(), "method") == 0)
+        {
+          int v;
+          iss >> v;
+          if (v >= 0 && v <= 6)
+          {
+            config.method = v;
+          }
+        }
+      }
+    }
+
+    WebPPicture picture;
+    WebPPreset preset;
+
+    if (!WebPPictureInit(&picture) || !WebPConfigInit(&config))
+    {
+      return WriteResult::ERROR_IN_WRITING_FILE;
+    }
+
+    picture.width = img.s();
+    picture.height = img.t();
+
+    switch (img.getPixelFormat())
+    {
+    case (GL_RGB):
+      WebPPictureImportRGB(&picture, img.data(), img.getRowSizeInBytes());
+      break;
+    case (GL_RGBA):
+      WebPPictureImportRGBA(&picture, img.data(), img.getRowSizeInBytes());
+      break;
+    case (GL_LUMINANCE):
+      WebPPictureImportRGBX(&picture, img.data(), img.getRowSizeInBytes());
+      break;
+    default:
+      return WriteResult::ERROR_IN_WRITING_FILE;
+      break;
+    }
+
+    switch (img.getPixelFormat())
+    {
+    case (GL_RGB):
+    case (GL_RGBA):
+      preset = WEBP_PRESET_PHOTO;
+      if (!WebPConfigPreset(&config, preset, config.quality))
+      {
+        return WriteResult::ERROR_IN_WRITING_FILE;
+      }
+
+      if (!WebPValidateConfig(&config))
+      {
+        return WriteResult::ERROR_IN_WRITING_FILE;
+      }
+
+      picture.writer = ReaderWriterWebP::ostream_writer;
+      picture.custom_ptr = (void *)&fout;
+      if (!WebPEncode(&config, &picture))
+      {
+        return WriteResult::ERROR_IN_WRITING_FILE;
+      }
+      break;
+    case (GL_LUMINANCE):
+      preset = WEBP_PRESET_DEFAULT;
+      if (!WebPConfigPreset(&config, preset, config.quality))
+      {
+        return WriteResult::ERROR_IN_WRITING_FILE;
+      }
+      config.lossless = 1;
+
+      if (!WebPValidateConfig(&config))
+      {
+        return WriteResult::ERROR_IN_WRITING_FILE;
+      }
+
+      picture.writer = ReaderWriterWebP::ostream_writer;
+      picture.custom_ptr = (void *)&fout;
+      if (!WebPEncode(&config, &picture))
+      {
+        return WriteResult::ERROR_IN_WRITING_FILE;
+      }
+      break;
+
+    default:
+      return WriteResult::ERROR_IN_WRITING_FILE;
+      break;
+    }
+
+    WebPPictureFree(&picture);
+    return WriteResult::FILE_SAVED;
+  }
+};
+
+// now register with Registry to instantiate the above
+// reader/writer.
+REGISTER_OSGPLUGIN(webp, ReaderWriterWebP)


=====================================
src/osgEarthUtil/GeodeticGraticule.cpp
=====================================
@@ -514,9 +514,11 @@ GeodeticGraticule::getViewExtent(osgUtil::CullVisitor* cullVisitor) const
     }
     else
     {
+        Horizon* h = Horizon::get(*cullVisitor);
         double f, a, zn, zf;
         proj.getPerspective(f,a,zn,zf);
-        zf = osg::minimum(zf, eye.length()-1000.0);
+        zf = h->getDistanceToVisibleHorizon();
+        zn = zf * cullVisitor->getNearFarRatio();
         proj.makePerspective(f, a, zn, zf);
 
         nearPlane = proj(3,2) / (proj(2,2)-1.0);


=====================================
src/osgEarthUtil/MGRSGraticule.cpp
=====================================
@@ -27,7 +27,6 @@
 #include <osgEarth/Registry>
 #include <osgEarth/PagedNode>
 #include <osgEarth/Endian>
-#include <osgEarth/LineDrawable>
 #include <osgEarth/GLUtils>
 #include <osgEarth/Text>
 
@@ -1061,7 +1060,7 @@ MGRSGraticule::rebuild()
         }
 
         // Root of the geometry tree
-        osg::Group* geomTop = new LineGroup(); //osg::Group();
+        osg::Group* geomTop = new osg::Group();
         top->addChild(geomTop);
 
         // Root of the text tree



View it on GitLab: https://salsa.debian.org/debian-gis-team/osgearth/commit/a258c9f1b2b484b5d334ccb369870b9cf51c6978

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/osgearth/commit/a258c9f1b2b484b5d334ccb369870b9cf51c6978
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20190712/9e75702b/attachment-0001.html>


More information about the Pkg-grass-devel mailing list