From 423c55ba3822135b01840c4804a8ddcb9e3f02b4 Mon Sep 17 00:00:00 2001 From: kalbl Date: Sun, 2 Oct 2016 21:30:26 +0200 Subject: [PATCH] Update structure of properties for renderable globes. --- data/scene/globebrowsing.scene | 4 +- modules/globebrowsing/chunk/chunk.cpp | 19 +- modules/globebrowsing/chunk/chunk.h | 10 +- .../globebrowsing/chunk/chunkedlodglobe.cpp | 160 +++++----- modules/globebrowsing/chunk/chunkedlodglobe.h | 63 +--- .../chunk/chunklevelevaluator.cpp | 19 +- modules/globebrowsing/chunk/chunkrenderer.cpp | 35 ++- modules/globebrowsing/chunk/culling.cpp | 8 +- .../globebrowsing/globes/renderableglobe.cpp | 291 +++++++++++------- .../globebrowsing/globes/renderableglobe.h | 153 ++++----- .../globebrowsing/tile/tileprovidermanager.h | 2 +- src/interaction/interactionmode.cpp | 8 +- 12 files changed, 399 insertions(+), 373 deletions(-) diff --git a/data/scene/globebrowsing.scene b/data/scene/globebrowsing.scene index b956eb6d18..12d622f20b 100644 --- a/data/scene/globebrowsing.scene +++ b/data/scene/globebrowsing.scene @@ -29,7 +29,7 @@ function postInitialization() openspace.setPropertyValue("SunGlare.renderable.enabled", false) openspace.setPropertyValue("SunMarker.renderable.enabled", false) - openspace.setPropertyValue("Earth.RenderableGlobe.Atmosphere", true) + openspace.setPropertyValue("Earth.RenderableGlobe.atmosphere", true) openspace.resetCameraDirection() openspace.time.setDeltaTime(0) @@ -54,7 +54,7 @@ return { --"lodmercury", "sun", "stars", - "milkyway", + "milkyway", } } diff --git a/modules/globebrowsing/chunk/chunk.cpp b/modules/globebrowsing/chunk/chunk.cpp index da46d3ac56..a7d2ea6e37 100644 --- a/modules/globebrowsing/chunk/chunk.cpp +++ b/modules/globebrowsing/chunk/chunk.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -42,7 +43,7 @@ namespace openspace { const float Chunk::DEFAULT_HEIGHT = 0.0f; - Chunk::Chunk(ChunkedLodGlobe* owner, const ChunkIndex& chunkIndex, bool initVisible) + Chunk::Chunk(const RenderableGlobe& owner, const ChunkIndex& chunkIndex, bool initVisible) : _owner(owner) , _surfacePatch(chunkIndex) , _index(chunkIndex) @@ -55,7 +56,7 @@ namespace openspace { return _surfacePatch; } - ChunkedLodGlobe* const Chunk::owner() const { + const RenderableGlobe& Chunk::owner() const { return _owner; } @@ -72,23 +73,19 @@ namespace openspace { _surfacePatch = GeodeticPatch(index); } - void Chunk::setOwner(ChunkedLodGlobe* newOwner) { - _owner = newOwner; - } - Chunk::Status Chunk::update(const RenderData& data) { - auto savedCamera = _owner->getSavedCamera(); + auto savedCamera = _owner.savedCamera(); const Camera& camRef = savedCamera != nullptr ? *savedCamera : data.camera; RenderData myRenderData = { camRef, data.position, data.doPerformanceMeasurement }; _isVisible = true; - if (_owner->testIfCullable(*this, myRenderData)) { + if (_owner.chunkedLodGlobe()->testIfCullable(*this, myRenderData)) { _isVisible = false; return Status::WANT_MERGE; } - int desiredLevel = _owner->getDesiredLevel(*this, myRenderData); + int desiredLevel = _owner.chunkedLodGlobe()->getDesiredLevel(*this, myRenderData); if (desiredLevel < _index.level) return Status::WANT_MERGE; else if (_index.level < desiredLevel) return Status::WANT_SPLIT; @@ -103,7 +100,7 @@ namespace openspace { // In the future, this should be abstracted away and more easily queryable. // One must also handle how to sample pick one out of multiplte heightmaps - auto tileProviderManager = owner()->getTileProviderManager(); + auto tileProviderManager = owner().chunkedLodGlobe()->getTileProviderManager(); auto heightMapProviders = tileProviderManager->getTileProviderGroup(LayeredTextures::HeightMaps).getActiveTileProviders(); @@ -148,7 +145,7 @@ namespace openspace { } std::vector Chunk::getBoundingPolyhedronCorners() const { - const Ellipsoid& ellipsoid = owner()->ellipsoid(); + const Ellipsoid& ellipsoid = owner().ellipsoid(); const GeodeticPatch& patch = surfacePatch(); BoundingHeights boundingHeight = getBoundingHeights(); diff --git a/modules/globebrowsing/chunk/chunk.h b/modules/globebrowsing/chunk/chunk.h index 8d0aafcbe5..db4f7d9146 100644 --- a/modules/globebrowsing/chunk/chunk.h +++ b/modules/globebrowsing/chunk/chunk.h @@ -41,7 +41,7 @@ namespace openspace { - class ChunkedLodGlobe; + class RenderableGlobe; class Chunk { public: @@ -59,7 +59,7 @@ namespace openspace { WANT_SPLIT, }; - Chunk(ChunkedLodGlobe* owner, const ChunkIndex& chunkIndex, bool initVisible = true); + Chunk(const RenderableGlobe& owner, const ChunkIndex& chunkIndex, bool initVisible = true); /// Updates chunk internally and returns a desired level Status update(const RenderData& data); @@ -67,18 +67,16 @@ namespace openspace { std::vector getBoundingPolyhedronCorners() const; const GeodeticPatch& surfacePatch() const; - ChunkedLodGlobe* const owner() const; + const RenderableGlobe& owner() const; const ChunkIndex index() const; bool isVisible() const; BoundingHeights getBoundingHeights() const; void setIndex(const ChunkIndex& index); - void setOwner(ChunkedLodGlobe* newOwner); - private: - ChunkedLodGlobe* _owner; + const RenderableGlobe& _owner; ChunkIndex _index; bool _isVisible; GeodeticPatch _surfacePatch; diff --git a/modules/globebrowsing/chunk/chunkedlodglobe.cpp b/modules/globebrowsing/chunk/chunkedlodglobe.cpp index f9b9b52239..4172989a63 100644 --- a/modules/globebrowsing/chunk/chunkedlodglobe.cpp +++ b/modules/globebrowsing/chunk/chunkedlodglobe.cpp @@ -24,13 +24,13 @@ #include +#include #include #include #include #include - // open space includes #include #include @@ -47,32 +47,34 @@ #include #include + namespace { - const std::string _loggerCat = "ChunkLodGlobe"; + const std::string _loggerCat = "ChunkedLodGlobe"; } namespace openspace { - const ChunkIndex ChunkedLodGlobe::LEFT_HEMISPHERE_INDEX = ChunkIndex(0, 0, 1); - const ChunkIndex ChunkedLodGlobe::RIGHT_HEMISPHERE_INDEX = ChunkIndex(1, 0, 1); - - const GeodeticPatch ChunkedLodGlobe::COVERAGE = GeodeticPatch(0, 0, 90, 180); - + const ChunkIndex ChunkedLodGlobe::LEFT_HEMISPHERE_INDEX = + ChunkIndex(0, 0, 1); + const ChunkIndex ChunkedLodGlobe::RIGHT_HEMISPHERE_INDEX = + ChunkIndex(1, 0, 1); + const GeodeticPatch ChunkedLodGlobe::COVERAGE = + GeodeticPatch(0, 0, 90, 180); ChunkedLodGlobe::ChunkedLodGlobe( - const Ellipsoid& ellipsoid, + const RenderableGlobe& owner, size_t segmentsPerPatch, std::shared_ptr tileProviderManager) - : _ellipsoid(ellipsoid) - , _leftRoot(std::make_unique(Chunk(this, LEFT_HEMISPHERE_INDEX))) - , _rightRoot(std::make_unique(Chunk(this, RIGHT_HEMISPHERE_INDEX))) + : _owner(owner) + , _leftRoot(std::make_unique( + Chunk(owner, LEFT_HEMISPHERE_INDEX))) + , _rightRoot(std::make_unique( + Chunk(owner, RIGHT_HEMISPHERE_INDEX))) , minSplitDepth(2) , maxSplitDepth(22) - , _savedCamera(nullptr) , _tileProviderManager(tileProviderManager) - , stats(StatsCollector(absPath("test_stats"), 1, StatsCollector::Enabled::No)) - { - + , stats(StatsCollector(absPath("test_stats"), 1, + StatsCollector::Enabled::No)) { auto geometry = std::make_shared( (unsigned int) segmentsPerPatch, (unsigned int) segmentsPerPatch, @@ -81,15 +83,18 @@ namespace openspace { TriangleSoup::Normals::No); _chunkCullers.push_back(std::make_unique()); - _chunkCullers.push_back(std::make_unique(AABB3(vec3(-1, -1, 0), vec3(1, 1, 1e35)))); + _chunkCullers.push_back(std::make_unique( + AABB3(vec3(-1, -1, 0), vec3(1, 1, 1e35)))); + _chunkEvaluatorByAvailableTiles = + std::make_unique(); + _chunkEvaluatorByProjectedArea = + std::make_unique(); + _chunkEvaluatorByDistance = + std::make_unique(); - _chunkEvaluatorByAvailableTiles = std::make_unique(); - _chunkEvaluatorByProjectedArea = std::make_unique(); - _chunkEvaluatorByDistance = std::make_unique(); - - _renderer = std::make_unique(geometry, tileProviderManager); - + _renderer = + std::make_unique(geometry, tileProviderManager); } ChunkedLodGlobe::~ChunkedLodGlobe() { @@ -109,42 +114,59 @@ namespace openspace { return ready; } - std::shared_ptr ChunkedLodGlobe::getTileProviderManager() const { + std::shared_ptr + ChunkedLodGlobe::getTileProviderManager() const { return _tileProviderManager; } - bool ChunkedLodGlobe::testIfCullable(const Chunk& chunk, const RenderData& renderData) const { - if (debugOptions.doHorizonCulling && _chunkCullers[0]->isCullable(chunk, renderData)) { + bool ChunkedLodGlobe::testIfCullable( + const Chunk& chunk, const RenderData& renderData) const { + if (_owner.debugProperties().performHorizonCulling && + _chunkCullers[0]->isCullable(chunk, renderData)) { return true; } - if (debugOptions.doFrustumCulling && _chunkCullers[1]->isCullable(chunk, renderData)) { + if (_owner.debugProperties().performFrustumCulling && + _chunkCullers[1]->isCullable(chunk, renderData)) { return true; } return false; } const ChunkNode& ChunkedLodGlobe::findChunkNode(const Geodetic2 p) const { - ghoul_assert(COVERAGE.contains(p), "Point must be in lat [-90, 90] and lon [-180, 180]"); - return p.lon < COVERAGE.center().lon ? _leftRoot->find(p) : _rightRoot->find(p); + ghoul_assert(COVERAGE.contains(p), + "Point must be in lat [-90, 90] and lon [-180, 180]"); + return + p.lon < COVERAGE.center().lon ? + _leftRoot->find(p) : + _rightRoot->find(p); } ChunkNode& ChunkedLodGlobe::findChunkNode(const Geodetic2 p) { - ghoul_assert(COVERAGE.contains(p), "Point must be in lat [-90, 90] and lon [-180, 180]"); - return p.lon < COVERAGE.center().lon ? _leftRoot->find(p) : _rightRoot->find(p); + ghoul_assert( + COVERAGE.contains(p), + "Point must be in lat [-90, 90] and lon [-180, 180]"); + return + p.lon < COVERAGE.center().lon ? + _leftRoot->find(p) : + _rightRoot->find(p); } - int ChunkedLodGlobe::getDesiredLevel(const Chunk& chunk, const RenderData& renderData) const { + int ChunkedLodGlobe::getDesiredLevel( + const Chunk& chunk, const RenderData& renderData) const { int desiredLevel = 0; - if (debugOptions.levelByProjAreaElseDistance) { - desiredLevel = _chunkEvaluatorByProjectedArea->getDesiredLevel(chunk, renderData); + if (_owner.debugProperties().levelByProjectedAreaElseDistance) { + desiredLevel = _chunkEvaluatorByProjectedArea->getDesiredLevel( + chunk, renderData); } else { - desiredLevel = _chunkEvaluatorByDistance->getDesiredLevel(chunk, renderData); + desiredLevel = _chunkEvaluatorByDistance->getDesiredLevel( + chunk, renderData); } - - int desiredLevelByAvailableData = _chunkEvaluatorByAvailableTiles->getDesiredLevel(chunk, renderData); - if (desiredLevelByAvailableData != ChunkLevelEvaluator::UNKNOWN_DESIRED_LEVEL) { + int desiredLevelByAvailableData = + _chunkEvaluatorByAvailableTiles->getDesiredLevel(chunk, renderData); + if (desiredLevelByAvailableData != + ChunkLevelEvaluator::UNKNOWN_DESIRED_LEVEL) { desiredLevel = min(desiredLevel, desiredLevelByAvailableData); } @@ -152,25 +174,22 @@ namespace openspace { return desiredLevel; } - void ChunkedLodGlobe::render(const RenderData& data){ - + void ChunkedLodGlobe::render(const RenderData& data) { stats.startNewRecord(); int j2000s = Time::now().j2000Seconds(); - auto duration = std::chrono::system_clock::now().time_since_epoch(); - auto millis = std::chrono::duration_cast(duration).count(); + auto millis = std::chrono::duration_cast( + duration).count(); stats.i["time"] = millis; - minDistToCamera = INFINITY; - _leftRoot->updateChunkTree(data); _rightRoot->updateChunkTree(data); // Calculate the MVP matrix dmat4 viewTransform = dmat4(data.camera.combinedViewMatrix()); dmat4 vp = dmat4(data.camera.projectionMatrix()) * viewTransform; - dmat4 mvp = vp * _cachedModelTransform; + dmat4 mvp = vp * _owner.modelTransform(); // Render function std::function renderJob = @@ -194,67 +213,42 @@ namespace openspace { //_leftRoot->reverseBreadthFirst(renderJob); //_rightRoot->reverseBreadthFirst(renderJob); - - if (_savedCamera != nullptr) { - DebugRenderer::ref().renderCameraFrustum(data, *_savedCamera); - } - - Vec3 cameraPos = data.camera.position().dvec3(); } - - void ChunkedLodGlobe::debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp) const { - if (debugOptions.showChunkBounds || debugOptions.showChunkAABB) { - const std::vector modelSpaceCorners = chunk.getBoundingPolyhedronCorners(); + void ChunkedLodGlobe::debugRenderChunk( + const Chunk& chunk, const glm::dmat4& mvp) const { + if (_owner.debugProperties().showChunkBounds || + _owner.debugProperties().showChunkAABB) { + const std::vector modelSpaceCorners = + chunk.getBoundingPolyhedronCorners(); std::vector clippingSpaceCorners(8); AABB3 screenSpaceBounds; + for (size_t i = 0; i < 8; i++) { const vec4& clippingSpaceCorner = mvp * modelSpaceCorners[i]; clippingSpaceCorners[i] = clippingSpaceCorner; - vec3 screenSpaceCorner = (1.0f / clippingSpaceCorner.w) * clippingSpaceCorner; + vec3 screenSpaceCorner = + (1.0f / clippingSpaceCorner.w) * clippingSpaceCorner; screenSpaceBounds.expand(screenSpaceCorner); } unsigned int colorBits = 1 + chunk.index().level % 6; vec4 color = vec4(colorBits & 1, colorBits & 2, colorBits & 4, 0.3); - if (debugOptions.showChunkBounds) { + if (_owner.debugProperties().showChunkBounds) { DebugRenderer::ref().renderNiceBox(clippingSpaceCorners, color); } - if (debugOptions.showChunkAABB) { - auto& screenSpacePoints = DebugRenderer::ref().verticesFor(screenSpaceBounds); + if (_owner.debugProperties().showChunkAABB) { + auto& screenSpacePoints = + DebugRenderer::ref().verticesFor(screenSpaceBounds); DebugRenderer::ref().renderNiceBox(screenSpacePoints, color); } } } void ChunkedLodGlobe::update(const UpdateData& data) { - glm::dmat4 translation = - glm::translate(glm::dmat4(1.0), data.modelTransform.translation); - glm::dmat4 rotation = glm::dmat4(data.modelTransform.rotation); - glm::dmat4 scaling = - glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale, - data.modelTransform.scale, data.modelTransform.scale)); - - _cachedModelTransform = translation * rotation * scaling; - _cachedInverseModelTransform = glm::inverse(_cachedModelTransform); - _renderer->update(); } - - const glm::dmat4& ChunkedLodGlobe::modelTransform() { - return _cachedModelTransform; - } - - const glm::dmat4& ChunkedLodGlobe::inverseModelTransform() { - return _cachedInverseModelTransform; - } - - const Ellipsoid& ChunkedLodGlobe::ellipsoid() const - { - return _ellipsoid; - } - -} // namespace openspace +} // namespace openspace \ No newline at end of file diff --git a/modules/globebrowsing/chunk/chunkedlodglobe.h b/modules/globebrowsing/chunk/chunkedlodglobe.h index f4fd3c0005..58eb40ae35 100644 --- a/modules/globebrowsing/chunk/chunkedlodglobe.h +++ b/modules/globebrowsing/chunk/chunkedlodglobe.h @@ -27,10 +27,8 @@ #include - #include - // open space includes #include #include @@ -38,30 +36,21 @@ #include #include - #include #include - #include #include - -namespace ghoul { - namespace opengl { - class ProgramObject; - } -} - namespace openspace { class ChunkLevelEvaluator; + class RenderableGlobe; } namespace openspace { - class ChunkedLodGlobe : public Renderable { public: ChunkedLodGlobe( - const Ellipsoid& ellipsoid, + const RenderableGlobe& owner, size_t segmentsPerPatch, std::shared_ptr tileProviderManager); virtual ~ChunkedLodGlobe(); @@ -79,49 +68,19 @@ namespace openspace { bool testIfCullable(const Chunk& chunk, const RenderData& renderData) const; int getDesiredLevel(const Chunk& chunk, const RenderData& renderData) const; - double minDistToCamera; - - const Ellipsoid& ellipsoid() const; - const glm::dmat4& modelTransform(); - const glm::dmat4& inverseModelTransform(); - const int minSplitDepth; const int maxSplitDepth; - std::shared_ptr getTileProviderManager() const; - - const std::shared_ptr getSavedCamera() const { return _savedCamera; } - void setSaveCamera(std::shared_ptr c) { - _savedCamera = c; - } - - - float lodScaleFactor; - - bool atmosphereEnabled; - bool performShading; - - struct DebugOptions { - bool showChunkEdges = false; - bool showChunkBounds = false; - bool showChunkAABB = false; - bool showHeightResolution = false; - bool showHeightIntensities = false; - - bool doHorizonCulling = true; - bool doFrustumCulling = true; - bool levelByProjAreaElseDistance = true; - } debugOptions; - StatsCollector stats; - + private: - void debugRenderChunk(const Chunk& chunk, const glm::dmat4& data) const; static const GeodeticPatch COVERAGE; + static const ChunkIndex LEFT_HEMISPHERE_INDEX; + static const ChunkIndex RIGHT_HEMISPHERE_INDEX; // Covers all negative longitudes std::unique_ptr _leftRoot; @@ -132,24 +91,16 @@ namespace openspace { // the patch used for actual rendering std::unique_ptr _renderer; - static const ChunkIndex LEFT_HEMISPHERE_INDEX; - static const ChunkIndex RIGHT_HEMISPHERE_INDEX; - std::vector> _chunkCullers; std::unique_ptr _chunkEvaluatorByAvailableTiles; std::unique_ptr _chunkEvaluatorByProjectedArea; std::unique_ptr _chunkEvaluatorByDistance; - const Ellipsoid& _ellipsoid; - glm::dmat4 _cachedModelTransform; - glm::dmat4 _cachedInverseModelTransform; - - std::shared_ptr _savedCamera; - std::shared_ptr _tileProviderManager; - }; + const RenderableGlobe& _owner; + }; } // namespace openspace #endif // __CHUNK_LOD_GLOBE__ diff --git a/modules/globebrowsing/chunk/chunklevelevaluator.cpp b/modules/globebrowsing/chunk/chunklevelevaluator.cpp index b0c761649f..9fef087804 100644 --- a/modules/globebrowsing/chunk/chunklevelevaluator.cpp +++ b/modules/globebrowsing/chunk/chunklevelevaluator.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -45,9 +46,9 @@ namespace openspace { int EvaluateChunkLevelByDistance::getDesiredLevel(const Chunk& chunk, const RenderData& data) const { // 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(); - ChunkedLodGlobe const * globe = chunk.owner(); - const Ellipsoid& ellipsoid = globe->ellipsoid(); + glm::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform(); + const RenderableGlobe& globe = chunk.owner(); + const Ellipsoid& ellipsoid = globe.ellipsoid(); Vec3 cameraPosition = glm::dvec3(inverseModelTransform * glm::dvec4(data.camera.positionVec3(), 1)); @@ -64,7 +65,7 @@ namespace openspace { Scalar distanceToPatch = glm::length(cameraToChunk); Scalar distance = distanceToPatch -heights.min; // distance to actual minimum heights - Scalar scaleFactor = globe->lodScaleFactor * ellipsoid.minimumRadius(); + Scalar scaleFactor = globe.generalProperties().lodScaleFactor * ellipsoid.minimumRadius(); Scalar projectedScaleFactor = scaleFactor / distance; int desiredLevel = ceil(log2(projectedScaleFactor)); return desiredLevel; @@ -73,10 +74,10 @@ namespace openspace { int EvaluateChunkLevelByProjectedArea::getDesiredLevel(const Chunk& chunk, const RenderData& data) const { // 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::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform(); - ChunkedLodGlobe const * globe = chunk.owner(); - const Ellipsoid& ellipsoid = globe->ellipsoid(); + const RenderableGlobe& globe = chunk.owner(); + const Ellipsoid& ellipsoid = globe.ellipsoid(); glm::dvec4 cameraPositionModelSpace = glm::dvec4(data.camera.positionVec3(), 1); Vec3 cameraPosition = glm::dvec3(inverseModelTransform * cameraPositionModelSpace); Vec3 cameraToEllipsoidCenter = -cameraPosition; @@ -156,12 +157,12 @@ namespace openspace { double areaABC = 0.5 * glm::length(glm::cross(AC, AB)); double projectedChunkAreaApprox = 8 * areaABC; - double scaledArea = globe->lodScaleFactor * projectedChunkAreaApprox; + double scaledArea = globe.generalProperties().lodScaleFactor * projectedChunkAreaApprox; return chunk.index().level + round(scaledArea - 1); } int EvaluateChunkLevelByAvailableTileData::getDesiredLevel(const Chunk& chunk, const RenderData& data) const { - auto tileProvidermanager = chunk.owner()->getTileProviderManager(); + auto tileProvidermanager = chunk.owner().chunkedLodGlobe()->getTileProviderManager(); auto heightMapProviders = tileProvidermanager->getTileProviderGroup(LayeredTextures::HeightMaps).getActiveTileProviders(); int currLevel = chunk.index().level; diff --git a/modules/globebrowsing/chunk/chunkrenderer.cpp b/modules/globebrowsing/chunk/chunkrenderer.cpp index bccd73e98e..88292e8a18 100644 --- a/modules/globebrowsing/chunk/chunkrenderer.cpp +++ b/modules/globebrowsing/chunk/chunkrenderer.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -179,27 +180,27 @@ namespace openspace { layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair( "useAtmosphere", - std::to_string(chunk.owner()->atmosphereEnabled))); + std::to_string(chunk.owner().generalProperties().atmosphereEnabled))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair( "performShading", - std::to_string(chunk.owner()->performShading))); + std::to_string(chunk.owner().generalProperties().performShading))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair( "showChunkEdges", - std::to_string(chunk.owner()->debugOptions.showChunkEdges))); + std::to_string(chunk.owner().debugProperties().showChunkEdges))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair( "showHeightResolution", - std::to_string(chunk.owner()->debugOptions.showHeightResolution))); + std::to_string(chunk.owner().debugProperties().showHeightResolution))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair( "showHeightIntensities", - std::to_string(chunk.owner()->debugOptions.showHeightIntensities))); + std::to_string(chunk.owner().debugProperties().showHeightIntensities))); layeredTexturePreprocessingData.keyValuePairs.push_back( std::pair( @@ -314,7 +315,7 @@ namespace openspace { programObject->setUniform("skirtLength", min(static_cast(chunk.surfacePatch().halfSize().lat * 1000000), 8700.0f)); programObject->setUniform("xSegments", _grid->xSegments()); - if (chunk.owner()->debugOptions.showHeightResolution) { + if (chunk.owner().debugProperties().showHeightResolution) { programObject->setUniform("vertexResolution", glm::vec2(_grid->xSegments(), _grid->ySegments())); } @@ -331,7 +332,7 @@ namespace openspace { return; } - const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); + const Ellipsoid& ellipsoid = chunk.owner().ellipsoid(); bool performAnyBlending = false; @@ -345,10 +346,10 @@ namespace openspace { 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::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform(); glm::dvec3 cameraPosition = glm::dvec3(inverseModelTransform * glm::dvec4(data.camera.positionVec3(), 1)); - float distanceScaleFactor = chunk.owner()->lodScaleFactor * ellipsoid.minimumRadius(); + float distanceScaleFactor = chunk.owner().generalProperties().lodScaleFactor * ellipsoid.minimumRadius(); programObject->setUniform("cameraPosition", vec3(cameraPosition)); programObject->setUniform("distanceScaleFactor", distanceScaleFactor); programObject->setUniform("chunkLevel", chunk.index().level); @@ -358,7 +359,7 @@ namespace openspace { Geodetic2 swCorner = chunk.surfacePatch().getCorner(Quad::SOUTH_WEST); auto patchSize = chunk.surfacePatch().size(); - dmat4 modelTransform = chunk.owner()->modelTransform(); + dmat4 modelTransform = chunk.owner().modelTransform(); dmat4 viewTransform = data.camera.combinedViewMatrix(); mat4 modelViewTransform = mat4(viewTransform * modelTransform); mat4 modelViewProjectionTransform = data.camera.projectionMatrix() * modelViewTransform; @@ -373,8 +374,8 @@ namespace openspace { LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || _tileProviderManager->getTileProviderGroup( LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0 || - chunk.owner()->atmosphereEnabled || - chunk.owner()->performShading) { + chunk.owner().generalProperties().atmosphereEnabled || + chunk.owner().generalProperties().performShading) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = @@ -410,7 +411,7 @@ namespace openspace { using namespace glm; - const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); + const Ellipsoid& ellipsoid = chunk.owner().ellipsoid(); bool performAnyBlending = false; @@ -422,13 +423,13 @@ namespace openspace { } } if (performAnyBlending) { - float distanceScaleFactor = chunk.owner()->lodScaleFactor * chunk.owner()->ellipsoid().minimumRadius(); + float distanceScaleFactor = chunk.owner().generalProperties().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 modelTransform = chunk.owner().modelTransform(); dmat4 viewTransform = data.camera.combinedViewMatrix(); dmat4 modelViewTransform = viewTransform * modelTransform; @@ -454,8 +455,8 @@ namespace openspace { LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || _tileProviderManager->getTileProviderGroup( LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0 || - chunk.owner()->atmosphereEnabled || - chunk.owner()->performShading) { + chunk.owner().generalProperties().atmosphereEnabled || + chunk.owner().generalProperties().performShading) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = diff --git a/modules/globebrowsing/chunk/culling.cpp b/modules/globebrowsing/chunk/culling.cpp index c281f6d7cb..5f8dc3de9c 100644 --- a/modules/globebrowsing/chunk/culling.cpp +++ b/modules/globebrowsing/chunk/culling.cpp @@ -27,7 +27,7 @@ #include -#include +#include #include #include @@ -57,7 +57,7 @@ namespace openspace { bool FrustumCuller::isCullable(const Chunk& chunk, const RenderData& data) { // Calculate the MVP matrix - dmat4 modelTransform = chunk.owner()->modelTransform(); + dmat4 modelTransform = chunk.owner().modelTransform(); dmat4 viewTransform = dmat4(data.camera.combinedViewMatrix()); dmat4 modelViewProjectionTransform = dmat4(data.camera.projectionMatrix()) * viewTransform * modelTransform; @@ -96,9 +96,9 @@ namespace openspace { // 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::dmat4 inverseModelTransform = chunk.owner().inverseModelTransform(); - const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid(); + const Ellipsoid& ellipsoid = chunk.owner().ellipsoid(); const GeodeticPatch& patch = chunk.surfacePatch(); float maxHeight = chunk.getBoundingHeights().max; Vec3 globePosition = glm::dvec3(0,0,0); // In model space it is 0 diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index a02eada5bb..b2c37ffa35 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -25,8 +25,8 @@ #include #include -#include +#include #include #include @@ -36,17 +36,19 @@ #include #include +#include + // ghoul includes #include - namespace { const std::string _loggerCat = "RenderableGlobe"; // Keys for the dictionary const std::string keyFrame = "Frame"; const std::string keyRadii = "Radii"; - const std::string keyInteractionDepthBelowEllipsoid = "InteractionDepthBelowEllipsoid"; + const std::string keyInteractionDepthBelowEllipsoid = + "InteractionDepthBelowEllipsoid"; const std::string keyCameraMinHeight = "CameraMinHeight"; const std::string keySegmentsPerPatch = "SegmentsPerPatch"; const std::string keyTextureInitData = "TextureInitData"; @@ -55,29 +57,82 @@ namespace { const std::string keyHeightMaps = "HeightMaps"; } - - namespace openspace { + SingleTexturePropertyOwner::SingleTexturePropertyOwner(std::string name) + : isEnabled("isEnabled", "isEnabled", true) + , opacity("opacity", "opacity", 1, 0, 1) { + setName(name); + addProperty(isEnabled); + addProperty(opacity); + } + + SingleTexturePropertyOwner::~SingleTexturePropertyOwner() { + + } + + LayeredCategoryPropertyOwner::LayeredCategoryPropertyOwner( + LayeredTextures::TextureCategory category, + TileProviderManager& tileProviderManager) + : _tileProviderManager(tileProviderManager) + , _levelBlendingEnabled("blendTileLevels", "blend tile levels", true){ + setName(LayeredTextures::TEXTURE_CATEGORY_NAMES[category]); + + // Create the property owners + auto& layerGroup = _tileProviderManager.getTileProviderGroup(category); + for (NamedTileProvider& tileProvider : layerGroup.tileProviders) { + _texturePropertyOwners.push_back( + std::make_unique(tileProvider.name)); + } + + // Specify and add the property owners + for (int i = 0; i < layerGroup.tileProviders.size(); i++) { + NamedTileProvider &tileProvider = layerGroup.tileProviders[i]; + SingleTexturePropertyOwner &prop = *_texturePropertyOwners[i].get(); + prop.isEnabled.set(tileProvider.isActive); + prop.isEnabled.onChange([&]{ + tileProvider.isActive = prop.isEnabled; + }); + addPropertySubOwner(prop); + } - + _levelBlendingEnabled.set(layerGroup.levelBlendingEnabled); + _levelBlendingEnabled.onChange([&]{ + layerGroup.levelBlendingEnabled = _levelBlendingEnabled; + }); + addProperty(_levelBlendingEnabled); + } + + LayeredCategoryPropertyOwner::~LayeredCategoryPropertyOwner() { + + } + RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) - : _isEnabled(properties::BoolProperty("Enabled", "Enabled", true)) - , _toggleEnabledEveryFrame(properties::BoolProperty( - "Toggle enabled every frame", "Toggle enabled every frame", false)) - , _saveOrThrowCamera( - properties::BoolProperty("saveOrThrowCamera", "saveOrThrowCamera")) - , _resetTileProviders( - properties::BoolProperty("resetTileProviders", "resetTileProviders")) - , _cameraMinHeight( - properties::FloatProperty( - "cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f)) - , lodScaleFactor( - properties::FloatProperty( - "lodScaleFactor", "lodScaleFactor", 10.0f, 1.0f, 50.0f)) - , debugSelection(ReferencedBoolSelection("Debug", "Debug")) - , atmosphereEnabled(properties::BoolProperty("Atmosphere", "Atmosphere", false)) - , _performShading( - properties::BoolProperty("performShading", "Perform shading", true)) + : _generalProperties({ + properties::BoolProperty("enabled", "Enabled", true), + properties::BoolProperty("performShading", "perform shading", true), + properties::BoolProperty("atmosphere", "atmosphere", false), + properties::FloatProperty("lodScaleFactor", "lodScaleFactor",10.0f, 1.0f, 50.0f), + properties::FloatProperty( + "cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f) + }) + , _debugProperties({ + properties::BoolProperty("saveOrThrowCamera", "save or throw camera", false), + properties::BoolProperty("showChunkEdges", "show chunk edges", false), + properties::BoolProperty("showChunkBounds", "show chunk bounds", false), + properties::BoolProperty("showChunkAABB", "show chunk AABB", false), + properties::BoolProperty("showHeightResolution", "show height resolution", false), + properties::BoolProperty( + "showHeightIntensities", "show height intensities", false), + properties::BoolProperty( + "performFrustumCulling", "perform frustum culling", true), + properties::BoolProperty( + "performHorizonCulling", "perform horizon culling", true), + properties::BoolProperty( + "levelByProjectedAreaElseDistance", "level by projected area (else distance)", + false), + properties::BoolProperty("resetTileProviders", "reset tile providers", false), + properties::BoolProperty( + "toggleEnabledEveryFrame", "toggle enabled every frame", false)}) { setName("RenderableGlobe"); @@ -89,15 +144,16 @@ namespace openspace { _ellipsoid = Ellipsoid(radii); setBoundingSphere(pss(_ellipsoid.averageRadius(), 0.0)); - // Ghoul can't read ints from lua dictionaries + // Ghoul can't read ints from lua dictionaries... double patchSegmentsd; dictionary.getValue(keySegmentsPerPatch, patchSegmentsd); int patchSegments = patchSegmentsd; - dictionary.getValue(keyInteractionDepthBelowEllipsoid, _interactionDepthBelowEllipsoid); + dictionary.getValue(keyInteractionDepthBelowEllipsoid, + _interactionDepthBelowEllipsoid); float cameraMinHeight; dictionary.getValue(keyCameraMinHeight, cameraMinHeight); - _cameraMinHeight.set(cameraMinHeight); + _generalProperties.cameraMinHeight.set(cameraMinHeight); // Init tile provider manager ghoul::Dictionary textureInitDataDictionary; @@ -109,49 +165,39 @@ namespace openspace { texturesDictionary, textureInitDataDictionary); _chunkedLodGlobe = std::make_shared( - _ellipsoid, patchSegments, _tileProviderManager); + *this, patchSegments, _tileProviderManager); _distanceSwitch.addSwitchValue(_chunkedLodGlobe, 1e12); - addProperty(_isEnabled); - addProperty(_toggleEnabledEveryFrame); + _debugPropertyOwner.setName("Debug"); + _texturePropertyOwner.setName("Textures"); - - // Add debug options - must be after chunkedLodGlobe has been created as it - // references its members - addProperty(debugSelection); - debugSelection.addOption("Show chunk edges", &_chunkedLodGlobe->debugOptions.showChunkEdges); - debugSelection.addOption("Show chunk bounds", &_chunkedLodGlobe->debugOptions.showChunkBounds); - debugSelection.addOption("Show chunk AABB", &_chunkedLodGlobe->debugOptions.showChunkAABB); - debugSelection.addOption("Show height resolution", &_chunkedLodGlobe->debugOptions.showHeightResolution); - debugSelection.addOption("Show height intensities", &_chunkedLodGlobe->debugOptions.showHeightIntensities); - - debugSelection.addOption("Culling: Frustum", &_chunkedLodGlobe->debugOptions.doFrustumCulling); - debugSelection.addOption("Culling: Horizon", &_chunkedLodGlobe->debugOptions.doHorizonCulling); - - debugSelection.addOption("Level by proj area (else distance)", &_chunkedLodGlobe->debugOptions.levelByProjAreaElseDistance); - - // Add all tile layers as being toggleable for each category - for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; i++){ - LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory) i; - std::string categoryName = LayeredTextures::TEXTURE_CATEGORY_NAMES[i]; - auto selection = std::make_unique(categoryName, categoryName); - - auto& categoryProviders = _tileProviderManager->getTileProviderGroup(category); - for (auto& provider : categoryProviders.tileProviders) { - selection->addOption(provider.name, &provider.isActive); - } - selection->addOption(" - Blend tile levels - ", &_tileProviderManager->getTileProviderGroup(i).levelBlendingEnabled); - - addProperty(selection.get()); - _categorySelections.push_back(std::move(selection)); + addProperty(_generalProperties.isEnabled); + addProperty(_generalProperties.atmosphereEnabled); + addProperty(_generalProperties.performShading); + addProperty(_generalProperties.lodScaleFactor); + addProperty(_generalProperties.cameraMinHeight); + + _debugPropertyOwner.addProperty(_debugProperties.saveOrThrowCamera); + _debugPropertyOwner.addProperty(_debugProperties.showChunkEdges); + _debugPropertyOwner.addProperty(_debugProperties.showChunkBounds); + _debugPropertyOwner.addProperty(_debugProperties.showChunkAABB); + _debugPropertyOwner.addProperty(_debugProperties.showHeightResolution); + _debugPropertyOwner.addProperty(_debugProperties.showHeightIntensities); + _debugPropertyOwner.addProperty(_debugProperties.performFrustumCulling); + _debugPropertyOwner.addProperty(_debugProperties.performHorizonCulling); + _debugPropertyOwner.addProperty( + _debugProperties.levelByProjectedAreaElseDistance); + _debugPropertyOwner.addProperty(_debugProperties.resetTileProviders); + _debugPropertyOwner.addProperty(_debugProperties.toggleEnabledEveryFrame); + + for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; i++) { + _textureProperties.push_back(std::make_unique + (LayeredTextures::TextureCategory(i), *_tileProviderManager)); + _texturePropertyOwner.addPropertySubOwner(*_textureProperties[i]); } - - addProperty(atmosphereEnabled); - addProperty(_performShading); - addProperty(_saveOrThrowCamera); - addProperty(_resetTileProviders); - addProperty(lodScaleFactor); - addProperty(_cameraMinHeight); + + addPropertySubOwner(_debugPropertyOwner); + addPropertySubOwner(_texturePropertyOwner); } RenderableGlobe::~RenderableGlobe() { @@ -159,11 +205,6 @@ namespace openspace { } bool RenderableGlobe::initialize() { - for (auto& selection : _categorySelections) { - selection->initialize(); - } - debugSelection.initialize(); - return _distanceSwitch.initialize(); } @@ -176,37 +217,47 @@ namespace openspace { } void RenderableGlobe::render(const RenderData& data) { - if (_toggleEnabledEveryFrame.value()) { - _isEnabled.setValue(!_isEnabled.value()); + if (_debugProperties.toggleEnabledEveryFrame.value()) { + _generalProperties.isEnabled.setValue( + !_generalProperties.isEnabled.value()); } - if (_isEnabled.value()) { - if (_saveOrThrowCamera.value()) { - _saveOrThrowCamera.setValue(false); + if (_generalProperties.isEnabled.value()) { + if (_debugProperties.saveOrThrowCamera.value()) { + _debugProperties.saveOrThrowCamera.setValue(false); - if (_chunkedLodGlobe->getSavedCamera() == nullptr) { // save camera + if (savedCamera() == nullptr) { // save camera LDEBUG("Saving snapshot of camera!"); - _chunkedLodGlobe->setSaveCamera(std::make_shared(data.camera)); + setSaveCamera(std::make_shared(data.camera)); } else { // throw camera LDEBUG("Throwing away saved camera!"); - _chunkedLodGlobe->setSaveCamera(nullptr); + setSaveCamera(nullptr); } } _distanceSwitch.render(data); } + if (_savedCamera != nullptr) { + DebugRenderer::ref().renderCameraFrustum(data, *_savedCamera); + } } void RenderableGlobe::update(const UpdateData& data) { _time = data.time; _distanceSwitch.update(data); - _chunkedLodGlobe->lodScaleFactor = lodScaleFactor.value(); - _chunkedLodGlobe->atmosphereEnabled = atmosphereEnabled.value(); - _chunkedLodGlobe->performShading = _performShading.value(); + glm::dmat4 translation = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation); + glm::dmat4 rotation = glm::dmat4(data.modelTransform.rotation); + glm::dmat4 scaling = + glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale, + data.modelTransform.scale, data.modelTransform.scale)); - if (_resetTileProviders) { + _cachedModelTransform = translation * rotation * scaling; + _cachedInverseModelTransform = glm::inverse(_cachedModelTransform); + + if (_debugProperties.resetTileProviders) { _tileProviderManager->reset(); - _resetTileProviders = false; + _debugProperties.resetTileProviders = false; } _tileProviderManager->update(); _chunkedLodGlobe->update(data); @@ -216,29 +267,31 @@ namespace openspace { return _ellipsoid.geodeticSurfaceProjection(position); } - const Ellipsoid& RenderableGlobe::ellipsoid() { - return _ellipsoid; - } - float RenderableGlobe::getHeight(glm::dvec3 position) { // Get the tile provider for the height map - const auto& heightMapProviders = _tileProviderManager->getTileProviderGroup(LayeredTextures::HeightMaps).getActiveTileProviders(); + const auto& heightMapProviders = _tileProviderManager->getTileProviderGroup( + LayeredTextures::HeightMaps).getActiveTileProviders(); if (heightMapProviders.size() == 0) return 0; const auto& tileProvider = heightMapProviders[0]; // Get the uv coordinates to sample from Geodetic2 geodeticPosition = _ellipsoid.cartesianToGeodetic2(position); - int chunkLevel = _chunkedLodGlobe->findChunkNode(geodeticPosition).getChunk().index().level; + int chunkLevel = _chunkedLodGlobe->findChunkNode( + geodeticPosition).getChunk().index().level; ChunkIndex chunkIdx = ChunkIndex(geodeticPosition, chunkLevel); GeodeticPatch patch = GeodeticPatch(chunkIdx); - Geodetic2 geoDiffPatch = patch.getCorner(Quad::NORTH_EAST) - patch.getCorner(Quad::SOUTH_WEST); + Geodetic2 geoDiffPatch = + patch.getCorner(Quad::NORTH_EAST) - + patch.getCorner(Quad::SOUTH_WEST); Geodetic2 geoDiffPoint = geodeticPosition - patch.getCorner(Quad::SOUTH_WEST); - glm::vec2 patchUV = glm::vec2(geoDiffPoint.lon / geoDiffPatch.lon, geoDiffPoint.lat / geoDiffPatch.lat); + glm::vec2 patchUV = glm::vec2( + geoDiffPoint.lon / geoDiffPatch.lon, geoDiffPoint.lat / geoDiffPatch.lat); // Transform the uv coordinates to the current tile texture - TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(tileProvider.get(), chunkIdx); + TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile( + tileProvider.get(), chunkIdx); const auto& tile = tileAndTransform.tile; const auto& uvTransform = tileAndTransform.uvTransform; const auto& depthTransform = tileProvider->depthTransform(); @@ -247,17 +300,22 @@ namespace openspace { } glm::vec2 transformedUv = uvTransform.uvOffset + uvTransform.uvScale * patchUV; - // Sample and do linear interpolation (could possibly be moved as a function in ghoul texture) + // Sample and do linear interpolation + // (could possibly be moved as a function in ghoul texture) glm::uvec3 dimensions = tile.texture->dimensions(); glm::vec2 samplePos = transformedUv * glm::vec2(dimensions); glm::uvec2 samplePos00 = samplePos; - samplePos00 = glm::clamp(samplePos00, glm::uvec2(0, 0), glm::uvec2(dimensions) - glm::uvec2(1)); + samplePos00 = glm::clamp( + samplePos00, glm::uvec2(0, 0), glm::uvec2(dimensions) - glm::uvec2(1)); glm::vec2 samplePosFract = samplePos - glm::vec2(samplePos00); - glm::uvec2 samplePos10 = glm::min(samplePos00 + glm::uvec2(1, 0), glm::uvec2(dimensions) - glm::uvec2(1)); - glm::uvec2 samplePos01 = glm::min(samplePos00 + glm::uvec2(0, 1), glm::uvec2(dimensions) - glm::uvec2(1)); - glm::uvec2 samplePos11 = glm::min(samplePos00 + glm::uvec2(1, 1), glm::uvec2(dimensions) - glm::uvec2(1)); + glm::uvec2 samplePos10 = glm::min( + samplePos00 + glm::uvec2(1, 0), glm::uvec2(dimensions) - glm::uvec2(1)); + glm::uvec2 samplePos01 = glm::min( + samplePos00 + glm::uvec2(0, 1), glm::uvec2(dimensions) - glm::uvec2(1)); + glm::uvec2 samplePos11 = glm::min( + samplePos00 + glm::uvec2(1, 1), glm::uvec2(dimensions) - glm::uvec2(1)); float sample00 = tile.texture->texelAsFloat(samplePos00).x; float sample10 = tile.texture->texelAsFloat(samplePos10).x; @@ -276,17 +334,42 @@ namespace openspace { return height; } + std::shared_ptr RenderableGlobe::chunkedLodGlobe() const{ + return _chunkedLodGlobe; + } + + const Ellipsoid& RenderableGlobe::ellipsoid() const{ + return _ellipsoid; + } + + const glm::dmat4& RenderableGlobe::modelTransform() const{ + return _cachedModelTransform; + } + + const glm::dmat4& RenderableGlobe::inverseModelTransform() const{ + return _cachedInverseModelTransform; + } + + const RenderableGlobe::DebugProperties& + RenderableGlobe::debugProperties() const{ + return _debugProperties; + } + + const RenderableGlobe::GeneralProperties& + RenderableGlobe::generalProperties() const{ + return _generalProperties; + } + + const std::shared_ptr RenderableGlobe::savedCamera() const { + return _savedCamera; + } + double RenderableGlobe::interactionDepthBelowEllipsoid() { return _interactionDepthBelowEllipsoid; } - float RenderableGlobe::cameraMinHeight() { - return _cameraMinHeight.value(); + void RenderableGlobe::setSaveCamera(std::shared_ptr camera) { + _savedCamera = camera; } - - std::shared_ptr RenderableGlobe::chunkedLodGlobe() { - return _chunkedLodGlobe; - } - } // namespace openspace diff --git a/modules/globebrowsing/globes/renderableglobe.h b/modules/globebrowsing/globes/renderableglobe.h index 643a3fb66c..f6540cca6c 100644 --- a/modules/globebrowsing/globes/renderableglobe.h +++ b/modules/globebrowsing/globes/renderableglobe.h @@ -26,82 +26,76 @@ #define __RENDERABLEGLOBE_H__ #include +#include -// open space includes #include - +#include #include #include #include - #include #include - #include - - -#include +#include #include #include -namespace ghoul { -namespace opengl { - class ProgramObject; -} -} - - namespace openspace { class ChunkedLodGlobe; class TileProviderManager; + +class SingleTexturePropertyOwner : public properties::PropertyOwner +{ +public: + SingleTexturePropertyOwner(std::string name); + ~SingleTexturePropertyOwner(); -struct ReferencedBoolSelection : public properties::SelectionProperty { - ReferencedBoolSelection(const std::string& identifier, const std::string& guiName) - : properties::SelectionProperty(identifier, guiName) { } - - void addOption(const std::string& name, bool* ref) { - int optionId= options().size(); - _referenceMap.insert({ optionId, ref }); - properties::SelectionProperty::addOption({ optionId, name}); - } - - void initialize() { - // Set values in GUI to the current values of the references - int nOptions = options().size(); - std::vector selected; - for (int i = 0; i < nOptions; ++i) { - if (*_referenceMap[i]) { - selected.push_back(i); - } - } - setValue(selected); - - - onChange([this]() { - int nOptions = this->options().size(); - for (int i = 0; i < nOptions; ++i) { - (*_referenceMap[i]) = false; - } - - const std::vector& selectedIndices = (*this); - for (auto selectedIndex : selectedIndices) { - (*_referenceMap[selectedIndex]) = true; - } - }); - } - - std::unordered_map _referenceMap; + properties::BoolProperty isEnabled; + properties::FloatProperty opacity; }; - - - +class LayeredCategoryPropertyOwner : public properties::PropertyOwner +{ +public: + LayeredCategoryPropertyOwner( + LayeredTextures::TextureCategory category, + TileProviderManager& tileProviderManager); + ~LayeredCategoryPropertyOwner(); +private: + TileProviderManager& _tileProviderManager; + std::vector > + _texturePropertyOwners; + properties::BoolProperty _levelBlendingEnabled; +}; class RenderableGlobe : public Renderable { public: + struct DebugProperties { + properties::BoolProperty saveOrThrowCamera; + properties::BoolProperty showChunkEdges; + properties::BoolProperty showChunkBounds; + properties::BoolProperty showChunkAABB; + properties::BoolProperty showHeightResolution; + properties::BoolProperty showHeightIntensities; + properties::BoolProperty performFrustumCulling; + properties::BoolProperty performHorizonCulling; + properties::BoolProperty levelByProjectedAreaElseDistance; + properties::BoolProperty resetTileProviders; + properties::BoolProperty toggleEnabledEveryFrame; + }; + + struct GeneralProperties { + properties::BoolProperty isEnabled; + properties::BoolProperty performShading; + properties::BoolProperty atmosphereEnabled; + properties::FloatProperty lodScaleFactor; + properties::FloatProperty cameraMinHeight; + + }; + RenderableGlobe(const ghoul::Dictionary& dictionary); ~RenderableGlobe(); @@ -112,38 +106,45 @@ public: void render(const RenderData& data) override; void update(const UpdateData& data) override; + // Getters that perform calculations glm::dvec3 projectOnEllipsoid(glm::dvec3 position); - const Ellipsoid& ellipsoid(); float getHeight(glm::dvec3 position); - float cameraMinHeight(); - double interactionDepthBelowEllipsoid(); - std::shared_ptr chunkedLodGlobe(); - - // Properties - properties::BoolProperty _isEnabled; - properties::BoolProperty _toggleEnabledEveryFrame; - properties::BoolProperty _performShading; - properties::FloatProperty lodScaleFactor; - std::vector> _categorySelections; - properties::BoolProperty atmosphereEnabled; - ReferencedBoolSelection debugSelection; - properties::BoolProperty _saveOrThrowCamera; - properties::BoolProperty _resetTileProviders; -private: - double _interactionDepthBelowEllipsoid; + // Getters + std::shared_ptr chunkedLodGlobe() const; + const Ellipsoid& ellipsoid() const; + const glm::dmat4& modelTransform() const; + const glm::dmat4& inverseModelTransform() const; + const DebugProperties& debugProperties() const; + const GeneralProperties& generalProperties() const; + const std::shared_ptr savedCamera() const; + double interactionDepthBelowEllipsoid(); + + // Setters + void setSaveCamera(std::shared_ptr camera); +private: + std::shared_ptr _chunkedLodGlobe; + Ellipsoid _ellipsoid; + std::shared_ptr _tileProviderManager; + DistanceSwitch _distanceSwitch; + std::shared_ptr _savedCamera; + + double _interactionDepthBelowEllipsoid; std::string _frame; double _time; - Ellipsoid _ellipsoid; + glm::dmat4 _cachedModelTransform; + glm::dmat4 _cachedInverseModelTransform; - std::shared_ptr _tileProviderManager; - std::shared_ptr _chunkedLodGlobe; + // Properties + DebugProperties _debugProperties; + GeneralProperties _generalProperties; + + properties::PropertyOwner _debugPropertyOwner; + properties::PropertyOwner _texturePropertyOwner; - DistanceSwitch _distanceSwitch; - - properties::FloatProperty _cameraMinHeight; + std::vector > _textureProperties; }; } // namespace openspace diff --git a/modules/globebrowsing/tile/tileprovidermanager.h b/modules/globebrowsing/tile/tileprovidermanager.h index f2ee5abcca..805d659ce9 100644 --- a/modules/globebrowsing/tile/tileprovidermanager.h +++ b/modules/globebrowsing/tile/tileprovidermanager.h @@ -86,4 +86,4 @@ namespace openspace { }; } // namespace openspace -#endif // __TILE_PROVIDER_MANAGER_H__ \ No newline at end of file +#endif // __TILE_PROVIDER_MANAGER_H__ diff --git a/src/interaction/interactionmode.cpp b/src/interaction/interactionmode.cpp index cfccd8da2a..add51dace5 100644 --- a/src/interaction/interactionmode.cpp +++ b/src/interaction/interactionmode.cpp @@ -457,7 +457,7 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came // Declare variables to use in interaction calculations // Shrink interaction ellipsoid to enable interaction below height = 0 double ellipsoidShrinkTerm = _globe->interactionDepthBelowEllipsoid(); - double minHeightAboveGround = _globe->cameraMinHeight(); + double minHeightAboveGround = _globe->generalProperties().cameraMinHeight; // Read the current state of the camera and focusnode dvec3 camPos = camera.positionVec3(); @@ -474,8 +474,8 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came // Sampling of height is done in the reference frame of the globe. // Hence, the camera position needs to be transformed with the inverse model matrix - glm::dmat4 inverseModelTransform = _globe->chunkedLodGlobe()->inverseModelTransform(); - glm::dmat4 modelTransform = _globe->chunkedLodGlobe()->modelTransform(); + glm::dmat4 inverseModelTransform = _globe->inverseModelTransform(); + glm::dmat4 modelTransform = _globe->modelTransform(); glm::dvec3 cameraPositionModelSpace = glm::dvec3(inverseModelTransform * glm::dvec4(camPos, 1)); @@ -591,7 +591,7 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came // Sampling of height is done in the reference frame of the globe. // Hence, the camera position needs to be transformed with the inverse model matrix - glm::dmat4 inverseModelTransform = _globe->chunkedLodGlobe()->inverseModelTransform(); + glm::dmat4 inverseModelTransform = _globe->inverseModelTransform(); glm::dvec3 cameraPositionModelSpace = glm::dvec3(inverseModelTransform * glm::dvec4(camPos, 1));