Update structure of properties for renderable globes.

This commit is contained in:
kalbl
2016-10-02 21:30:26 +02:00
parent c2603e5712
commit 423c55ba38
12 changed files with 399 additions and 373 deletions

View File

@@ -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",
}
}

View File

@@ -28,6 +28,7 @@
#include <openspace/engine/openspaceengine.h>
#include <modules/globebrowsing/chunk/chunk.h>
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/chunk/chunkedlodglobe.h>
#include <modules/globebrowsing/tile/layeredtextures.h>
#include <modules/globebrowsing/tile/tileioresult.h>
@@ -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<glm::dvec4> Chunk::getBoundingPolyhedronCorners() const {
const Ellipsoid& ellipsoid = owner()->ellipsoid();
const Ellipsoid& ellipsoid = owner().ellipsoid();
const GeodeticPatch& patch = surfacePatch();
BoundingHeights boundingHeight = getBoundingHeights();

View File

@@ -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<glm::dvec4> 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;

View File

@@ -24,13 +24,13 @@
#include <modules/globebrowsing/chunk/chunkedlodglobe.h>
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/meshes/skirtedgrid.h>
#include <modules/globebrowsing/chunk/culling.h>
#include <modules/globebrowsing/chunk/chunklevelevaluator.h>
#include <modules/debugging/rendering/debugrenderer.h>
// open space includes
#include <openspace/engine/openspaceengine.h>
#include <openspace/rendering/renderengine.h>
@@ -47,32 +47,34 @@
#include <ctime>
#include <chrono>
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> tileProviderManager)
: _ellipsoid(ellipsoid)
, _leftRoot(std::make_unique<ChunkNode>(Chunk(this, LEFT_HEMISPHERE_INDEX)))
, _rightRoot(std::make_unique<ChunkNode>(Chunk(this, RIGHT_HEMISPHERE_INDEX)))
: _owner(owner)
, _leftRoot(std::make_unique<ChunkNode>(
Chunk(owner, LEFT_HEMISPHERE_INDEX)))
, _rightRoot(std::make_unique<ChunkNode>(
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<SkirtedGrid>(
(unsigned int) segmentsPerPatch,
(unsigned int) segmentsPerPatch,
@@ -81,15 +83,18 @@ namespace openspace {
TriangleSoup::Normals::No);
_chunkCullers.push_back(std::make_unique<HorizonCuller>());
_chunkCullers.push_back(std::make_unique<FrustumCuller>(AABB3(vec3(-1, -1, 0), vec3(1, 1, 1e35))));
_chunkCullers.push_back(std::make_unique<FrustumCuller>(
AABB3(vec3(-1, -1, 0), vec3(1, 1, 1e35))));
_chunkEvaluatorByAvailableTiles =
std::make_unique<EvaluateChunkLevelByAvailableTileData>();
_chunkEvaluatorByProjectedArea =
std::make_unique<EvaluateChunkLevelByProjectedArea>();
_chunkEvaluatorByDistance =
std::make_unique<EvaluateChunkLevelByDistance>();
_chunkEvaluatorByAvailableTiles = std::make_unique<EvaluateChunkLevelByAvailableTileData>();
_chunkEvaluatorByProjectedArea = std::make_unique<EvaluateChunkLevelByProjectedArea>();
_chunkEvaluatorByDistance = std::make_unique<EvaluateChunkLevelByDistance>();
_renderer = std::make_unique<ChunkRenderer>(geometry, tileProviderManager);
_renderer =
std::make_unique<ChunkRenderer>(geometry, tileProviderManager);
}
ChunkedLodGlobe::~ChunkedLodGlobe() {
@@ -109,42 +114,59 @@ namespace openspace {
return ready;
}
std::shared_ptr<TileProviderManager> ChunkedLodGlobe::getTileProviderManager() const {
std::shared_ptr<TileProviderManager>
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<std::chrono::milliseconds>(duration).count();
auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(
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<void(const ChunkNode&)> 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<glm::dvec4> modelSpaceCorners = chunk.getBoundingPolyhedronCorners();
void ChunkedLodGlobe::debugRenderChunk(
const Chunk& chunk, const glm::dmat4& mvp) const {
if (_owner.debugProperties().showChunkBounds ||
_owner.debugProperties().showChunkAABB) {
const std::vector<glm::dvec4> modelSpaceCorners =
chunk.getBoundingPolyhedronCorners();
std::vector<glm::vec4> 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

View File

@@ -27,10 +27,8 @@
#include <memory>
#include <ghoul/logging/logmanager.h>
// open space includes
#include <openspace/rendering/renderengine.h>
#include <openspace/rendering/renderable.h>
@@ -38,30 +36,21 @@
#include <openspace/util/updatestructures.h>
#include <modules/globebrowsing/geometry/ellipsoid.h>
#include <modules/globebrowsing/chunk/chunknode.h>
#include <modules/globebrowsing/chunk/chunkrenderer.h>
#include <modules/globebrowsing/tile/tileprovider/tileprovider.h>
#include <modules/globebrowsing/other/statscollector.h>
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> 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<TileProviderManager> getTileProviderManager() const;
const std::shared_ptr<const Camera> getSavedCamera() const { return _savedCamera; }
void setSaveCamera(std::shared_ptr<Camera> 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<ChunkNode> _leftRoot;
@@ -132,24 +91,16 @@ namespace openspace {
// the patch used for actual rendering
std::unique_ptr<ChunkRenderer> _renderer;
static const ChunkIndex LEFT_HEMISPHERE_INDEX;
static const ChunkIndex RIGHT_HEMISPHERE_INDEX;
std::vector<std::unique_ptr<ChunkCuller>> _chunkCullers;
std::unique_ptr<ChunkLevelEvaluator> _chunkEvaluatorByAvailableTiles;
std::unique_ptr<ChunkLevelEvaluator> _chunkEvaluatorByProjectedArea;
std::unique_ptr<ChunkLevelEvaluator> _chunkEvaluatorByDistance;
const Ellipsoid& _ellipsoid;
glm::dmat4 _cachedModelTransform;
glm::dmat4 _cachedInverseModelTransform;
std::shared_ptr<Camera> _savedCamera;
std::shared_ptr<TileProviderManager> _tileProviderManager;
};
const RenderableGlobe& _owner;
};
} // namespace openspace
#endif // __CHUNK_LOD_GLOBE__

View File

@@ -30,6 +30,7 @@
#include <modules/globebrowsing/chunk/chunklevelevaluator.h>
#include <modules/globebrowsing/chunk/chunk.h>
#include <modules/globebrowsing/chunk/chunkedlodglobe.h>
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/tile/layeredtextures.h>
@@ -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;

View File

@@ -25,6 +25,7 @@
#include <modules/globebrowsing/chunk/chunkrenderer.h>
#include <modules/globebrowsing/chunk/chunkedlodglobe.h>
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/tile/layeredtextures.h>
#include <modules/globebrowsing/tile/tileprovidermanager.h>
@@ -179,27 +180,27 @@ namespace openspace {
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"useAtmosphere",
std::to_string(chunk.owner()->atmosphereEnabled)));
std::to_string(chunk.owner().generalProperties().atmosphereEnabled)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"performShading",
std::to_string(chunk.owner()->performShading)));
std::to_string(chunk.owner().generalProperties().performShading)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showChunkEdges",
std::to_string(chunk.owner()->debugOptions.showChunkEdges)));
std::to_string(chunk.owner().debugProperties().showChunkEdges)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showHeightResolution",
std::to_string(chunk.owner()->debugOptions.showHeightResolution)));
std::to_string(chunk.owner().debugProperties().showHeightResolution)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showHeightIntensities",
std::to_string(chunk.owner()->debugOptions.showHeightIntensities)));
std::to_string(chunk.owner().debugProperties().showHeightIntensities)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
@@ -314,7 +315,7 @@ namespace openspace {
programObject->setUniform("skirtLength", min(static_cast<float>(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 =

View File

@@ -27,7 +27,7 @@
#include <modules/globebrowsing/chunk/culling.h>
#include <modules/globebrowsing/chunk/chunkedlodglobe.h>
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <modules/globebrowsing/chunk/chunk.h>
#include <modules/globebrowsing/geometry/ellipsoid.h>
@@ -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

View File

@@ -25,8 +25,8 @@
#include <modules/globebrowsing/globes/renderableglobe.h>
#include <ghoul/misc/threadpool.h>
#include <modules/globebrowsing/tile/tileselector.h>
#include <modules/globebrowsing/tile/tileselector.h>
#include <modules/globebrowsing/chunk/chunkedlodglobe.h>
#include <modules/globebrowsing/tile/tileprovidermanager.h>
@@ -36,17 +36,19 @@
#include <openspace/util/spicemanager.h>
#include <openspace/scene/scenegraphnode.h>
#include <modules/debugging/rendering/debugrenderer.h>
// ghoul includes
#include <ghoul/misc/assert.h>
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<SingleTexturePropertyOwner>(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<ChunkedLodGlobe>(
_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<ReferencedBoolSelection>(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<LayeredCategoryPropertyOwner>
(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<Camera>(data.camera));
setSaveCamera(std::make_shared<Camera>(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<ChunkedLodGlobe> 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<const Camera> RenderableGlobe::savedCamera() const {
return _savedCamera;
}
double RenderableGlobe::interactionDepthBelowEllipsoid() {
return _interactionDepthBelowEllipsoid;
}
float RenderableGlobe::cameraMinHeight() {
return _cameraMinHeight.value();
void RenderableGlobe::setSaveCamera(std::shared_ptr<Camera> camera) {
_savedCamera = camera;
}
std::shared_ptr<ChunkedLodGlobe> RenderableGlobe::chunkedLodGlobe() {
return _chunkedLodGlobe;
}
} // namespace openspace

View File

@@ -26,82 +26,76 @@
#define __RENDERABLEGLOBE_H__
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/threadpool.h>
// open space includes
#include <openspace/rendering/renderable.h>
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/properties/selectionproperty.h>
#include <openspace/util/updatestructures.h>
#include <modules/globebrowsing/meshes/trianglesoup.h>
#include <modules/globebrowsing/geometry/ellipsoid.h>
#include <ghoul/misc/threadpool.h>
#include <modules/globebrowsing/tile/layeredtextures.h>
#include <modules/globebrowsing/other/distanceswitch.h>
#include <unordered_map>
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<int> 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<int>& selectedIndices = (*this);
for (auto selectedIndex : selectedIndices) {
(*_referenceMap[selectedIndex]) = true;
}
});
}
std::unordered_map<int, bool* const> _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<std::unique_ptr<SingleTexturePropertyOwner> >
_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> chunkedLodGlobe();
// Properties
properties::BoolProperty _isEnabled;
properties::BoolProperty _toggleEnabledEveryFrame;
properties::BoolProperty _performShading;
properties::FloatProperty lodScaleFactor;
std::vector<std::unique_ptr<ReferencedBoolSelection>> _categorySelections;
properties::BoolProperty atmosphereEnabled;
ReferencedBoolSelection debugSelection;
properties::BoolProperty _saveOrThrowCamera;
properties::BoolProperty _resetTileProviders;
private:
double _interactionDepthBelowEllipsoid;
// Getters
std::shared_ptr<ChunkedLodGlobe> 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<const Camera> savedCamera() const;
double interactionDepthBelowEllipsoid();
// Setters
void setSaveCamera(std::shared_ptr<Camera> camera);
private:
std::shared_ptr<ChunkedLodGlobe> _chunkedLodGlobe;
Ellipsoid _ellipsoid;
std::shared_ptr<TileProviderManager> _tileProviderManager;
DistanceSwitch _distanceSwitch;
std::shared_ptr<Camera> _savedCamera;
double _interactionDepthBelowEllipsoid;
std::string _frame;
double _time;
Ellipsoid _ellipsoid;
glm::dmat4 _cachedModelTransform;
glm::dmat4 _cachedInverseModelTransform;
std::shared_ptr<TileProviderManager> _tileProviderManager;
std::shared_ptr<ChunkedLodGlobe> _chunkedLodGlobe;
// Properties
DebugProperties _debugProperties;
GeneralProperties _generalProperties;
properties::PropertyOwner _debugPropertyOwner;
properties::PropertyOwner _texturePropertyOwner;
DistanceSwitch _distanceSwitch;
properties::FloatProperty _cameraMinHeight;
std::vector<std::unique_ptr<LayeredCategoryPropertyOwner> > _textureProperties;
};
} // namespace openspace

View File

@@ -86,4 +86,4 @@ namespace openspace {
};
} // namespace openspace
#endif // __TILE_PROVIDER_MANAGER_H__
#endif // __TILE_PROVIDER_MANAGER_H__

View File

@@ -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));