More cleanup for newhorizons and globebrowsing module

This commit is contained in:
Alexander Bock
2016-12-07 21:56:59 +01:00
parent b3db661277
commit 8da0684ae2
11 changed files with 124 additions and 1331 deletions

View File

@@ -32,6 +32,7 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.h
${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.h
${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.inl
${CMAKE_CURRENT_SOURCE_DIR}/geometry/convexhull.h
${CMAKE_CURRENT_SOURCE_DIR}/geometry/ellipsoid.h
${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic2.h
@@ -45,14 +46,16 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.h
${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.h
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.h
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.h
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.h
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.h
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.h
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentqueue.h
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentqueue.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.h
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.h
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.h
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpulayermanager.h
@@ -85,7 +88,6 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling.cpp
${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.cpp
${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.inl
${CMAKE_CURRENT_SOURCE_DIR}/geometry/convexhull.cpp
${CMAKE_CURRENT_SOURCE_DIR}/geometry/ellipsoid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic2.cpp
@@ -99,6 +101,15 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/meshes/skirtedgrid.cpp
${CMAKE_CURRENT_SOURCE_DIR}/meshes/trianglesoup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpulayermanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layershadermanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layermanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/asynctilereader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/pixelregion.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tile.cpp
@@ -114,18 +125,6 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileprovider.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbyindex.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tile/tileprovider/tileproviderbylevel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/chunkrenderer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/gpulayermanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layershadermanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/layermanager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/concurrentjobmanager.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/lrucache.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/statscollector.inl
${CMAKE_CURRENT_SOURCE_DIR}/other/threadpool.cpp
)
source_group("Source Files" FILES ${SOURCE_FILES})

View File

@@ -1,471 +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/chunk/chunkrenderer.h>
#include <modules/globebrowsing/chunk/chunkedlodglobe.h>
#include <modules/globebrowsing/tile/layeredtextures.h>
#include <modules/globebrowsing/tile/tileprovidermanager.h>
// open space includes
#include <openspace/engine/wrapper/windowwrapper.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
// ghoul includes
#include <ghoul/misc/assert.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
// STL includes
#include <sstream>
#define _USE_MATH_DEFINES
#include <math.h>
namespace {
const std::string _loggerCat = "PatchRenderer";
const char* keyFrame = "Frame";
const char* keyGeometry = "Geometry";
const char* keyShading = "PerformShading";
const char* keyBody = "Body";
}
namespace openspace {
ChunkRenderer::ChunkRenderer(
std::shared_ptr<Grid> grid,
std::shared_ptr<TileProviderManager> tileProviderManager)
: _tileProviderManager(tileProviderManager)
, _grid(grid)
{
_globalRenderingShaderProvider = std::make_shared<LayeredTextureShaderProvider>(
"GlobalChunkedLodPatch",
"${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_vs.glsl",
"${MODULE_GLOBEBROWSING}/shaders/globalchunkedlodpatch_fs.glsl");
_localRenderingShaderProvider = std::make_shared<LayeredTextureShaderProvider>(
"LocalChunkedLodPatch",
"${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_vs.glsl",
"${MODULE_GLOBEBROWSING}/shaders/localchunkedlodpatch_fs.glsl");
_globalProgramUniformHandler = std::make_shared<LayeredTextureShaderUniformIdHandler>();
_localProgramUniformHandler = std::make_shared<LayeredTextureShaderUniformIdHandler>();
}
void ChunkRenderer::renderChunk(const Chunk& chunk, const RenderData& data) {
if (chunk.index().level < 10) {
renderChunkGlobally(chunk, data);
}
else {
renderChunkLocally(chunk, data);
}
}
void ChunkRenderer::update() {
// unued atm. Could be used for caching or precalculating
}
void ChunkRenderer::setDepthTransformUniforms(
std::shared_ptr<LayeredTextureShaderUniformIdHandler> uniformIdHandler,
LayeredTextures::TextureCategory textureCategory,
LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes blendLayerSuffix,
size_t layerIndex,
const TileDepthTransform& tileDepthTransform)
{
uniformIdHandler->programObject().setUniform(
uniformIdHandler->getId(
textureCategory,
blendLayerSuffix,
layerIndex,
LayeredTextureShaderUniformIdHandler::GlslTileDataId::depthTransform_depthScale),
tileDepthTransform.depthScale);
uniformIdHandler->programObject().setUniform(
uniformIdHandler->getId(
textureCategory,
blendLayerSuffix,
layerIndex,
LayeredTextureShaderUniformIdHandler::GlslTileDataId::depthTransform_depthOffset),
tileDepthTransform.depthOffset);
}
void ChunkRenderer::activateTileAndSetTileUniforms(
std::shared_ptr<LayeredTextureShaderUniformIdHandler> uniformIdHandler,
LayeredTextures::TextureCategory textureCategory,
LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes blendLayerSuffix,
size_t layerIndex,
ghoul::opengl::TextureUnit& texUnit,
const TileAndTransform& tileAndTransform)
{
// Blend tile with two parents
// The texture needs a unit to sample from
texUnit.activate();
tileAndTransform.tile.texture->bind();
uniformIdHandler->programObject().setUniform(
uniformIdHandler->getId(
textureCategory,
blendLayerSuffix,
layerIndex,
LayeredTextureShaderUniformIdHandler::GlslTileDataId::textureSampler),
texUnit);
uniformIdHandler->programObject().setUniform(
uniformIdHandler->getId(
textureCategory,
blendLayerSuffix,
layerIndex,
LayeredTextureShaderUniformIdHandler::GlslTileDataId::uvTransform_uvScale),
tileAndTransform.uvTransform.uvScale);
uniformIdHandler->programObject().setUniform(
uniformIdHandler->getId(
textureCategory,
blendLayerSuffix,
layerIndex,
LayeredTextureShaderUniformIdHandler::GlslTileDataId::uvTransform_uvOffset),
tileAndTransform.uvTransform.uvOffset);
}
ProgramObject* ChunkRenderer::getActivatedProgramWithTileData(
LayeredTextureShaderProvider* layeredTextureShaderProvider,
std::shared_ptr<LayeredTextureShaderUniformIdHandler> programUniformHandler,
const Chunk& chunk)
{
const ChunkIndex& chunkIndex = chunk.index();
std::array<std::vector<std::shared_ptr<TileProvider> >,
LayeredTextures::NUM_TEXTURE_CATEGORIES> tileProviders;
LayeredTexturePreprocessingData layeredTexturePreprocessingData;
for (size_t category = 0; category < LayeredTextures::NUM_TEXTURE_CATEGORIES; category++) {
tileProviders[category] = _tileProviderManager->getTileProviderGroup(category).getActiveTileProviders();
LayeredTextureInfo layeredTextureInfo;
layeredTextureInfo.lastLayerIdx = tileProviders[category].size() - 1;
layeredTextureInfo.layerBlendingEnabled = _tileProviderManager->getTileProviderGroup(category).levelBlendingEnabled;
layeredTexturePreprocessingData.layeredTextureInfo[category] = layeredTextureInfo;
}
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"useAtmosphere",
std::to_string(chunk.owner()->atmosphereEnabled)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showChunkEdges",
std::to_string(chunk.owner()->debugOptions.showChunkEdges)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showHeightResolution",
std::to_string(chunk.owner()->debugOptions.showHeightResolution)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showHeightIntensities",
std::to_string(chunk.owner()->debugOptions.showHeightIntensities)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"defaultHeight",
std::to_string(Chunk::DEFAULT_HEIGHT)));
// Now the shader program can be accessed
ProgramObject* programObject =
layeredTextureShaderProvider->getUpdatedShaderProgram(
layeredTexturePreprocessingData);
programUniformHandler->updateIdsIfNecessary(layeredTextureShaderProvider);
// Activate the shader program
programObject->activate();
// Initialize all texture units
struct BlendTexUnits {
ghoul::opengl::TextureUnit blendTexture0;
ghoul::opengl::TextureUnit blendTexture1;
ghoul::opengl::TextureUnit blendTexture2;
};
std::array<std::vector<BlendTexUnits>, LayeredTextures::NUM_TEXTURE_CATEGORIES> texUnits;
for (size_t category = 0; category < LayeredTextures::NUM_TEXTURE_CATEGORIES; category++) {
texUnits[category].resize(tileProviders[category].size());
}
// Go through all the categories
for (size_t category = 0; category < LayeredTextures::NUM_TEXTURE_CATEGORIES; category++) {
// Go through all the providers in this category
int i = 0;
for (auto it = tileProviders[category].begin(); it != tileProviders[category].end(); it++) {
auto tileProvider = it->get();
// Get the texture that should be used for rendering
TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(tileProvider, chunkIndex);
if (tileAndTransform.tile.status == Tile::Status::Unavailable) {
tileAndTransform.tile = tileProvider->getDefaultTile();
tileAndTransform.uvTransform.uvOffset = { 0, 0 };
tileAndTransform.uvTransform.uvScale = { 1, 1 };
}
activateTileAndSetTileUniforms(
programUniformHandler,
LayeredTextures::TextureCategory(category),
LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::none,
i,
texUnits[category][i].blendTexture0,
tileAndTransform);
// If blending is enabled, two more textures are needed
if (layeredTexturePreprocessingData.layeredTextureInfo[category].layerBlendingEnabled) {
TileAndTransform tileAndTransformParent1 = TileSelector::getHighestResolutionTile(tileProvider, chunkIndex, 1);
if (tileAndTransformParent1.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent1 = tileAndTransform;
}
activateTileAndSetTileUniforms(
programUniformHandler,
LayeredTextures::TextureCategory(category),
LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::Parent1,
i,
texUnits[category][i].blendTexture1,
tileAndTransformParent1);
TileAndTransform tileAndTransformParent2 = TileSelector::getHighestResolutionTile(tileProvider, chunkIndex, 2);
if (tileAndTransformParent2.tile.status == Tile::Status::Unavailable) {
tileAndTransformParent2 = tileAndTransformParent1;
}
activateTileAndSetTileUniforms(
programUniformHandler,
LayeredTextures::TextureCategory(category),
LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::Parent2,
i,
texUnits[category][i].blendTexture2,
tileAndTransformParent2);
}
/*
if (category == LayeredTextures::HeightMaps && tileAndTransform.tile.preprocessData) {
//auto preprocessingData = tileAndTransform.tile.preprocessData;
//float noDataValue = preprocessingData->noDataValues[0];
programObject->setUniform(
"minimumValidHeight[" + std::to_string(i) + "]",
-100000);
}
*/
i++;
}
}
// Go through all the height maps and set depth tranforms
int i = 0;
auto it = tileProviders[LayeredTextures::HeightMaps].begin();
auto end = tileProviders[LayeredTextures::HeightMaps].end();
for (; it != end; it++) {
auto tileProvider = *it;
TileDepthTransform depthTransform = tileProvider->depthTransform();
setDepthTransformUniforms(
programUniformHandler,
LayeredTextures::TextureCategory::HeightMaps,
LayeredTextureShaderUniformIdHandler::BlendLayerSuffixes::none,
i,
depthTransform);
i++;
}
// The length of the skirts is proportional to its size
programObject->setUniform("skirtLength", min(static_cast<float>(chunk.surfacePatch().halfSize().lat * 1000000), 8700.0f));
programObject->setUniform("xSegments", _grid->xSegments());
if (chunk.owner()->debugOptions.showHeightResolution) {
programObject->setUniform("vertexResolution", glm::vec2(_grid->xSegments(), _grid->ySegments()));
}
return programObject;
}
void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& data){
ProgramObject* programObject = getActivatedProgramWithTileData(
_globalRenderingShaderProvider.get(),
_globalProgramUniformHandler,
chunk);
if (programObject == nullptr) {
return;
}
const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid();
bool performAnyBlending = false;
for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; ++i) {
LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory)i;
if(_tileProviderManager->getTileProviderGroup(i).levelBlendingEnabled && _tileProviderManager->getTileProviderGroup(category).getActiveTileProviders().size() > 0){
performAnyBlending = true;
break;
}
}
if (performAnyBlending) {
// Calculations are done in the reference frame of the globe. Hence, the camera
// position needs to be transformed with the inverse model matrix
glm::dmat4 inverseModelTransform = chunk.owner()->inverseModelTransform();
glm::dvec3 cameraPosition =
glm::dvec3(inverseModelTransform * glm::dvec4(data.camera.positionVec3(), 1));
float distanceScaleFactor = chunk.owner()->lodScaleFactor * ellipsoid.minimumRadius();
programObject->setUniform("cameraPosition", vec3(cameraPosition));
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
programObject->setUniform("chunkLevel", chunk.index().level);
}
// Calculate other uniform variables needed for rendering
Geodetic2 swCorner = chunk.surfacePatch().getCorner(Quad::SOUTH_WEST);
auto patchSize = chunk.surfacePatch().size();
dmat4 modelTransform = chunk.owner()->modelTransform();
dmat4 viewTransform = data.camera.combinedViewMatrix();
mat4 modelViewTransform = mat4(viewTransform * modelTransform);
mat4 modelViewProjectionTransform = data.camera.projectionMatrix() * modelViewTransform;
// Upload the uniform variables
programObject->setUniform("modelViewProjectionTransform", modelViewProjectionTransform);
programObject->setUniform("minLatLon", vec2(swCorner.toLonLatVec2()));
programObject->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2()));
programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared()));
if (_tileProviderManager->getTileProviderGroup(
LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 ||
_tileProviderManager->getTileProviderGroup(
LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) {
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::vec3 directionToSunCameraSpace =
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
data.modelTransform.translation;
programObject->setUniform("modelViewTransform", modelViewTransform);
programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace);
}
// OpenGL rendering settings
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// render
_grid->geometry().drawUsingActiveProgram();
// disable shader
programObject->deactivate();
}
void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& data) {
ProgramObject* programObject = getActivatedProgramWithTileData(
_localRenderingShaderProvider.get(),
_localProgramUniformHandler,
chunk);
if (programObject == nullptr) {
return;
}
using namespace glm;
const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid();
bool performAnyBlending = false;
for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; ++i) {
LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory)i;
if (_tileProviderManager->getTileProviderGroup(i).levelBlendingEnabled && _tileProviderManager->getTileProviderGroup(category).getActiveTileProviders().size() > 0) {
performAnyBlending = true;
break;
}
}
if (performAnyBlending) {
float distanceScaleFactor = chunk.owner()->lodScaleFactor * chunk.owner()->ellipsoid().minimumRadius();
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
programObject->setUniform("chunkLevel", chunk.index().level);
}
// Calculate other uniform variables needed for rendering
dmat4 modelTransform = chunk.owner()->modelTransform();
dmat4 viewTransform = data.camera.combinedViewMatrix();
dmat4 modelViewTransform = viewTransform * modelTransform;
std::vector<std::string> cornerNames = { "p01", "p11", "p00", "p10" };
std::vector<Vec3> cornersCameraSpace(4);
for (int i = 0; i < 4; ++i) {
Quad q = (Quad)i;
Geodetic2 corner = chunk.surfacePatch().getCorner(q);
Vec3 cornerModelSpace = ellipsoid.cartesianSurfacePosition(corner);
Vec3 cornerCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(cornerModelSpace, 1));
cornersCameraSpace[i] = cornerCameraSpace;
programObject->setUniform(cornerNames[i], vec3(cornerCameraSpace));
}
vec3 patchNormalCameraSpace = normalize(
cross(cornersCameraSpace[Quad::SOUTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST],
cornersCameraSpace[Quad::NORTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST]));
programObject->setUniform("patchNormalCameraSpace", patchNormalCameraSpace);
programObject->setUniform("projectionTransform", data.camera.projectionMatrix());
if (_tileProviderManager->getTileProviderGroup(
LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 ||
_tileProviderManager->getTileProviderGroup(
LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) {
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::vec3 directionToSunCameraSpace =
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
data.modelTransform.translation;
programObject->setUniform("lightDirectionCameraSpace", -directionToSunCameraSpace);
}
// OpenGL rendering settings
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// render
_grid->geometry().drawUsingActiveProgram();
// disable shader
programObject->deactivate();
}
} // namespace openspace

View File

@@ -1,447 +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/meshes/clipmapgrid.h>
#include <ghoul/opengl/ghoul_gl.h>
namespace {
const std::string _loggerCat = "ClipMapGrid";
}
namespace openspace {
namespace globebrowsing {
//////////////////////////////////////////////////////////////////////////////////////////
// CLIPMAP GRID (Abstract class) //
//////////////////////////////////////////////////////////////////////////////////////////
ClipMapGrid::ClipMapGrid(unsigned int segments)
: Grid(
segments,
segments,
TriangleSoup::Positions::No,
TriangleSoup::TextureCoordinates::Yes,
TriangleSoup::Normals::No)
{}
ClipMapGrid::~ClipMapGrid()
{}
int ClipMapGrid::xSegments() const {
return segments();
}
int ClipMapGrid::ySegments() const {
return segments();
}
int ClipMapGrid::segments() const {
return _xSegments;
}
//////////////////////////////////////////////////////////////////////////////////////////
// OUTER CLIPMAP GRID //
//////////////////////////////////////////////////////////////////////////////////////////
OuterClipMapGrid::OuterClipMapGrid(unsigned int segments)
: ClipMapGrid(segments)
{
_geometry = std::unique_ptr<TriangleSoup>(new TriangleSoup(
CreateElements(segments, segments),
TriangleSoup::Positions::No,
TriangleSoup::TextureCoordinates::Yes,
TriangleSoup::Normals::No));
_geometry->setVertexTextureCoordinates(CreateTextureCoordinates(segments, segments));
}
OuterClipMapGrid::~OuterClipMapGrid()
{
}
size_t OuterClipMapGrid::numElements(int segments)
{
int numElementsInTotalSquare = 6 * (segments + 1) * (segments + 1);
int numElementsInHole = 6 * (segments / 4 * segments / 4);
return numElementsInTotalSquare - numElementsInHole;
}
size_t OuterClipMapGrid::numVerticesBottom(int segments)
{
return (segments + 1 + 2) * (segments / 4 + 1 + 1);
}
size_t OuterClipMapGrid::numVerticesLeft(int segments)
{
return (segments / 4 + 1 + 1) * (segments / 2 + 1);
}
size_t OuterClipMapGrid::numVerticesRight(int segments)
{
return (segments / 4 + 1 + 1) * (segments / 2 + 1);
}
size_t OuterClipMapGrid::numVerticesTop(int segments)
{
return (segments + 1 + 2) * (segments / 4 + 1 + 1);
}
size_t OuterClipMapGrid::numVertices(int segments)
{
return numVerticesBottom(segments) +
numVerticesLeft(segments) +
numVerticesRight(segments) +
numVerticesTop(segments);
}
void OuterClipMapGrid::validate(int xRes, int yRes) {
ghoul_assert(xRes == yRes,
"segments must be equal in x and in y. ");
int segments = xRes;
ghoul_assert(segments >= 8,
"segments must be at least 8. (" << segments << ")");
ghoul_assert(segments == pow(2, int(log2(segments))),
"segments must be a power of 2. (" << segments << ")");
}
std::vector<GLuint> OuterClipMapGrid::CreateElements(int xRes, int yRes) {
validate(xRes, yRes);
int segments = xRes;
std::vector<GLuint> elements;
elements.reserve(numElements(segments));
// The clipmap geometry is built up by four parts as follows:
// 0 = Bottom part
// 1 = Left part
// 2 = Right part
// 3 = Top part
//
// 33333333
// 33333333
// 11 22
// 11 22
// 00000000
// 00000000
// x v01---v11 x ..
// | / |
// x v00---v10 x ..
//
// x x x x ..
// : : : :
unsigned int previousVerts[4];
previousVerts[0] = 0;
previousVerts[1] = previousVerts[0] + numVerticesBottom(segments);
previousVerts[2] = previousVerts[1] + numVerticesLeft(segments);
previousVerts[3] = previousVerts[2] + numVerticesRight(segments);
// Build the bottom part of the clipmap geometry
for (unsigned int y = 0; y < segments / 4 + 1; y++) {
for (unsigned int x = 0; x < segments + 2; x++) {
GLuint v00 = previousVerts[0] + (y + 0) * (segments + 3) + x + 0;
GLuint v10 = previousVerts[0] + (y + 0) * (segments + 3) + x + 1;
GLuint v01 = previousVerts[0] + (y + 1) * (segments + 3) + x + 0;
GLuint v11 = previousVerts[0] + (y + 1) * (segments + 3) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
// Build the left part of the clipmap geometry
for (unsigned int y = 0; y < segments / 2; y++) {
for (unsigned int x = 0; x < segments / 4 + 1; x++) {
GLuint v00 = previousVerts[1] + (y + 0) * (segments / 4 + 2) + x + 0;
GLuint v10 = previousVerts[1] + (y + 0) * (segments / 4 + 2) + x + 1;
GLuint v01 = previousVerts[1] + (y + 1) * (segments / 4 + 2) + x + 0;
GLuint v11 = previousVerts[1] + (y + 1) * (segments / 4 + 2) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
// Build the left part of the clipmap geometry
for (unsigned int y = 0; y < segments / 2; y++) {
for (unsigned int x = 0; x < segments / 4 + 1; x++) {
GLuint v00 = previousVerts[2] + (y + 0) * (segments / 4 + 2) + x + 0;
GLuint v10 = previousVerts[2] + (y + 0) * (segments / 4 + 2) + x + 1;
GLuint v01 = previousVerts[2] + (y + 1) * (segments / 4 + 2) + x + 0;
GLuint v11 = previousVerts[2] + (y + 1) * (segments / 4 + 2) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
// Build the left part of the clipmap geometry
for (unsigned int y = 0; y < segments / 4 + 1; y++) {
for (unsigned int x = 0; x < segments + 2; x++) {
GLuint v00 = previousVerts[3] + (y + 0) * (segments + 3) + x + 0;
GLuint v10 = previousVerts[3] + (y + 0) * (segments + 3) + x + 1;
GLuint v01 = previousVerts[3] + (y + 1) * (segments + 3) + x + 0;
GLuint v11 = previousVerts[3] + (y + 1) * (segments + 3) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
return elements;
}
std::vector<glm::vec4> OuterClipMapGrid::CreatePositions(int xRes, int yRes)
{
validate(xRes, yRes);
int segments = xRes;
std::vector<glm::vec4> positions;
positions.reserve(numVertices(segments));
std::vector<glm::vec2> templateTextureCoords = CreateTextureCoordinates(xRes, yRes);
// Copy from 2d texture coordinates and use as template to create positions
for (unsigned int i = 0; i < templateTextureCoords.size(); i++) {
positions.push_back(
glm::vec4(
templateTextureCoords[i].x,
templateTextureCoords[i].y,
0,
1));
}
return positions;
}
std::vector<glm::vec2> OuterClipMapGrid::CreateTextureCoordinates(int xRes, int yRes){
validate(xRes, yRes);
int segments = xRes;
std::vector<glm::vec2> textureCoordinates;
textureCoordinates.reserve(numVertices(segments));
// Build the bottom part of the clipmap geometry
for (int y = -1; y < segments / 4 + 1; y++) {
for (int x = -1; x < segments + 2; x++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / segments,
static_cast<float>(y) / segments));
}
}
// Build the left part of the clipmap geometry
for (int y = segments / 4; y < 3 * segments / 4 + 1; y++) {
for (int x = -1; x < segments / 4 + 1; x++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / segments,
static_cast<float>(y) / segments));
}
}
// Build the right part of the clipmap geometry
for (int y = segments / 4; y < 3 * segments / 4 + 1; y++) {
for (int x = 3 * segments / 4; x < segments + 2; x++) {
float u = static_cast<float>(x) / segments;
float v = static_cast<float>(y) / segments;
textureCoordinates.push_back(glm::vec2(u, v));
}
}
// Build the top part of the clipmap geometry
for (int y = 3 * segments / 4; y < segments + 2; y++) {
for (int x = -1; x < segments + 2; x++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / segments,
static_cast<float>(y) / segments));
}
}
return textureCoordinates;
}
std::vector<glm::vec3> OuterClipMapGrid::CreateNormals(int xRes, int yRes) {
validate(xRes, yRes);
int segments = xRes;
std::vector<glm::vec3> normals;
normals.reserve(numVertices(segments));
for (int y = -1; y < segments + 2; y++) {
for (int x = -1; x < segments + 2; x++) {
normals.push_back(glm::vec3(0, 0, 1));
}
}
return normals;
}
//////////////////////////////////////////////////////////////////////////////////////////
// INNER CLIPMAP GRID //
//////////////////////////////////////////////////////////////////////////////////////////
InnerClipMapGrid::InnerClipMapGrid(unsigned int segments)
: ClipMapGrid(segments)
{
_geometry = std::unique_ptr<TriangleSoup>(new TriangleSoup(
CreateElements(segments, segments),
TriangleSoup::Positions::No,
TriangleSoup::TextureCoordinates::Yes,
TriangleSoup::Normals::No));
_geometry->setVertexTextureCoordinates(CreateTextureCoordinates(segments, segments));
}
InnerClipMapGrid::~InnerClipMapGrid()
{
}
size_t InnerClipMapGrid::numElements(int segments)
{
return segments * segments * 6;
}
size_t InnerClipMapGrid::numVertices(int segments)
{
return (segments + 1) * (segments + 1);
}
void InnerClipMapGrid::validate(int xRes, int yRes) {
ghoul_assert(xRes == yRes,
"segments must be equal in x and in y. ");
int segments = xRes;
ghoul_assert(segments >= 1,
"segments must be at least 1. (" << segments << ")");
}
std::vector<GLuint> InnerClipMapGrid::CreateElements(int xRes, int yRes) {
validate(xRes, yRes);
int segments = xRes;
std::vector<GLuint> elements;
elements.reserve(numElements(segments));
// x v01---v11 x ..
// | / |
// x v00---v10 x ..
//
// x x x x ..
// : : : :
for (unsigned int y = 0; y < segments + 2; y++) {
for (unsigned int x = 0; x < segments + 2; x++) {
GLuint v00 = (y + 0) * (segments + 3) + x + 0;
GLuint v10 = (y + 0) * (segments + 3) + x + 1;
GLuint v01 = (y + 1) * (segments + 3) + x + 0;
GLuint v11 = (y + 1) * (segments + 3) + x + 1;
elements.push_back(v00);
elements.push_back(v10);
elements.push_back(v11);
elements.push_back(v00);
elements.push_back(v11);
elements.push_back(v01);
}
}
return elements;
}
std::vector<glm::vec4> InnerClipMapGrid::CreatePositions(int xRes, int yRes)
{
validate(xRes, yRes);
int segments = xRes;
std::vector<glm::vec4> positions;
positions.reserve(numVertices(segments));
std::vector<glm::vec2> templateTextureCoords = CreateTextureCoordinates(xRes, yRes);
// Copy from 2d texture coordinates and use as template to create positions
for (unsigned int i = 0; i < templateTextureCoords.size(); i++) {
positions.push_back(
glm::vec4(
templateTextureCoords[i].x,
templateTextureCoords[i].y,
0,
1));
}
return positions;
}
std::vector<glm::vec2> InnerClipMapGrid::CreateTextureCoordinates(int xRes, int yRes) {
validate(xRes, yRes);
int segments = xRes;
std::vector<glm::vec2> textureCoordinates;
textureCoordinates.reserve(numVertices(segments));
// Build the bottom part of the clipmap geometry
for (int y = -1; y < segments + 2; y++) {
for (int x = -1; x < segments + 2; x++) {
textureCoordinates.push_back(glm::vec2(
static_cast<float>(x) / segments,
static_cast<float>(y) / segments));
}
}
return textureCoordinates;
}
std::vector<glm::vec3> InnerClipMapGrid::CreateNormals(int xRes, int yRes) {
validate(xRes, yRes);
int segments = xRes;
std::vector<glm::vec3> normals;
normals.reserve(numVertices(segments));
for (int y = -1; y < segments + 2; y++) {
for (int x = -1; x < segments + 2; x++) {
normals.push_back(glm::vec3(0, 0, 1));
}
}
return normals;
}
} // namespace globebrowsing
} // namespace openspace

View File

@@ -1,132 +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 __CLIPMAPGEOMETRY_H__
#define __CLIPMAPGEOMETRY_H__
#include <modules/globebrowsing/meshes/grid.h>
#include <vector>
#include <glm/glm.hpp>
namespace openspace {
namespace globebrowsing {
//////////////////////////////////////////////////////////////////////////////////////////
// CLIPMAP GRID (Abstract class) //
//////////////////////////////////////////////////////////////////////////////////////////
/**
This class defines a grid used for the layers of a geometry clipmap. A geometry
clipmap is built up from a pyramid of clipmaps so the majority of the grids used
are of the class OuterClipMapGrid. The vertex positions and texture coordinated are
defined differently than for a normal BasicGrid. Other than having the basic grid
vertices it also creates padding of one grid cell on the perimeter. This padding can be
used when rendering a ClipMapGrid so that an inner layer of the pyramid can move and
snap to the outer layers grid cells.
*/
class ClipMapGrid : public Grid
{
public:
ClipMapGrid(unsigned int segments);
~ClipMapGrid();
virtual int xSegments() const;
virtual int ySegments() const;
/**
Returns the segments of the grid. A ClipMapGrid must have the segments in x and
y direction equal so this function works as a wrapper for xSegments() and
ySegments().
*/
int segments() const;
};
//////////////////////////////////////////////////////////////////////////////////////////
// OUTER CLIPMAP GRID //
//////////////////////////////////////////////////////////////////////////////////////////
/**
The outer layers of a geometry clipmap pyramid can be built up by grids with sizes
increasing with the power of 2. The OuterClipMapGrid has a whole in the middle where
a smaller ClipMapGrid of half the size can fit.
*/
class OuterClipMapGrid : public ClipMapGrid
{
public:
OuterClipMapGrid(unsigned int segments);
~OuterClipMapGrid();
protected:
virtual std::vector<GLuint> CreateElements(int xSegments, int ySegments);
virtual std::vector<glm::vec4> CreatePositions(int xSegments, int ySegments);
virtual std::vector<glm::vec2> CreateTextureCoordinates(int xSegments, int ySegments);
virtual std::vector<glm::vec3> CreateNormals(int xSegments, int ySegments);
private:
void validate(int xSegments, int ySegments);
static size_t numVerticesBottom(int segments);
static size_t numVerticesLeft(int segments);
static size_t numVerticesRight(int segments);
static size_t numVerticesTop(int segments);
static size_t numElements(int segments);
static size_t numVertices(int segments);
};
//////////////////////////////////////////////////////////////////////////////////////////
// INNER CLIPMAP GRID //
//////////////////////////////////////////////////////////////////////////////////////////
/**
The InnerClipMapGrid can be used for the inner most (smallest) grid of a geometry clipmap
pyramid. The only difference from a OuterClipMapGrid is that this grid does not have
a whole where a smaller ClipMapGrid can be positioned.
*/
class InnerClipMapGrid : public ClipMapGrid
{
public:
InnerClipMapGrid(unsigned int segments);
~InnerClipMapGrid();
private:
virtual std::vector<GLuint> CreateElements( int xSegments, int ySegments);
virtual std::vector<glm::vec4> CreatePositions(int xSegments, int ySegments);
virtual std::vector<glm::vec2> CreateTextureCoordinates(int xSegments, int ySegments);
virtual std::vector<glm::vec3> CreateNormals(int xSegments, int ySegments);
void validate(int xSegments, int ySegments);
static size_t numElements(int segments);
static size_t numVertices(int segments);
};
} // namespace globebrowsing
} // namespace openspace
#endif // __CLIPMAPGEOMETRY_H__

View File

@@ -1,49 +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 <ogr_featurestyle.h>
#include <ogr_spatialref.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h> // abspath
#include <ghoul/misc/assert.h>
#include <modules/globebrowsing/tile/tile.h>
#include <modules/globebrowsing/geometry/angle.h>
#include <float.h>
#include <sstream>
#include <algorithm>
namespace {
const std::string _loggerCat = "RawTile";
}
namespace openspace {
namespace globebrowsing {
} // namespace globebrowsing
} // namespace openspace

View File

@@ -1,46 +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 __TILE_IO_RESULT_H__
#define __TILE_IO_RESULT_H__
#include <ghoul/opengl/texture.h>
#include <ghoul/filesystem/file.h>
#include <modules/globebrowsing/geometry/geodetic2.h>
#include <modules/globebrowsing/tile/tiledepthtransform.h>
#include "gdal_priv.h"
#include <memory>
#include <iostream>
namespace openspace {
namespace globebrowsing {
} // namespace globebrowsing
} // namespace openspace
#endif // __TILE_IO_RESULT_H__

View File

@@ -1,54 +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 __OPENSPACE_MODULE_GLOBEBROWSING_TILEPILE_H__
#define __OPENSPACE_MODULE_GLOBEBROWSING_TILEPILE_H__
#include <ghoul/opengl/texture.h> // Texture
#include <modules/globebrowsing/tile/tile.h>
#include <modules/globebrowsing/tile/tileindex.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <vector>
#include <array>
namespace openspace {
namespace globebrowsing {
using namespace ghoul::opengl;
/*
struct ChunkTilePile {
std::array<ChunkTile, 3> chunkTiles;
};
*/
} // namespace globebrowsing
} // namespace openspace
#endif // __OPENSPACE_MODULE_GLOBEBROWSING_TILEPILE_H__

View File

@@ -24,23 +24,21 @@
#include <modules/newhorizons/newhorizonsmodule.h>
#include <openspace/rendering/renderable.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
#include <modules/newhorizons/rendering/renderablecrawlingline.h>
#include <modules/newhorizons/rendering/renderableshadowcylinder.h>
#include <modules/newhorizons/rendering/renderablefov.h>
#include <modules/newhorizons/rendering/renderablemodelprojection.h>
#include <modules/newhorizons/rendering/renderableplaneprojection.h>
#include <modules/newhorizons/rendering/renderableplanetprojection.h>
#include <modules/newhorizons/rendering/renderablemodelprojection.h>
#include <modules/newhorizons/rendering/renderableshadowcylinder.h>
#include <modules/newhorizons/util/decoder.h>
#include <modules/newhorizons/util/instrumentdecoder.h>
#include <modules/newhorizons/util/targetdecoder.h>
#include <modules/newhorizons/util/imagesequencer.h>
#include <openspace/rendering/renderable.h>
#include <openspace/util/factorymanager.h>
#include <ghoul/misc/assert.h>
namespace openspace {

View File

@@ -322,7 +322,6 @@ glm::dvec3 RenderableFov::bisection(glm::dvec3 p1, glm::dvec3 p2) {
}
}
void RenderableFov::fovSurfaceIntercept(bool H[], std::vector<glm::dvec3> bounds) {
_nrInserted = 0;
_fovPlane.clear(); // empty the array

View File

@@ -27,35 +27,23 @@
#include <modules/newhorizons/util/imagesequencer.h>
#include <modules/newhorizons/util/instrumentdecoder.h>
#include <openspace/util/time.h>
#include <openspace/util/spicemanager.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
#include <fstream>
#include <iterator>
#include <iomanip>
#include <limits>
#include <modules/newhorizons/util/imagesequencer.h>
#include <ghoul/misc/dictionary.h>
#include <map>
#include <string>
#include <vector>
namespace {
const char* keyTranslation = "DataInputTranslation";
const std::string PlaybookIdentifierName = "HongKang";
const char* PlaybookIdentifierName = "HongKang";
}
namespace openspace {
HongKangParser::HongKangParser(std::string name, std::string fileName,
HongKangParser::HongKangParser(std::string name, std::string fileName,
std::string spacecraft,
ghoul::Dictionary translationDictionary,
std::vector<std::string> potentialTargets)
@@ -98,12 +86,12 @@ void HongKangParser::findPlaybookSpecifiedTarget(std::string line, std::string&
std::vector<std::string> ptarg = _potentialTargets;
for (const auto& p : ptarg) {
// loop over all targets and determine from 4th col which target this instrument points to
if (line.find(p) != std::string::npos){
if (line.find(p) != std::string::npos) {
target = p;
break;
}
else {
// not found - we set void until we have more info.
// not found - we set void until we have more info.
target = "VOID";
}
}
@@ -129,7 +117,7 @@ bool HongKangParser::create() {
if (position != std::string::npos){
std::string extension = ghoul::filesystem::File(_fileName).fileExtension();
if (extension == "txt") {// Hong Kang. pre-parsed playbook
if (extension == "txt") { // Hong Kang. pre-parsed playbook
std::ifstream file;
file.exceptions(std::ofstream::failbit | std::ofstream::badbit);
//std::ifstream file(_fileName , std::ios::binary);
@@ -159,7 +147,7 @@ bool HongKangParser::create() {
std::string cameraTarget = "VOID";
std::string scannerTarget = "VOID";
while (!file.eof()){
while (!file.eof()) {
std::getline(file, line);
std::string event = line.substr(0, line.find_first_of(" "));
@@ -174,8 +162,8 @@ bool HongKangParser::create() {
//store the time, this is used for getNextCaptureTime()
_captureProgression.push_back(time);
if (it->second->getDecoderType() == "CAMERA"){
if (capture_start == -1){
if (it->second->getDecoderType() == "CAMERA") {
if (capture_start == -1) {
//encountered new camera sequence- store start time
capture_start = time;
previousCamera = it->first;
@@ -197,7 +185,7 @@ bool HongKangParser::create() {
//createImage(image, time, time + shutter, cameraSpiceID, cameraTarget, _defaultCaptureImage);
//IFF spaccraft has decided to switch target, store in target map (used for: 'next observation focus')
if (previousTarget != image.target){
if (previousTarget != image.target) {
previousTarget = image.target;
std::pair<double, std::string> v_target = std::make_pair(time, image.target);
_targetTimes.push_back(v_target);
@@ -208,7 +196,7 @@ bool HongKangParser::create() {
//compute and store the range for each subset
_subsetMap[image.target]._range.include(time);
}
if (it->second->getDecoderType() == "SCANNER"){ // SCANNER START
if (it->second->getDecoderType() == "SCANNER") { // SCANNER START
scan_start = time;
InstrumentDecoder* scanner = static_cast<InstrumentDecoder*>(it->second.get());
@@ -218,10 +206,10 @@ bool HongKangParser::create() {
std::streampos len = file.tellg();
std::string linePeek;
bool foundstop = false;
while (!file.eof() && !foundstop){
while (!file.eof() && !foundstop) {
//continue grabbing next line until we find what we need
getline(file, linePeek);
if (linePeek.find(endNominal) != std::string::npos){
if (linePeek.find(endNominal) != std::string::npos) {
foundstop = true;
met = linePeek.substr(25, 9);
@@ -250,8 +238,8 @@ bool HongKangParser::create() {
file.seekg(len, std::ios_base::beg);
}
}
else{ // we have reached the end of a scan or consecutive capture sequence!
if (capture_start != -1){
else { // we have reached the end of a scan or consecutive capture sequence!
if (capture_start != -1) {
//end of capture sequence for camera, store end time of this sequence
capture_stop = time;
cameraRange = { capture_start, capture_stop };
@@ -266,13 +254,11 @@ bool HongKangParser::create() {
}
}
sendPlaybookInformation(PlaybookIdentifierName);
return true;
}
bool HongKangParser::augmentWithSpice(Image& image,
std::string spacecraft,
bool HongKangParser::augmentWithSpice(Image& image, std::string spacecraft,
std::vector<std::string> payload,
std::vector<std::string> potentialTargets)
{
@@ -290,7 +276,7 @@ bool HongKangParser::augmentWithSpice(Image& image,
bool _withinFOV = false;
for (int j = 0; j < image.activeInstruments.size(); ++j) {
double time = image.timeRange.start;
for (int k = 0; k < exposureTime; k++){
for (int k = 0; k < exposureTime; k++) {
time += k;
_withinFOV = SpiceManager::ref().isTargetInFieldOfView(
potentialTargets[i],
@@ -311,54 +297,34 @@ bool HongKangParser::augmentWithSpice(Image& image,
return false;
}
//Image HongKangParser::createImage(double startTime, double stopTime, std::vector<std::string> instr, std::string targ, std::string path) {
// image.startTime = startTime;
// image.stopTime = stopTime;
// image.path = path;
// for (int i = 0; i < instr.size(); i++){
// image.activeInstruments.push_back(instr[i]);
// }
// image.target = targ;
// image.projected = false;
// image.isPlaceholder = true;
//}
double HongKangParser::getETfromMet(std::string line){
double HongKangParser::getETfromMet(std::string line) {
std::string::size_type sz;
return getETfromMet(std::stod(line, &sz));
}
double HongKangParser::getETfromMet(double met){
double diff;
double referenceET =
double HongKangParser::getETfromMet(double met) {
const double referenceET =
SpiceManager::ref().ephemerisTimeFromDate("2015-07-14T11:50:00.00");
double et = referenceET;
//_metRef += 3; // MET reference time is off by 3 sec?
diff = std::abs(met - _metRef);
if (met > _metRef){
et = referenceET + diff;
} else if (met < _metRef){
et = referenceET - diff;
const double diff = std::abs(met - _metRef);
if (met > _metRef) {
return referenceET + diff;
} else if (met < _metRef) {
return referenceET - diff;
}
return et;
}
double HongKangParser::getMetFromET(double et){
double met;
double referenceET =
double HongKangParser::getMetFromET(double et) {
const double referenceET =
SpiceManager::ref().ephemerisTimeFromDate("2015-07-14T11:50:00.00");
if (et >= referenceET){
met = _metRef + (et - referenceET);
}else{
met = _metRef - (referenceET - et);
if (et >= referenceET) {
return _metRef + (et - referenceET);
}else {
return _metRef - (referenceET - et);
}
return met;
}
}
} // namespace openspace

View File

@@ -23,6 +23,7 @@
****************************************************************************************/
#include <modules/newhorizons/util/imagesequencer.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/directory.h>
@@ -30,6 +31,7 @@
#include <ghoul/filesystem/cachemanager.h>
#include <modules/newhorizons/util/decoder.h>
#include <ghoul/misc/assert.h>
#include <openspace/util/spicemanager.h>
#include <fstream>
#include <iterator>
@@ -44,10 +46,6 @@
#include <map>
#include <vector>
namespace {
const std::string _loggerCat = "ImageSequencer";
}
@@ -65,13 +63,14 @@ ImageSequencer::ImageSequencer()
{}
ImageSequencer& ImageSequencer::ref() {
assert(_instance != nullptr);
ghoul_assert(_instance != nullptr, "Instance has not been initialized");
return *_instance;
}
void ImageSequencer::initialize() {
assert(_instance == nullptr);
ghoul_assert(_instance == nullptr, "Instance already has been initialized");
_instance = new ImageSequencer;
_instance->_defaultCaptureImage = absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png");
_instance->_defaultCaptureImage =
absPath("${OPENSPACE_DATA}/scene/common/textures/placeholder_blank.png");
}
void ImageSequencer::deinitialize() {
@@ -101,12 +100,19 @@ std::pair<double, std::string> ImageSequencer::getNextTarget() {
};
std::pair<double, std::string> findEqualToThis;
findEqualToThis.first = _currentTime;
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
auto it = std::lower_bound(
_targetTimes.begin(),
_targetTimes.end(),
findEqualToThis,
compareTime
);
if (it != _targetTimes.end() && it != _targetTimes.begin())
if (it != _targetTimes.end() && it != _targetTimes.begin()) {
return (*it);
else
return std::make_pair(0.0, "");
}
else {
return { 0.0, "" };
}
}
std::pair<double, std::string> ImageSequencer::getCurrentTarget() {
@@ -116,26 +122,39 @@ std::pair<double, std::string> ImageSequencer::getCurrentTarget() {
};
std::pair<double, std::string> findEqualToThis;
findEqualToThis.first = _currentTime;
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
auto it = std::lower_bound(
_targetTimes.begin(),
_targetTimes.end(),
findEqualToThis,
compareTime
);
if (it != _targetTimes.end() && it != _targetTimes.begin()){
return *std::prev(it);
return *(std::prev(it));
}
else
return std::make_pair(0.0, "No Target");
return { 0.0, "No Target" };
}
std::pair<double, std::vector<std::string>> ImageSequencer::getIncidentTargetList(int range) {
std::pair<double, std::vector<std::string>> ImageSequencer::getIncidentTargetList(
int range)
{
std::pair<double, std::vector<std::string>> incidentTargets;
auto compareTime = [](const std::pair<double, std::string> &a,
const std::pair<double, std::string> &b)->bool{
auto compareTime = [](const std::pair<double, std::string>& a,
const std::pair<double, std::string>& b) -> bool {
return a.first < b.first;
};
// what to look for
std::pair<double, std::string> findEqualToThis;
findEqualToThis.first = _currentTime;
auto it = std::lower_bound(_targetTimes.begin(), _targetTimes.end(), findEqualToThis, compareTime);
auto it = std::lower_bound(
_targetTimes.begin(),
_targetTimes.end(),
findEqualToThis,
compareTime
);
if (it != _targetTimes.end() && it != _targetTimes.begin()){
// move the iterator to the first element of the range
@@ -146,17 +165,18 @@ std::pair<double, std::vector<std::string>> ImageSequencer::getIncidentTargetLis
incidentTargets.first = it->first;
incidentTargets.second.push_back(it->second);
it++;
if (it == _targetTimes.end())
if (it == _targetTimes.end()) {
break;
}
}
}
return incidentTargets;
}
double ImageSequencer::getIntervalLength(){
double ImageSequencer::getIntervalLength() {
double upcoming = getNextCaptureTime();
if (_nextCapture != upcoming){
if (_nextCapture != upcoming) {
_nextCapture = upcoming;
_intervalLength = upcoming - _currentTime;
}
@@ -164,46 +184,56 @@ double ImageSequencer::getIntervalLength(){
}
double ImageSequencer::getNextCaptureTime(){
auto compareTime = [](const double &a, const double &b)->bool{
auto compareTime = [](const double &a, const double &b) -> bool {
return a < b;
};
double nextCaptureTime = 0;
auto it = std::lower_bound(_captureProgression.begin(), _captureProgression.end(), _currentTime, compareTime);
if (it != _captureProgression.end())
auto it = std::lower_bound(
_captureProgression.begin(),
_captureProgression.end(),
_currentTime,
compareTime
);
if (it != _captureProgression.end()) {
nextCaptureTime = *it;
}
return nextCaptureTime;
}
Image ImageSequencer::getLatestImageForInstrument(const std::string& _instrumentID){
Image ImageSequencer::getLatestImageForInstrument(const std::string& _instrumentID) {
auto it = _latestImages.find(_instrumentID);
if (it != _latestImages.end())
if (it != _latestImages.end()) {
return _latestImages[_instrumentID];
}
else {
return Image();
}
}
std::map<std::string, bool> ImageSequencer::getActiveInstruments(){
std::map<std::string, bool> ImageSequencer::getActiveInstruments() {
// first set all instruments to off
for (auto i : _switchingMap)
for (const auto& i : _switchingMap) {
_switchingMap[i.first] = false;
}
// go over the filetranslation map
for (const auto &key : _fileTranslation){
for (const auto& key : _fileTranslation) {
// for each spice-instrument
for (const auto &instrumentID : key.second->getTranslation()){
for (const auto& instrumentID : key.second->getTranslation()) {
// check if the spice-instrument is active
if (instrumentActive(instrumentID)){
// go over switching map
for (const auto &instrument : _switchingMap){
// if instrument is present in switching map
if (instrumentID == instrument.first){
// set as active
_switchingMap[instrumentID] = true;
}
if (instrumentActive(instrumentID)) {
// go over switching map
for (const auto& instrument : _switchingMap) {
// if instrument is present in switching map
if (instrumentID == instrument.first) {
// set as active
_switchingMap[instrumentID] = true;
}
}
}
}
}
// return entire map, seen in GUI.
return _switchingMap;
}
@@ -215,7 +245,7 @@ bool ImageSequencer::instrumentActive(std::string instrumentID) {
//if so, then get the corresponding spiceID
std::vector<std::string> spiceIDs = _fileTranslation[i.first]->getTranslation();
//check which specific subinstrument is firing
for (auto s : spiceIDs) {
for (const auto& s : spiceIDs) {
if (s == instrumentID) {
return true;
}