Solve merge conflict

This commit is contained in:
Kalle Bladin
2016-06-02 12:57:25 -04:00
47 changed files with 1545 additions and 2214 deletions

View File

@@ -6,34 +6,29 @@ return {
Renderable = {
Type = "RenderableGlobe",
Radii = {6378137.0, 6378137.0, 6356752.314245}, -- Earth's radii
SegmentsPerPatch = 64,
Textures = {
ColorTextures = {
{
Name = "ESRI Imagery World 2D",
FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms",
},
--[[
{
Name = "Coastlines",
FilePath = "map_service_configs/Coastlines.xml",
},
{
Name = "VIIRS_SNPP_CorrectedReflectance_TrueColor",
FilePath = "map_service_configs/VIIRS_SNPP_CorrectedReflectance_TrueColor.xml"
},
{
Name = "MODIS_Terra_CorrectedReflectance_TrueColor",
FilePath = "map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml"
},
{
Name = "MODIS_Water_Mask",
FilePath = "map_service_configs/MODIS_Water_Mask.xml"
},
{
Name = "Coastlines",
FilePath = "map_service_configs/Coastlines.xml",
},
{
Name = "ESRI Imagery World 2D",
FilePath = "map_service_configs/ESRI_Imagery_World_2D.wms",
},
{
Name = "MODIS_Terra_CorrectedReflectance_TrueColor",
FilePath = "map_service_configs/MODIS_Terra_CorrectedReflectance_TrueColor.xml",
},
--]]
},
HeightMaps = {
{

View File

@@ -34,6 +34,8 @@
#include <openspace/util/keys.h>
#include <list>
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <mutex>
namespace openspace {
@@ -189,7 +191,7 @@ public:
~InteractionMode();
// Mutators
void setFocusNode(SceneGraphNode* focusNode);
virtual void setFocusNode(SceneGraphNode* focusNode);
void setCamera(Camera* camera);
// Accessors
@@ -256,7 +258,7 @@ public:
~OrbitalInteractionMode();
virtual void update(double deltaTime);
private:
protected:
void updateMouseStatesFromInput(double deltaTime);
void updateCameraStateFromMouseStates();
@@ -271,6 +273,22 @@ private:
glm::dquat _globalCameraRotation;
};
class GlobeBrowsingInteractionMode : public OrbitalInteractionMode
{
public:
GlobeBrowsingInteractionMode(
std::shared_ptr<InputState> inputState,
double sensitivity,
double velocityScaleFactor);
~GlobeBrowsingInteractionMode();
virtual void setFocusNode(SceneGraphNode* focusNode);
virtual void update(double deltaTime);
private:
void updateCameraStateFromMouseStates();
RenderableGlobe* _globe;
};
class InteractionHandler : public properties::PropertyOwner
{

View File

@@ -73,9 +73,9 @@ namespace openspace {
// now working with float precision. To be changed to double later.
// The reason double does not work yet is because of the setUniform function
// in ghoul::opengl
typedef glm::quat Quat;
typedef glm::mat4 Mat4;
typedef glm::vec3 Vec3;
typedef glm::dquat Quat;
typedef glm::dmat4 Mat4;
typedef glm::dvec3 Vec3;
// Static constants
static const Vec3 _VIEW_DIRECTION_CAMERA_SPACE;
@@ -113,6 +113,8 @@ namespace openspace {
// @TODO this should simply be called viewMatrix!
// Or it needs to be changed so that it actually is combined. Right now it is
// only the view matrix that is the same for all SGCT cameras.
// Right now this function returns the actual combined matrix which makes some
// of the old calls to the function wrong..
const Mat4& combinedViewMatrix() const;
// Synchronization

View File

@@ -58,6 +58,10 @@ class SyncBuffer;
class Time {
public:
Time();
Time(const Time& other);
/**
* Initializes the Time singleton.
* \return <code>true</code> if the initialization succeeded, <code>false</code>
@@ -123,6 +127,12 @@ public:
*/
std::string currentTimeUTC() const;
/**
* Returns the current time as a ISO 8601 formatted, i.e YYYY-MM-DDThh:mm:ssZ
* \return The current time as a ISO 8601 formatted string
*/
std::string ISO8601() const;
/**
* Sets the delta time value that is the number of seconds that should pass for each
* real-time second. This value is used in the advanceTime(double) method to easily

View File

@@ -28,8 +28,6 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/globes/renderableglobe.h
${CMAKE_CURRENT_SOURCE_DIR}/globes/globemesh.h
${CMAKE_CURRENT_SOURCE_DIR}/globes/clipmapglobe.h
${CMAKE_CURRENT_SOURCE_DIR}/globes/clipmappyramid.h
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkedlodglobe.h
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunknode.h
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkindex.h
@@ -38,7 +36,7 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.h
${CMAKE_CURRENT_SOURCE_DIR}/meshes/grid.h
${CMAKE_CURRENT_SOURCE_DIR}/meshes/basicgrid.h
${CMAKE_CURRENT_SOURCE_DIR}/meshes/clipmapgrid.h
${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.h
${CMAKE_CURRENT_SOURCE_DIR}/geodetics/geodetic2.h
${CMAKE_CURRENT_SOURCE_DIR}/geodetics/angle.h
@@ -49,9 +47,10 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/aabb.h
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.h
${CMAKE_CURRENT_SOURCE_DIR}/other/patchcoverageprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/other/temporaltileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/other/texturedataprovider.h
${CMAKE_CURRENT_SOURCE_DIR}/other/tiledataset.h
${CMAKE_CURRENT_SOURCE_DIR}/other/asynctilereader.h
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.h
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.h
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.h
@@ -64,8 +63,6 @@ set(HEADER_FILES
set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/globes/renderableglobe.cpp
${CMAKE_CURRENT_SOURCE_DIR}/globes/globemesh.cpp
${CMAKE_CURRENT_SOURCE_DIR}/globes/clipmapglobe.cpp
${CMAKE_CURRENT_SOURCE_DIR}/globes/clipmappyramid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkedlodglobe.cpp
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunknode.cpp
${CMAKE_CURRENT_SOURCE_DIR}/globes/chunkindex.cpp
@@ -74,7 +71,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/meshes/grid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/meshes/basicgrid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/meshes/clipmapgrid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/geodetics/geodetic2.cpp
${CMAKE_CURRENT_SOURCE_DIR}/geodetics/angle.inl
@@ -85,9 +82,10 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/aabb.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/patchcoverageprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/temporaltileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/tileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/texturedataprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/tiledataset.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/asynctilereader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.cpp
@@ -103,11 +101,6 @@ set(SHADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalchunkedlodpatch_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalchunkedlodpatch_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalclipmappatch_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalclipmappatch_fs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/localclipmappatch_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/simple_vs.glsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/simple_fs.glsl
)
source_group("Shader Files" FILES ${SHADER_FILES})

View File

@@ -121,7 +121,7 @@ namespace openspace {
Scalar scaleFactor = _owner->lodScaleFactor * ellipsoid.minimumRadius();;
Scalar projectedScaleFactor = scaleFactor / distance;
int desiredLevel = floor(log2(projectedScaleFactor));
int desiredLevel = ceil(log2(projectedScaleFactor));
// clamp level
desiredLevel = glm::clamp(desiredLevel, _owner->minSplitDepth, _owner->maxSplitDepth);

View File

@@ -24,7 +24,7 @@
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
#include <modules/globebrowsing/meshes/basicgrid.h>
#include <modules/globebrowsing/meshes/skirtedgrid.h>
// open space includes
#include <openspace/engine/openspaceengine.h>
@@ -53,6 +53,7 @@ namespace openspace {
ChunkedLodGlobe::ChunkedLodGlobe(
const Ellipsoid& ellipsoid,
size_t segmentsPerPatch,
std::shared_ptr<TileProviderManager> tileProviderManager)
: _ellipsoid(ellipsoid)
, _leftRoot(new ChunkNode(Chunk(this, LEFT_HEMISPHERE_INDEX)))
@@ -62,9 +63,9 @@ namespace openspace {
, _savedCamera(nullptr)
{
auto geometry = std::shared_ptr<BasicGrid>(new BasicGrid(
64,
64,
auto geometry = std::shared_ptr<SkirtedGrid>(new SkirtedGrid(
segmentsPerPatch,
segmentsPerPatch,
TriangleSoup::Positions::No,
TriangleSoup::TextureCoordinates::Yes,
TriangleSoup::Normals::No));

View File

@@ -56,6 +56,7 @@ namespace openspace {
public:
ChunkedLodGlobe(
const Ellipsoid& ellipsoid,
size_t segmentsPerPatch,
std::shared_ptr<TileProviderManager> tileProviderManager);
virtual ~ChunkedLodGlobe();

View File

@@ -1,142 +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 <modules/globebrowsing/globes/clipmapglobe.h>
#include <modules/globebrowsing/meshes/clipmapgrid.h>
// open space includes
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
#include <openspace/util/spicemanager.h>
#include <openspace/scene/scenegraphnode.h>
// ghoul includes
#include <ghoul/misc/assert.h>
#define _USE_MATH_DEFINES
#include <math.h>
namespace {
const std::string _loggerCat = "ClipMapGlobe";
}
namespace openspace {
ClipMapGlobe::ClipMapGlobe(
const Ellipsoid& ellipsoid,
std::shared_ptr<TileProviderManager> tileProviderManager)
: _clipMapPyramid(Geodetic2(M_PI / 2, M_PI / 2))
, _ellipsoid(ellipsoid)
{
// init Renderer
auto outerPatchRenderer = new ClipMapPatchRenderer(
shared_ptr<OuterClipMapGrid>(new OuterClipMapGrid(256)),
tileProviderManager);
_outerPatchRenderer.reset(outerPatchRenderer);
auto innerPatchRenderer = new ClipMapPatchRenderer(
shared_ptr<InnerClipMapGrid>(new InnerClipMapGrid(256)),
tileProviderManager);
_innerPatchRenderer.reset(innerPatchRenderer);
}
ClipMapGlobe::~ClipMapGlobe() {
}
const Ellipsoid& ClipMapGlobe::ellipsoid() const
{
return _ellipsoid;
}
bool ClipMapGlobe::initialize() {
return isReady();
}
bool ClipMapGlobe::deinitialize() {
return true;
}
bool ClipMapGlobe::isReady() const {
bool ready = true;
return ready;
}
void ClipMapGlobe::render(const RenderData& data)
{
int minDepth, maxDepth;
calculateDesiredMinAndMaxDepth(data, minDepth, maxDepth);
// render patches
for (size_t i = minDepth; i < maxDepth; i++)
{
Geodetic2 patchSize = _clipMapPyramid.getPatchSizeAtLevel(i);
_outerPatchRenderer->renderPatch(patchSize, data, _ellipsoid);
}
Geodetic2 patchSize = _clipMapPyramid.getPatchSizeAtLevel(maxDepth);
_innerPatchRenderer->renderPatch(patchSize, data, _ellipsoid);
}
void ClipMapGlobe::update(const UpdateData& data) {
_innerPatchRenderer->update();
_outerPatchRenderer->update();
}
void ClipMapGlobe::calculateDesiredMinAndMaxDepth(
const RenderData& data,
int& minDepth,
int& maxDepth)
{
Scalar minimumRadius = _ellipsoid.minimumRadius();
Vec3 cameraPosition = data.camera.position().dvec3();
Vec3 cameraPositionOnSurface = _ellipsoid.geodeticSurfaceProjection(cameraPosition);
Scalar h = glm::length(cameraPosition - cameraPositionOnSurface);
Scalar cosAngleToHorizon = minimumRadius / (minimumRadius + h);
Scalar angleToHorizon = glm::acos(cosAngleToHorizon);
Scalar minimumPatchSize = glm::min(
_clipMapPyramid.getPatchSizeAtLevel0().lat,
_clipMapPyramid.getPatchSizeAtLevel0().lon);
minDepth = log2(minimumPatchSize / 2 / angleToHorizon);
// Calculate desired level based on distance
Scalar scaleFactor = 1 * minimumRadius;
Scalar projectedScaleFactor = scaleFactor / h;
maxDepth = glm::max(static_cast<int>(log2(projectedScaleFactor)), 0);
// Test smaller and smaller patches until one is outside of frustum
int i;
for (i = minDepth; i < maxDepth; i++)
{
Geodetic2 center = _ellipsoid.cartesianToGeodetic2(cameraPosition);
Geodetic2 halfSize = _clipMapPyramid.getPatchSizeAtLevel(i) / 2;
GeodeticPatch testPatch(center, halfSize);
// Do frustrum culling
if (FrustumCuller::isVisible(data, testPatch, _ellipsoid)) {
break;
}
}
maxDepth = i;
}
} // namespace openspace

View File

@@ -1,81 +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. *
****************************************************************************************/
#ifndef __CLIPMAPGLOBE_H__
#define __CLIPMAPGLOBE_H__
// open space includes
#include <openspace/rendering/renderable.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/util/updatestructures.h>
#include <modules/globebrowsing/meshes/trianglesoup.h>
#include <modules/globebrowsing/meshes/grid.h>
#include <modules/globebrowsing/other/distanceswitch.h>
#include <modules/globebrowsing/rendering/patchrenderer.h>
#include <modules/globebrowsing/rendering/culling.h>
#include <modules/globebrowsing/globes/clipmappyramid.h>
#include <modules/globebrowsing/other/TileProviderManager.h>
namespace ghoul {
namespace opengl {
class ProgramObject;
}
}
namespace openspace {
class ClipMapGlobe : public Renderable {
public:
ClipMapGlobe(
const Ellipsoid& ellipsoid,
std::shared_ptr<TileProviderManager> tileProviderManager);
~ClipMapGlobe();
bool initialize() override;
bool deinitialize() override;
bool isReady() const override;
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
const Ellipsoid& ellipsoid() const;
private:
void calculateDesiredMinAndMaxDepth(
const RenderData& data,
int& minDepth,
int& maxDepth);
//shared_ptr<TileProvider> _tileProvider;
std::unique_ptr<ClipMapPatchRenderer> _outerPatchRenderer;
std::unique_ptr<ClipMapPatchRenderer> _innerPatchRenderer;
ClipMapPyramid _clipMapPyramid;
const Ellipsoid& _ellipsoid;
};
} // namespace openspace
#endif // __CLIPMAPGLOBE_H__

View File

@@ -25,7 +25,8 @@
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/globes/globemesh.h>
#include <modules/globebrowsing/globes/clipmapglobe.h>
#include <modules/globebrowsing/other/threadpool.h>
// open space includes
#include <openspace/engine/openspaceengine.h>
@@ -41,6 +42,7 @@ namespace {
// Keys for the dictionary
const std::string keyRadii = "Radii";
const std::string keySegmentsPerPatch = "SegmentsPerPatch";
const std::string keyTextures = "Textures";
const std::string keyColorTextures = "ColorTextures";
const std::string keyHeightMaps = "HeightMaps";
@@ -57,7 +59,7 @@ namespace openspace {
, doFrustumCulling(properties::BoolProperty("doFrustumCulling", "doFrustumCulling"))
, doHorizonCulling(properties::BoolProperty("doHorizonCulling", "doHorizonCulling"))
, mergeInvisible(properties::BoolProperty("mergeInvisible", "mergeInvisible", true))
, lodScaleFactor(properties::FloatProperty("lodScaleFactor", "lodScaleFactor", 10.0f, 0.0f, 100.0f))
, lodScaleFactor(properties::FloatProperty("lodScaleFactor", "lodScaleFactor", 5.0f, 1.0f, 20.0f))
, initChunkVisible(properties::BoolProperty("initChunkVisible", "initChunkVisible", true))
, renderSmallChunksFirst(properties::BoolProperty("renderSmallChunksFirst", "renderSmallChunksFirst", true))
{
@@ -81,7 +83,13 @@ namespace openspace {
// Read the radii in to its own dictionary
Vec3 radii;
double patchSegmentsd;
dictionary.getValue(keyRadii, radii);
// Ghoul can't read ints from lua dictionaries
dictionary.getValue(keySegmentsPerPatch, patchSegmentsd);
int patchSegments = patchSegmentsd;
_ellipsoid = Ellipsoid(radii);
@@ -94,52 +102,95 @@ namespace openspace {
ghoul::Dictionary colorTexturesDictionary;
texturesDictionary.getValue(keyColorTextures, colorTexturesDictionary);
int minimumTextureSide = 1024;
int minimumHeightmapSize = 64;
int frameUntilFlushRequestQueue = 60;
int cacheSize = 5000;
// Create TileProviders for all color textures
for (size_t i = 1; i < colorTexturesDictionary.size() + 1; i++)
for (size_t i = 0; i < colorTexturesDictionary.size(); i++)
{
std::string name, path;
std::string dictionaryKey = std::to_string(i + 1);
ghoul::Dictionary colorTextureDictionary =
colorTexturesDictionary.value<ghoul::Dictionary>(std::to_string(i));
colorTexturesDictionary.value<ghoul::Dictionary>(dictionaryKey);
colorTextureDictionary.getValue("Name", name);
colorTextureDictionary.getValue("FilePath", path);
std::shared_ptr<TileProvider> colorTextureProvider =
std::shared_ptr<TileProvider>(new TileProvider(
path, 5000, 1024, 60));
_tileProviderManager->addColorTexture(name, colorTextureProvider);
std::shared_ptr<TileDataset> tileDataset = std::shared_ptr<TileDataset>(
new TileDataset(path, minimumTextureSide));
std::shared_ptr<ThreadPool> threadPool = std::shared_ptr<ThreadPool>(
new ThreadPool(1));
std::shared_ptr<AsyncTileDataProvider> tileReader = std::shared_ptr<AsyncTileDataProvider>(
new AsyncTileDataProvider(tileDataset, threadPool));
std::shared_ptr<TileProvider> colorTextureProvider = std::shared_ptr<TileProvider>(
new TileProvider(tileReader, cacheSize, frameUntilFlushRequestQueue));
_tileProviderManager->addColorTexture(name, colorTextureProvider, true);
// Create property for this tile provider
bool enabled = i == 0; // Only enable first layer
_activeColorLayers.push_back(properties::BoolProperty(name, name, enabled));
}
ghoul::Dictionary heightMapsDictionary;
texturesDictionary.getValue(keyHeightMaps, heightMapsDictionary);
// Create TileProviders for all height maps
for (size_t i = 1; i < heightMapsDictionary.size() + 1; i++)
for (size_t i = 0; i < heightMapsDictionary.size(); i++)
{
std::string name, path;
std::string dictionaryKey = std::to_string(i + 1);
ghoul::Dictionary heightMapDictionary =
heightMapsDictionary.value<ghoul::Dictionary>(std::to_string(i));
heightMapsDictionary.value<ghoul::Dictionary>(dictionaryKey);
heightMapDictionary.getValue("Name", name);
heightMapDictionary.getValue("FilePath", path);
std::shared_ptr<TileProvider> heightMapProvider =
std::shared_ptr<TileProvider>(new TileProvider(
path, 5000, 64, 60));
_tileProviderManager->addHeightMap(name, heightMapProvider);
std::shared_ptr<TileDataset> tileDataset = std::shared_ptr<TileDataset>(
new TileDataset(path, minimumHeightmapSize));
std::shared_ptr<ThreadPool> threadPool = std::shared_ptr<ThreadPool>(
new ThreadPool(1));
std::shared_ptr<AsyncTileDataProvider> tileReader = std::shared_ptr<AsyncTileDataProvider>(
new AsyncTileDataProvider(tileDataset, threadPool));
std::shared_ptr<TileProvider> heightMapProvider = std::shared_ptr<TileProvider>(
new TileProvider(tileReader, cacheSize, frameUntilFlushRequestQueue));
_tileProviderManager->addHeightMap(name, heightMapProvider, true);
// Create property for this tile provider
bool enabled = i == 0; // Only enable first layer
_activeHeightMapLayers.push_back(properties::BoolProperty(name, name, enabled));
}
// Add properties for the tile providers
for (auto it = _activeColorLayers.begin(); it != _activeColorLayers.end(); it++) {
addProperty(*it);
}
for (auto it = _activeHeightMapLayers.begin(); it != _activeHeightMapLayers.end(); it++) {
addProperty(*it);
}
//addSwitchValue(std::shared_ptr<ClipMapGlobe>(
// new ClipMapGlobe(_ellipsoid, _tileProviderManager)), 1e8);
_chunkedLodGlobe = std::shared_ptr<ChunkedLodGlobe>(
new ChunkedLodGlobe(_ellipsoid, _tileProviderManager));
new ChunkedLodGlobe(_ellipsoid, patchSegments, _tileProviderManager));
_distanceSwitch.addSwitchValue(_chunkedLodGlobe, 1e9);
//_distanceSwitch.addSwitchValue(std::shared_ptr<GlobeMesh>(new GlobeMesh()), 1e10);
_distanceSwitch.addSwitchValue(_chunkedLodGlobe, 1e12);
}
RenderableGlobe::~RenderableGlobe() {
}
bool RenderableGlobe::initialize() {
return _distanceSwitch.initialize();
}
@@ -165,17 +216,36 @@ namespace openspace {
_chunkedLodGlobe->setSaveCamera(nullptr);
}
}
_chunkedLodGlobe->doFrustumCulling = doFrustumCulling.value();
_chunkedLodGlobe->doHorizonCulling = doHorizonCulling.value();
_chunkedLodGlobe->mergeInvisible = mergeInvisible.value();
_chunkedLodGlobe->lodScaleFactor= lodScaleFactor.value();
_chunkedLodGlobe->initChunkVisible = initChunkVisible.value();
_distanceSwitch.render(data);
}
void RenderableGlobe::update(const UpdateData& data) {
_time = data.time;
_distanceSwitch.update(data);
_chunkedLodGlobe->doFrustumCulling = doFrustumCulling.value();
_chunkedLodGlobe->doHorizonCulling = doHorizonCulling.value();
_chunkedLodGlobe->mergeInvisible = mergeInvisible.value();
_chunkedLodGlobe->lodScaleFactor = lodScaleFactor.value();
_chunkedLodGlobe->initChunkVisible = initChunkVisible.value();
std::vector<TileProviderManager::TileProviderWithName>& colorTextureProviders =
_tileProviderManager->colorTextureProviders();
std::vector<TileProviderManager::TileProviderWithName>& heightMapProviders =
_tileProviderManager->heightMapProviders();
for (size_t i = 0; i < colorTextureProviders.size(); i++) {
colorTextureProviders[i].isActive = _activeColorLayers[i].value();
}
for (size_t i = 0; i < heightMapProviders.size(); i++) {
heightMapProviders[i].isActive = _activeHeightMapLayers[i].value();
}
}
glm::dvec3 RenderableGlobe::geodeticSurfaceProjection(glm::dvec3 position) {
return _ellipsoid.geodeticSurfaceProjection(position);
}
} // namespace openspace

View File

@@ -64,6 +64,8 @@ public:
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
glm::dvec3 geodeticSurfaceProjection(glm::dvec3 position);
properties::BoolProperty doFrustumCulling;
properties::BoolProperty doHorizonCulling;
properties::BoolProperty mergeInvisible;
@@ -86,6 +88,9 @@ private:
properties::BoolProperty _saveOrThrowCamera;
std::vector<properties::BoolProperty> _activeColorLayers;
std::vector<properties::BoolProperty> _activeHeightMapLayers;
DistanceSwitch _distanceSwitch;
};

View File

@@ -0,0 +1,174 @@
/*****************************************************************************************
* *
* 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/meshes/skirtedgrid.h>
namespace {
const std::string _loggerCat = "SkirtedGrid";
}
namespace openspace {
SkirtedGrid::SkirtedGrid(
unsigned int xSegments,
unsigned int ySegments,
TriangleSoup::Positions usePositions,
TriangleSoup::TextureCoordinates useTextureCoordinates,
TriangleSoup::Normals useNormals)
: Grid(
xSegments,
ySegments,
usePositions,
useTextureCoordinates,
useNormals)
{
_geometry = std::unique_ptr<TriangleSoup>(new TriangleSoup(
CreateElements(xSegments, ySegments),
usePositions,
useTextureCoordinates,
useNormals));
if (usePositions == TriangleSoup::Positions::Yes) {
_geometry->setVertexPositions(CreatePositions(_xSegments, _ySegments));
}
if (useTextureCoordinates == TriangleSoup::TextureCoordinates::Yes) {
_geometry->setVertexTextureCoordinates(CreateTextureCoordinates(_xSegments, _ySegments));
}
if (useNormals == TriangleSoup::Normals::Yes) {
_geometry->setVertexNormals(CreateNormals(_xSegments, _ySegments));
}
}
SkirtedGrid::~SkirtedGrid()
{
}
int SkirtedGrid::xSegments() const {
return _xSegments;
}
int SkirtedGrid::ySegments() const {
return _ySegments;
}
void SkirtedGrid::validate(int xSegments, int ySegments) {
ghoul_assert(xSegments > 0 && ySegments > 0,
"Resolution must be at least 1x1. (" << xSegments << ", " << ySegments << ")");
}
inline size_t SkirtedGrid::numElements(int xSegments, int ySegments) {
return 3 * 2 * xSegments * ySegments;
}
inline size_t SkirtedGrid::numVertices(int xSegments, int ySegments) {
return (xSegments + 1) * (ySegments + 1);
}
std::vector<GLuint> SkirtedGrid::CreateElements(int xSegments, int ySegments) {
validate(xSegments, ySegments);
std::vector<GLuint> elements;
elements.reserve(numElements(xSegments + 2, ySegments + 2));
for (unsigned int y = 0; y < ySegments + 2; y++) {
for (unsigned int x = 0; x < xSegments + 2; x++) {
// x v01---v11 x ..
// | / |
// x v00---v10 x ..
//
// x x x x ..
// : : : :
GLuint v00 = (y + 0) * (xSegments + 2 + 1) + x + 0;
GLuint v10 = (y + 0) * (xSegments + 2 + 1) + x + 1;
GLuint v01 = (y + 1) * (xSegments + 2 + 1) + x + 0;
GLuint v11 = (y + 1) * (xSegments + 2 + 1) + x + 1;
// add upper triangle
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
// add lower triangle
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
return elements;
}
std::vector<glm::vec4> SkirtedGrid::CreatePositions(
int xSegments,
int ySegments)
{
validate(xSegments, ySegments);
std::vector<glm::vec4> positions;
positions.reserve(numVertices(xSegments, ySegments));
// Copy from 2d texture coordinates and use as template to create positions
std::vector<glm::vec2> templateTextureCoords = CreateTextureCoordinates(xSegments, ySegments);
for (unsigned int i = 0; i < templateTextureCoords.size(); i++)
{
positions.push_back(glm::vec4(
templateTextureCoords[i],
0.0f,
1.0f
));
}
return positions;
}
std::vector<glm::vec2> SkirtedGrid::CreateTextureCoordinates(int xSegments, int ySegments) {
validate(xSegments, ySegments);
std::vector<glm::vec2> textureCoordinates;
textureCoordinates.reserve(numVertices(xSegments + 2, ySegments + 2));
for (int y = -1; y < ySegments + 2; y++) {
for (int x = -1; x < xSegments + 2; x++) {
textureCoordinates.push_back(glm::vec2(
glm::clamp(static_cast<float>(x) / static_cast<float>(xSegments), 0 - 1.0f / (2 * xSegments), 1 + 1.0f / (2 * xSegments)),
glm::clamp(static_cast<float>(y) / static_cast<float>(ySegments), 0 - 1.0f / (2 * ySegments), 1 + 1.0f / (2 * ySegments))
));
}
}
return textureCoordinates;
}
std::vector<glm::vec3> SkirtedGrid::CreateNormals(int xSegments, int ySegments) {
validate(xSegments, ySegments);
std::vector<glm::vec3> normals;
normals.reserve(numVertices(xSegments + 2, ySegments + 2));
for (int y = -1; y < ySegments + 2; y++) {
for (int x = -1; x < xSegments + 2; x++) {
normals.push_back(glm::vec3(0, 0, 1));
}
}
return normals;
}
}// namespace openspace

View File

@@ -23,37 +23,52 @@
****************************************************************************************/
#ifndef __SKIRTEDGRID_H__
#define __SKIRTEDGRID_H__
#include <modules/globebrowsing/globes/clipmappyramid.h>
#include <glm/glm.hpp>
#define _USE_MATH_DEFINES
#include <math.h>
#include <modules/globebrowsing/meshes/basicgrid.h>
// ghoul includes
#include <ghoul/misc/assert.h>
namespace {
const std::string _loggerCat = "ClipMapPyramid";
}
#include <vector>
namespace openspace {
ClipMapPyramid::ClipMapPyramid(Geodetic2 sizeLevel0)
: _sizeLevel0(sizeLevel0)
{
}
class SkirtedGrid : public Grid
{
public:
/**
\param xSegments is the number of grid cells in the x direction.
\param ySegments is the number of grid cells in the y direction.
\param usePositions determines whether or not to upload any vertex position data
to the GPU.
\param useTextureCoordinates determines whether or not to upload any vertex texture
coordinate data to the GPU.
\param useNormals determines whether or not to upload any vertex normal data
to the GPU.
*/
SkirtedGrid(
unsigned int xSegments,
unsigned int ySegments,
TriangleSoup::Positions usePositions,
TriangleSoup::TextureCoordinates useTextureCoordinates,
TriangleSoup::Normals useNormals);
~SkirtedGrid();
ClipMapPyramid::~ClipMapPyramid()
{}
Geodetic2 ClipMapPyramid::getPatchSizeAtLevel(int level)
{
return Geodetic2(_sizeLevel0.lat / pow(2, level), _sizeLevel0.lon / pow(2, level));
}
virtual int xSegments() const;
virtual int ySegments() const;
Geodetic2 ClipMapPyramid::getPatchSizeAtLevel0()
{
return _sizeLevel0;
}
private:
virtual std::vector<GLuint> CreateElements(int xRes, int yRes);
virtual std::vector<glm::vec4> CreatePositions(int xRes, int yRes);
virtual std::vector<glm::vec2> CreateTextureCoordinates(int xRes, int yRes);
virtual std::vector<glm::vec3> CreateNormals(int xRes, int yRes);
} // namespace openspace
void validate(int xSegments, int ySegments);
inline size_t numElements(int xSegments, int ySegments);
inline size_t numVertices(int xSegments, int ySegments);
};
} // namespace openspace
#endif // __SKIRTEDGRID_H__

View File

@@ -44,29 +44,57 @@ namespace openspace {
void TileProviderManager::addHeightMap(
std::string name,
std::shared_ptr<TileProvider> tileProvider)
std::shared_ptr<TileProvider> tileProvider,
bool isActive)
{
_heightMapProviders.push_back(tileProvider);
_heightMapProviders.push_back({ name , tileProvider, isActive});
}
void TileProviderManager::addColorTexture(
std::string name,
std::shared_ptr<TileProvider> tileProvider)
std::shared_ptr<TileProvider> tileProvider,
bool isActive)
{
_colorTextureProviders.push_back(tileProvider);
_colorTextureProviders.push_back({ name , tileProvider, isActive });
}
const std::vector<std::shared_ptr<TileProvider> >&
std::vector<TileProviderManager::TileProviderWithName>&
TileProviderManager::heightMapProviders()
{
return _heightMapProviders;
}
const std::vector<std::shared_ptr<TileProvider> >&
std::vector<TileProviderManager::TileProviderWithName>&
TileProviderManager::colorTextureProviders()
{
return _colorTextureProviders;
}
const std::vector<std::shared_ptr<TileProvider> >
TileProviderManager::getActiveHeightMapProviders()
{
std::vector<std::shared_ptr<TileProvider> > tileProviders;
for (auto it = _heightMapProviders.begin(); it != _heightMapProviders.end(); it++)
{
if (it->isActive) {
tileProviders.push_back(it->tileProvider);
}
}
return tileProviders;
}
const std::vector<std::shared_ptr<TileProvider> >
TileProviderManager::getActiveColorTextureProviders()
{
std::vector<std::shared_ptr<TileProvider> > tileProviders;
for (auto it = _colorTextureProviders.begin(); it != _colorTextureProviders.end(); it++)
{
if (it->isActive) {
tileProviders.push_back(it->tileProvider);
}
}
return tileProviders;
}
} // namespace openspace

View File

@@ -37,23 +37,38 @@ namespace openspace {
class TileProviderManager {
public:
struct TileProviderWithName {
std::string name;
std::shared_ptr<TileProvider> tileProvider;
bool isActive;
};
TileProviderManager();
~TileProviderManager();
static ThreadPool tileRequestThreadPool;
void addHeightMap(std::string name, std::shared_ptr<TileProvider> tileProvider);
void addColorTexture(std::string name, std::shared_ptr<TileProvider> tileProvider);
void addHeightMap(
std::string name,
std::shared_ptr<TileProvider> tileProvider,
bool isActive);
void addColorTexture(
std::string name,
std::shared_ptr<TileProvider> tileProvider,
bool isActive);
/*
std::shared_ptr<TileProvider> getHeightMap(std::string name);
std::shared_ptr<TileProvider> getColorTexture(std::string name);
*/
const std::vector<std::shared_ptr<TileProvider> >& heightMapProviders();
const std::vector<std::shared_ptr<TileProvider> >& colorTextureProviders();
const std::vector<std::shared_ptr<TileProvider> > getActiveHeightMapProviders();
const std::vector<std::shared_ptr<TileProvider> > getActiveColorTextureProviders();
std::vector<TileProviderWithName>& heightMapProviders();
std::vector<TileProviderWithName>& colorTextureProviders();
private:
std::vector<std::shared_ptr<TileProvider> > _heightMapProviders;
std::vector<std::shared_ptr<TileProvider> > _colorTextureProviders;
std::vector<TileProviderWithName> _heightMapProviders;
std::vector<TileProviderWithName> _colorTextureProviders;
};
} // namespace openspace

View File

@@ -0,0 +1,107 @@
/*****************************************************************************************
* *
* 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 <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h> // abspath
#include <ghoul/misc/assert.h>
#include <modules/globebrowsing/other/asynctilereader.h>
#include <modules/globebrowsing/other/tileprovider.h>
#include <modules/globebrowsing/geodetics/angle.h>
namespace {
const std::string _loggerCat = "AsyncTextureDataProvider";
}
namespace openspace {
AsyncTileDataProvider::AsyncTileDataProvider(
std::shared_ptr<TileDataset> tileDataset,
std::shared_ptr<ThreadPool> pool)
: _tileDataset(tileDataset)
, _concurrentJobManager(pool)
{
}
AsyncTileDataProvider::~AsyncTileDataProvider() {
}
std::shared_ptr<TileDataset> AsyncTileDataProvider::getTextureDataProvider() const {
return _tileDataset;
}
bool AsyncTileDataProvider::enqueueTextureData(const ChunkIndex& chunkIndex) {
if (satisfiesEnqueueCriteria(chunkIndex)) {
std::shared_ptr<TileLoadJob> job = std::shared_ptr<TileLoadJob>(
new TileLoadJob(_tileDataset, chunkIndex));
_concurrentJobManager.enqueueJob(job);
_enqueuedTileRequests[chunkIndex.hashKey()] = chunkIndex;
return true;
}
return false;
}
bool AsyncTileDataProvider::hasLoadedTextureData() const{
return _concurrentJobManager.numFinishedJobs() > 0;
}
std::shared_ptr<TileIOResult> AsyncTileDataProvider::nextTileIOResult() {
auto tileIOResult = _concurrentJobManager.popFinishedJob()->product();
HashKey key = tileIOResult->rawTileData->chunkIndex.hashKey();
if (_enqueuedTileRequests.find(key) != _enqueuedTileRequests.end()) {
_enqueuedTileRequests.erase(key);
}
return tileIOResult;
}
bool AsyncTileDataProvider::satisfiesEnqueueCriteria(const ChunkIndex& chunkIndex) const {
auto it = _enqueuedTileRequests.begin();
auto end = _enqueuedTileRequests.end();
for (; it != end; it++) {
const ChunkIndex& otherChunk = it->second;
if (chunkIndex.level == otherChunk.level &&
chunkIndex.manhattan(otherChunk) < 1) {
return false;
}
}
return true;
}
void AsyncTileDataProvider::clearRequestQueue() {
_concurrentJobManager.clearEnqueuedJobs();
_enqueuedTileRequests.clear();
}
} // namespace openspace

View File

@@ -22,31 +22,99 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __CLIPMAPPYRAMID_H__
#define __CLIPMAPPYRAMID_H__
// open space includes
#ifndef __ASYNC_TILE_DATA_PROVIDER_H__
#define __ASYNC_TILE_DATA_PROVIDER_H__
//#include <modules/globebrowsing/other/tileprovider.h>
#include <ghoul/opengl/texture.h>
#include <modules/globebrowsing/geodetics/geodetic2.h>
#include <modules/globebrowsing/other/concurrentjobmanager.h>
#include <modules/globebrowsing/other/threadpool.h>
#include <modules/globebrowsing/other/tiledataset.h>
#include <memory>
#include <queue>
#include <unordered_map>
namespace openspace {
class ClipMapPyramid {
public:
/**
\Param sizeLevel0 is the size of the biggest patch in the pyramid.
The parameter needs to be M_PI / pow(2, i) where i is a positive or zero
valued integer.
*/
ClipMapPyramid(Geodetic2 sizeLevel0);
~ClipMapPyramid();
Geodetic2 getPatchSizeAtLevel(int level);
Geodetic2 getPatchSizeAtLevel0();
struct TileLoadJob : public Job<TileIOResult> {
TileLoadJob(std::shared_ptr<TileDataset> textureDataProvider,
const ChunkIndex& chunkIndex)
: _tileDataset(textureDataProvider)
, _chunkIndex(chunkIndex)
{
}
virtual ~TileLoadJob() { }
virtual void execute() {
_uninitedTexture = _tileDataset->readTileData(_chunkIndex);
}
virtual std::shared_ptr<TileIOResult> product() {
return _uninitedTexture;
}
private:
const Geodetic2 _sizeLevel0;
ChunkIndex _chunkIndex;
std::shared_ptr<TileDataset> _tileDataset;
std::shared_ptr<TileIOResult> _uninitedTexture;
};
} // namespace openspace
#endif // __CLIPMAPPYRAMID_H__
class AsyncTileDataProvider {
public:
AsyncTileDataProvider(std::shared_ptr<TileDataset> textureDataProvider,
std::shared_ptr<ThreadPool> pool);
~AsyncTileDataProvider();
bool enqueueTextureData(const ChunkIndex& chunkIndex);
bool hasLoadedTextureData() const;
std::shared_ptr<TileIOResult> nextTileIOResult();
void clearRequestQueue();
std::shared_ptr<TileDataset> getTextureDataProvider() const;
protected:
virtual bool satisfiesEnqueueCriteria(const ChunkIndex&) const;
private:
std::shared_ptr<TileDataset> _tileDataset;
ConcurrentJobManager<TileIOResult> _concurrentJobManager;
std::unordered_map<HashKey, ChunkIndex> _enqueuedTileRequests;
};
} // namespace openspace
#endif // __ASYNC_TILE_DATA_PROVIDER_H__

View File

@@ -64,7 +64,7 @@ namespace openspace {
template<typename P>
class ConcurrentJobManager{
public:
ConcurrentJobManager(ThreadPool& pool) : threadPool(pool)
ConcurrentJobManager(std::shared_ptr<ThreadPool> pool) : threadPool(pool)
{
}
@@ -75,14 +75,14 @@ namespace openspace {
void enqueueJob(std::shared_ptr<Job<P>> job) {
threadPool.enqueue([this, job]() {
threadPool->enqueue([this, job]() {
job->execute();
_finishedJobs.push(job);
});
}
void clearEnqueuedJobs() {
threadPool.clearTasks();
threadPool->clearTasks();
}
std::shared_ptr<Job<P>> popFinishedJob() {
@@ -90,7 +90,7 @@ namespace openspace {
return _finishedJobs.pop();
}
size_t numFinishedJobs() {
size_t numFinishedJobs() const{
return _finishedJobs.size();
}
@@ -99,7 +99,7 @@ namespace openspace {
private:
ConcurrentQueue<std::shared_ptr<Job<P>>> _finishedJobs;
ThreadPool& threadPool;
std::shared_ptr<ThreadPool> threadPool;
};

View File

@@ -77,7 +77,7 @@ public:
_cond.notify_one();
}
size_t size() {
size_t size() const{
std::unique_lock<std::mutex> mlock(_mutex);
size_t s = _queue.size();
mlock.unlock();
@@ -87,8 +87,8 @@ public:
private:
std::queue<T> _queue;
std::mutex _mutex;
std::condition_variable _cond;
mutable std::mutex _mutex;
mutable std::condition_variable _cond;
};
}

View File

@@ -107,6 +107,9 @@ namespace openspace {
textureTypes[i].keyNumLayers, textureTypes[i].numLayers);
}
// Remove old program
_programObject.release();
_programObject = OsEng.renderEngine().buildRenderProgram(
_shaderName,
_vsPath,

View File

@@ -1,182 +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 <modules/globebrowsing/other/patchcoverageprovider.h>
#include <ghoul/logging/logmanager.h>
#include <glm/glm.hpp>
namespace {
const std::string _loggerCat = "PatchCoverageProvider";
}
namespace openspace {
PatchCoverageProvider::PatchCoverageProvider(
Geodetic2 sizeLevel0,
Geodetic2 offsetLevel0,
int depth)
: _sizeLevel0(sizeLevel0)
, _offsetLevel0(offsetLevel0)
, _depth(depth)
{
}
PatchCoverageProvider::~PatchCoverageProvider(){
}
ChunkIndex PatchCoverageProvider::getChunkIndex(const GeodeticPatch& patch) {
// Calculate the level of the index depending on the size of the incoming patch.
// The level is as big as possible (as far down as possible) but it can't be
// too big since at maximum four tiles should be used to cover a patch
int level = log2(static_cast<int>(glm::max(
_sizeLevel0.lat / (patch.size().lat),
_sizeLevel0.lon / (patch.size().lon))));
// If the depth is not big enough, the level must be clamped.
level = glm::min(level, _depth);
// Calculate the index in x y where the tile should be positioned
int nIndices = pow(2, level);
Geodetic2 tileSize = _sizeLevel0 / nIndices;
Geodetic2 nw = patch.northWestCorner();
glm::ivec2 chunkIndexXY =
glm::floor((nw.toLonLatVec2() - _offsetLevel0.toLonLatVec2()) / tileSize.toLonLatVec2());
// Flip y since indices increase from top to bottom
chunkIndexXY.y = nIndices - 1 - chunkIndexXY.y;
// Create the tileindex
ChunkIndex chunkIndex = { chunkIndexXY.x, chunkIndexXY.y, level };
return chunkIndex;
}
glm::mat3 PatchCoverageProvider::getUvTransformationPatchToTile(
GeodeticPatch patch,
const ChunkIndex& chunkIndex)
{
GeodeticPatch otherPatch(chunkIndex);
return getUvTransformationPatchToTile(patch, otherPatch);
}
glm::mat3 PatchCoverageProvider::getUvTransformationPatchToTile(
GeodeticPatch patch,
GeodeticPatch tile)
{
Vec2 posDiff =
patch.southWestCorner().toLonLatVec2() -
tile.southWestCorner().toLonLatVec2();
glm::mat3 invTileScale = glm::mat3(
{ 1 / (tile.size().lon), 0, 0,
0, 1 / (tile.size().lat), 0,
0, 0, 1 });
glm::mat3 globalTranslation = glm::mat3(
{ 1, 0, 0,
0, 1, 0,
posDiff.x, posDiff.y, 1 });
glm::mat3 patchScale = glm::mat3(
{ (patch.halfSize().lon * 2), 0, 0,
0, (patch.halfSize().lat * 2), 0,
0, 0, 1 });
return invTileScale * globalTranslation * patchScale;
}
PatchCoverage PatchCoverageProvider::getCoverage(
GeodeticPatch patch,
std::shared_ptr<TileProvider> tileProvider)
{
static const int numTilesInCoverageX = 2;
static const int numTilesInCoverageY = 2;
PatchCoverage patchCoverageToReturn;
Geodetic2 startPoint = patch.northWestCorner();
int level = (int) patch.minimumTileLevel();
ChunkIndex startIndex = ChunkIndex(startPoint, level);
for (int y = 0; y < numTilesInCoverageY; y++)
{
for (int x = 0; x < numTilesInCoverageX; x++)
{
int linearIdx = x + y * numTilesInCoverageX;
// May return negative indices
ChunkIndex chunkIndex = getChunkIndex(patch);
// Offset chunkIndex
chunkIndex.x += x;
chunkIndex.y += y;
// If the tile index is negative or too big it needs to wrap around
int nIndices = pow(2, chunkIndex.level);
ChunkIndex positiveChunkIndex = ChunkIndex(chunkIndex);
positiveChunkIndex.x += (chunkIndex.x < 0) ? nIndices : ((chunkIndex.x > nIndices - 1) ? -nIndices : 0);
positiveChunkIndex.y += (chunkIndex.y < 0) ? nIndices : ((chunkIndex.y > nIndices - 1) ? -nIndices : 0);
int numLevelsToLoop = chunkIndex.level;
// Start at the highest level and go down if the texture don't exist
for (int j = numLevelsToLoop; j >= 0; j--)
{
// Try if the texture exists
std::shared_ptr<Texture> tile = tileProvider->getOrStartFetchingTile(positiveChunkIndex);
if (tile == nullptr)
{ // If it doesn't exist, go down a level
chunkIndex.x /= 2;
chunkIndex.y /= 2;
chunkIndex.level -= 1;
}
else
{ // A texture was found, put it in the data structure to return
patchCoverageToReturn.textureTransformPairs[linearIdx].first =
tile;
patchCoverageToReturn.textureTransformPairs[linearIdx].second =
getUvTransformationPatchToTile(patch, chunkIndex);
}
}
// If the texture still doesn't exist put a temporary texture
if (patchCoverageToReturn.textureTransformPairs[linearIdx].first == nullptr)
{
patchCoverageToReturn.textureTransformPairs[linearIdx].first =
tileProvider->getDefaultTexture();
patchCoverageToReturn.textureTransformPairs[linearIdx].second =
getUvTransformationPatchToTile(patch, chunkIndex);
}
}
}
return patchCoverageToReturn;
}
} // namespace openspace

View File

@@ -0,0 +1,119 @@
/*****************************************************************************************
* *
* 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/geodetics/geodetic2.h>
#include <modules/globebrowsing/other/temporaltileprovider.h>
#include <modules/globebrowsing/globes/chunkindex.h>
#include <openspace/engine/downloadmanager.h>
#include <ghoul/logging/logmanager.h>
#include <openspace/util/time.h>
#include <string>
#include <fstream>
#include <streambuf>
namespace {
const std::string _loggerCat = "TemporalTileProvider";
}
namespace openspace {
const std::string TemporalTileProvider::TIME_PLACEHOLDER("${t}");
TemporalTileProvider::TemporalTileProvider(const std::string& datasetFile,
const TileProviderInitData& tileProviderInitData)
: _datasetFile(datasetFile)
, _tileProviderInitData(tileProviderInitData)
{
std::ifstream in(datasetFile.c_str());
ghoul_assert(errno == 0, strerror(errno) << std::endl << datasetFile);
// read file
std::string str( (std::istreambuf_iterator<char>(in)), (std::istreambuf_iterator<char>()));
_dataSourceXmlTemplate = std::string(str);
}
std::shared_ptr<TileProvider> TemporalTileProvider::getTileProvider(Time t) {
TimeKey timekey = getTimeKey(t);
auto it = _tileProviderMap.find(timekey);
if (it != _tileProviderMap.end()) {
return it->second;
}
else {
auto tileProvider = initTileProvider(timekey);
_tileProviderMap[timekey] = tileProvider;
return tileProvider;
}
}
std::shared_ptr<TileProvider> TemporalTileProvider::initTileProvider(TimeKey timekey) {
std::string gdalDatasetXml = getGdalDatasetXML(timekey);
std::shared_ptr<TileDataset> tileDataset = std::shared_ptr<TileDataset>(
new TileDataset(gdalDatasetXml, _tileProviderInitData.minimumPixelSize));
std::shared_ptr<ThreadPool> threadPool = std::shared_ptr<ThreadPool>(
new ThreadPool(_tileProviderInitData.threads));
std::shared_ptr<AsyncTileDataProvider> tileReader = std::shared_ptr<AsyncTileDataProvider>(
new AsyncTileDataProvider(tileDataset, threadPool));
std::shared_ptr<TileProvider> tileProvider= std::shared_ptr<TileProvider>(
new TileProvider(tileReader,
_tileProviderInitData.cacheSize,
_tileProviderInitData.framesUntilRequestQueueFlush));
return tileProvider;
}
TemporalTileProvider::TimeKey TemporalTileProvider::getTimeKey(const Time& t) {
std::string datestring = t.ISO8601();
datestring = datestring.substr(0, 10);
return datestring;
}
std::string TemporalTileProvider::getGdalDatasetXML(Time t) {
return getGdalDatasetXML(getTimeKey(t));
}
std::string TemporalTileProvider::getGdalDatasetXML(TimeKey timeKey) {
std::string xmlTemplate(_dataSourceXmlTemplate);
size_t pos = xmlTemplate.find(TIME_PLACEHOLDER);
size_t numChars = TIME_PLACEHOLDER.length();
ghoul_assert(pos != std::string::npos, "Invalid dataset file");
std::string timeSpecifiedXml = xmlTemplate.replace(pos, numChars, timeKey);
return timeSpecifiedXml;
}
} // namespace openspace

View File

@@ -22,73 +22,77 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __PATCHCOVERAGEPROVIDER_H__
#define __PATCHCOVERAGEPROVIDER_H__
#ifndef __TEMPORAL_TILE_PROVIDER_H__
#define __TEMPORAL_TILE_PROVIDER_H__
#include <ghoul/logging/logmanager.h>
#include <modules/globebrowsing/globes/chunkindex.h>
#include <ghoul/opengl/texture.h>
#include <modules/globebrowsing/geodetics/geodetic2.h>
#include <modules/globebrowsing/other/tileprovider.h>
#include <ghoul/opengl/texture.h>
#include <openspace/util/time.h>
#include <unordered_map>
#include "gdal_priv.h"
#include "vrtdataset.h"
//////////////////////////////////////////////////////////////////////////////////////////
// PATCH COVERAGE PROVIDER //
// TILE PROVIDER //
//////////////////////////////////////////////////////////////////////////////////////////
namespace openspace {
using namespace ghoul::opengl;
struct PatchCoverage
{
using TextureTransformPair = std::pair<std::shared_ptr<Texture>, glm::mat3>;
TextureTransformPair textureTransformPairs[4];
struct TileProviderInitData {
int minimumPixelSize;
int threads;
int cacheSize;
int framesUntilRequestQueueFlush;
};
class PatchCoverageProvider
{
class TemporalTileProvider {
public:
PatchCoverageProvider(
Geodetic2 sizeLevel0,
Geodetic2 offsetLevel0,
int depth);
~PatchCoverageProvider();
TemporalTileProvider(const std::string& datasetFile, const TileProviderInitData& tileProviderInitData);
/**
Returns the index of the tile at an appropriate level.
Appropriate meaning that the tile should be at as high level as possible
Without the tile being smaller than the patch in lat-lon space.
The tile is at least as big as the patch.
*/
ChunkIndex getChunkIndex(const GeodeticPatch& patch);
/**
A transformation (translation and scaling) from the texture space of a patch
to the texture space of a tile.
*/
glm::mat3 getUvTransformationPatchToTile(
GeodeticPatch patch,
const ChunkIndex& chunkIndex);
/**
Overloaded function
*/
glm::mat3 getUvTransformationPatchToTile(
GeodeticPatch patch,
GeodeticPatch tile);
PatchCoverage getCoverage(
GeodeticPatch patch,
std::shared_ptr<TileProvider> tileProvider);
std::shared_ptr<TileProvider> getTileProvider(Time t = Time::ref());
private:
Geodetic2 _sizeLevel0;
Geodetic2 _offsetLevel0;
int _depth;
typedef std::string TimeKey;
std::string getGdalDatasetXML(Time t);
std::string getGdalDatasetXML(TimeKey key);
static const std::string TIME_PLACEHOLDER;
TimeKey getTimeKey(const Time& t);
std::shared_ptr<TileProvider> initTileProvider(TimeKey timekey);
//////////////////////////////////////////////////////////////////////////////////
// Members variables //
//////////////////////////////////////////////////////////////////////////////////
const std::string _datasetFile;
std::string _dataSourceXmlTemplate;
std::unordered_map<TimeKey, std::shared_ptr<TileProvider> > _tileProviderMap;
TileProviderInitData _tileProviderInitData;
};
} // namespace openspace
#endif // __PATCHCOVERAGEPROVIDER_H__
#endif // __TEMPORAL_TILE_PROVIDER_H__

View File

@@ -27,12 +27,14 @@
#include <ghoul/filesystem/filesystem.h> // abspath
#include <ghoul/misc/assert.h>
#include <modules/globebrowsing/other/texturedataprovider.h>
#include <modules/globebrowsing/other/tiledataset.h>
#include <modules/globebrowsing/other/tileprovider.h>
#include <modules/globebrowsing/geodetics/angle.h>
namespace {
const std::string _loggerCat = "TextureDataProvider";
const std::string _loggerCat = "TileDataset";
}
@@ -40,42 +42,42 @@ namespace {
namespace openspace {
// INIT THIS TO FALSE AFTER REMOVED FROM TILEPROVIDER
bool TextureDataProvider::GdalHasBeenInitialized = false;
bool TileDataset::GdalHasBeenInitialized = false;
TextureDataProvider::TextureDataProvider(const std::string& fileName, int minimumPixelSize)
TileDataset::TileDataset(const std::string& gdalDatasetDesc, int minimumPixelSize, GLuint dataType)
: _minimumPixelSize(minimumPixelSize)
{
if (!GdalHasBeenInitialized) {
GDALAllRegister();
GdalHasBeenInitialized = true;
}
_dataset = (GDALDataset *)GDALOpen(absPath(fileName).c_str(), GA_ReadOnly);
ghoul_assert(_dataset != nullptr, "Failed to load dataset: " << fileName);
_dataset = (GDALDataset *)GDALOpen(gdalDatasetDesc.c_str(), GA_ReadOnly);
ghoul_assert(_dataset != nullptr, "Failed to load dataset:\n" << gdalDatasetDesc);
_dataLayout = DataLayout(_dataset, dataType);
_depthTransform = calculateTileDepthTransform();
_tileLevelDifference = calculateTileLevelDifference(_dataset, minimumPixelSize);
}
TextureDataProvider::~TextureDataProvider() {
TileDataset::~TileDataset() {
delete _dataset;
}
int TextureDataProvider::calculateTileLevelDifference(GDALDataset* dataset, int minimumPixelSize) {
int TileDataset::calculateTileLevelDifference(GDALDataset* dataset, int minimumPixelSize) {
GDALRasterBand* firstBand = dataset->GetRasterBand(1);
int numOverviews = firstBand->GetOverviewCount();
int sizeLevel0 = firstBand->GetOverview(numOverviews - 1)->GetXSize();
return log2(minimumPixelSize) - log2(sizeLevel0);
}
TileDepthTransform TextureDataProvider::calculateTileDepthTransform() {
TileDepthTransform TileDataset::calculateTileDepthTransform() {
GDALRasterBand* firstBand = _dataset->GetRasterBand(1);
GDALDataType gdalType = firstBand->GetRasterDataType();
double maximumValue = (gdalType == GDT_Float32 || gdalType == GDT_Float64) ?
1.0 : firstBand->GetMaximum();
// Floating point types does not have a fix maximum or minimum value and
// can not be normalized when sampling a texture. Hence no rescaling is needed.
double maximumValue = (_dataLayout.gdalType == GDT_Float32 || _dataLayout.gdalType == GDT_Float64) ?
1.0 : getMaximumValue(_dataLayout.gdalType);
TileDepthTransform transform;
transform.depthOffset = firstBand->GetOffset();
@@ -83,21 +85,22 @@ namespace openspace {
return transform;
}
int TextureDataProvider::getMaximumLevel() const {
int TileDataset::getMaximumLevel() const {
int numOverviews = _dataset->GetRasterBand(1)->GetOverviewCount();
int maximumLevel = numOverviews - 1 - _tileLevelDifference;
return maximumLevel;
}
TileDepthTransform TextureDataProvider::getDepthTransform() const {
TileDepthTransform TileDataset::getDepthTransform() const {
return _depthTransform;
}
std::shared_ptr<TileIOResult> TextureDataProvider::getTextureData(ChunkIndex chunkIndex)
std::shared_ptr<TileIOResult> TileDataset::readTileData(ChunkIndex chunkIndex)
{
GdalDataRegion region(_dataset, chunkIndex, _tileLevelDifference);
DataLayout dataLayout(_dataset, region);
char* imageData = new char[dataLayout.totalNumBytes];
size_t bytesPerLine = _dataLayout.bytesPerPixel * region.numPixels.x;
size_t totalNumBytes = bytesPerLine * region.numPixels.y;
char* imageData = new char[totalNumBytes];
CPLErr worstError = CPLErr::CE_None;
@@ -105,7 +108,7 @@ namespace openspace {
for (size_t i = 0; i < region.numRasters; i++) {
GDALRasterBand* rasterBand = _dataset->GetRasterBand(i + 1)->GetOverview(region.overview);
char* dataDestination = imageData + (i * dataLayout.bytesPerDatum);
char* dataDestination = imageData + (i * _dataLayout.bytesPerDatum);
CPLErr err = rasterBand->RasterIO(
GF_Read,
@@ -116,16 +119,16 @@ namespace openspace {
dataDestination, // Where to put data
region.numPixels.x, // width to write x in destination
region.numPixels.y, // width to write y in destination
dataLayout.gdalType, // Type
dataLayout.bytesPerPixel, // Pixel spacing
dataLayout.bytesPerLine); // Line spacing
_dataLayout.gdalType, // Type
_dataLayout.bytesPerPixel, // Pixel spacing
bytesPerLine); // Line spacing
// CE_None = 0, CE_Debug = 1, CE_Warning = 2, CE_Failure = 3, CE_Fatal = 4
worstError = std::max(worstError, err);
}
std::shared_ptr<RawTileData> tileData = nullptr;
tileData = createRawTileData(region, dataLayout, imageData);
tileData = createRawTileData(region, _dataLayout, imageData);
std::shared_ptr<TileIOResult> result(new TileIOResult);
result->error = worstError;
@@ -135,18 +138,20 @@ namespace openspace {
}
std::shared_ptr<RawTileData> TextureDataProvider::createRawTileData(const GdalDataRegion& region,
std::shared_ptr<RawTileData> TileDataset::createRawTileData(const GdalDataRegion& region,
const DataLayout& dataLayout, const char* imageData)
{
size_t bytesPerLine = dataLayout.bytesPerPixel * region.numPixels.x;
size_t totalNumBytes = bytesPerLine * region.numPixels.y;
//if(cplError == CPLErr::CE_Fatal)
// GDAL reads image data top to bottom. We want the opposite.
char* imageDataYflipped = new char[dataLayout.totalNumBytes];
char* imageDataYflipped = new char[totalNumBytes];
for (size_t y = 0; y < region.numPixels.y; y++) {
for (size_t x = 0; x < dataLayout.bytesPerLine; x++) {
imageDataYflipped[x + y * dataLayout.bytesPerLine] =
imageData[x + (region.numPixels.y - 1 - y) * dataLayout.bytesPerLine];
for (size_t x = 0; x < bytesPerLine; x++) {
imageDataYflipped[x + y * bytesPerLine] =
imageData[x + (region.numPixels.y - 1 - y) * bytesPerLine];
}
}
@@ -168,7 +173,7 @@ namespace openspace {
size_t TextureDataProvider::numberOfBytes(GDALDataType gdalType) {
size_t TileDataset::numberOfBytes(GDALDataType gdalType) {
switch (gdalType) {
case GDT_Byte: return sizeof(GLubyte);
case GDT_UInt16: return sizeof(GLushort);
@@ -178,13 +183,27 @@ namespace openspace {
case GDT_Float32: return sizeof(GLfloat);
case GDT_Float64: return sizeof(GLdouble);
default:
//LERROR("Unknown data type");
LERROR("Unknown data type");
return -1;
}
}
size_t TileDataset::getMaximumValue(GDALDataType gdalType) {
switch (gdalType) {
case GDT_Byte: return 2 << 7;
case GDT_UInt16: return 2 << 15;
case GDT_Int16: return 2 << 14;
case GDT_UInt32: return 2 << 31;
case GDT_Int32: return 2 << 30;
default:
LERROR("Unknown data type");
return -1;
}
}
glm::uvec2 TextureDataProvider::geodeticToPixel(GDALDataset* dataSet, const Geodetic2& geo) {
glm::uvec2 TileDataset::geodeticToPixel(GDALDataset* dataSet, const Geodetic2& geo) {
double padfTransform[6];
CPLErr err = dataSet->GetGeoTransform(padfTransform);
@@ -222,7 +241,7 @@ namespace openspace {
}
RawTileData::TextureFormat TextureDataProvider::getTextureFormat(
RawTileData::TextureFormat TileDataset::getTextureFormat(
int rasterCount, GDALDataType gdalType)
{
RawTileData::TextureFormat format;
@@ -238,7 +257,7 @@ namespace openspace {
case GDT_Int32: format.glFormat = GL_R32I; break;
case GDT_Float32: format.glFormat = GL_R32F; break;
//case GDT_Float64: format.glFormat = GL_RED; break; // No representation of 64 bit float?
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
}
break;
case 2:
@@ -251,7 +270,7 @@ namespace openspace {
case GDT_Int32: format.glFormat = GL_RG32I; break;
case GDT_Float32: format.glFormat = GL_RG32F; break;
case GDT_Float64: format.glFormat = GL_RED; break; // No representation of 64 bit float?
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
}
break;
case 3:
@@ -264,7 +283,7 @@ namespace openspace {
case GDT_Int32: format.glFormat = GL_RGB32I; break;
case GDT_Float32: format.glFormat = GL_RGB32F; break;
// case GDT_Float64: format.glFormat = GL_RED; break;// No representation of 64 bit float?
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
}
break;
case 4:
@@ -277,11 +296,11 @@ namespace openspace {
case GDT_Int32: format.glFormat = GL_RGBA32I; break;
case GDT_Float32: format.glFormat = GL_RGBA32F; break;
case GDT_Float64: format.glFormat = GL_RED; break; // No representation of 64 bit float?
default: ;//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
default: LERROR("GDAL data type unknown to OpenGL: " << gdalType);
}
break;
default:
//LERROR("Unknown number of channels for OpenGL texture: " << rasterCount);
LERROR("Unknown number of channels for OpenGL texture: " << rasterCount);
break;
}
return format;
@@ -292,7 +311,7 @@ namespace openspace {
GLuint TextureDataProvider::getOpenGLDataType(GDALDataType gdalType) {
GLuint TileDataset::getOpenGLDataType(GDALDataType gdalType) {
switch (gdalType) {
case GDT_Byte: return GL_UNSIGNED_BYTE;
case GDT_UInt16: return GL_UNSIGNED_SHORT;
@@ -302,13 +321,28 @@ namespace openspace {
case GDT_Float32: return GL_FLOAT;
case GDT_Float64: return GL_DOUBLE;
default:
//LERROR("GDAL data type unknown to OpenGL: " << gdalType);
LERROR("GDAL data type unknown to OpenGL: " << gdalType);
return GL_UNSIGNED_BYTE;
}
}
GDALDataType TileDataset::getGdalDataType(GLuint glType) {
switch (glType) {
case GL_UNSIGNED_BYTE: return GDT_Byte;
case GL_UNSIGNED_SHORT: return GDT_UInt16;
case GL_SHORT: return GDT_Int16;
case GL_UNSIGNED_INT: return GDT_UInt32;
case GL_INT: return GDT_Int32;
case GL_FLOAT: return GDT_Float32;
case GL_DOUBLE: return GDT_Float64;
default:
LERROR("OpenGL data type unknown to GDAL: " << glType);
return GDT_Unknown;
}
}
TextureDataProvider::GdalDataRegion::GdalDataRegion(GDALDataset * dataSet,
TileDataset::GdalDataRegion::GdalDataRegion(GDALDataset * dataSet,
const ChunkIndex& chunkIndex, int tileLevelDifference)
: chunkIndex(chunkIndex)
{
@@ -351,14 +385,14 @@ namespace openspace {
numPixels = pixelEnd - pixelStart;
}
TileDataset::DataLayout::DataLayout() {
}
TextureDataProvider::DataLayout::DataLayout(GDALDataset* dataSet, const GdalDataRegion& region) {
TileDataset::DataLayout::DataLayout(GDALDataset* dataSet, GLuint glType) {
// Assume all raster bands have the same data type
gdalType = dataSet->GetRasterBand(1)->GetRasterDataType();
gdalType = glType != 0 ? getGdalDataType(glType) : dataSet->GetRasterBand(1)->GetRasterDataType();
bytesPerDatum = numberOfBytes(gdalType);
bytesPerPixel = bytesPerDatum * region.numRasters;
bytesPerLine = bytesPerPixel * region.numPixels.x;
totalNumBytes = bytesPerLine * region.numPixels.y;
bytesPerPixel = bytesPerDatum * dataSet->GetRasterCount();
}

View File

@@ -22,8 +22,8 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __TEXTURE_DATA_PROVIDER_H__
#define __TEXTURE_DATA_PROVIDER_H__
#ifndef __TILE_DATASET_H__
#define __TILE_DATASET_H__
//#include <modules/globebrowsing/other/tileprovider.h>
@@ -34,6 +34,7 @@
#include "gdal_priv.h"
#include <memory>
#include <set>
#include <queue>
@@ -86,14 +87,26 @@ namespace openspace {
class TextureDataProvider {
class TileDataset {
public:
TextureDataProvider(const std::string& fileName, int minimumPixelSize);
~TextureDataProvider();
/**
* Opens a GDALDataset in readonly mode and calculates meta data required for
* reading tile using a ChunkIndex.
*
* \param gdalDatasetDesc - A path to a specific file or raw XML describing the dataset
* \param minimumPixelSize - minimum number of pixels per side per tile requested
* \param datatype - datatype for storing pixel data in requested tile
*/
TileDataset(const std::string& gdalDatasetDesc, int minimumPixelSize, GLuint dataType = 0);
~TileDataset();
std::shared_ptr<TileIOResult> getTextureData(ChunkIndex chunkIndex);
std::shared_ptr<TileIOResult> readTileData(ChunkIndex chunkIndex);
int getMaximumLevel() const;
@@ -103,6 +116,7 @@ namespace openspace {
private:
//////////////////////////////////////////////////////////////////////////////////
// HELPER STRUCTS //
//////////////////////////////////////////////////////////////////////////////////
@@ -126,13 +140,12 @@ namespace openspace {
};
struct DataLayout {
DataLayout(GDALDataset* dataSet, const GdalDataRegion& region);
DataLayout();
DataLayout(GDALDataset* dataSet, GLuint glType);
GDALDataType gdalType;
size_t bytesPerDatum;
size_t bytesPerPixel;
size_t bytesPerLine;
size_t totalNumBytes;
};
@@ -153,10 +166,14 @@ namespace openspace {
static GLuint getOpenGLDataType(GDALDataType gdalType);
static GDALDataType getGdalDataType(GLuint glType);
static RawTileData::TextureFormat getTextureFormat(int rasterCount, GDALDataType gdalType);
static size_t numberOfBytes(GDALDataType gdalType);
static size_t getMaximumValue(GDALDataType gdalType);
static std::shared_ptr<RawTileData> createRawTileData(const GdalDataRegion& region,
const DataLayout& dataLayout, const char* imageData);
@@ -173,6 +190,7 @@ namespace openspace {
TileDepthTransform _depthTransform;
GDALDataset* _dataset;
DataLayout _dataLayout;
};
@@ -184,4 +202,4 @@ namespace openspace {
#endif // __TEXTURE_DATA_PROVIDER_H__
#endif // __TILE_DATASET_H__

View File

@@ -46,79 +46,48 @@ namespace {
namespace openspace {
TileProvider::TileProvider(
const std::string& filePath,
int tileCacheSize,
int minimumPixelSize,
int framesUntilRequestFlush)
: _filePath(filePath)
, _tileCache(tileCacheSize) // setting cache size
TileProvider::TileProvider(std::shared_ptr<AsyncTileDataProvider> tileReader, int tileCacheSize,
int framesUntilFlushRequestQueue)
: _asyncTextureDataProvider(tileReader)
, _tileCache(tileCacheSize)
, _framesSinceLastRequestFlush(0)
, _framesUntilRequestFlush(framesUntilRequestFlush)
, _tileLoadManager(TileProviderManager::tileRequestThreadPool)
, _rawTextureTileDataProvider(filePath, minimumPixelSize)
{
// Set a temporary texture
std::string fileName = "textures/earth_bluemarble.jpg";
_defaultTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(fileName)));
if (_defaultTexture) {
LDEBUG("Loaded texture from '" << fileName << "'");
_defaultTexture->uploadTexture();
// Textures of planets looks much smoother with AnisotropicMipMap rather than linear
// TODO: AnisotropicMipMap crashes on ATI cards ---abock
//_testTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_defaultTexture->setFilter(ghoul::opengl::Texture::FilterMode::Linear);
_defaultTexture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToBorder);
}
}
TileProvider::~TileProvider(){
clearRequestQueue();
}
void TileProvider::prerender() {
//_rawTextureTileDataProvider.updateAsyncRequests();
initTexturesFromLoadedData();
if (_framesSinceLastRequestFlush++ > _framesUntilRequestFlush) {
clearRequestQueue();
}
}
void TileProvider::initTexturesFromLoadedData() {
while (_tileLoadManager.numFinishedJobs() > 0) {
std::shared_ptr<TileIOResult> tileIOResult= _tileLoadManager.popFinishedJob()->product();
while (_asyncTextureDataProvider->hasLoadedTextureData()) {
std::shared_ptr<TileIOResult> tileIOResult = _asyncTextureDataProvider->nextTileIOResult();
initializeAndAddToCache(tileIOResult);
}
/*
while (_rawTextureTileDataProvider.hasTextureTileData()) {
auto rawTextureTile = _rawTextureTileDataProvider.nextTextureTile();
initializeAndAddToCache(rawTextureTile);
}
*/
}
void TileProvider::clearRequestQueue() {
_tileLoadManager.clearEnqueuedJobs();
_queuedTileRequests.clear();
_asyncTextureDataProvider->clearRequestQueue();
_framesSinceLastRequestFlush = 0;
}
Tile TileProvider::getHighestResolutionTile(ChunkIndex chunkIndex) {
TileUvTransform uvTransform;
uvTransform.uvOffset = glm::vec2(0, 0);
uvTransform.uvScale = glm::vec2(1, 1);
int maximumLevel = _rawTextureTileDataProvider.getMaximumLevel();
Tile TileProvider::getHighestResolutionTile(ChunkIndex chunkIndex, int parents, TileUvTransform uvTransform) {
for (int i = 0; i < parents && chunkIndex.level > 1; i++) {
transformFromParent(chunkIndex, uvTransform);
chunkIndex = chunkIndex.parent();
}
int maximumLevel = _asyncTextureDataProvider->getTextureDataProvider()->getMaximumLevel();
while(chunkIndex.level > maximumLevel){
transformFromParent(chunkIndex, uvTransform);
chunkIndex = chunkIndex.parent();
@@ -130,13 +99,14 @@ namespace openspace {
Tile TileProvider::getOrEnqueueHighestResolutionTile(const ChunkIndex& chunkIndex,
TileUvTransform& uvTransform)
{
HashKey key = chunkIndex.hashKey();
if (_tileCache.exist(key) && _tileCache.get(key).ioError == CPLErr::CE_None) {
std::shared_ptr<Texture> texture = _tileCache.get(key).texture;
return { texture, uvTransform };
return { _tileCache.get(key).texture, uvTransform };
}
else if (chunkIndex.level <= 1) {
return { getDefaultTexture(), uvTransform };
else if (chunkIndex.level < 1) {
return { nullptr, uvTransform };
}
else {
// We don't have the tile for the requested level
@@ -146,7 +116,7 @@ namespace openspace {
// As we didn't have this tile, push it to the request queue
// post order enqueueing tiles --> enqueue tiles at low levels first
enqueueTileRequest(chunkIndex);
_asyncTextureDataProvider->enqueueTextureData(chunkIndex);
return tile;
}
@@ -175,51 +145,16 @@ namespace openspace {
return _tileCache.get(hashkey).texture;
}
else {
enqueueTileRequest(chunkIndex);
_asyncTextureDataProvider->enqueueTextureData(chunkIndex);
return nullptr;
}
}
bool TileProvider::enqueueTileRequest(const ChunkIndex& chunkIndex) {
HashKey key = chunkIndex.hashKey();
auto it = _queuedTileRequests.begin();
auto end = _queuedTileRequests.end();
for (; it != end; it++) {
const ChunkIndex& otherChunk = it->second;
if (chunkIndex.level == otherChunk.level &&
chunkIndex.manhattan(otherChunk) < 1) {
return false;
}
}
std::shared_ptr<TextureTileLoadJob> job = std::shared_ptr<TextureTileLoadJob>(
new TextureTileLoadJob(this, chunkIndex));
_tileLoadManager.enqueueJob(job);
_queuedTileRequests[key] = chunkIndex;
return true;
}
std::shared_ptr<Texture> TileProvider::getDefaultTexture() {
return _defaultTexture;
}
TileDepthTransform TileProvider::depthTransform() {
return _rawTextureTileDataProvider.getDepthTransform();
return _asyncTextureDataProvider->getTextureDataProvider()->getDepthTransform();
}
std::shared_ptr<TileIOResult> TileProvider::syncDownloadData(
const ChunkIndex& chunkIndex) {
std::shared_ptr<TileIOResult> res = _rawTextureTileDataProvider.getTextureData(chunkIndex);
return res;
}
void TileProvider::initializeAndAddToCache(std::shared_ptr<TileIOResult> tileIOResult) {
std::shared_ptr<RawTileData> tileData = tileIOResult->rawTileData;

View File

@@ -37,8 +37,7 @@
#include <modules/globebrowsing/geodetics/geodetic2.h>
#include <modules/globebrowsing/other/lrucache.h>
#include <modules/globebrowsing/other/concurrentjobmanager.h>
#include <modules/globebrowsing/other/texturedataprovider.h>
#include <modules/globebrowsing/other/asynctilereader.h>
//////////////////////////////////////////////////////////////////////////////////////////
// TILE PROVIDER //
@@ -47,76 +46,68 @@
namespace openspace {
using namespace ghoul::opengl;
struct TileUvTransform
{
glm::vec2 uvOffset;
glm::vec2 uvScale;
};
struct Tile {
std::shared_ptr<Texture> texture;
TileUvTransform uvTransform;
};
struct MetaTexture {
std::shared_ptr<Texture> texture;
CPLErr ioError;
};
/**
Provides tiles through GDAL datasets which can be defined with xml files
for example for wms.
*/
class TileProvider {
public:
TileProvider(const std::string& fileName, int tileCacheSize, int minimumPixelSize,
int framesUntilRequestFlush);
TileProvider(std::shared_ptr<AsyncTileDataProvider> tileReader, int tileCacheSize,
int framesUntilFlushRequestQueue);
~TileProvider();
Tile getHighestResolutionTile(ChunkIndex chunkIndex);
Tile getHighestResolutionTile(ChunkIndex chunkIndex, int parents = 0,
TileUvTransform uvTransform = { glm::vec2(0, 0), glm::vec2(1, 1)});
std::shared_ptr<Texture> getOrStartFetchingTile(ChunkIndex chunkIndex);
std::shared_ptr<Texture> getDefaultTexture();
TileDepthTransform depthTransform();
void prerender();
static ThreadPool threadPool;
private:
friend class TextureTileLoadJob;
//////////////////////////////////////////////////////////////////////////////////
// Helper functions //
//////////////////////////////////////////////////////////////////////////////////
Tile getOrEnqueueHighestResolutionTile(const ChunkIndex& ci, TileUvTransform& uvTransform);
Tile getOrEnqueueHighestResolutionTile(const ChunkIndex& ci,
TileUvTransform& uvTransform);
std::shared_ptr<Texture> getOrStartFetchingTile(ChunkIndex chunkIndex);
void transformFromParent(const ChunkIndex& ci, TileUvTransform& uv) const;
/**
Fetches all the needeed texture data from the GDAL dataset.
*/
std::shared_ptr<TileIOResult> syncDownloadData(
const ChunkIndex& chunkIndex);
/**
Creates an OpenGL texture and pushes the data to the GPU.
*/
void initializeAndAddToCache(
std::shared_ptr<TileIOResult> uninitedTexture);
bool enqueueTileRequest(const ChunkIndex& ci);
void initializeAndAddToCache(std::shared_ptr<TileIOResult> uninitedTexture);
void clearRequestQueue();
@@ -124,27 +115,17 @@ namespace openspace {
//////////////////////////////////////////////////////////////////////////////////
// Member variables //
//////////////////////////////////////////////////////////////////////////////////
LRUCache<HashKey, MetaTexture> _tileCache;
std::unordered_map<HashKey, ChunkIndex> _queuedTileRequests;
int _framesSinceLastRequestFlush;
int _framesUntilRequestFlush;
const std::string _filePath;
TextureDataProvider _rawTextureTileDataProvider;
ConcurrentJobManager<TileIOResult> _tileLoadManager;
std::shared_ptr<Texture> _defaultTexture;
std::shared_ptr<AsyncTileDataProvider> _asyncTextureDataProvider;
};
@@ -155,38 +136,4 @@ namespace openspace {
namespace openspace {
using namespace ghoul::opengl;
struct TextureTileLoadJob : public Job<TileIOResult> {
TextureTileLoadJob(TileProvider * tileProvider, const ChunkIndex& chunkIndex)
: _tileProvider(tileProvider)
, _chunkIndex(chunkIndex) {
}
virtual ~TextureTileLoadJob() { }
virtual void execute() {
_uninitedTexture = _tileProvider->syncDownloadData(_chunkIndex);
}
virtual std::shared_ptr<TileIOResult> product() {
return _uninitedTexture;
}
private:
ChunkIndex _chunkIndex;
TileProvider * _tileProvider;
std::shared_ptr<TileIOResult> _uninitedTexture;
};
}
#endif // __TILE_PROVIDER_H__

File diff suppressed because it is too large Load Diff

View File

@@ -34,10 +34,9 @@
#include <modules/globebrowsing/geodetics/geodetic2.h>
#include <modules/globebrowsing/geodetics/ellipsoid.h>
#include <modules/globebrowsing/meshes/grid.h>
#include <modules/globebrowsing/meshes/clipmapgrid.h>
//#include <modules/globebrowsing/rendering/frustumculler.h>
#include <modules/globebrowsing/other/patchcoverageprovider.h>
#include <modules/globebrowsing/other/tileprovidermanager.h>
#include <modules/globebrowsing/other/layeredtextureshaderprovider.h>
#include <modules/globebrowsing/globes/chunknode.h>
@@ -95,35 +94,6 @@ namespace openspace {
class ClipMapPatchRenderer : public PatchRenderer {
public:
ClipMapPatchRenderer(
shared_ptr<ClipMapGrid> grid,
shared_ptr<TileProviderManager> tileProviderManager);
~ClipMapPatchRenderer();
void renderPatch(
const Geodetic2& patchSize,
const RenderData& data,
const Ellipsoid& ellipsoid);
private:
void renderPatchGlobally(
const Geodetic2& patchSize,
const RenderData& data,
const Ellipsoid& ellipsoid);
void renderPatchLocally(
const Geodetic2& patchSize,
const RenderData& data,
const Ellipsoid& ellipsoid);
unique_ptr<ProgramObject> _programObjectGlobalRendering;
unique_ptr<ProgramObject> _programObjectLocalRendering;
PatchCoverageProvider _patchCoverageProvider;
shared_ptr<ClipMapGrid> _grid;
};
} // namespace openspace

View File

@@ -31,31 +31,43 @@
#define NUMLAYERS_HEIGHTMAP #{numLayersHeight}
uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE];
uniform TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE];
uniform TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE];
in vec4 fs_position;
in vec2 fs_uv;
in float tileInterpolationParameter;
Fragment getFragment() {
Fragment frag;
#for i in 0..#{numLayersColor}
// tileInterpolationParameter increases with distance
float w1 = clamp(1 - tileInterpolationParameter, 0 , 1);
float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1));
float w3 = clamp(tileInterpolationParameter - 1, 0 , 1);
#for j in 1..#{numLayersColor}
{
int i = #{j} - 1;
vec2 samplePos =
colorTiles[#{i}].uvTransform.uvScale * fs_uv +
colorTiles[#{i}].uvTransform.uvOffset;
vec4 colorSample = texture(colorTiles[#{i}].textureSampler, samplePos);
colorTiles[i].uvTransform.uvScale * fs_uv +
colorTiles[i].uvTransform.uvOffset;
vec2 samplePosParent1 =
colorTilesParent1[i].uvTransform.uvScale * fs_uv +
colorTilesParent1[i].uvTransform.uvOffset;
vec2 samplePosParent2 =
colorTilesParent2[i].uvTransform.uvScale * fs_uv +
colorTilesParent2[i].uvTransform.uvOffset;
vec4 colorSample =
w1 * texture(colorTiles[i].textureSampler, samplePos) +
w2 * texture(colorTilesParent1[i].textureSampler, samplePosParent1) +
w3 * texture(colorTilesParent2[i].textureSampler, samplePosParent2);
frag.color = blendOver(frag.color, colorSample);
}
#endfor
//frag.color.rgb *= 10;
// Sample position overlay
//frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1);
// Border overlay
//frag.color = frag.color + patchBorderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.depth = fs_position.w;
return frag;

View File

@@ -37,12 +37,24 @@ uniform vec3 radiiSquared;
uniform vec2 minLatLon;
uniform vec2 lonLatScalingFactor;
uniform int xSegments;
uniform float skirtLength;
uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP];
uniform TextureTile heightTilesParent1[NUMLAYERS_HEIGHTMAP];
uniform TextureTile heightTilesParent2[NUMLAYERS_HEIGHTMAP];
uniform vec3 cameraPosition;
uniform float distanceScaleFactor;
uniform int chunkLevel;
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
// tileInterpolationParameter is used to interpolate between a tile and its parent tiles
// The value increases with the distance from the vertex (or fragment) to the camera
out float tileInterpolationParameter;
PositionNormalPair globalInterpolation() {
vec2 lonLatInput;
@@ -58,18 +70,49 @@ void main()
float height = 0;
#for i in 0..#{numLayersHeight}
{
vec2 samplePos =
heightTiles[#{i}].uvTransform.uvScale * in_uv +
heightTiles[#{i}].uvTransform.uvOffset;
// Calculate desired level based on distance to the vertex on the ellipsoid
// Before any heightmapping is done
float distToVertexOnEllipsoid = length(pair.position - cameraPosition);
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
float desiredLevel = log2(projectedScaleFactor);
float sampledValue = texture(heightTiles[#{i}].textureSampler, samplePos).r;
tileInterpolationParameter = chunkLevel - desiredLevel;
float w1 = clamp(1 - tileInterpolationParameter, 0 , 1);
float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1));
float w3 = clamp(tileInterpolationParameter - 1, 0 , 1);
#for j in 1..#{numLayersHeight}
{
int i = #{j} - 1;
vec2 samplePos =
heightTiles[i].uvTransform.uvScale * in_uv +
heightTiles[i].uvTransform.uvOffset;
vec2 samplePosParent1 =
heightTilesParent1[i].uvTransform.uvScale * in_uv +
heightTilesParent1[i].uvTransform.uvOffset;
vec2 samplePosParent2 =
heightTilesParent2[i].uvTransform.uvScale * in_uv +
heightTilesParent2[i].uvTransform.uvOffset;
float sampledValue =
w1 * texture(heightTiles[i].textureSampler, samplePos).r +
w2 * texture(heightTilesParent1[i].textureSampler, samplePosParent1).r +
w3 * texture(heightTilesParent2[i].textureSampler, samplePosParent2).r;
// TODO : Some kind of blending here. Now it just writes over
height = (sampledValue *
heightTiles[#{i}].depthTransform.depthScale +
heightTiles[#{i}].depthTransform.depthOffset);
heightTiles[i].depthTransform.depthScale +
heightTiles[i].depthTransform.depthOffset);
// Skirts
int vertexIDx = gl_VertexID % (xSegments + 3);
int vertexIDy = gl_VertexID / (xSegments + 3);
if (vertexIDx == 0 ||
vertexIDy == 0 ||
vertexIDx == (xSegments + 2) ||
vertexIDy == (xSegments + 2) ) {
height -= skirtLength;
}
}
#endfor

View File

@@ -1,92 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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. *
****************************************************************************************/
/*
// Heightmap coverage
uniform sampler2D textureSamplerHeight00;
uniform sampler2D textureSamplerHeight10;
uniform sampler2D textureSamplerHeight01;
uniform sampler2D textureSamplerHeight11;
uniform mat3 uvTransformPatchToTileHeight00;
uniform mat3 uvTransformPatchToTileHeight10;
uniform mat3 uvTransformPatchToTileHeight01;
uniform mat3 uvTransformPatchToTileHeight11;
*/
// Colortexture coverage
uniform sampler2D textureSamplerColor00;
uniform sampler2D textureSamplerColor10;
uniform sampler2D textureSamplerColor01;
uniform sampler2D textureSamplerColor11;
uniform mat3 uvTransformPatchToTileColor00;
uniform mat3 uvTransformPatchToTileColor10;
uniform mat3 uvTransformPatchToTileColor01;
uniform mat3 uvTransformPatchToTileColor11;
uniform uvec2 texture00DimensionsColor;
uniform uvec2 texture10DimensionsColor;
uniform uvec2 texture01DimensionsColor;
uniform uvec2 texture11DimensionsColor;
//uniform int segmentsPerPatch;
in vec4 vs_position;
in vec3 fs_position;
in vec2 fs_uv;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
Fragment frag;
frag.color = vec4(0);
vec4 color00, color10, color01, color11;
vec2 uv00 = vec2(uvTransformPatchToTileColor00 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv10 = vec2(uvTransformPatchToTileColor10 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv01 = vec2(uvTransformPatchToTileColor01 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv11 = vec2(uvTransformPatchToTileColor11 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 d00 = 1 / vec2(texture00DimensionsColor);
vec2 d10 = 1 / vec2(texture10DimensionsColor);
vec2 d01 = 1 / vec2(texture01DimensionsColor);
vec2 d11 = 1 / vec2(texture11DimensionsColor);
if (uv00.x > -d00.x && uv00.x < 1 + d00.x && uv00.y > -d00.y && uv00.y < 1 + d00.y)
color00 = texture(textureSamplerColor00, uv00);
if (uv10.x > -d10.x && uv10.x < 1 + d10.x && uv10.y > -d10.y && uv10.y < 1 + d10.y)
color10 = texture(textureSamplerColor10, uv10);
if (uv01.x > -d01.x && uv01.x < 1 + d01.x && uv01.y > -d01.y && uv01.y < 1 + d01.y)
color01 = texture(textureSamplerColor01, uv01);
if (uv11.x > -d11.x && uv11.x < 1 + d11.x && uv11.y > -d11.y && uv11.y < 1 + d11.y)
color11 = texture(textureSamplerColor11, uv11);
frag.color = max(color00, max(color10, max(color01, color11)));
//frag.color = vec4(frag.color.r, frag.color.r, frag.color.r, 1);
frag.depth = vs_position.w;
return frag;
}

View File

@@ -1,113 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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. *
****************************************************************************************/
#version __CONTEXT__
uniform mat4 modelViewProjectionTransform;
uniform vec3 radiiSquared;
uniform vec2 minLatLon;
uniform vec2 lonLatScalingFactor;
uniform ivec2 contraction; // [-1, 1]
uniform int segmentsPerPatch;
uniform sampler2D textureSamplerHeight00;
uniform sampler2D textureSamplerHeight10;
uniform sampler2D textureSamplerHeight01;
uniform sampler2D textureSamplerHeight11;
uniform mat3 uvTransformPatchToTileHeight00;
uniform mat3 uvTransformPatchToTileHeight10;
uniform mat3 uvTransformPatchToTileHeight01;
uniform mat3 uvTransformPatchToTileHeight11;
uniform uvec2 texture00DimensionsHeight;
uniform uvec2 texture10DimensionsHeight;
uniform uvec2 texture01DimensionsHeight;
uniform uvec2 texture11DimensionsHeight;
layout(location = 1) in vec2 in_uv;
out vec4 vs_position;
out vec3 fs_position;
out vec2 fs_uv;
#include "PowerScaling/powerScaling_vs.hglsl"
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
PositionNormalPair globalInterpolation(vec2 uv) {
vec2 lonLatInput;
lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * uv.y; // Lat
lonLatInput.x = minLatLon.x + lonLatScalingFactor.x * uv.x; // Lon
return geodetic2ToCartesian(lonLatInput.y, lonLatInput.x, radiiSquared);;
}
void main()
{
fs_uv = in_uv;
// Contract
vec2 scaledContraction = contraction / float(segmentsPerPatch);
fs_uv += scaledContraction;
fs_uv = clamp(fs_uv, 0, 1);
fs_uv -= scaledContraction;
PositionNormalPair pair = globalInterpolation(fs_uv);
float sampledHeight00 = 0;
float sampledHeight10 = 0;
float sampledHeight01 = 0;
float sampledHeight11 = 0;
vec2 uv00 = vec2(uvTransformPatchToTileHeight00 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv10 = vec2(uvTransformPatchToTileHeight10 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv01 = vec2(uvTransformPatchToTileHeight01 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv11 = vec2(uvTransformPatchToTileHeight11 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 d00 = vec2(1,1) / texture00DimensionsHeight;
vec2 d10 = vec2(1,1) / texture10DimensionsHeight;
vec2 d01 = vec2(1,1) / texture01DimensionsHeight;
vec2 d11 = vec2(1,1) / texture11DimensionsHeight;
if (uv00.x > -d00.x && uv00.x < 1 + d00.x && uv00.y > -d00.y && uv00.y < 1 + d00.y)
sampledHeight00 = texture(textureSamplerHeight00, uv00).r;
if (uv10.x > -d10.x && uv10.x < 1 + d10.x && uv10.y > -d10.y && uv10.y < 1 + d10.y)
sampledHeight10 = texture(textureSamplerHeight10, uv10).r;
if (uv01.x > -d01.x && uv01.x < 1 + d01.x && uv01.y > -d01.y && uv01.y < 1 + d01.y)
sampledHeight01 = texture(textureSamplerHeight01, uv01).r;
if (uv11.x > -d11.x && uv11.x < 1 + d11.x && uv11.y > -d11.y && uv11.y < 1 + d11.y)
sampledHeight11 = texture(textureSamplerHeight11, uv11).r;
float sampledHeight = max(sampledHeight00, max(sampledHeight10, max(sampledHeight01, sampledHeight11)));
pair.position += pair.normal * sampledHeight * pow(2,15);
vec4 position = modelViewProjectionTransform * vec4(pair.position, 1);
fs_position = pair.position;
gl_Position = z_normalization(position);
vs_position = gl_Position;
}

View File

@@ -31,6 +31,12 @@
#define NUMLAYERS_HEIGHTMAP #{numLayersHeight}
uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE];
uniform TextureTile colorTilesParent1[NUMLAYERS_COLORTEXTURE];
uniform TextureTile colorTilesParent2[NUMLAYERS_COLORTEXTURE];
// tileInterpolationParameter is used to interpolate between a tile and its parent tiles
// The value increases with the distance from the vertex (or fragment) to the camera
in float tileInterpolationParameter;
in vec4 fs_position;
in vec2 fs_uv;
@@ -38,29 +44,33 @@ in vec2 fs_uv;
Fragment getFragment() {
Fragment frag;
#for i in 0..#{numLayersColor}
// tileInterpolationParameter increases with distance to camera
float w1 = clamp(1 - tileInterpolationParameter, 0 , 1);
float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1));
float w3 = clamp(tileInterpolationParameter - 1, 0 , 1);
#for j in 1..#{numLayersColor}
{
int i = #{j} - 1;
vec2 samplePos =
colorTiles[#{i}].uvTransform.uvScale * fs_uv +
colorTiles[#{i}].uvTransform.uvOffset;
vec4 colorSample = texture(colorTiles[#{i}].textureSampler, samplePos);
colorTiles[i].uvTransform.uvScale * fs_uv +
colorTiles[i].uvTransform.uvOffset;
vec2 samplePosParent1 =
colorTilesParent1[i].uvTransform.uvScale * fs_uv +
colorTilesParent1[i].uvTransform.uvOffset;
vec2 samplePosParent2 =
colorTilesParent2[i].uvTransform.uvScale * fs_uv +
colorTilesParent2[i].uvTransform.uvOffset;
vec4 colorSample =
w1 * texture(colorTiles[i].textureSampler, samplePos) +
w2 * texture(colorTilesParent1[i].textureSampler, samplePosParent1) +
w3 * texture(colorTilesParent2[i].textureSampler, samplePosParent2);
frag.color = blendOver(frag.color, colorSample);
}
#endfor
//vec2 samplePos =
// colorTile.uvTransform.uvScale * fs_uv +
// colorTile.uvTransform.uvOffset;
//frag.color = texture(colorTile.textureSampler, samplePos);
//frag.color.rgb *= 10;
// Sample position overlay
//frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1);
// Border overlay
//frag.color = frag.color + patchBorderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.depth = fs_position.w;
return frag;

View File

@@ -41,11 +41,22 @@ uniform vec3 p11;
uniform vec3 patchNormalCameraSpace;
uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP];
uniform TextureTile heightTilesParent1[NUMLAYERS_HEIGHTMAP];
uniform TextureTile heightTilesParent2[NUMLAYERS_HEIGHTMAP];
uniform int xSegments;
uniform float skirtLength;
uniform float distanceScaleFactor;
uniform int chunkLevel;
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
// tileInterpolationParameter is used to interpolate between a tile and its parent tiles
// The value increases with the distance from the vertex (or fragment) to the camera
out float tileInterpolationParameter;
vec3 bilinearInterpolation(vec2 uv) {
// Bilinear interpolation
@@ -62,18 +73,49 @@ void main()
float height = 0;
#for i in 0..#{numLayersHeight}
{
vec2 samplePos =
heightTiles[#{i}].uvTransform.uvScale * in_uv +
heightTiles[#{i}].uvTransform.uvOffset;
// Calculate desired level based on distance to the vertex on the ellipsoid
// Before any heightmapping is done
float distToVertexOnEllipsoid = length(p);
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
float desiredLevel = log2(projectedScaleFactor);
float sampledValue = texture(heightTiles[#{i}].textureSampler, samplePos).r;
tileInterpolationParameter = chunkLevel - desiredLevel;
float w1 = clamp(1 - tileInterpolationParameter, 0 , 1);
float w2 = (clamp(tileInterpolationParameter, 0 , 1) - clamp(tileInterpolationParameter - 1, 0 , 1));
float w3 = clamp(tileInterpolationParameter - 1, 0 , 1);
#for j in 1..#{numLayersHeight}
{
int i = #{j} - 1;
vec2 samplePos =
heightTiles[i].uvTransform.uvScale * in_uv +
heightTiles[i].uvTransform.uvOffset;
vec2 samplePosParent1 =
heightTilesParent1[i].uvTransform.uvScale * in_uv +
heightTilesParent1[i].uvTransform.uvOffset;
vec2 samplePosParent2 =
heightTilesParent2[i].uvTransform.uvScale * in_uv +
heightTilesParent2[i].uvTransform.uvOffset;
float sampledValue =
w1 * texture(heightTiles[i].textureSampler, samplePos).r +
w2 * texture(heightTilesParent1[i].textureSampler, samplePosParent1).r +
w3 * texture(heightTilesParent2[i].textureSampler, samplePosParent2).r;
// TODO : Some kind of blending here. Now it just writes over
height = (sampledValue *
heightTiles[#{i}].depthTransform.depthScale +
heightTiles[#{i}].depthTransform.depthOffset);
heightTiles[i].depthTransform.depthScale +
heightTiles[i].depthTransform.depthOffset);
// Skirts
int vertexIDx = gl_VertexID % (xSegments + 3);
int vertexIDy = gl_VertexID / (xSegments + 3);
if (vertexIDx == 0 ||
vertexIDy == 0 ||
vertexIDx == (xSegments + 2) ||
vertexIDy == (xSegments + 2) ) {
height -= skirtLength;
}
}
#endfor

View File

@@ -1,92 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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. *
****************************************************************************************/
/*
// Heightmap coverage
uniform sampler2D textureSamplerHeight00;
uniform sampler2D textureSamplerHeight10;
uniform sampler2D textureSamplerHeight01;
uniform sampler2D textureSamplerHeight11;
uniform mat3 uvTransformPatchToTileHeight00;
uniform mat3 uvTransformPatchToTileHeight10;
uniform mat3 uvTransformPatchToTileHeight01;
uniform mat3 uvTransformPatchToTileHeight11;
*/
// Colortexture coverage
uniform sampler2D textureSamplerColor00;
uniform sampler2D textureSamplerColor10;
uniform sampler2D textureSamplerColor01;
uniform sampler2D textureSamplerColor11;
uniform mat3 uvTransformPatchToTileColor00;
uniform mat3 uvTransformPatchToTileColor10;
uniform mat3 uvTransformPatchToTileColor01;
uniform mat3 uvTransformPatchToTileColor11;
uniform uvec2 texture00DimensionsColor;
uniform uvec2 texture10DimensionsColor;
uniform uvec2 texture01DimensionsColor;
uniform uvec2 texture11DimensionsColor;
//uniform int segmentsPerPatch;
in vec4 vs_position;
in vec3 fs_position;
in vec2 fs_uv;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
Fragment frag;
frag.color = vec4(0);
vec4 color00, color10, color01, color11;
vec2 uv00 = vec2(uvTransformPatchToTileColor00 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv10 = vec2(uvTransformPatchToTileColor10 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv01 = vec2(uvTransformPatchToTileColor01 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv11 = vec2(uvTransformPatchToTileColor11 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 d00 = vec2(1,1) / texture00DimensionsColor;
vec2 d10 = vec2(1,1) / texture10DimensionsColor;
vec2 d01 = vec2(1,1) / texture01DimensionsColor;
vec2 d11 = vec2(1,1) / texture11DimensionsColor;
if (uv00.x > -d00.x && uv00.x < 1 + d00.x && uv00.y > -d00.y && uv00.y < 1 + d00.y)
color00 = texture(textureSamplerColor00, uv00);
if (uv10.x > -d10.x && uv10.x < 1 + d10.x && uv10.y > -d10.y && uv10.y < 1 + d10.y)
color10 = texture(textureSamplerColor10, uv10);
if (uv01.x > -d01.x && uv01.x < 1 + d01.x && uv01.y > -d01.y && uv01.y < 1 + d01.y)
color01 = texture(textureSamplerColor01, uv01);
if (uv11.x > -d11.x && uv11.x < 1 + d11.x && uv11.y > -d11.y && uv11.y < 1 + d11.y)
color11 = texture(textureSamplerColor11, uv11);
frag.color = max(color00, max(color10, max(color01, color11)));
//frag.color = vec4(frag.color.r, frag.color.r, 0, 1);
frag.depth = vs_position.w;
return frag;
}

View File

@@ -1,117 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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. *
****************************************************************************************/
#version __CONTEXT__
uniform mat4 projectionTransform;
uniform ivec2 contraction; // [-1, 1]
uniform vec3 p00;
uniform vec3 p10;
uniform vec3 p01;
uniform vec3 p11;
uniform vec3 patchNormal;
uniform int segmentsPerPatch;
uniform mat3 uvTransformPatchToTileHeight00;
uniform mat3 uvTransformPatchToTileHeight10;
uniform mat3 uvTransformPatchToTileHeight01;
uniform mat3 uvTransformPatchToTileHeight11;
uniform sampler2D textureSamplerHeight00;
uniform sampler2D textureSamplerHeight10;
uniform sampler2D textureSamplerHeight01;
uniform sampler2D textureSamplerHeight11;
uniform uvec2 texture00DimensionsHeight;
uniform uvec2 texture10DimensionsHeight;
uniform uvec2 texture01DimensionsHeight;
uniform uvec2 texture11DimensionsHeight;
layout(location = 1) in vec2 in_uv;
out vec4 vs_position;
out vec3 fs_position;
out vec2 fs_uv;
#include "PowerScaling/powerScaling_vs.hglsl"
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
vec3 bilinearInterpolation(vec2 uv) {
// Bilinear interpolation
vec3 p0 = (1 - uv.x) * p00 + uv.x * p10;
vec3 p1 = (1 - uv.x) * p01 + uv.x * p11;
vec3 p = (1 - uv.y) * p0 + uv.y * p1;
return p;
}
void main()
{
fs_uv = in_uv;
// Contract
vec2 scaledContraction = contraction / float(segmentsPerPatch);
fs_uv += scaledContraction;
fs_uv = clamp(fs_uv, 0, 1);
fs_uv -= scaledContraction;
// Position in cameraspace
vec3 p = bilinearInterpolation(fs_uv);
float sampledHeight00 = 0;
float sampledHeight10 = 0;
float sampledHeight01 = 0;
float sampledHeight11 = 0;
vec2 uv00 = vec2(uvTransformPatchToTileHeight00 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv10 = vec2(uvTransformPatchToTileHeight10 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv01 = vec2(uvTransformPatchToTileHeight01 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 uv11 = vec2(uvTransformPatchToTileHeight11 * vec3(fs_uv.s, fs_uv.t, 1));
vec2 d00 = vec2(1,1) / texture00DimensionsHeight;
vec2 d10 = vec2(1,1) / texture10DimensionsHeight;
vec2 d01 = vec2(1,1) / texture01DimensionsHeight;
vec2 d11 = vec2(1,1) / texture11DimensionsHeight;
if (uv00.x > -d00.x && uv00.x < 1 + d00.x && uv00.y > -d00.y && uv00.y < 1 + d00.y)
sampledHeight00 = texture(textureSamplerHeight00, uv00).r;
if (uv10.x > -d10.x && uv10.x < 1 + d10.x && uv10.y > -d10.y && uv10.y < 1 + d10.y)
sampledHeight10 = texture(textureSamplerHeight10, uv10).r;
if (uv01.x > -d01.x && uv01.x < 1 + d01.x && uv01.y > -d01.y && uv01.y < 1 + d01.y)
sampledHeight01 = texture(textureSamplerHeight01, uv01).r;
if (uv11.x > -d11.x && uv11.x < 1 + d11.x && uv11.y > -d11.y && uv11.y < 1 + d11.y)
sampledHeight11 = texture(textureSamplerHeight11, uv11).r;
float sampledHeight = max(sampledHeight00, max(sampledHeight10, max(sampledHeight01, sampledHeight11)));
p += patchNormal * sampledHeight * pow(2,15);
vec4 position = projectionTransform * vec4(p, 1);
fs_position = p;
gl_Position = z_normalization(position);
vs_position = gl_Position;
}

View File

@@ -1,71 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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 <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl>
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
#define NUMLAYERS_COLORTEXTURE #{numLayersColor}
#define NUMLAYERS_HEIGHTMAP #{numLayersHeight}
uniform TextureTile colorTiles[NUMLAYERS_COLORTEXTURE];
in vec4 fs_position;
in vec2 fs_uv;
vec4 blendOver(vec4 oldColor, vec4 newColor)
{
vec4 toReturn;
toReturn.rgb =
(newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) /
(newColor.a + oldColor.a * (1 - newColor.a));
toReturn.a = newColor.a + oldColor.a * (1 - newColor.a);
return toReturn;
}
Fragment getFragment() {
Fragment frag;
for (int i = 0; i < NUMLAYERS_COLORTEXTURE; ++i)
{
vec2 samplePos =
colorTile.uvTransform.uvScale * fs_uv +
colorTile.uvTransform.uvOffset;
vec4 colorSample = texture(colorTile.textureSampler, samplePos);
frag.color = blendOver(frag.color, colorSample);
}
//frag.color.rgb *= 10;
// Sample position overlay
//frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1);
// Border overlay
//frag.color = frag.color + patchBorderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.depth = fs_position.w;
return frag;
}

View File

@@ -1,83 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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. *
****************************************************************************************/
#version __CONTEXT__
#include "PowerScaling/powerScaling_vs.hglsl"
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/texturetile.hglsl>
#define NUMLAYERS_COLORTEXTURE #{numLayersColor}
#define NUMLAYERS_HEIGHTMAP #{numLayersHeight}
uniform mat4 modelViewProjectionTransform;
uniform vec3 radiiSquared;
uniform vec2 minLatLon;
uniform vec2 lonLatScalingFactor;
uniform TextureTile heightTiles[NUMLAYERS_HEIGHTMAP];
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
PositionNormalPair globalInterpolation() {
vec2 lonLatInput;
lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * in_uv.y; // Lat
lonLatInput.x = minLatLon.x + lonLatScalingFactor.x * in_uv.x; // Lon
PositionNormalPair positionPairModelSpace = geodetic2ToCartesian(lonLatInput.y, lonLatInput.x, radiiSquared);
return positionPairModelSpace;
}
void main()
{
PositionNormalPair pair = globalInterpolation();
float height = 0;
for (int i = 0; i < NUMLAYERS_HEIGHTMAP; ++i)
{
vec2 samplePos =
heightTiles[i].uvTransform.uvScale * in_uv +
heightTiles[i].uvTransform.uvOffset;
float sampledValue = texture(heightTiles[i].textureSampler, samplePos).r;
// TODO : Some kind of blending here. Now it just writes over
height = (sampledValue *
heightTiles[i].depthTransform.depthScale +
heightTiles[i].depthTransform.depthOffset);
}
// Add the height in the direction of the normal
pair.position += pair.normal * height;
vec4 position = modelViewProjectionTransform * vec4(pair.position, 1);
// Write output
fs_uv = in_uv;
fs_position = z_normalization(position);
gl_Position = fs_position;
}

View File

@@ -1,101 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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. *
****************************************************************************************/
uniform vec4 campos;
uniform vec4 objpos;
uniform vec3 sun_pos;
uniform bool _performShading = true;
uniform float transparency;
uniform int shadows;
uniform float time;
uniform sampler2D texture1;
uniform sampler2D nightTex;
/*
// Heightmap coverage
uniform sampler2D textureSamplerHeight00;
uniform sampler2D textureSamplerHeight10;
uniform sampler2D textureSamplerHeight01;
uniform sampler2D textureSamplerHeight11;
uniform mat3 uvTransformPatchToTileHeight00;
uniform mat3 uvTransformPatchToTileHeight10;
uniform mat3 uvTransformPatchToTileHeight01;
uniform mat3 uvTransformPatchToTileHeight11;
*/
// Colortexture coverage
uniform sampler2D textureSamplerColor00;
uniform sampler2D textureSamplerColor10;
uniform sampler2D textureSamplerColor01;
uniform sampler2D textureSamplerColor11;
uniform mat3 uvTransformPatchToTileColor00;
uniform mat3 uvTransformPatchToTileColor10;
uniform mat3 uvTransformPatchToTileColor01;
uniform mat3 uvTransformPatchToTileColor11;
//uniform int segmentsPerPatch;
in vec4 vs_position;
in vec3 fs_position;
in vec2 fs_uv;
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
Fragment getFragment() {
Fragment frag;
frag.color = vec4(0);
vec4 color00, color10, color01, color11;
vec2 uv00 = vec2(uvTransformPatchToTileColor00 * vec3(fs_uv.s, fs_uv.t, 1));
color00 = texture(textureSamplerColor00, uv00);
vec2 uv10 = vec2(uvTransformPatchToTileColor10 * vec3(fs_uv.s, fs_uv.t, 1));
color10 += texture(textureSamplerColor10, uv10);
vec2 uv01 = vec2(uvTransformPatchToTileColor01 * vec3(fs_uv.s, fs_uv.t, 1));
color01 += texture(textureSamplerColor01, uv01);
vec2 uv11 = vec2(uvTransformPatchToTileColor11 * vec3(fs_uv.s, fs_uv.t, 1));
color11 += texture(textureSamplerColor11, uv11);
frag.color = max(color00, max(color10, max(color01, color11))) * 10;
//vec4 uvColor = vec4(fract(fs_uv * segmentsPerPatch), 0.4,1);
//frag.color = frag.color.a < 0.1 ? uvColor * 0.5 : frag.color;
frag.color = vec4(frag.color.r, frag.color.r, frag.color.r, 1);
frag.depth = vs_position.w;
return frag;
}

View File

@@ -1,48 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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. *
****************************************************************************************/
#version __CONTEXT__
uniform mat4 ViewProjection;
uniform mat4 ModelTransform;
layout(location = 0) in vec4 in_position;
out vec4 vs_position;
out vec2 vs_uv;
#include "PowerScaling/powerScaling_vs.hglsl"
void main()
{
// set variables
vs_position = vec4(in_position.xyz * 60000000.0f, 1);
vec4 tmp = vec4(in_position.xyz * 60000000.0f, 1);
vec4 position = pscTransform(tmp, ModelTransform);
vs_position = tmp;
vs_uv = vec2(0,0);
position = ViewProjection * position;
gl_Position = z_normalization(position);
}

View File

@@ -40,7 +40,7 @@ namespace gui {
void GuiTimeComponent::render() {
float deltaTime = static_cast<float>(Time::ref().deltaTime());
bool changed = ImGui::SliderFloat("Delta Time", &deltaTime, -100.f, 100.f);
bool changed = ImGui::SliderFloat("Delta Time", &deltaTime, -500000.f, 500000.f);
if (changed)
OsEng.scriptEngine().queueScript("openspace.time.setDeltaTime(" + std::to_string(deltaTime) + ")");

View File

@@ -885,6 +885,109 @@ void OrbitalInteractionMode::update(double deltaTime) {
updateCameraStateFromMouseStates();
}
GlobeBrowsingInteractionMode::GlobeBrowsingInteractionMode(
std::shared_ptr<InputState> inputState,
double sensitivity,
double velocityScaleFactor)
: OrbitalInteractionMode(inputState, sensitivity, velocityScaleFactor) {
}
GlobeBrowsingInteractionMode::~GlobeBrowsingInteractionMode() {
}
void GlobeBrowsingInteractionMode::setFocusNode(SceneGraphNode* focusNode) {
_focusNode = focusNode;
Renderable* baseRenderable = _focusNode->renderable();
if (RenderableGlobe* globe = dynamic_cast<RenderableGlobe*>(baseRenderable)) {
_globe = globe;
}
else {
_globe = nullptr;
}
}
void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates() {
if (_focusNode && _globe) {
// Declare variables to use in interaction calculations
glm::dvec3 centerPos = _focusNode->worldPosition().dvec3();
glm::dvec3 camPos = _camera->positionVec3();
glm::dvec3 posDiff = camPos - centerPos;
glm::dvec3 newPosition = camPos;
glm::dvec3 centerToSurface = _globe->geodeticSurfaceProjection(camPos);
glm::dvec3 surfaceToCamera = camPos - (centerPos + centerToSurface);
glm::dvec3 directionFromSurfaceToCamera = glm::normalize(surfaceToCamera);
double distFromCenterToSurface =
glm::length(centerToSurface);
double distFromSurfaceToCamera = glm::length(surfaceToCamera);
double distFromCenterToCamera = glm::length(posDiff);
{ // Do local rotation
glm::dvec3 eulerAngles(_localRotationMouseState.velocity.get().y, 0, 0);
glm::dquat rotationDiff = glm::dquat(eulerAngles);
_localCameraRotation = _localCameraRotation * rotationDiff;
}
{ // Do global rotation
glm::dvec3 eulerAngles(
-_globalRotationMouseState.velocity.get().y,
-_globalRotationMouseState.velocity.get().x,
0);
glm::dquat rotationDiffCamSpace = glm::dquat(eulerAngles);
glm::dquat rotationDiffWorldSpace =
_globalCameraRotation *
rotationDiffCamSpace *
glm::inverse(_globalCameraRotation);
glm::dvec3 rotationDiffVec3 =
(distFromCenterToCamera * directionFromSurfaceToCamera)
* rotationDiffWorldSpace
- (distFromCenterToCamera * directionFromSurfaceToCamera);
rotationDiffVec3 *= glm::clamp(distFromSurfaceToCamera / distFromCenterToSurface, 0.0, 1.0);
newPosition = camPos + rotationDiffVec3;
glm::dvec3 newCenterToSurface = _globe->geodeticSurfaceProjection(newPosition);
glm::dvec3 newSurfaceToCamera = newPosition - (centerPos + newCenterToSurface);
glm::dvec3 newDirectionFromSurfaceToCamera = glm::normalize(newSurfaceToCamera);
glm::dvec3 lookUpWhenFacingSurface =
_globalCameraRotation * glm::dvec3(_camera->lookUpVectorCameraSpace());
glm::dmat4 lookAtMat = glm::lookAt(
glm::dvec3(0, 0, 0),
-newDirectionFromSurfaceToCamera,
lookUpWhenFacingSurface);
_globalCameraRotation =
glm::normalize(glm::quat_cast(glm::inverse(lookAtMat)));
}
{ // Move position towards or away from focus node
newPosition += -(posDiff - centerToSurface) *
_truckMovementMouseState.velocity.get().y;
}
{ // Do roll
glm::dquat cameraRollRotation =
glm::angleAxis(_rollMouseState.velocity.get().x, directionFromSurfaceToCamera);
_globalCameraRotation = cameraRollRotation * _globalCameraRotation;
}
// Update the camera state
_camera->setRotation(_globalCameraRotation * _localCameraRotation);
_camera->setPositionVec3(newPosition);
}
}
void GlobeBrowsingInteractionMode::update(double deltaTime) {
updateMouseStatesFromInput(deltaTime);
updateCameraStateFromMouseStates();
}
// InteractionHandler
InteractionHandler::InteractionHandler()
: _origin("origin", "Origin", "")
@@ -908,7 +1011,7 @@ InteractionHandler::InteractionHandler()
_inputState = std::shared_ptr<InputState>(new InputState());
_interactor = std::shared_ptr<InteractionMode>(
new OrbitalInteractionMode(_inputState, 0.002, 0.02));
new GlobeBrowsingInteractionMode(_inputState, 0.002, 0.02));
}
InteractionHandler::~InteractionHandler() {

View File

@@ -43,8 +43,8 @@ namespace openspace {
, _focusPosition()
{
_scaling.local = glm::vec2(1.f, 0.f);
_position.local = Vec3(0, 0, 0);
Vec3 eulerAngles(0, 0, 0);
_position.local = Vec3(1.0, 1.0, 1.0);
Vec3 eulerAngles(1.0, 1.0, 1.0);
_rotation.local = Quat(eulerAngles);
}
@@ -153,11 +153,12 @@ namespace openspace {
const Camera::Mat4& Camera::combinedViewMatrix() const {
if (_cachedCombinedViewMatrix.isDirty) {
glm::vec3 cameraPosition = position().vec3();
glm::mat4 cameraTranslation =
glm::inverse(glm::translate(glm::mat4(1.0), cameraPosition));
Mat4 cameraTranslation =
glm::inverse(glm::translate(Mat4(1.0), _position.shared));
_cachedCombinedViewMatrix.datum =
glm::mat4(viewRotationMatrix()) * cameraTranslation;
Mat4(sgctInternal.viewMatrix()) *
Mat4(viewRotationMatrix()) *
cameraTranslation;
}
return _cachedCombinedViewMatrix.datum;
}

View File

@@ -37,6 +37,45 @@ namespace openspace {
Time* Time::_instance = nullptr;
Time::Time()
: _time(-1.0)
, _dt(1.0)
//local copies
, _timeJumped(false)
, _timePaused(false)
, _jockeHasToFixThisLater(false)
//shared copies
, _sharedTime(-1.0)
, _sharedDt(1.0)
, _sharedTimeJumped(false)
//synced copies
, _syncedTime(-1.0)
, _syncedDt(1.0)
, _syncedTimeJumped(false)
{
}
Time::Time(const Time& other)
: _time(other._time)
, _dt(other._dt)
//local copies
, _timeJumped(other._timeJumped)
, _timePaused(other._timePaused)
, _jockeHasToFixThisLater(other._jockeHasToFixThisLater)
//shared copies
, _sharedTime(other._sharedTime)
, _sharedDt(other._sharedDt)
, _sharedTimeJumped(other._sharedTimeJumped)
//synced copies
, _syncedTime(other._syncedTime)
, _syncedDt(other._syncedDt)
, _syncedTimeJumped(other._syncedTimeJumped)
{
}
void Time::initialize() {
ghoul_assert(_instance == nullptr, "Static time must not have been ininitialized");
_instance = new Time();
@@ -99,6 +138,29 @@ std::string Time::currentTimeUTC() const {
return SpiceManager::ref().dateFromEphemerisTime(_syncedTime);
}
std::string Time::ISO8601() const {
std::string datetime = currentTimeUTC();
std::string month = datetime.substr(5, 3);
std::string MM = "";
if (month == "JAN") MM = "01";
else if (month == "FEB") MM = "02";
else if (month == "MAR") MM = "03";
else if (month == "APR") MM = "04";
else if (month == "MAY") MM = "05";
else if (month == "JUN") MM = "06";
else if (month == "JUL") MM = "07";
else if (month == "AUG") MM = "08";
else if (month == "SEP") MM = "09";
else if (month == "OCT") MM = "10";
else if (month == "NOV") MM = "11";
else if (month == "DEC") MM = "12";
else ghoul_assert(false, "Bad month");
datetime.replace(4, 5, "-" + MM + "-");
return datetime;
}
void Time::serialize(SyncBuffer* syncBuffer) {
_syncMutex.lock();