mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-08 12:30:00 -05:00
Merge branch 'feature/globebrowsing' of https://github.com/OpenSpace/OpenSpace into feature/globebrowsing
This commit is contained in:
@@ -57,8 +57,18 @@ return {
|
||||
Layers = {
|
||||
ColorLayers = {
|
||||
{
|
||||
Name = "ESRI Imagery World 2D",
|
||||
FilePath = "map_service_configs/ESRI/ESRI_Imagery_World_2D.wms",
|
||||
Name = "ESRI VIIRS Combo",
|
||||
Type = "ByLevel",
|
||||
LevelTileProviders = {
|
||||
{
|
||||
MaxLevel = 7,
|
||||
TileProvider = { FilePath = "map_service_configs/GIBS/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml", },
|
||||
},
|
||||
{
|
||||
MaxLevel = 22,
|
||||
TileProvider = { FilePath = "map_service_configs/ESRI/ESRI_Imagery_World_2D.wms" },
|
||||
},
|
||||
},
|
||||
Enabled = true,
|
||||
},
|
||||
{
|
||||
@@ -71,15 +81,10 @@ return {
|
||||
Name = "Temporal_GHRSST_L4_MUR_Sea_Surface_Temperature",
|
||||
FilePath = "map_service_configs/GIBS/Temporal_GHRSST_L4_MUR_Sea_Surface_Temperature.xml",
|
||||
},
|
||||
{
|
||||
Name = "VIIRS_SNPP_CorrectedReflectance_TrueColor",
|
||||
FilePath = "map_service_configs/GIBS/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml",
|
||||
Enabled = true,
|
||||
},
|
||||
{
|
||||
Type = "SingleImage",
|
||||
Name = "Debug Tiles",
|
||||
FilePath = "textures/test_tile.png",
|
||||
FilePath = "../../debugglobe/textures/test_tile.png",
|
||||
},
|
||||
},
|
||||
GrayScaleLayers = { },
|
||||
@@ -111,12 +116,30 @@ return {
|
||||
Name = "Reference_Labels",
|
||||
FilePath = "map_service_configs/GIBS/Reference_Labels.xml",
|
||||
},
|
||||
{
|
||||
Type = "TileIndex",
|
||||
Name = "Tile Indices",
|
||||
},
|
||||
{
|
||||
Type = "SizeReference",
|
||||
Name = "Size Reference",
|
||||
Radii = earthEllipsoid,
|
||||
BackgroundImagePath = "../../debugglobe/textures/arrows.png",
|
||||
},
|
||||
--[[{
|
||||
Name = "Test",
|
||||
Type = "LevelSpecific",
|
||||
LevelTileProviders = {
|
||||
{
|
||||
MaxLevel = 5,
|
||||
TileProvider = { Type = "TileIndex" },
|
||||
},
|
||||
{
|
||||
MaxLevel = 7,
|
||||
TileProvider = { Type = "SingleImage", FilePath = "../../debugglobe/textures/test_tile.png",},
|
||||
},
|
||||
},
|
||||
},]]
|
||||
},
|
||||
HeightLayers = {
|
||||
{
|
||||
|
||||
@@ -65,7 +65,10 @@ public:
|
||||
// Interaction mode setters
|
||||
void setCameraStateFromDictionary(const ghoul::Dictionary& cameraDict);
|
||||
void setInteractionMode(const std::string& interactionModeKey);
|
||||
|
||||
|
||||
void goToChunk(int x, int y, int level);
|
||||
void goToGeo(double latitude, double longitude);
|
||||
|
||||
void resetKeyBindings();
|
||||
|
||||
void addKeyframe(const datamessagestructures::CameraKeyframe &kf);
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#include <openspace/util/mouse.h>
|
||||
#include <openspace/util/keys.h>
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
#include <modules/globebrowsing/tile/tileindex.h>
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#endif
|
||||
|
||||
#include <list>
|
||||
|
||||
@@ -258,7 +262,15 @@ public:
|
||||
virtual void setFocusNode(SceneGraphNode* focusNode);
|
||||
//virtual void update(Camera& camera, const InputState& inputState, double deltaTime);
|
||||
virtual void updateCameraStateFromMouseStates(Camera& camera, double deltaTime);
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
void goToChunk(Camera& camera, globebrowsing::TileIndex ti, glm::vec2 uv,
|
||||
bool resetCameraDirection);
|
||||
void goToGeodetic2(Camera& camera, globebrowsing::Geodetic2 geo2,
|
||||
bool resetCameraDirection);
|
||||
|
||||
void goToGeodetic3(Camera& camera, globebrowsing::Geodetic3 geo3);
|
||||
void resetCameraDirection(Camera& camera, globebrowsing::Geodetic2 geo2);
|
||||
#endif
|
||||
private:
|
||||
//void updateCameraStateFromMouseStates(Camera& camera, double deltaTime);
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
|
||||
@@ -50,6 +50,8 @@ set(HEADER_FILES
|
||||
${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/tileprovider/tileproviderbylevel.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbyindex.h
|
||||
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tilepile.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.h
|
||||
@@ -102,6 +104,8 @@ set(SOURCE_FILES
|
||||
${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/tileprovider/tileproviderbylevel.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbyindex.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tilepile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tile/chunktile.cpp
|
||||
|
||||
@@ -149,6 +149,11 @@ namespace globebrowsing {
|
||||
}
|
||||
}
|
||||
|
||||
Geodetic2 GeodeticPatch::getSize() const {
|
||||
return _halfSize * 2;
|
||||
}
|
||||
|
||||
|
||||
Scalar GeodeticPatch::minLat() const {
|
||||
return _center.lat - _halfSize.lat;
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ public:
|
||||
Scalar isNorthern() const;
|
||||
|
||||
Geodetic2 getCorner(Quad q) const;
|
||||
Geodetic2 getSize() const;
|
||||
|
||||
Scalar minLat() const;
|
||||
Scalar maxLat() const;
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include <modules/globebrowsing/tile/tileprovider/singleimageprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/temporaltileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/texttileprovider.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileproviderbylevel.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileproviderbyindex.h>
|
||||
|
||||
|
||||
namespace openspace {
|
||||
@@ -65,6 +67,10 @@ void GlobeBrowsingModule::internalInitialize() {
|
||||
fTileProvider->registerClass<globebrowsing::TemporalTileProvider>("Temporal");
|
||||
fTileProvider->registerClass<globebrowsing::TileIndexTileProvider>("TileIndex");
|
||||
fTileProvider->registerClass<globebrowsing::SizeReferenceTileProvider>("SizeReference");
|
||||
|
||||
// Combining Tile Providers
|
||||
fTileProvider->registerClass<globebrowsing::TileProviderByLevel>("ByLevel");
|
||||
fTileProvider->registerClass<globebrowsing::TileProviderByIndex>("ByIndex");
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace globebrowsing {
|
||||
for (const auto& layer : heightMapLayers) {
|
||||
TileProvider* tileProvider = layer->tileProvider();
|
||||
// Transform the uv coordinates to the current tile texture
|
||||
ChunkTile chunkTile = TileSelector::getHighestResolutionTile(tileProvider, tileIndex);
|
||||
ChunkTile chunkTile = tileProvider->getChunkTile(tileIndex);
|
||||
const auto& tile = chunkTile.tile;
|
||||
const auto& uvTransform = chunkTile.uvTransform;
|
||||
const auto& depthTransform = tileProvider->depthTransform();
|
||||
|
||||
@@ -80,7 +80,8 @@ namespace globebrowsing {
|
||||
properties::BoolProperty("levelByProjectedAreaElseDistance", "level by projected area (else distance)",false),
|
||||
properties::BoolProperty("resetTileProviders", "reset tile providers", false),
|
||||
properties::BoolProperty("toggleEnabledEveryFrame", "toggle enabled every frame", false),
|
||||
properties::BoolProperty("collectStats", "collect stats", false)
|
||||
properties::BoolProperty("collectStats", "collect stats", false),
|
||||
properties::BoolProperty("onlyModelSpaceRendering", "Only Model Space Rendering", false)
|
||||
})
|
||||
|
||||
{
|
||||
@@ -144,6 +145,7 @@ namespace globebrowsing {
|
||||
_debugPropertyOwner.addProperty(_debugProperties.resetTileProviders);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.toggleEnabledEveryFrame);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.collectStats);
|
||||
_debugPropertyOwner.addProperty(_debugProperties.onlyModelSpaceRendering);
|
||||
|
||||
addPropertySubOwner(_debugPropertyOwner);
|
||||
addPropertySubOwner(_layerManager.get());
|
||||
|
||||
@@ -73,6 +73,7 @@ public:
|
||||
properties::BoolProperty resetTileProviders;
|
||||
properties::BoolProperty toggleEnabledEveryFrame;
|
||||
properties::BoolProperty collectStats;
|
||||
properties::BoolProperty onlyModelSpaceRendering;
|
||||
};
|
||||
|
||||
struct GeneralProperties {
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace globebrowsing {
|
||||
|
||||
void ChunkRenderer::renderChunk(const Chunk& chunk, const RenderData& data) {
|
||||
// A little arbitrary with 10 but it works
|
||||
if (chunk.tileIndex().level < 10) {
|
||||
if (chunk.owner().debugProperties().onlyModelSpaceRendering || chunk.tileIndex().level < 10) {
|
||||
renderChunkGlobally(chunk, data);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -83,11 +83,8 @@ namespace globebrowsing {
|
||||
|
||||
}
|
||||
|
||||
ChunkTilePile Layer::getChunkTilePile(
|
||||
const TileIndex& tileIndex,
|
||||
int pileSize) const {
|
||||
return std::move(TileSelector::getHighestResolutionTilePile(
|
||||
_tileProvider.get(), tileIndex, pileSize));
|
||||
ChunkTilePile Layer::getChunkTilePile(const TileIndex& tileIndex, int pileSize) const {
|
||||
return std::move(_tileProvider->getChunkTilePile(tileIndex, pileSize));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -30,7 +30,7 @@ Fragment getFragment() {
|
||||
frag.color = getTileFragColor();
|
||||
|
||||
#if SHOW_CHUNK_EDGES
|
||||
frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.005);
|
||||
frag.color += patchBorderOverlay(fs_uv, vec3(0,1,0), 0.02);
|
||||
#endif // SHOW_CHUNK_EDGES
|
||||
|
||||
frag.depth = fs_position.w;
|
||||
|
||||
@@ -25,10 +25,16 @@
|
||||
#include <modules/globebrowsing/tile/tileindex.h>
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
|
||||
#include <ghoul/misc/dictionary.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "TileIndex";
|
||||
|
||||
const std::string KeyLevel = "Level";
|
||||
const std::string KeyX = "X";
|
||||
const std::string KeyY = "Y";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -50,6 +56,15 @@ namespace globebrowsing {
|
||||
y = floor(yIndexSpace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a TileIndex from a Dictionary
|
||||
*/
|
||||
TileIndex::TileIndex(const ghoul::Dictionary& dict){
|
||||
level = static_cast<int>(dict.value<double>(KeyLevel));
|
||||
x = static_cast<int>(dict.value<double>(KeyX));
|
||||
y = static_cast<int>(dict.value<double>(KeyY));
|
||||
}
|
||||
|
||||
TileIndex TileIndex::child(Quad q) const {
|
||||
return TileIndex(2 * x + q % 2, 2 * y + q / 2, level + 1);
|
||||
}
|
||||
@@ -79,6 +94,12 @@ namespace globebrowsing {
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
glm::vec2 TileIndex::positionRelativeParent() const{
|
||||
// In OpenGL, positive y direction is up
|
||||
return glm::vec2(isEastChild() ? 0.5 : 0, isNorthChild() ? 0.5 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
Gets the tile at a specified offset from this tile.
|
||||
Accepts delta indices ranging from [-2^level, Infinity[
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ghoul{
|
||||
class Dictionary;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace globebrowsing {
|
||||
|
||||
@@ -59,6 +63,7 @@ struct TileIndex {
|
||||
TileIndex(int x, int y, int level) : x(x), y(y), level(level) { }
|
||||
TileIndex(const TileIndex& other) : x(other.x), y(other.y), level(other.level) { }
|
||||
TileIndex(const Geodetic2& point, int level);
|
||||
TileIndex(const ghoul::Dictionary& dict);
|
||||
|
||||
|
||||
bool hasParent() const {
|
||||
@@ -72,24 +77,26 @@ struct TileIndex {
|
||||
|
||||
TileIndex& operator-=(unsigned int levels);
|
||||
|
||||
bool isWestChild() const {
|
||||
inline bool isWestChild() const {
|
||||
return x % 2 == 0;
|
||||
}
|
||||
|
||||
bool isEastChild() const {
|
||||
inline bool isEastChild() const {
|
||||
return x % 2 == 1;
|
||||
}
|
||||
|
||||
bool isNorthChild() const {
|
||||
inline bool isNorthChild() const {
|
||||
return y % 2 == 0;
|
||||
}
|
||||
|
||||
bool isSouthChild() const {
|
||||
inline bool isSouthChild() const {
|
||||
return y % 2 == 1;
|
||||
}
|
||||
|
||||
TileIndex child(Quad q) const;
|
||||
|
||||
glm::vec2 positionRelativeParent() const;
|
||||
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <openspace/engine/downloadmanager.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h> // abspath
|
||||
|
||||
#include <openspace/util/time.h>
|
||||
|
||||
@@ -108,8 +109,17 @@ namespace globebrowsing {
|
||||
throw ghoul::RuntimeError("Invalid Time Format " + timeIdFormat + " in " + _datasetFile);
|
||||
}
|
||||
|
||||
std::string gdalDescription;
|
||||
CPLXMLNode* gdalNode = CPLSearchXMLNode(node, "GDAL_WMS");
|
||||
return CPLSerializeXMLTree(gdalNode);
|
||||
if (gdalNode) {
|
||||
gdalDescription = CPLSerializeXMLTree(gdalNode);
|
||||
}
|
||||
if (!gdalNode) {
|
||||
CPLXMLNode* gdalNode = CPLSearchXMLNode(node, "FilePath");
|
||||
gdalDescription = std::string(gdalNode->psChild->pszValue);
|
||||
}
|
||||
|
||||
return gdalDescription;
|
||||
}
|
||||
|
||||
std::string TemporalTileProvider::getXMLValue(CPLXMLNode* root, const std::string& key, const std::string& defaultVal) {
|
||||
@@ -155,7 +165,10 @@ namespace globebrowsing {
|
||||
}
|
||||
|
||||
void TemporalTileProvider::update() {
|
||||
_currentTileProvider = getTileProvider();
|
||||
auto newCurrent = getTileProvider();
|
||||
if (newCurrent) {
|
||||
_currentTileProvider = newCurrent;
|
||||
}
|
||||
_currentTileProvider->update();
|
||||
}
|
||||
|
||||
@@ -198,7 +211,8 @@ namespace globebrowsing {
|
||||
std::shared_ptr<TileProvider> TemporalTileProvider::initTileProvider(TimeKey timekey) {
|
||||
std::string gdalDatasetXml = getGdalDatasetXML(timekey);
|
||||
_initDict.setValue<std::string>(KeyFilePath, gdalDatasetXml);
|
||||
return std::make_shared<CachingTileProvider>(_initDict);
|
||||
auto tileProvider = std::make_shared<CachingTileProvider>(_initDict);
|
||||
return tileProvider;
|
||||
}
|
||||
|
||||
std::string TemporalTileProvider::getGdalDatasetXML(Time t) {
|
||||
@@ -222,9 +236,15 @@ namespace globebrowsing {
|
||||
return t.ISO8601().substr(0, 10);
|
||||
}
|
||||
|
||||
std::string YYYY_MM_DDThh_mm_ssZ::stringify(const Time& t) const {
|
||||
std::string YYYY_MM_DDThhColonmmColonssZ::stringify(const Time& t) const {
|
||||
return t.ISO8601().substr(0, 19) + "Z";
|
||||
}
|
||||
|
||||
std::string YYYY_MM_DDThh_mm_ssZ::stringify(const Time& t) const {
|
||||
std::string timeString = t.ISO8601().substr(0, 19) + "Z";
|
||||
replace( timeString.begin(), timeString.end(), ':', '_' );
|
||||
return timeString;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Time Id Providers Facotry //
|
||||
@@ -237,7 +257,9 @@ namespace globebrowsing {
|
||||
void TimeIdProviderFactory::init() {
|
||||
_timeIdProviderMap.insert(
|
||||
std::pair<std::string, std::unique_ptr<TimeFormat> >( "YYYY-MM-DD", std::make_unique<YYYY_MM_DD>() ));
|
||||
_timeIdProviderMap.insert(std::pair<std::string, std::unique_ptr<TimeFormat> > ( "YYYY-MM-DDThh:mm:ssZ", std::make_unique<YYYY_MM_DDThh_mm_ssZ>() ));
|
||||
_timeIdProviderMap.insert(std::pair<std::string, std::unique_ptr<TimeFormat> > ( "YYYY-MM-DDThh:mm:ssZ", std::make_unique<YYYY_MM_DDThhColonmmColonssZ>() ));
|
||||
initialized = true;
|
||||
_timeIdProviderMap.insert(std::pair<std::string, std::unique_ptr<TimeFormat> > ( "YYYY-MM-DDThh_mm_ssZ", std::make_unique<YYYY_MM_DDThh_mm_ssZ>() ));
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,14 @@ namespace globebrowsing {
|
||||
* Stringifies OpenSpace to the format "YYYY-MM-DDThh:mm:ssZ"
|
||||
* Example: 2016-09-08T23:05:05Z
|
||||
*/
|
||||
struct YYYY_MM_DDThhColonmmColonssZ : public TimeFormat {
|
||||
virtual std::string stringify(const Time& t) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stringifies OpenSpace to the format "YYYY-MM-DDThh:mm:ssZ"
|
||||
* Example: 2016-09-08T23:05:05Z
|
||||
*/
|
||||
struct YYYY_MM_DDThh_mm_ssZ : public TimeFormat {
|
||||
virtual std::string stringify(const Time& t) const;
|
||||
};
|
||||
@@ -312,4 +320,4 @@ namespace globebrowsing {
|
||||
} // namespace globebrowsing
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __TEMPORAL_TILE_PROVIDER_H__
|
||||
#endif // __TEMPORAL_TILE_PROVIDER_H__
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
|
||||
#include <openspace/util/factorymanager.h>
|
||||
#include <modules/globebrowsing/tile/chunktile.h>
|
||||
#include <modules/globebrowsing/tile/tileselector.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
@@ -61,5 +63,65 @@ float TileProvider::noDataValueAsFloat() {
|
||||
return std::numeric_limits<float>::min();
|
||||
}
|
||||
|
||||
ChunkTile TileProvider::getChunkTile(TileIndex tileIndex, int parents, int maxParents){
|
||||
TileUvTransform uvTransform;
|
||||
uvTransform.uvOffset = glm::vec2(0, 0);
|
||||
uvTransform.uvScale = glm::vec2(1, 1);
|
||||
|
||||
// Step 1. Traverse 0 or more parents up the chunkTree as requested by the caller
|
||||
for (int i = 0; i < parents && tileIndex.level > 1; i++) {
|
||||
TileSelector::ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
maxParents -= parents;
|
||||
|
||||
// Step 2. Traverse 0 or more parents up the chunkTree to make sure we're inside
|
||||
// the range of defined data.
|
||||
int maximumLevel = maxLevel();
|
||||
while(tileIndex.level > maximumLevel){
|
||||
TileSelector::ascendToParent(tileIndex, uvTransform);
|
||||
maxParents--;
|
||||
}
|
||||
if(maxParents < 0){
|
||||
return{ Tile::TileUnavailable, uvTransform };
|
||||
}
|
||||
|
||||
// Step 3. Traverse 0 or more parents up the chunkTree until we find a chunk that
|
||||
// has a loaded tile ready to use.
|
||||
while (tileIndex.level > 1) {
|
||||
Tile tile = getTile(tileIndex);
|
||||
if (tile.status != Tile::Status::OK) {
|
||||
if(--maxParents < 0){
|
||||
return{ Tile::TileUnavailable, uvTransform };
|
||||
}
|
||||
TileSelector::ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
else return { tile, uvTransform };
|
||||
}
|
||||
|
||||
return{ Tile::TileUnavailable, uvTransform };
|
||||
}
|
||||
|
||||
ChunkTilePile TileProvider::getChunkTilePile(TileIndex tileIndex, int pileSize){
|
||||
ghoul_assert(pileSize >= 0, "pileSize must be positive");
|
||||
ChunkTilePile chunkTilePile;
|
||||
chunkTilePile.chunkTiles.resize(pileSize);
|
||||
for (size_t i = 0; i < pileSize; ++i){
|
||||
chunkTilePile.chunkTiles[i] = getChunkTile(tileIndex, i);
|
||||
if (chunkTilePile.chunkTiles[i].tile.status == Tile::Status::Unavailable) {
|
||||
if(i>0){
|
||||
chunkTilePile.chunkTiles[i].tile = chunkTilePile.chunkTiles[i-1].tile;
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvOffset = chunkTilePile.chunkTiles[i-1].uvTransform.uvOffset;
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvScale = chunkTilePile.chunkTiles[i-1].uvTransform.uvScale;
|
||||
}
|
||||
else{
|
||||
chunkTilePile.chunkTiles[i].tile = getDefaultTile();
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvOffset = { 0, 0 };
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvScale = { 1, 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::move(chunkTilePile);
|
||||
}
|
||||
|
||||
} // namespace globebrowsing
|
||||
} // namespace openspace
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
|
||||
namespace openspace {
|
||||
namespace globebrowsing {
|
||||
|
||||
class ChunkTile;
|
||||
class ChunkTilePile;
|
||||
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
@@ -96,6 +99,13 @@ namespace globebrowsing {
|
||||
*/
|
||||
virtual Tile getTile(const TileIndex& tileIndex) = 0;
|
||||
|
||||
|
||||
virtual ChunkTile getChunkTile(TileIndex tileIndex, int parents = 0, int maxParents = 1337);
|
||||
|
||||
|
||||
virtual ChunkTilePile getChunkTilePile(TileIndex tileIndex, int pileSize);
|
||||
|
||||
|
||||
/**
|
||||
* TileProviders must be able to provide a defualt
|
||||
* <code>Tile</code> which may be used by clients in cases when
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileproviderbyindex.h>
|
||||
#include <modules/globebrowsing/tile/tileindex.h>
|
||||
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "TileProviderByIndex";
|
||||
|
||||
const std::string KeyDefaultProvider = "DefaultProvider";
|
||||
const std::string KeyProviders = "IndexTileProviders";
|
||||
const std::string KeyTileIndex = "TileIndex";
|
||||
const std::string KeyTileProvider = "TileProvider";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace globebrowsing {
|
||||
|
||||
TileProviderByIndex::TileProviderByIndex(const ghoul::Dictionary& dictionary) {
|
||||
ghoul::Dictionary defaultProviderDict = dictionary.value<ghoul::Dictionary>(KeyDefaultProvider);
|
||||
TileProvider * defaultProvider = TileProvider::createFromDictionary(defaultProviderDict);
|
||||
_defaultTileProvider = std::shared_ptr<TileProvider>(defaultProvider);
|
||||
|
||||
ghoul::Dictionary indexProvidersDict = dictionary.value<ghoul::Dictionary>(KeyProviders);
|
||||
for (size_t i = 0; i < indexProvidersDict.size(); i++) {
|
||||
std::string dictKey = std::to_string(i + 1);
|
||||
ghoul::Dictionary indexProviderDict = indexProvidersDict.value<ghoul::Dictionary>(dictKey);
|
||||
ghoul::Dictionary tileIndexDict = indexProviderDict.value<ghoul::Dictionary>(KeyTileIndex);
|
||||
ghoul::Dictionary providerDict = indexProviderDict.value<ghoul::Dictionary>(KeyTileProvider);
|
||||
|
||||
TileIndex tileIndex(tileIndexDict);
|
||||
TileProvider* tileProvider = TileProvider::createFromDictionary(providerDict);
|
||||
std::shared_ptr<TileProvider> stp = std::shared_ptr<TileProvider>(tileProvider);
|
||||
TileHashKey key = tileIndex.hashKey();
|
||||
_tileProviderMap.insert(std::make_pair(key, stp));
|
||||
}
|
||||
}
|
||||
|
||||
Tile TileProviderByIndex::getTile(const TileIndex& tileIndex) {
|
||||
auto it = _tileProviderMap.find(tileIndex.hashKey());
|
||||
bool hasProvider = it != _tileProviderMap.end();
|
||||
return hasProvider ? it->second->getTile(tileIndex) : Tile::TileUnavailable;
|
||||
}
|
||||
|
||||
Tile TileProviderByIndex::getDefaultTile() {
|
||||
return _defaultTileProvider->getDefaultTile();
|
||||
}
|
||||
|
||||
Tile::Status TileProviderByIndex::getTileStatus(const TileIndex& tileIndex) {
|
||||
auto it = _tileProviderMap.find(tileIndex.hashKey());
|
||||
bool hasProvider = it != _tileProviderMap.end();
|
||||
return hasProvider ? it->second->getTileStatus(tileIndex) : Tile::Status::Unavailable;
|
||||
}
|
||||
|
||||
TileDepthTransform TileProviderByIndex::depthTransform() {
|
||||
_defaultTileProvider->depthTransform();
|
||||
}
|
||||
|
||||
void TileProviderByIndex::update() {
|
||||
for(auto it : _tileProviderMap){
|
||||
it.second->update();
|
||||
}
|
||||
_defaultTileProvider->update();
|
||||
}
|
||||
|
||||
void TileProviderByIndex::reset() {
|
||||
for(auto it : _tileProviderMap){
|
||||
it.second->reset();
|
||||
}
|
||||
_defaultTileProvider->reset();
|
||||
}
|
||||
|
||||
int TileProviderByIndex::maxLevel() {
|
||||
return _defaultTileProvider->maxLevel();
|
||||
}
|
||||
|
||||
TileProvider* TileProviderByIndex::indexProvider(const TileIndex& tileIndex) const{
|
||||
auto it = _tileProviderMap.find(tileIndex.hashKey());
|
||||
return (it != _tileProviderMap.end()) ? it->second.get() : nullptr;
|
||||
}
|
||||
|
||||
} // namespace globebrowsing
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,75 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __TILE_PROVIDER_BY_INDEX__
|
||||
#define __TILE_PROVIDER_BY_INDEX__
|
||||
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/tile/asynctilereader.h>
|
||||
|
||||
#include <gdal_priv.h>
|
||||
|
||||
#include <openspace/engine/downloadmanager.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h> // absPath
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace openspace {
|
||||
namespace globebrowsing {
|
||||
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
class TileProviderByIndex : public TileProvider {
|
||||
public:
|
||||
|
||||
TileProviderByIndex(const ghoul::Dictionary& dictionary);
|
||||
TileProviderByIndex(const std::string& imagePath);
|
||||
virtual ~TileProviderByIndex() { }
|
||||
|
||||
virtual Tile getTile(const TileIndex& tileIndex);
|
||||
virtual Tile getDefaultTile();
|
||||
virtual Tile::Status getTileStatus(const TileIndex& index);
|
||||
virtual TileDepthTransform depthTransform();
|
||||
virtual void update();
|
||||
virtual void reset();
|
||||
virtual int maxLevel();
|
||||
|
||||
private:
|
||||
|
||||
inline TileProvider* indexProvider(const TileIndex& tileIndex) const;
|
||||
|
||||
std::unordered_map<TileHashKey, std::shared_ptr<TileProvider>> _tileProviderMap;
|
||||
std::shared_ptr<TileProvider> _defaultTileProvider;
|
||||
};
|
||||
|
||||
} // namespace globebrowsing
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __TILE_PROVIDER_BY_INDEX__
|
||||
@@ -0,0 +1,129 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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 <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileproviderbylevel.h>
|
||||
#include <modules/globebrowsing/tile/tileindex.h>
|
||||
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "TileProviderByLevel";
|
||||
|
||||
const std::string KeyProviders = "LevelTileProviders";
|
||||
const std::string KeyMaxLevel = "MaxLevel";
|
||||
const std::string KeyTileProvider = "TileProvider";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
namespace globebrowsing {
|
||||
|
||||
TileProviderByLevel::TileProviderByLevel(const ghoul::Dictionary& dictionary) {
|
||||
|
||||
ghoul::Dictionary levelProvidersDict = dictionary.value<ghoul::Dictionary>(KeyProviders);
|
||||
for (size_t i = 0; i < levelProvidersDict.size(); i++) {
|
||||
std::string dictKey = std::to_string(i + 1);
|
||||
ghoul::Dictionary levelProviderDict = levelProvidersDict.value<ghoul::Dictionary>(dictKey);
|
||||
double floatMaxLevel;
|
||||
int maxLevel = 0;
|
||||
if (!levelProviderDict.getValue<double>(KeyMaxLevel, floatMaxLevel)) {
|
||||
throw std::runtime_error("Must define key '" + KeyMaxLevel + "'");
|
||||
}
|
||||
maxLevel = std::round(floatMaxLevel);
|
||||
|
||||
ghoul::Dictionary providerDict;
|
||||
if (!levelProviderDict.getValue<ghoul::Dictionary>(KeyTileProvider, providerDict)) {
|
||||
throw std::runtime_error("Must define key '" + KeyTileProvider + "'");
|
||||
}
|
||||
|
||||
TileProvider* tileProvider = TileProvider::createFromDictionary(providerDict);
|
||||
_levelTileProviders.push_back(std::shared_ptr<TileProvider>(tileProvider));
|
||||
|
||||
// Ensure we can represent the max level
|
||||
if(_providerIndices.size() < maxLevel){
|
||||
_providerIndices.resize(maxLevel+1, -1);
|
||||
}
|
||||
|
||||
// map this level to the tile provider index
|
||||
_providerIndices[maxLevel] = _levelTileProviders.size() - 1;
|
||||
}
|
||||
|
||||
// Fill in the gaps (value -1) in provider indices, from back to end
|
||||
for(int i = _providerIndices.size() - 2; i>=0; --i){
|
||||
if(_providerIndices[i] == -1){
|
||||
_providerIndices[i] = _providerIndices[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tile TileProviderByLevel::getTile(const TileIndex& tileIndex) {
|
||||
return levelProvider(tileIndex.level)->getTile(tileIndex);
|
||||
}
|
||||
|
||||
Tile TileProviderByLevel::getDefaultTile() {
|
||||
return levelProvider(0)->getDefaultTile();
|
||||
}
|
||||
|
||||
Tile::Status TileProviderByLevel::getTileStatus(const TileIndex& index) {
|
||||
return levelProvider(index.level)->getTileStatus(index);
|
||||
}
|
||||
|
||||
TileDepthTransform TileProviderByLevel::depthTransform() {
|
||||
TileDepthTransform transform;
|
||||
transform.depthOffset = 0.0f;
|
||||
transform.depthScale = 1.0f;
|
||||
return transform;
|
||||
}
|
||||
|
||||
void TileProviderByLevel::update() {
|
||||
for(auto provider : _levelTileProviders){
|
||||
provider->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TileProviderByLevel::reset() {
|
||||
for(auto provider : _levelTileProviders){
|
||||
provider->reset();
|
||||
}
|
||||
}
|
||||
|
||||
int TileProviderByLevel::maxLevel() {
|
||||
return _providerIndices.size()-1;
|
||||
}
|
||||
|
||||
int TileProviderByLevel::providerIndex(int level) const {
|
||||
int clampedLevel = std::max(0, std::min(level, (int)_providerIndices.size()-1));
|
||||
return _providerIndices[clampedLevel];
|
||||
}
|
||||
|
||||
TileProvider* TileProviderByLevel::levelProvider(int level) const{
|
||||
return _levelTileProviders[providerIndex(level)].get();
|
||||
}
|
||||
|
||||
} // namespace globebrowsing
|
||||
} // namespace openspace
|
||||
@@ -0,0 +1,74 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __TILE_PROVIDER_BY_LEVEL__
|
||||
#define __TILE_PROVIDER_BY_LEVEL__
|
||||
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
|
||||
#include <modules/globebrowsing/tile/asynctilereader.h>
|
||||
|
||||
#include <gdal_priv.h>
|
||||
|
||||
#include <openspace/engine/downloadmanager.h>
|
||||
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h> // absPath
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/font/fontrenderer.h>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace openspace {
|
||||
namespace globebrowsing {
|
||||
|
||||
using namespace ghoul::opengl;
|
||||
|
||||
class TileProviderByLevel : public TileProvider {
|
||||
public:
|
||||
|
||||
TileProviderByLevel(const ghoul::Dictionary& dictionary);
|
||||
TileProviderByLevel(const std::string& imagePath);
|
||||
virtual ~TileProviderByLevel() { }
|
||||
|
||||
virtual Tile getTile(const TileIndex& tileIndex);
|
||||
virtual Tile getDefaultTile();
|
||||
virtual Tile::Status getTileStatus(const TileIndex& index);
|
||||
virtual TileDepthTransform depthTransform();
|
||||
virtual void update();
|
||||
virtual void reset();
|
||||
virtual int maxLevel();
|
||||
private:
|
||||
inline int providerIndex(int level) const;
|
||||
inline TileProvider* levelProvider(int level) const;
|
||||
|
||||
std::vector<int> _providerIndices;
|
||||
std::vector<std::shared_ptr<TileProvider>> _levelTileProviders;
|
||||
};
|
||||
|
||||
} // namespace globebrowsing
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __TILE_PROVIDER_BY_LEVEL__
|
||||
@@ -42,65 +42,13 @@ namespace globebrowsing {
|
||||
|
||||
const TileSelector::CompareResolution TileSelector::HIGHEST_RES = TileSelector::CompareResolution();
|
||||
|
||||
ChunkTilePile TileSelector::getHighestResolutionTilePile(TileProvider* tileProvider, TileIndex tileIndex, int pileSize){
|
||||
ghoul_assert(pileSize >= 0, "pileSize must be positive");
|
||||
ChunkTilePile chunkTilePile;
|
||||
chunkTilePile.chunkTiles.resize(pileSize);
|
||||
for (size_t i = 0; i < pileSize; ++i){
|
||||
chunkTilePile.chunkTiles[i] = TileSelector::getHighestResolutionTile(tileProvider, tileIndex, i);
|
||||
if (chunkTilePile.chunkTiles[i].tile.status == Tile::Status::Unavailable) {
|
||||
if(i>0){
|
||||
chunkTilePile.chunkTiles[i].tile = chunkTilePile.chunkTiles[i-1].tile;
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvOffset = chunkTilePile.chunkTiles[i-1].uvTransform.uvOffset;
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvScale = chunkTilePile.chunkTiles[i-1].uvTransform.uvScale;
|
||||
}
|
||||
else{
|
||||
chunkTilePile.chunkTiles[i].tile = tileProvider->getDefaultTile();
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvOffset = { 0, 0 };
|
||||
chunkTilePile.chunkTiles[i].uvTransform.uvScale = { 1, 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::move(chunkTilePile);
|
||||
}
|
||||
|
||||
ChunkTile TileSelector::getHighestResolutionTile(TileProvider* tileProvider, TileIndex tileIndex, int parents) {
|
||||
TileUvTransform uvTransform;
|
||||
uvTransform.uvOffset = glm::vec2(0, 0);
|
||||
uvTransform.uvScale = glm::vec2(1, 1);
|
||||
|
||||
// Step 1. Traverse 0 or more parents up the chunkTree as requested by the caller
|
||||
for (int i = 0; i < parents && tileIndex.level > 1; i++) {
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
|
||||
// Step 2. Traverse 0 or more parents up the chunkTree to make sure we're inside
|
||||
// the range of defined data.
|
||||
int maximumLevel = tileProvider->maxLevel();
|
||||
while(tileIndex.level > maximumLevel){
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
|
||||
// Step 3. Traverse 0 or more parents up the chunkTree until we find a chunk that
|
||||
// has a loaded tile ready to use.
|
||||
while (tileIndex.level > 1) {
|
||||
Tile tile = tileProvider->getTile(tileIndex);
|
||||
if (tile.status != Tile::Status::OK) {
|
||||
ascendToParent(tileIndex, uvTransform);
|
||||
}
|
||||
else return { tile, uvTransform };
|
||||
}
|
||||
|
||||
return{ Tile::TileUnavailable, uvTransform };
|
||||
}
|
||||
|
||||
ChunkTile TileSelector::getHighestResolutionTile(const LayerGroup& layerGroup, TileIndex tileIndex) {
|
||||
ChunkTile mostHighResolution;
|
||||
mostHighResolution.tile = Tile::TileUnavailable;
|
||||
mostHighResolution.uvTransform.uvScale.x = 0;
|
||||
|
||||
for (const auto& layer : layerGroup.activeLayers()) {
|
||||
ChunkTile chunkTile = getHighestResolutionTile(layer->tileProvider(), tileIndex);
|
||||
ChunkTile chunkTile = layer->tileProvider()->getChunkTile(tileIndex);
|
||||
bool tileIsOk = chunkTile.tile.status == Tile::Status::OK;
|
||||
bool tileHasMetaData = chunkTile.tile.metaData != nullptr;
|
||||
bool tileIsHigherResolution = chunkTile.uvTransform.uvScale.x > mostHighResolution.uvTransform.uvScale.x;
|
||||
@@ -120,7 +68,7 @@ namespace globebrowsing {
|
||||
std::vector<ChunkTile> TileSelector::getTilesSortedByHighestResolution(const LayerGroup& layerGroup, const TileIndex& tileIndex) {
|
||||
std::vector<ChunkTile> tiles;
|
||||
for (const auto& layer : layerGroup.activeLayers()) {
|
||||
tiles.push_back(getHighestResolutionTile(layer->tileProvider(), tileIndex));
|
||||
tiles.push_back(layer->tileProvider()->getChunkTile(tileIndex));
|
||||
}
|
||||
|
||||
std::sort(tiles.begin(), tiles.end(), TileSelector::HIGHEST_RES);
|
||||
@@ -132,14 +80,7 @@ namespace globebrowsing {
|
||||
uv.uvOffset *= 0.5;
|
||||
uv.uvScale *= 0.5;
|
||||
|
||||
if (tileIndex.isEastChild()) {
|
||||
uv.uvOffset.x += 0.5;
|
||||
}
|
||||
|
||||
// In OpenGL, positive y direction is up
|
||||
if (tileIndex.isNorthChild()) {
|
||||
uv.uvOffset.y += 0.5;
|
||||
}
|
||||
uv.uvOffset += tileIndex.positionRelativeParent();
|
||||
|
||||
--tileIndex;
|
||||
}
|
||||
|
||||
@@ -41,12 +41,7 @@ namespace globebrowsing {
|
||||
|
||||
class TileSelector {
|
||||
public:
|
||||
static ChunkTile getHighestResolutionTile(TileProvider* tileProvider, TileIndex tileIndex, int parents = 0);
|
||||
static ChunkTile getHighestResolutionTile(
|
||||
const LayerGroup& layerGroup,
|
||||
TileIndex tileIndex
|
||||
);
|
||||
static ChunkTilePile getHighestResolutionTilePile(TileProvider* tileProvider, TileIndex tileIndex, int pileSize);
|
||||
static ChunkTile getHighestResolutionTile(const LayerGroup& layerGroup, TileIndex tileIndex);
|
||||
static std::vector<ChunkTile> getTilesSortedByHighestResolution(const LayerGroup& layerGroup, const TileIndex& tileIndex);
|
||||
|
||||
struct CompareResolution {
|
||||
@@ -55,7 +50,6 @@ namespace globebrowsing {
|
||||
|
||||
static const CompareResolution HIGHEST_RES;
|
||||
|
||||
private:
|
||||
static void ascendToParent(TileIndex& tileIndex, TileUvTransform& uv);
|
||||
};
|
||||
|
||||
|
||||
@@ -203,6 +203,28 @@ void InteractionHandler::setInteractionMode(const std::string& interactionModeKe
|
||||
"' is not a valid interaction mode. Candidates are " << listInteractionModes);
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::goToChunk(int x, int y, int level) {
|
||||
std::shared_ptr<GlobeBrowsingInteractionMode> gbim =
|
||||
std::dynamic_pointer_cast<GlobeBrowsingInteractionMode> (_currentInteractionMode);
|
||||
|
||||
if (gbim) {
|
||||
gbim->goToChunk(*_camera, globebrowsing::TileIndex(x,y,level), glm::vec2(0.5,0.5), true);
|
||||
} else {
|
||||
LWARNING("Interaction mode must be set to 'GlobeBrowsing'");
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::goToGeo(double latitude, double longitude) {
|
||||
std::shared_ptr<GlobeBrowsingInteractionMode> gbim =
|
||||
std::dynamic_pointer_cast<GlobeBrowsingInteractionMode> (_currentInteractionMode);
|
||||
|
||||
if (gbim) {
|
||||
gbim->goToGeodetic2(*_camera, globebrowsing::Geodetic2(latitude, longitude) / 180 * M_PI, true);
|
||||
} else {
|
||||
LWARNING("Interaction mode must be set to 'GlobeBrowsing'");
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionHandler::lockControls() {
|
||||
|
||||
@@ -568,6 +590,18 @@ scripting::LuaLibrary InteractionHandler::luaLibrary() {
|
||||
"void",
|
||||
"Reset the camera direction to point at the focus node"
|
||||
},
|
||||
{
|
||||
"goToChunk",
|
||||
&luascriptfunctions::goToChunk,
|
||||
"void",
|
||||
"Go to chunk with given index x, y, level"
|
||||
},
|
||||
{
|
||||
"goToGeo",
|
||||
&luascriptfunctions::goToGeo,
|
||||
"void",
|
||||
"Go to geographic coordinates latitude and longitude"
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -191,6 +191,37 @@ int setInteractionMode(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToChunk(lua_State* L) {
|
||||
using ghoul::lua::luaTypeToString;
|
||||
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 3)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 3, nArguments);
|
||||
|
||||
int x = lua_tonumber(L, 1);
|
||||
int y = lua_tonumber(L, 2);
|
||||
int level = lua_tonumber(L, 3);
|
||||
|
||||
OsEng.interactionHandler().goToChunk(x, y, level);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int goToGeo(lua_State* L) {
|
||||
using ghoul::lua::luaTypeToString;
|
||||
|
||||
int nArguments = lua_gettop(L);
|
||||
if (nArguments != 2)
|
||||
return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments);
|
||||
|
||||
double latitude = lua_tonumber(L, 1);
|
||||
double longitude = lua_tonumber(L, 2);
|
||||
|
||||
OsEng.interactionHandler().goToGeo(latitude, longitude);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int restoreCameraStateFromFile(lua_State* L) {
|
||||
using ghoul::lua::luaTypeToString;
|
||||
const std::string _loggerCat = "lua.restoreCameraStateFromFile";
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
#include <modules/globebrowsing/globes/renderableglobe.h>
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/geometry/geodetic2.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -685,5 +686,92 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came
|
||||
#endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
}
|
||||
|
||||
#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
void GlobeBrowsingInteractionMode::goToChunk(Camera& camera,
|
||||
globebrowsing::TileIndex ti, glm::vec2 uv, bool resetCameraDirection) {
|
||||
using namespace globebrowsing;
|
||||
|
||||
// Camera position in model space
|
||||
glm::dvec3 camPos = camera.positionVec3();
|
||||
glm::dmat4 inverseModelTransform = _globe->inverseModelTransform();
|
||||
glm::dvec3 cameraPositionModelSpace =
|
||||
glm::dvec3(inverseModelTransform * glm::dvec4(camPos, 1));
|
||||
|
||||
GeodeticPatch patch(ti);
|
||||
Geodetic2 corner = patch.getCorner(SOUTH_WEST);
|
||||
Geodetic2 positionOnPatch = patch.getSize();
|
||||
positionOnPatch.lat *= uv.y;
|
||||
positionOnPatch.lon *= uv.x;
|
||||
Geodetic2 pointPosition = corner + positionOnPatch;
|
||||
|
||||
glm::dvec3 positionOnEllipsoid =
|
||||
_globe->ellipsoid().geodeticSurfaceProjection(cameraPositionModelSpace);
|
||||
double altitude = glm::length(cameraPositionModelSpace - positionOnEllipsoid);
|
||||
|
||||
goToGeodetic3(camera, {pointPosition, altitude});
|
||||
|
||||
if (resetCameraDirection) {
|
||||
this->resetCameraDirection(camera, pointPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void GlobeBrowsingInteractionMode::goToGeodetic2(Camera& camera,
|
||||
globebrowsing::Geodetic2 geo2, bool resetCameraDirection) {
|
||||
using namespace globebrowsing;
|
||||
|
||||
// Camera position in model space
|
||||
glm::dvec3 camPos = camera.positionVec3();
|
||||
glm::dmat4 inverseModelTransform = _globe->inverseModelTransform();
|
||||
glm::dvec3 cameraPositionModelSpace =
|
||||
glm::dvec3(inverseModelTransform * glm::dvec4(camPos, 1));
|
||||
|
||||
glm::dvec3 positionOnEllipsoid =
|
||||
_globe->ellipsoid().geodeticSurfaceProjection(cameraPositionModelSpace);
|
||||
double altitude = glm::length(cameraPositionModelSpace - positionOnEllipsoid);
|
||||
|
||||
goToGeodetic3(camera, {geo2, altitude});
|
||||
|
||||
if (resetCameraDirection) {
|
||||
this->resetCameraDirection(camera, geo2);
|
||||
}
|
||||
}
|
||||
|
||||
void GlobeBrowsingInteractionMode::goToGeodetic3(Camera& camera, globebrowsing::Geodetic3 geo3) {
|
||||
glm::dvec3 positionModelSpace = _globe->ellipsoid().cartesianPosition(geo3);
|
||||
glm::dmat4 modelTransform = _globe->modelTransform();
|
||||
glm::dvec3 positionWorldSpace = modelTransform * glm::dvec4(positionModelSpace, 1.0);
|
||||
camera.setPositionVec3(positionWorldSpace);
|
||||
}
|
||||
|
||||
void GlobeBrowsingInteractionMode::resetCameraDirection(Camera& camera, globebrowsing::Geodetic2 geo2) {
|
||||
using namespace globebrowsing;
|
||||
|
||||
// Camera is described in world space
|
||||
glm::dmat4 modelTransform = _globe->modelTransform();
|
||||
|
||||
// Lookup vector
|
||||
glm::dvec3 positionModelSpace = _globe->ellipsoid().cartesianSurfacePosition(geo2);
|
||||
glm::dvec3 slightlyNorth = _globe->ellipsoid().cartesianSurfacePosition(
|
||||
Geodetic2(geo2.lat + 0.001, geo2.lon));
|
||||
glm::dvec3 lookUpModelSpace = glm::normalize(slightlyNorth - positionModelSpace);
|
||||
glm::dvec3 lookUpWorldSpace = glm::dmat3(modelTransform) * lookUpModelSpace;
|
||||
|
||||
// Lookat vector
|
||||
glm::dvec3 lookAtWorldSpace = modelTransform * glm::dvec4(positionModelSpace, 1.0);
|
||||
|
||||
// Eye position
|
||||
glm::dvec3 eye = camera.positionVec3();
|
||||
|
||||
// Matrix
|
||||
glm::dmat4 lookAtMatrix = glm::lookAt(
|
||||
eye, lookAtWorldSpace, lookUpWorldSpace);
|
||||
|
||||
// Set rotation
|
||||
glm::dquat rotation = glm::quat_cast(inverse(lookAtMatrix));
|
||||
camera.setRotation(rotation);
|
||||
}
|
||||
|
||||
#endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED
|
||||
|
||||
} // namespace interaction
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user