diff --git a/data/scene/debugglobe/textures/arrows.png b/data/scene/debugglobe/textures/arrows.png new file mode 100644 index 0000000000..d10df6684c Binary files /dev/null and b/data/scene/debugglobe/textures/arrows.png differ diff --git a/data/scene/globebrowsing.scene b/data/scene/globebrowsing.scene index df55b5969a..b20941da3d 100644 --- a/data/scene/globebrowsing.scene +++ b/data/scene/globebrowsing.scene @@ -41,7 +41,7 @@ return { ScenePath = ".", CommonFolder = "common", Camera = { - Focus = "LodMars", + Focus = "Mars", Position = {138530625167.228241, 42217005217.825005, -46336405755.934372}, Rotation = {0.633883, 0.492158, -0.123913, -0.583625}, }, diff --git a/data/scene/lodearth/lodearth.mod b/data/scene/lodearth/lodearth.mod index f348f51905..ca206ebeab 100644 --- a/data/scene/lodearth/lodearth.mod +++ b/data/scene/lodearth/lodearth.mod @@ -1,3 +1,4 @@ +earthEllipsoid = {6378137.0, 6378137.0, 6356752.314245} -- Earth's radii return { -- Earth barycenter module { @@ -6,7 +7,7 @@ return { Transform = { Translation = { Type = "SpiceEphemeris", - Body = "EARTH BARYCENTER", + Body = "EARTH", Reference = "ECLIPJ2000", Observer = "SUN", Kernels = { @@ -36,15 +37,6 @@ return { Name = "Earth", Parent = "EarthBarycenter", Transform = { - Translation = { - Type = "SpiceEphemeris", - Body = "EARTH", - Reference = "ECLIPJ2000", - Observer = "EARTH BARYCENTER", - Kernels = { - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" - } - }, Rotation = { Type = "SpiceRotation", SourceFrame = "IAU_EARTH", @@ -57,7 +49,7 @@ return { }, Renderable = { Type = "RenderableGlobe", - Radii = {6378137.0, 6378137.0, 6356752.314245}, -- Earth's radii + Radii = earthEllipsoid, CameraMinHeight = 300, InteractionDepthBelowEllipsoid = 0, -- Useful when having negative height map values SegmentsPerPatch = 64, @@ -121,12 +113,20 @@ return { Name = "Reference_Labels", FilePath = "map_service_configs/Reference_Labels.xml", }, + { + Type = "SizeReference", + Name = "Size Reference", + Radii = earthEllipsoid, + BackgroundImagePath = "../debugglobe/textures/arrows.png", + }, }, HeightMaps = { { Name = "Terrain tileset", FilePath = "map_service_configs/TERRAIN.wms", Enabled = true, + MinimumPixelSize = 90, + DoPreProcessing = true, }, }, HeightMapOverlays = { @@ -134,6 +134,6 @@ return { }, }, }, - GuiName = "/Solar/Planets/Earth" + GuiName = "/Solar/Planets/LodEarth" }, } \ No newline at end of file diff --git a/data/scene/lodmars/lodmars.mod b/data/scene/lodmars/lodmars.mod index 7e3072298b..c5f7f83b20 100644 --- a/data/scene/lodmars/lodmars.mod +++ b/data/scene/lodmars/lodmars.mod @@ -1,13 +1,9 @@ +local marsEllipsoid = {3396190.0, 3396190.0, 3376200.0} return { -- Mars barycenter module { Name = "MarsBarycenter", Parent = "SolarSystemBarycenter", - }, - -- RenderableGlobe module - { - Name = "Mars", - Parent = "MarsBarycenter", Transform = { Translation = { Type = "SpiceEphemeris", @@ -18,6 +14,13 @@ return { "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp" } }, + }, + }, + -- RenderableGlobe module + { + Name = "Mars", + Parent = "MarsBarycenter", + Transform = { Rotation = { Type = "SpiceRotation", SourceFrame = "IAU_MARS", @@ -30,7 +33,7 @@ return { }, Renderable = { Type = "RenderableGlobe", - Radii = {3396190.0, 3396190.0, 3376200.0}, -- Mars' radii + Radii = marsEllipsoid, CameraMinHeight = 1000, InteractionDepthBelowEllipsoid = 10000, -- Useful when having negative height map values SegmentsPerPatch = 90, @@ -49,7 +52,6 @@ return { { Name = "MARS_Viking_MDIM21", FilePath = "map_service_configs/MARS_Viking_MDIM21.xml", - Enabled = true, }, { Name = "Mars Viking Clr", @@ -74,11 +76,11 @@ return { }, }, NightTextures = { - { + --[[{ Name = "Mars Night Texture", FilePath = "map_datasets/MarsNight.vrt", Enabled = true, - }, + },]] }, WaterMasks = { @@ -88,21 +90,33 @@ return { Type = "ChunkIndex", Name = "Indices", }, + { + Type = "SizeReference", + Name = "Size Reference", + Radii = marsEllipsoid, + BackgroundImagePath = "../debugglobe/textures/arrows.png", + }, }, HeightMaps = { { Name = "Mola Elevation", FilePath = "map_service_configs/Mola_Elevation.xml", Enabled = true, + MinimumPixelSize = 90, + DoPreProcessing = true, }, { Name = "West_Candor_Chasma_DEM_longlat_global", FilePath = "map_datasets/West_Candor_Chasma_DEM_longlat_global.vrt", --Enabled = true, + MinimumPixelSize = 90, + DoPreProcessing = true, }, { Name = "Layered Rock Outcrops in Southwest Candor Chasma", FilePath = "map_datasets/Layered_Rock_Outcrops_in_Southwest_Candor_Chasma_DEM.vrt", + MinimumPixelSize = 90, + DoPreProcessing = true, }, }, HeightMapOverlays = { @@ -115,7 +129,7 @@ return { -- MarsTrail module { Name = "MarsTrail", - Parent = "MarsBarycenter", + Parent = "Sun", Renderable = { Type = "RenderableTrail", Body = "MARS BARYCENTER", diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 69353783a9..e73af3e486 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -50,10 +50,11 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.h - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/chunkindextileprovider.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/texttileprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/cachingtileprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.h + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tilediskcache.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.h @@ -62,7 +63,6 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileioresult.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctilereader.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovidermanager.h - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileproviderfactory.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextureshaderprovider.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextures.h ${CMAKE_CURRENT_SOURCE_DIR}/tile/pixelregion.h @@ -102,11 +102,11 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/singleimageprovider.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/chunkindextileprovider.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/texttileprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/cachingtileprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/temporaltileprovider.cpp - + ${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileselector.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tilediskcache.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tiledataset.cpp @@ -114,7 +114,6 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileioresult.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctilereader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovidermanager.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/tile/tileproviderfactory.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextureshaderprovider.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/layeredtextures.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tile/pixelregion.cpp diff --git a/modules/globebrowsing/geometry/ellipsoid.cpp b/modules/globebrowsing/geometry/ellipsoid.cpp index 2dc96f427d..6bd4c5a056 100644 --- a/modules/globebrowsing/geometry/ellipsoid.cpp +++ b/modules/globebrowsing/geometry/ellipsoid.cpp @@ -115,15 +115,20 @@ namespace openspace { sin(geodetic2.lat)); } - Vec3 Ellipsoid::radiiSquared() const { + const Vec3& Ellipsoid::radii() const { + return _radii; + } + + + const Vec3& Ellipsoid::radiiSquared() const { return _cached._radiiSquared; } - Vec3 Ellipsoid::oneOverRadiiSquared() const { + const Vec3& Ellipsoid::oneOverRadiiSquared() const { return _cached._oneOverRadiiSquared; } - Vec3 Ellipsoid::radiiToTheFourth() const { + const Vec3& Ellipsoid::radiiToTheFourth() const { return _cached._radiiToTheFourth; } @@ -139,6 +144,27 @@ namespace openspace { return (_radii.x + _radii.y + _radii.z) / 3.0; } + Scalar Ellipsoid::longitudalDistance(Scalar lat, Scalar lon1, Scalar lon2) const { + Vec2 ellipseRadii = glm::cos(lat) * _radii.xy(); + // Approximating with the ellipse mean radius + Scalar meanRadius = 0.5 * (ellipseRadii.x + ellipseRadii.y); + return meanRadius * std::abs(lon2 - lon1); + } + + Scalar Ellipsoid::greatCircleDistance(const Geodetic2& p1, const Geodetic2& p2) const{ + // https://en.wikipedia.org/wiki/Meridian_arc + // https://en.wikipedia.org/wiki/Great-circle_distance#Vector_version + + Vec3 n1 = geodeticSurfaceNormal(p1); + Vec3 n2 = geodeticSurfaceNormal(p2); + Scalar centralAngle = glm::atan(glm::length(glm::cross(n1, n2)) / glm::dot(n1, n2)); + + Geodetic2 pMid = (p1 + p2) / 2; + Vec3 centralNormal = cartesianSurfacePosition(pMid); + + return centralAngle * glm::length(centralNormal); + } + Geodetic2 Ellipsoid::cartesianToGeodetic2(const Vec3& p) const { Vec3 normal = geodeticSurfaceNormalForGeocentricallyProjectedPoint(p); diff --git a/modules/globebrowsing/geometry/ellipsoid.h b/modules/globebrowsing/geometry/ellipsoid.h index 041d729ccd..a65c3d00e8 100644 --- a/modules/globebrowsing/geometry/ellipsoid.h +++ b/modules/globebrowsing/geometry/ellipsoid.h @@ -76,14 +76,19 @@ public: Vec3 geodeticSurfaceNormalForGeocentricallyProjectedPoint(const Vec3& p) const; Vec3 geodeticSurfaceNormal(Geodetic2 geodetic2) const; - Vec3 radiiSquared() const; - Vec3 oneOverRadiiSquared() const; - Vec3 radiiToTheFourth() const; + const Vec3& radii() const; + const Vec3& radiiSquared() const; + const Vec3& oneOverRadiiSquared() const; + const Vec3& radiiToTheFourth() const; + Scalar minimumRadius() const; Scalar maximumRadius() const; Scalar averageRadius() const; + Scalar longitudalDistance(Scalar lat, Scalar lon1, Scalar lon2) const; + Scalar greatCircleDistance(const Geodetic2& p1, const Geodetic2& p2) const; + Geodetic2 cartesianToGeodetic2(const Vec3& p) const; Vec3 cartesianSurfacePosition(const Geodetic2& geodetic2) const; Vec3 cartesianPosition(const Geodetic3& geodetic3) const; diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index c4bdc00a2b..7f511f938b 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -30,8 +30,15 @@ #include #include +#include #include +#include +#include +#include +#include +#include + namespace openspace { @@ -40,28 +47,24 @@ namespace openspace { {} void GlobeBrowsingModule::internalInitialize() { - /* - auto fRenderable = FactoryManager::ref().factory(); - ghoul_assert(fRenderable, "Renderable factory was not created"); - - fRenderable->registerClass("Planet"); - fRenderable->registerClass("RenderableTestPlanet"); - //fRenderable->registerClass("PlanetTestGeometry"); - - auto fPlanetGeometry = FactoryManager::ref().factory(); - ghoul_assert(fPlanetGeometry, "Planet test geometry factory was not created"); - fPlanetGeometry->registerClass("SimpleSphereTest"); - - */ - - - - auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "Renderable factory was not created"); - fRenderable->registerClass("RenderableGlobe"); + + void addFactory(std::unique_ptr factory); + + // add Tile Provider factory + FactoryManager::ref().addFactory( + std::make_unique>()); + + auto fTileProvider = FactoryManager::ref().factory(); + fTileProvider->registerClass("LRUCaching"); + fTileProvider->registerClass("SingleImage"); + fTileProvider->registerClass("Temporal"); + fTileProvider->registerClass("ChunkIndex"); + fTileProvider->registerClass("SizeReference"); + } } // namespace openspace diff --git a/modules/globebrowsing/tile/tile.cpp b/modules/globebrowsing/tile/tile.cpp new file mode 100644 index 0000000000..a7489dfe60 --- /dev/null +++ b/modules/globebrowsing/tile/tile.cpp @@ -0,0 +1,72 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2016 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* 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. * +****************************************************************************************/ + +#include + +#include + +namespace { + const std::string _loggerCat = "Tile"; +} + + +namespace openspace { + + const Tile Tile::TileUnavailable = {nullptr, nullptr, Tile::Status::Unavailable }; + + + Tile Tile::createPlainTile(const glm::uvec2& size, const glm::uvec4& color) { + using namespace ghoul::opengl; + + // Create pixel data + int numBytes = size.x * size.y * 4 * 1; + char* pixels = new char[numBytes]; + size_t numPixels = size.x * size.y; + size_t i = 0; + for (size_t p = 0; p < numPixels; p++){ + pixels[i++] = color.r; + pixels[i++] = color.g; + pixels[i++] = color.b; + pixels[i++] = color.a; + } + + // Create ghoul texture + auto texture = std::make_shared(glm::uvec3(size, 1)); + texture->setDataOwnership(Texture::TakeOwnership::Yes); + texture->setPixelData(pixels); + texture->uploadTexture(); + texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + + // Create tile + Tile tile; + tile.status = Tile::Status::OK; + tile.preprocessData = nullptr; + tile.texture = texture; + + return tile; + } + + + +} // namespace openspace diff --git a/modules/globebrowsing/tile/tileproviderfactory.h b/modules/globebrowsing/tile/tile.h similarity index 71% rename from modules/globebrowsing/tile/tileproviderfactory.h rename to modules/globebrowsing/tile/tile.h index d963d42f93..9d3feaf409 100644 --- a/modules/globebrowsing/tile/tileproviderfactory.h +++ b/modules/globebrowsing/tile/tile.h @@ -22,40 +22,38 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __TILE_PROVIDER_FACTORY_H__ -#define __TILE_PROVIDER_FACTORY_H__ +#ifndef __TILE_H__ +#define __TILE_H__ +#include // Texture -#include - -#include - -#include -#include -#include +#include // TilePreprocessData namespace openspace { + + using namespace ghoul::opengl; - class TileProviderFactory { - public: + struct Tile { + std::shared_ptr texture; + std::shared_ptr preprocessData; - static std::shared_ptr ref(); + enum class Status { Unavailable, OutOfRange, IOError, OK } status; + + + /** + * Instantiaes a new tile unicolored tile. The texture gets the provided size and + * color in rgba. Color values ranges between 0-255. + */ + static Tile createPlainTile(const glm::uvec2& size, const glm::uvec4& color); - std::shared_ptr create(const std::string& type, const std::string& desc, const TileProviderInitData& initData); + static const Tile TileUnavailable; - private: - - TileProviderFactory(); - void initialize(); - - typedef std::function(const std::string&, const TileProviderInitData&)> ConcreteFactory; - - std::unordered_map _factoryMap; - - static std::shared_ptr _ref; }; - -} // namespace openspace -#endif // __TILE_PROVIDER_FACTORY_H__ \ No newline at end of file +} // namespace openspace + + + + +#endif // __TILE_H__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tiledataset.cpp b/modules/globebrowsing/tile/tiledataset.cpp index 161b37dc9f..66b8d897ff 100644 --- a/modules/globebrowsing/tile/tiledataset.cpp +++ b/modules/globebrowsing/tile/tiledataset.cpp @@ -473,7 +473,7 @@ namespace openspace { io.write.region.roundDownToQuadratic(); io.write.region.roundUpNumPixelToNearestMultipleOf(2); if (preRound != io.write.region.numPixels) { - LDEBUG(chunkIndex << " | " << preRound.x << ", " << preRound.y << " --> " << io.write.region.numPixels.x << ", " << io.write.region.numPixels.y); + //LDEBUG(chunkIndex << " | " << preRound.x << ", " << preRound.y << " --> " << io.write.region.numPixels.x << ", " << io.write.region.numPixels.y); } @@ -612,8 +612,8 @@ namespace openspace { } if (depth == 0) { - LDEBUG(indentation << "main rasterIO read: " << io.read.region); - LDEBUG(indentation << "main rasterIO write: " << io.write.region); + //LDEBUG(indentation << "main rasterIO read: " << io.read.region); + //LDEBUG(indentation << "main rasterIO write: " << io.write.region); } else if (worstError > CPLErr::CE_None) { diff --git a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp index defef66ff3..4e4bd7defb 100644 --- a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.cpp @@ -38,12 +38,69 @@ namespace { - const std::string _loggerCat = "TileProvider"; + const std::string _loggerCat = "CachingTileProvider"; + + const std::string KeyDoPreProcessing = "DoPreProcessing"; + const std::string KeyMinimumPixelSize = "MinimumPixelSize"; + const std::string KeyFilePath = "FilePath"; + const std::string KeyCacheSize = "CacheSize"; + const std::string KeyFlushInterval = "FlushInterval"; } namespace openspace { + CachingTileProvider::CachingTileProvider(const ghoul::Dictionary& dictionary) + : _framesSinceLastRequestFlush(0) + { + // + std::string name = "Name unspecified"; + dictionary.getValue("Name", name); + std::string _loggerCat = "CachingTileProvider : " + name; + + + // 1. Get required Keys + std::string filePath; + if (!dictionary.getValue(KeyFilePath, filePath)) { + throw std::runtime_error("Must define key '" + KeyFilePath + "'"); + } + + // 2. Initialize default values for any optional Keys + TileDataset::Configuration config; + config.doPreProcessing = false; + config.minimumTilePixelSize = 512; + + // getValue does not work for integers + double minimumPixelSize; + double cacheSize = 512; + double framesUntilRequestFlush = 60; + + // 3. Check for used spcified optional keys + if (dictionary.getValue(KeyDoPreProcessing, config.doPreProcessing)) { + LDEBUG("Default doPreProcessing overridden: " << config.doPreProcessing); + } + if (dictionary.getValue(KeyMinimumPixelSize, minimumPixelSize)) { + LDEBUG("Default minimumPixelSize overridden: " << minimumPixelSize); + config.minimumTilePixelSize = static_cast(minimumPixelSize); + } + if (dictionary.getValue(KeyCacheSize, cacheSize)) { + LDEBUG("Default cacheSize overridden: " << cacheSize); + } + if (dictionary.getValue(KeyFlushInterval, framesUntilRequestFlush)) { + LDEBUG("Default framesUntilRequestFlush overridden: " << framesUntilRequestFlush); + } + + + // Initialize instance variables + auto tileDataset = std::make_shared(filePath, config); + + // only one thread per provider supported atm + auto threadPool = std::make_shared(1); + + _asyncTextureDataProvider = std::make_shared(tileDataset, threadPool); + _tileCache = std::make_shared(cacheSize); + _framesUntilRequestFlush = framesUntilRequestFlush; + } CachingTileProvider::CachingTileProvider(std::shared_ptr tileReader, std::shared_ptr tileCache, diff --git a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h index f06c7e774b..5f569793e7 100644 --- a/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/cachingtileprovider.h @@ -25,7 +25,6 @@ #ifndef __CACHING_TILE_PROVIDER_H__ #define __CACHING_TILE_PROVIDER_H__ -#include #include #include // absPath @@ -51,6 +50,7 @@ namespace openspace { class CachingTileProvider : public TileProvider { public: + CachingTileProvider(const ghoul::Dictionary& dictionary); CachingTileProvider( std::shared_ptr tileReader, @@ -101,7 +101,6 @@ namespace openspace { int _framesSinceLastRequestFlush; int _framesUntilRequestFlush; - std::shared_ptr _asyncTextureDataProvider; }; diff --git a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.cpp b/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.cpp deleted file mode 100644 index b734b4e3d7..0000000000 --- a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* 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. * -****************************************************************************************/ - -#include - -#include - -#include -#include - -#include -#include - -#include - -#include - - - - -namespace { - const std::string _loggerCat = "TileProvider"; -} - - -namespace openspace { - - ChunkIndexTileProvider::ChunkIndexTileProvider(const glm::uvec2& textureSize, size_t fontSize) - : _tileCache(500) - , _textureSize(textureSize) - , _fontSize(fontSize) - { - using namespace ghoul::fontrendering; - - _font = OsEng.fontManager().font("Mono", _fontSize); - _fontRenderer = std::unique_ptr(FontRenderer::createDefault()); - _fontRenderer->setFramebufferSize(textureSize); - - - glGenFramebuffers(1, &_fbo); - } - - ChunkIndexTileProvider::~ChunkIndexTileProvider() { - glDeleteFramebuffers(1, &_fbo); - } - - Tile ChunkIndexTileProvider::getTile(const ChunkIndex& chunkIndex) { - ChunkHashKey key = chunkIndex.hashKey(); - - if (!_tileCache.exist(key)) { - _tileCache.put(key, createChunkIndexTile(chunkIndex)); - } - - return _tileCache.get(key); - } - - Tile ChunkIndexTileProvider::getDefaultTile() { - return Tile::TileUnavailable; - } - - - Tile::Status ChunkIndexTileProvider::getTileStatus(const ChunkIndex& index) { - return Tile::Status::OK; - } - - TileDepthTransform ChunkIndexTileProvider::depthTransform() { - TileDepthTransform transform; - transform.depthOffset = 0.0f; - transform.depthScale = 1.0f; - return transform; - } - - void ChunkIndexTileProvider::update() { - // nothing to be done - } - - void ChunkIndexTileProvider::reset() { - _tileCache.clear(); - } - - Tile ChunkIndexTileProvider::createChunkIndexTile(const ChunkIndex& chunkIndex) { - glm::uvec4 color = { 0, 0, 0, 0 }; - Tile tile = Tile::createPlainTile(_textureSize, color); - - // Keep track of defaultFBO and viewport to be able to reset state when done - GLint defaultFBO; - GLint viewport[4]; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); - glGetIntegerv(GL_VIEWPORT, viewport); - - // Render to texture - glBindFramebuffer(GL_FRAMEBUFFER, _fbo); - glFramebufferTexture2D( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - *(tile.texture), - 0 - ); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - //LDEBUG(status); - - glViewport( - 0, 0, - static_cast(tile.texture->width()), - static_cast(tile.texture->height()) - ); - - _fontRenderer->render( - *_font, - glm::vec2( - _textureSize.x / 4 - (_textureSize.x / 32) * log10(1 << chunkIndex.level), - _textureSize.y / 2 + _fontSize), - glm::vec4(1.0, 0.0, 0.0, 1.0), - "level: %i \nx: %i \ny: %i", - chunkIndex.level, chunkIndex.x, chunkIndex.y - ); - - // Reset state: bind default FBO and set viewport to what it was - glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); - - return tile; - } - - - int ChunkIndexTileProvider::maxLevel() { - return 1337; // unlimited - } - - -} // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp b/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp index 4642dc7e1c..b7e8b010f0 100644 --- a/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/singleimageprovider.cpp @@ -38,44 +38,54 @@ namespace { const std::string _loggerCat = "SingleImageProvider"; + + const std::string KeyFilePath = "FilePath"; } namespace openspace { + SingleImageProvider::SingleImageProvider(const ghoul::Dictionary& dictionary) { + // Required input + if (!dictionary.getValue(KeyFilePath, _imagePath)) { + throw std::runtime_error("Must define key '" + KeyFilePath + "'"); + } + + reset(); + } - SingleImagePrivoder::SingleImagePrivoder(const std::string& imagePath) + SingleImageProvider::SingleImageProvider(const std::string& imagePath) : _imagePath(imagePath) { reset(); } - Tile SingleImagePrivoder::getTile(const ChunkIndex& chunkIndex) { + Tile SingleImageProvider::getTile(const ChunkIndex& chunkIndex) { return _tile; } - Tile SingleImagePrivoder::getDefaultTile() { + Tile SingleImageProvider::getDefaultTile() { return _tile; } - Tile::Status SingleImagePrivoder::getTileStatus(const ChunkIndex& index) { + Tile::Status SingleImageProvider::getTileStatus(const ChunkIndex& index) { return _tile.status; } - TileDepthTransform SingleImagePrivoder::depthTransform() { + TileDepthTransform SingleImageProvider::depthTransform() { TileDepthTransform transform; transform.depthOffset = 0.0f; transform.depthScale = 1.0f; return transform; } - void SingleImagePrivoder::update() { + void SingleImageProvider::update() { // nothing to be done } - void SingleImagePrivoder::reset() { + void SingleImageProvider::reset() { _tile = Tile(); _tile.texture = std::shared_ptr(ghoul::io::TextureReader::ref().loadTexture(_imagePath).release()); _tile.status = _tile.texture != nullptr ? Tile::Status::OK : Tile::Status::IOError; @@ -85,7 +95,7 @@ namespace openspace { _tile.texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); } - int SingleImagePrivoder::maxLevel() { + int SingleImageProvider::maxLevel() { return 1337; // unlimited } diff --git a/modules/globebrowsing/tile/tileprovider/singleimageprovider.h b/modules/globebrowsing/tile/tileprovider/singleimageprovider.h index 817562c2fa..dd8143e7b9 100644 --- a/modules/globebrowsing/tile/tileprovider/singleimageprovider.h +++ b/modules/globebrowsing/tile/tileprovider/singleimageprovider.h @@ -49,10 +49,12 @@ namespace openspace { using namespace ghoul::opengl; - class SingleImagePrivoder : public TileProvider { + class SingleImageProvider : public TileProvider { public: - SingleImagePrivoder(const std::string& imagePath); - virtual ~SingleImagePrivoder() { } + + SingleImageProvider(const ghoul::Dictionary& dictionary); + SingleImageProvider(const std::string& imagePath); + virtual ~SingleImageProvider() { } virtual Tile getTile(const ChunkIndex& chunkIndex); virtual Tile getDefaultTile(); diff --git a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp index 4adaef4a26..567d22572f 100644 --- a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.cpp @@ -25,7 +25,8 @@ #include #include -#include +#include + #include @@ -46,6 +47,12 @@ namespace { const std::string _loggerCat = "TemporalTileProvider"; + + const std::string KeyDoPreProcessing = "DoPreProcessing"; + const std::string KeyMinimumPixelSize = "MinimumPixelSize"; + const std::string KeyFilePath = "FilePath"; + const std::string KeyCacheSize = "CacheSize"; + const std::string KeyFlushInterval = "FlushInterval"; } @@ -53,16 +60,21 @@ namespace openspace { const std::string TemporalTileProvider::TIME_PLACEHOLDER("${OpenSpaceTimeId}"); - TemporalTileProvider::TemporalTileProvider(const std::string& datasetFile, - const TileProviderInitData& tileProviderInitData) - : _datasetFile(datasetFile) - , _tileProviderInitData(tileProviderInitData) + + TemporalTileProvider::TemporalTileProvider(const ghoul::Dictionary& dictionary) + : _initDict(dictionary) { - std::ifstream in(datasetFile.c_str()); - ghoul_assert(errno == 0, strerror(errno) << std::endl << datasetFile); + + if (!dictionary.getValue(KeyFilePath, _datasetFile)) { + throw std::runtime_error("Must define key '" + KeyFilePath + "'"); + } + + + std::ifstream in(_datasetFile.c_str()); + ghoul_assert(errno == 0, strerror(errno) << std::endl << _datasetFile); // read file - std::string xml( (std::istreambuf_iterator(in)), (std::istreambuf_iterator())); + std::string xml((std::istreambuf_iterator(in)), (std::istreambuf_iterator())); _gdalXmlTemplate = consumeTemporalMetaData(xml); _defaultTile = getTileProvider()->getDefaultTile(); } @@ -185,7 +197,8 @@ namespace openspace { std::shared_ptr TemporalTileProvider::initTileProvider(TimeKey timekey) { std::string gdalDatasetXml = getGdalDatasetXML(timekey); - return TileProviderFactory::ref()->create("LRUCaching", gdalDatasetXml, _tileProviderInitData); + _initDict.setValue(KeyFilePath, gdalDatasetXml); + return std::make_shared(_initDict); } std::string TemporalTileProvider::getGdalDatasetXML(Time t) { diff --git a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h index 211becda87..d53ec668f9 100644 --- a/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/temporaltileprovider.h @@ -27,6 +27,7 @@ #include +#include #include #include @@ -102,8 +103,7 @@ namespace openspace { class TemporalTileProvider : public TileProvider { public: - TemporalTileProvider(const std::string& datasetFile, const TileProviderInitData& tileProviderInitData); - + TemporalTileProvider(const ghoul::Dictionary& dictionary); // These methods implements TileProvider @@ -143,16 +143,20 @@ namespace openspace { // Members variables // ////////////////////////////////////////////////////////////////////////////////// - const std::string _datasetFile; + std::string _datasetFile; std::string _gdalXmlTemplate; std::unordered_map > _tileProviderMap; - TileProviderInitData _tileProviderInitData; + + // Used for creation of time specific instances of CachingTileProvider + ghoul::Dictionary _initDict; + Tile _defaultTile; std::shared_ptr _currentTileProvider; + TimeFormat * _timeFormat; TimeQuantizer _timeQuantizer; }; diff --git a/modules/globebrowsing/tile/tileprovider/texttileprovider.cpp b/modules/globebrowsing/tile/tileprovider/texttileprovider.cpp new file mode 100644 index 0000000000..39b070b628 --- /dev/null +++ b/modules/globebrowsing/tile/tileprovider/texttileprovider.cpp @@ -0,0 +1,274 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2016 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* 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. * +****************************************************************************************/ + +#include + +#include + +#include +#include + +#include +#include + +#include + +#include + + + + +namespace { + const std::string _loggerCat = "TextTileProvider"; +} + + +namespace openspace { + + TextTileProvider::TextTileProvider(const glm::uvec2& textureSize, size_t fontSize) + : _tileCache(500) + , _textureSize(textureSize) + , _fontSize(fontSize) + { + + _font = OsEng.fontManager().font("Mono", _fontSize); + + _fontRenderer = std::unique_ptr(FontRenderer::createDefault()); + _fontRenderer->setFramebufferSize(textureSize); + + + glGenFramebuffers(1, &_fbo); + } + + TextTileProvider::~TextTileProvider() { + glDeleteFramebuffers(1, &_fbo); + } + + Tile TextTileProvider::getTile(const ChunkIndex& chunkIndex) { + ChunkHashKey key = chunkIndex.hashKey(); + + if (!_tileCache.exist(key)) { + _tileCache.put(key, createChunkIndexTile(chunkIndex)); + } + + return _tileCache.get(key); + } + + Tile TextTileProvider::getDefaultTile() { + return Tile::TileUnavailable; + } + + + Tile::Status TextTileProvider::getTileStatus(const ChunkIndex& index) { + return Tile::Status::OK; + } + + TileDepthTransform TextTileProvider::depthTransform() { + TileDepthTransform transform; + transform.depthOffset = 0.0f; + transform.depthScale = 1.0f; + return transform; + } + + void TextTileProvider::update() { + // nothing to be done + } + + void TextTileProvider::reset() { + _tileCache.clear(); + } + + Tile TextTileProvider::createChunkIndexTile(const ChunkIndex& chunkIndex) { + Tile tile = backgroundTile(chunkIndex); + + // Keep track of defaultFBO and viewport to be able to reset state when done + GLint defaultFBO; + GLint viewport[4]; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + glGetIntegerv(GL_VIEWPORT, viewport); + + // Render to texture + glBindFramebuffer(GL_FRAMEBUFFER, _fbo); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + *(tile.texture), + 0 + ); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + //LDEBUG(status); + + glViewport( + 0, 0, + static_cast(tile.texture->width()), + static_cast(tile.texture->height()) + ); + + ghoul_assert(_fontRenderer != nullptr, "_fontRenderer must not be null"); + renderText(*_fontRenderer, chunkIndex); + + // Reset state: bind default FBO and set viewport to what it was + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + return tile; + } + + int TextTileProvider::maxLevel() { + return 1337; // unlimited + } + + ChunkHashKey TextTileProvider::toHash(const ChunkIndex& chunkIndex) const { + return chunkIndex.hashKey(); + } + + + Tile TextTileProvider::backgroundTile(const ChunkIndex& chunkIndex) const { + glm::uvec4 color = { 0, 0, 0, 0 }; + return Tile::createPlainTile(_textureSize, color); + } + + + ////////////////////////////////////////////////////////////////////////////////////// + // Chunk Index Tile Provider // + ////////////////////////////////////////////////////////////////////////////////////// + + void ChunkIndexTileProvider::renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const { + fontRenderer.render( + *_font, + glm::vec2( + _textureSize.x / 4 - (_textureSize.x / 32) * log10(1 << chunkIndex.level), + _textureSize.y / 2 + _fontSize), + glm::vec4(1.0, 0.0, 0.0, 1.0), + "level: %i \nx: %i \ny: %i", + chunkIndex.level, chunkIndex.x, chunkIndex.y + ); + } + + ////////////////////////////////////////////////////////////////////////////////////// + // Tile Size Reference Tile Provider // + ////////////////////////////////////////////////////////////////////////////////////// + + namespace { + const std::string KeyRadii = "Radii"; + const std::string KeyBackgroundImagePath = "BackgroundImagePath"; + } + + SizeReferenceTileProvider::SizeReferenceTileProvider(const ghoul::Dictionary& dictionary) { + _fontSize = 50; + ghoul::fontrendering::FontManager& fm = OsEng.fontManager(); + _font = fm.font("Mono", _fontSize); + + glm::dvec3 radii(1,1,1); + if (!dictionary.getValue(KeyRadii, radii)) { + throw std::runtime_error("Must define key '" + KeyRadii + "'"); + } + _ellipsoid = Ellipsoid(radii); + + _backgroundTile.status = Tile::Status::Unavailable; + std::string backgroundImagePath; + if (dictionary.getValue(KeyBackgroundImagePath, backgroundImagePath)) { + using namespace ghoul::io; + std::string imgAbsPath = absPath(backgroundImagePath); + _backgroundTile.texture = TextureReader::ref().loadTexture(imgAbsPath); + _backgroundTile.texture->uploadTexture(); + _backgroundTile.texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); + _backgroundTile.status = Tile::Status::OK; + } + + } + + void SizeReferenceTileProvider::renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const { + GeodeticPatch patch(chunkIndex); + bool aboveEquator = patch.isNorthern(); + + double tileLongitudalLength = roundedLongitudalLength(chunkIndex); + + std::string unit = "m"; + if (tileLongitudalLength > 9999) { + tileLongitudalLength *= 0.001; + unit = "km"; + } + + glm::vec2 textPosition; + textPosition.x = 0; + textPosition.y = aboveEquator ? _fontSize / 2 : _textureSize.y - 3 * _fontSize / 2; + glm::vec4 color(1.0, 1.0, 1.0, 1.0); + + fontRenderer.render( + *_font, + textPosition, + color, + " %.0f %s", + tileLongitudalLength, unit.c_str() + ); + } + + int SizeReferenceTileProvider::roundedLongitudalLength(const ChunkIndex& chunkIndex) const { + GeodeticPatch patch(chunkIndex); + bool aboveEquator = patch.isNorthern(); + double lat = aboveEquator ? patch.minLat() : patch.maxLat(); + double lon1 = patch.minLon(); + double lon2 = patch.maxLon(); + int l = static_cast(_ellipsoid.longitudalDistance(lat, lon1, lon2)); + + bool useKm = l > 9999; + if (useKm) l /= 1000; + l = std::round(l); + if (useKm) l *= 1000; + + return l; + } + + ChunkHashKey SizeReferenceTileProvider::toHash(const ChunkIndex& chunkIndex) const { + int l = roundedLongitudalLength(chunkIndex); + ChunkHashKey key = static_cast(l); + return key; + } + + Tile SizeReferenceTileProvider::backgroundTile(const ChunkIndex& chunkIndex) const { + if (_backgroundTile.status == Tile::Status::OK) { + Tile tile; + auto t = _backgroundTile.texture; + void* pixelData = new char[t->expectedPixelDataSize()]; + memcpy(pixelData, t->pixelData(), t->expectedPixelDataSize()); + tile.texture = std::make_shared( + pixelData, t->dimensions(), t->format(), t->internalFormat(), t->dataType(), t->filter(), t->wrapping()); + tile.texture->uploadTexture(); + tile.texture->setDataOwnership(Texture::TakeOwnership::Yes); + tile.status = Tile::Status::OK; + return tile; + } + else { + // use default background + return TextTileProvider::backgroundTile(chunkIndex); + } + } + + + + +} // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h b/modules/globebrowsing/tile/tileprovider/texttileprovider.h similarity index 60% rename from modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h rename to modules/globebrowsing/tile/tileprovider/texttileprovider.h index 5e8215d985..fe2d7bf065 100644 --- a/modules/globebrowsing/tile/tileprovider/chunkindextileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/texttileprovider.h @@ -22,8 +22,10 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __CHUNK_INDEX_TILE_PROVIDER_H__ -#define __CHUNK_INDEX_TILE_PROVIDER_H__ +#ifndef __TEXT_TILE_PROVIDER_H__ +#define __TEXT_TILE_PROVIDER_H__ + +#include #include #include // absPath @@ -37,6 +39,7 @@ #include #include #include +#include ////////////////////////////////////////////////////////////////////////////////////////// @@ -45,12 +48,22 @@ namespace openspace { - - - class ChunkIndexTileProvider : public TileProvider { + using namespace ghoul::fontrendering; + + /** + * This abstract class implements the TilProvider interface and enables a simple way + * of providing tiles with any type of rendered text. + * Internally it handles setting up a FBO for rendering the text, and defines a new + * interface, consisting of only a single method for subclasses to implement: + * \code renderText(const FontRenderer&, const ChunkIndex&) const \endcode + */ + class TextTileProvider : public TileProvider { public: - ChunkIndexTileProvider(const glm::uvec2& textureSize = {512, 512}, size_t fontSize = 48); - virtual ~ChunkIndexTileProvider(); + + TextTileProvider(const glm::uvec2& textureSize = {512, 512}, size_t fontSize = 48); + virtual ~TextTileProvider(); + + // The TileProvider interface below is implemented in this class virtual Tile getTile(const ChunkIndex& chunkIndex); virtual Tile getDefaultTile(); @@ -59,24 +72,60 @@ namespace openspace { virtual void update(); virtual void reset(); virtual int maxLevel(); - private: - Tile createChunkIndexTile(const ChunkIndex& chunkIndex); - std::shared_ptr _font; - std::unique_ptr _fontRenderer; + // Returns the tile which will be used to draw text onto. + // Default implementation returns a tile with a plain transparent texture. + virtual Tile backgroundTile(const ChunkIndex& chunkIndex) const; + + // Default implementation uses ChunkIndex::hashKey() + virtual ChunkHashKey toHash(const ChunkIndex& chunkIndex) const; - TileCache _tileCache; + // This method is pure and should be implemented by subclasses + virtual void renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const = 0; + + protected: + std::shared_ptr _font; glm::uvec2 _textureSize; size_t _fontSize; - - GLuint _fbo; + private: + Tile createChunkIndexTile(const ChunkIndex& chunkIndex); + std::unique_ptr _fontRenderer; + + TileCache _tileCache; + GLuint _fbo; }; + /** + * Provides \class Tiles with the chunk index rendered as text onto its tiles. + */ + class ChunkIndexTileProvider : public TextTileProvider { + public: + virtual void renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const; + }; + + + class SizeReferenceTileProvider : public TextTileProvider { + public: + SizeReferenceTileProvider(const ghoul::Dictionary& dictionary); + + virtual void renderText(const FontRenderer& fontRenderer, const ChunkIndex& chunkIndex) const; + virtual Tile backgroundTile(const ChunkIndex& chunkIndex) const; + + virtual ChunkHashKey toHash(const ChunkIndex& chunkIndex) const; + + + private: + + int roundedLongitudalLength(const ChunkIndex& chunkIndex) const; + + Ellipsoid _ellipsoid; + Tile _backgroundTile; + }; } // namespace openspace -#endif // __CHUNK_INDEX_TILE_PROVIDER_H__ \ No newline at end of file +#endif // __TEXT_TILE_PROVIDER_H__ \ No newline at end of file diff --git a/modules/globebrowsing/tile/tileprovider/tileprovider.cpp b/modules/globebrowsing/tile/tileprovider/tileprovider.cpp index 387e95d1a5..9e2af512ac 100644 --- a/modules/globebrowsing/tile/tileprovider/tileprovider.cpp +++ b/modules/globebrowsing/tile/tileprovider/tileprovider.cpp @@ -22,72 +22,42 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include - #include -#include +#include -#include - -#include - -#include -#include #include -#include -#include - -#include - -#include - -#include - - namespace { const std::string _loggerCat = "TileProvider"; + + const std::string KeyType = "Type"; } namespace openspace { - const Tile Tile::TileUnavailable = {nullptr, nullptr, Tile::Status::Unavailable }; - - - Tile Tile::createPlainTile(const glm::uvec2& size, const glm::uvec4& color) { - using namespace ghoul::opengl; - - // Create pixel data - int numBytes = size.x * size.y * 4 * 1; - char* pixels = new char[numBytes]; - size_t numPixels = size.x * size.y; - size_t i = 0; - for (size_t p = 0; p < numPixels; p++){ - pixels[i++] = color.r; - pixels[i++] = color.g; - pixels[i++] = color.b; - pixels[i++] = color.a; - } - - // Create ghoul texture - auto texture = std::make_shared(glm::uvec3(size, 1)); - texture->setDataOwnership(Texture::TakeOwnership::Yes); - texture->setPixelData(pixels); - texture->uploadTexture(); - texture->setFilter(ghoul::opengl::Texture::FilterMode::Linear); - - // Create tile - Tile tile; - tile.status = Tile::Status::OK; - tile.preprocessData = nullptr; - tile.texture = texture; - - return tile; +TileProvider* TileProvider::createFromDictionary(const ghoul::Dictionary& dictionary) { + if (!dictionary.hasValue(KeyType)) { + LERROR("TileProvider did not have key '" << KeyType << "'"); + return nullptr; } + std::string type; + dictionary.getValue(KeyType, type); + ghoul::TemplateFactory* factory + = FactoryManager::ref().factory(); + TileProvider* result = factory->create(type, dictionary); + if (result == nullptr) { + LERROR("Failed creating Ephemeris object of type '" << type << "'"); + return nullptr; + } + + return result; +} + +TileProvider::TileProvider(const ghoul::Dictionary& dictionary) { }; } // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovider/tileprovider.h b/modules/globebrowsing/tile/tileprovider/tileprovider.h index 31a4f5c99e..36ff0c15cc 100644 --- a/modules/globebrowsing/tile/tileprovider/tileprovider.h +++ b/modules/globebrowsing/tile/tileprovider/tileprovider.h @@ -26,55 +26,31 @@ #define __TILE_PROVIDER_H__ -#include -#include - -#include #include // absPath #include -#include -#include +#include #include - -#include - - +#include #include ////////////////////////////////////////////////////////////////////////////////////////// -// TILE PROVIDER // +// TILE PROVIDER // ////////////////////////////////////////////////////////////////////////////////////////// namespace openspace { -class TilePreprocessData; - - // TODO: Remove using directive in header file ---abock using namespace ghoul::opengl; - - - struct Tile { - std::shared_ptr texture; - std::shared_ptr preprocessData; - - enum class Status { Unavailable, OutOfRange, IOError, OK } status; - - /** - * Instantiaes a new tile unicolored tile. The texture gets the provided size and - * color in rgba. Color values ranges between 0-255. - */ - static Tile createPlainTile(const glm::uvec2& size, const glm::uvec4& color); - - static const Tile TileUnavailable; - - }; - class TileProvider { public: + static TileProvider* createFromDictionary(const ghoul::Dictionary& dictionary); + + TileProvider() {}; + TileProvider(const ghoul::Dictionary& dictionary); + virtual ~TileProvider() { } virtual Tile getTile(const ChunkIndex& chunkIndex) = 0; diff --git a/modules/globebrowsing/tile/tileproviderfactory.cpp b/modules/globebrowsing/tile/tileproviderfactory.cpp deleted file mode 100644 index c1a88c4d22..0000000000 --- a/modules/globebrowsing/tile/tileproviderfactory.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* 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. * -****************************************************************************************/ - -#include -#include - -#include -#include -#include -#include - -#include - -#include "cpl_minixml.h" - - -namespace { - const std::string _loggerCat = "TileProviderFactory"; -} - - -namespace openspace { - - std::shared_ptr TileProviderFactory::_ref = nullptr; - - - TileProviderFactory::TileProviderFactory() { - initialize(); - } - - - std::shared_ptr TileProviderFactory::ref() { - if (_ref == nullptr) { - // Need to explicitly use new here, since constructor is private - TileProviderFactory* ptr = new TileProviderFactory(); - _ref = std::shared_ptr(ptr); - } - return _ref; - } - - std::shared_ptr TileProviderFactory::create(const std::string& type, - const std::string& desc, const TileProviderInitData& initData) - { - auto concreteFactoryIterator = _factoryMap.find(type); - - if (concreteFactoryIterator == _factoryMap.end()) { - LERROR("Unknown type: " << type); - return nullptr; - } - - std::shared_ptr tileProvider; - - try { - tileProvider = concreteFactoryIterator->second(desc, initData); - } - catch (const std::exception& e) { - LERROR(e.what()); - } - catch (...) { - LERROR("Could not open dataset:\n" << desc << "\n"); - } - return tileProvider; - } - - void TileProviderFactory::initialize() { - _factoryMap.insert({"LRUCaching", [](const std::string& desc, const TileProviderInitData& initData) { - TileDataset::Configuration config; - config.doPreProcessing = initData.preprocessTiles; - config.minimumTilePixelSize = initData.minimumPixelSize; - - auto tileDataset = std::make_shared(desc, config); - auto threadPool = std::make_shared(1); - auto tileReader = std::make_shared(tileDataset, threadPool); - auto tileCache = std::make_shared(initData.cacheSize); - auto tileProvider = std::make_shared(tileReader, tileCache, initData.framesUntilRequestQueueFlush); - return tileProvider; - }}); - - _factoryMap.insert({ "Temporal", [](const std::string& file, const TileProviderInitData& initData) { - CPLXMLNode * node = CPLParseXMLFile(file.c_str()); - if (!node) { - throw ghoul::RuntimeError("Unable to parse file:\n" + file); - } - if (std::string(node->pszValue) == "OpenSpaceTemporalGDALDataset") { - auto tileProvider = std::make_shared(file, initData); - return tileProvider; - } - }}); - - _factoryMap.insert({ "SingleImage", [](const std::string& file, const TileProviderInitData& initData) { - auto tileProvider = std::make_shared(file); - return tileProvider; - } }); - - _factoryMap.insert({ "ChunkIndex", [](const std::string& file, const TileProviderInitData& initData) { - auto tileProvider = std::make_shared(); - return tileProvider; - } }); - } - - -} // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovidermanager.cpp b/modules/globebrowsing/tile/tileprovidermanager.cpp index 90faed250b..43dba6486e 100644 --- a/modules/globebrowsing/tile/tileprovidermanager.cpp +++ b/modules/globebrowsing/tile/tileprovidermanager.cpp @@ -22,9 +22,9 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +#include + #include -#include -#include #include @@ -134,16 +134,18 @@ namespace openspace { std::string type = "LRUCaching"; // if type is unspecified texDict.getValue("Type", type); - - std::shared_ptr tileProvider = TileProviderFactory::ref()->create(type, path, initData); + + auto tileProviderFactory = FactoryManager::ref().factory(); + TileProvider* tileProvider = tileProviderFactory->create(type, texDict); if (tileProvider == nullptr) { + LERROR("Unable to create TileProvider '" << name << "' of type '" << type << "'"); continue; } bool enabled = false; // defaults to false if unspecified texDict.getValue("Enabled", enabled); - dest.push_back({ name, tileProvider, enabled }); + dest.push_back({ name, std::shared_ptr(tileProvider), enabled }); } } diff --git a/openspace.cfg b/openspace.cfg index 09d68485d9..b612a364f0 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -13,7 +13,7 @@ return { -- Scene = "${SCENE}/rosetta.scene", -- Scene = "${SCENE}/dawn.scene", -- Scene = "${SCENE}/newhorizons.scene", - Scene = "${SCENE}/osirisrex.scene", + Scene = "${SCENE}/osirisrex.scene", Paths = { SGCT = "${BASE_PATH}/config/sgct", diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index af047bb2e4..ba677c900b 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -432,6 +432,9 @@ bool OpenSpaceEngine::initialize() { _settingsEngine->initialize(); _settingsEngine->setModules(_moduleEngine->modules()); + // Load a light and a monospaced font + loadFonts(); + // Initialize the Scene Scene* sceneGraph = new Scene; sceneGraph->initialize(); @@ -453,8 +456,6 @@ bool OpenSpaceEngine::initialize() { // Run start up scripts runPreInitializationScripts(scenePath); - // Load a light and a monospaced font - loadFonts(); #ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED LINFO("Initializing GUI"); diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index f1bf90b1aa..21abed382e 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -795,7 +795,9 @@ void InteractionHandler::postSynchronizationPreDraw() { } else { _currentInteractionMode->updateCameraStateFromMouseStates(*_camera); - _camera->setFocusPositionVec3(focusNode()->worldPosition()); + if(focusNode() != nullptr){ + _camera->setFocusPositionVec3(focusNode()->worldPosition()); + } } } diff --git a/src/scene/scenegraph.cpp b/src/scene/scenegraph.cpp index 3f4f6469e6..4c84157a54 100644 --- a/src/scene/scenegraph.cpp +++ b/src/scene/scenegraph.cpp @@ -310,6 +310,7 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { element.getValue(SceneGraphNode::KeyParentName, parentName); FileSys.setCurrentDirectory(modulePath); + LDEBUGC("Create from dictionary", "Node name: " << nodeName << " Parent name:" << parentName << " Path: " << modulePath); SceneGraphNode* node = SceneGraphNode::createFromDictionary(element); if (node == nullptr) { LERROR("Error loading SceneGraphNode '" << nodeName << "' in module '" << moduleName << "'"); @@ -344,6 +345,7 @@ bool SceneGraph::loadFromFile(const std::string& sceneDescription) { }; for (const ModuleInformation& i : moduleDictionaries) { + LINFO("Adding module: " << i.moduleName); addModule(i); } }