mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-05-23 04:48:53 -05:00
Merge branch 'feature/globebrowsing' of github.com:OpenSpace/OpenSpace-Development into feature/globebrowsing
This commit is contained in:
@@ -65,7 +65,7 @@ namespace openspace {
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
void DebugRenderer::renderVertices(const std::vector<glm::vec4>& clippingSpacePoints, GLenum mode, glm::vec4 rgba) const {
|
||||
void DebugRenderer::renderVertices(const Vertices& clippingSpacePoints, GLenum mode, RGBA rgba) const {
|
||||
if (clippingSpacePoints.size() == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -114,7 +114,7 @@ namespace openspace {
|
||||
|
||||
}
|
||||
|
||||
void DebugRenderer::renderBoxFaces(const std::vector<glm::vec4>& clippingSpaceBoxCorners, glm::vec4 rgba) const {
|
||||
void DebugRenderer::renderBoxFaces(const Vertices& clippingSpaceBoxCorners, RGBA rgba) const {
|
||||
const std::vector<glm::vec4>& V = clippingSpaceBoxCorners;
|
||||
std::vector<glm::vec4> T;
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace openspace {
|
||||
renderVertices(T, GL_TRIANGLES, rgba);
|
||||
}
|
||||
|
||||
void DebugRenderer::renderBoxEdges(const std::vector<glm::vec4>& clippingSpacePoints, glm::vec4 rgba) const {
|
||||
void DebugRenderer::renderBoxEdges(const Vertices& clippingSpacePoints, RGBA rgba) const {
|
||||
const std::vector<glm::vec4>& V = clippingSpacePoints;
|
||||
std::vector<glm::vec4> lineVertices;
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
@@ -159,7 +159,7 @@ namespace openspace {
|
||||
DebugRenderer::ref()->renderVertices(lineVertices, GL_LINES, rgba);
|
||||
}
|
||||
|
||||
void DebugRenderer::renderNiceBox(const std::vector<glm::vec4>& clippingSpacePoints, glm::vec4 rgba) const {
|
||||
void DebugRenderer::renderNiceBox(const Vertices& clippingSpacePoints, RGBA rgba) const {
|
||||
renderBoxFaces(clippingSpacePoints, rgba);
|
||||
|
||||
glLineWidth(4.0f);
|
||||
@@ -208,4 +208,31 @@ namespace openspace {
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void DebugRenderer::renderAABB2(const AABB2& screenSpaceAABB, RGBA rgba) const {
|
||||
std::vector<vec4> vertices(4);
|
||||
vertices[0] = vec4(screenSpaceAABB.min.x, screenSpaceAABB.min.y, 1, 1);
|
||||
vertices[1] = vec4(screenSpaceAABB.min.x, screenSpaceAABB.max.y, 1, 1);
|
||||
vertices[2] = vec4(screenSpaceAABB.max.x, screenSpaceAABB.min.y, 1, 1);
|
||||
vertices[3] = vec4(screenSpaceAABB.max.x, screenSpaceAABB.max.y, 1, 1);
|
||||
|
||||
renderVertices(vertices, GL_LINES, rgba);
|
||||
}
|
||||
|
||||
const DebugRenderer::Vertices DebugRenderer::verticesFor(const AABB3& screenSpaceAABB) const {
|
||||
std::vector<vec4> vertices(8);
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
bool cornerIsRight = i % 2 == 0;
|
||||
bool cornerIsUp = i > 3;
|
||||
bool cornerIsFar = (i / 2) % 2 == 1;
|
||||
|
||||
double x = cornerIsRight ? screenSpaceAABB.max.x : screenSpaceAABB.min.x;
|
||||
double y = cornerIsUp ? screenSpaceAABB.max.y : screenSpaceAABB.min.y;
|
||||
double z = cornerIsFar ? screenSpaceAABB.max.z : screenSpaceAABB.min.z;
|
||||
|
||||
vertices[i] = vec4(x, y, z, 1);
|
||||
}
|
||||
return std::move(vertices);
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
|
||||
#include <openspace/util/updatestructures.h>
|
||||
#include <modules/globebrowsing/geometry/aabb.h>
|
||||
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
@@ -51,12 +52,20 @@ namespace openspace {
|
||||
|
||||
static std::shared_ptr<DebugRenderer> ref();
|
||||
|
||||
typedef std::vector<glm::vec4> Vertices;
|
||||
typedef glm::vec4 RGBA;
|
||||
|
||||
|
||||
void renderVertices(const Vertices& clippingSpacePoints, GLenum mode, RGBA = {1, 0, 0, 1}) const;
|
||||
void renderBoxFaces(const Vertices& clippingSpacePoints, RGBA rgba = { 1, 0, 0, 1 }) const;
|
||||
void renderBoxEdges(const Vertices& clippingSpacePoints, RGBA rgba = { 1, 0, 0, 1 }) const;
|
||||
void renderNiceBox(const Vertices& clippingSpacePoints, RGBA rgba = { 1, 0, 0, 0.3 }) const;
|
||||
|
||||
void renderVertices(const std::vector<glm::vec4>& clippingSpacePoints, GLenum mode, glm::vec4 rgba = {1, 0, 0, 1}) const;
|
||||
void renderBoxFaces(const std::vector<glm::vec4>& clippingSpacePoints, glm::vec4 rgba = { 1, 0, 0, 1 }) const;
|
||||
void renderBoxEdges(const std::vector<glm::vec4>& clippingSpacePoints, glm::vec4 rgba = { 1, 0, 0, 1 }) const;
|
||||
void renderNiceBox(const std::vector<glm::vec4>& clippingSpacePoints, glm::vec4 rgba = { 1, 0, 0, 0.3 }) const;
|
||||
void renderCameraFrustum(const RenderData& data, const Camera& otherCamera) const;
|
||||
void renderAABB2(const AABB2& screenSpaceAABB, RGBA rgba = { 1, 1, 1, 0.3 }) const;
|
||||
|
||||
|
||||
const Vertices verticesFor(const AABB3& screenSpaceAABB) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace openspace {
|
||||
}
|
||||
|
||||
Chunk::Status Chunk::update(const RenderData& data) {
|
||||
Camera* savedCamera = _owner->getSavedCamera();
|
||||
auto savedCamera = _owner->getSavedCamera();
|
||||
const Camera& camRef = savedCamera != nullptr ? *savedCamera : data.camera;
|
||||
RenderData myRenderData = { camRef, data.position, data.doPerformanceMeasurement };
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace openspace {
|
||||
|
||||
Chunk::BoundingHeights Chunk::getBoundingHeights() const {
|
||||
BoundingHeights boundingHeights;
|
||||
boundingHeights.max = _owner->chunkHeight;
|
||||
boundingHeights.max = 0;
|
||||
boundingHeights.min = 0;
|
||||
boundingHeights.available = false;
|
||||
|
||||
@@ -172,10 +172,4 @@ namespace openspace {
|
||||
}
|
||||
|
||||
|
||||
void Chunk::render(const RenderData& data) const {
|
||||
_owner->getPatchRenderer().renderChunk(*this, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -60,8 +60,6 @@ namespace openspace {
|
||||
|
||||
/// Updates chunk internally and returns a desired level
|
||||
Status update(const RenderData& data);
|
||||
void render(const RenderData& data) const;
|
||||
|
||||
|
||||
std::vector<glm::dvec4> getBoundingPolyhedronCorners() const;
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ namespace openspace {
|
||||
TriangleSoup::TextureCoordinates::Yes,
|
||||
TriangleSoup::Normals::No);
|
||||
|
||||
_chunkCullers.push_back(new HorizonCuller());
|
||||
_chunkCullers.push_back(new FrustumCuller(AABB3(vec3(-1, -1, 0), vec3(1, 1, 1e35))));
|
||||
_chunkCullers.push_back(std::make_unique<HorizonCuller>());
|
||||
_chunkCullers.push_back(std::make_unique<FrustumCuller>(AABB3(vec3(-1, -1, 0), vec3(1, 1, 1e35))));
|
||||
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace openspace {
|
||||
_chunkEvaluatorByProjectedArea = std::make_unique<EvaluateChunkLevelByProjectedArea>();
|
||||
_chunkEvaluatorByDistance = std::make_unique<EvaluateChunkLevelByDistance>();
|
||||
|
||||
_patchRenderer = std::make_unique<ChunkRenderer>(geometry, tileProviderManager);
|
||||
_renderer = std::make_unique<ChunkRenderer>(geometry, tileProviderManager);
|
||||
}
|
||||
|
||||
ChunkedLodGlobe::~ChunkedLodGlobe() {
|
||||
@@ -109,16 +109,11 @@ namespace openspace {
|
||||
return _tileProviderManager;
|
||||
}
|
||||
|
||||
|
||||
ChunkRenderer& ChunkedLodGlobe::getPatchRenderer() const{
|
||||
return *_patchRenderer;
|
||||
}
|
||||
|
||||
bool ChunkedLodGlobe::testIfCullable(const Chunk& chunk, const RenderData& renderData) const {
|
||||
if (doHorizonCulling && _chunkCullers[0]->isCullable(chunk, renderData)) {
|
||||
if (debugOptions.doHorizonCulling && _chunkCullers[0]->isCullable(chunk, renderData)) {
|
||||
return true;
|
||||
}
|
||||
if (doFrustumCulling && _chunkCullers[1]->isCullable(chunk, renderData)) {
|
||||
if (debugOptions.doFrustumCulling && _chunkCullers[1]->isCullable(chunk, renderData)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -126,14 +121,14 @@ namespace openspace {
|
||||
|
||||
int ChunkedLodGlobe::getDesiredLevel(const Chunk& chunk, const RenderData& renderData) const {
|
||||
int desiredLevel = 0;
|
||||
if (levelByProjArea) {
|
||||
if (debugOptions.levelByProjAreaElseDistance) {
|
||||
desiredLevel = _chunkEvaluatorByProjectedArea->getDesiredLevel(chunk, renderData);
|
||||
}
|
||||
else {
|
||||
desiredLevel = _chunkEvaluatorByDistance->getDesiredLevel(chunk, renderData);
|
||||
}
|
||||
|
||||
if (limitLevelByAvailableHeightData) {
|
||||
if (debugOptions.limitLevelByAvailableHeightData) {
|
||||
int desiredLevelByAvailableData = _chunkEvaluatorByAvailableTiles->getDesiredLevel(chunk, renderData);
|
||||
if (desiredLevelByAvailableData != ChunkLevelEvaluator::UNKNOWN_DESIRED_LEVEL) {
|
||||
desiredLevel = min(desiredLevel, desiredLevelByAvailableData);
|
||||
@@ -147,17 +142,28 @@ namespace openspace {
|
||||
|
||||
void ChunkedLodGlobe::render(const RenderData& data){
|
||||
minDistToCamera = INFINITY;
|
||||
ChunkNode::renderedChunks = 0;
|
||||
|
||||
_leftRoot->updateChunkTree(data);
|
||||
_rightRoot->updateChunkTree(data);
|
||||
|
||||
renderChunkTree(_leftRoot.get(), data);
|
||||
renderChunkTree(_rightRoot.get(), data);
|
||||
// Calculate the MVP matrix
|
||||
dmat4 modelTransform = translate(dmat4(1), data.position.dvec3());
|
||||
dmat4 viewTransform = dmat4(data.camera.combinedViewMatrix());
|
||||
dmat4 vp = dmat4(data.camera.projectionMatrix()) * viewTransform;
|
||||
dmat4 mvp = vp * modelTransform;
|
||||
|
||||
// Render function
|
||||
std::function<void(const ChunkNode&)> renderJob = [this, &data, &mvp](const ChunkNode& chunkNode) {
|
||||
const Chunk& chunk = chunkNode.getChunk();
|
||||
if (chunkNode.isLeaf() && chunk.isVisible()) {
|
||||
_renderer->renderChunk(chunkNode.getChunk(), data);
|
||||
debugRenderChunk(chunk, mvp);
|
||||
}
|
||||
};
|
||||
|
||||
_leftRoot->reverseBreadthFirst(renderJob);
|
||||
_rightRoot->reverseBreadthFirst(renderJob);
|
||||
|
||||
if (showChunkBounds) {
|
||||
renderChunkBounds(data);
|
||||
}
|
||||
|
||||
if (_savedCamera != nullptr) {
|
||||
DebugRenderer::ref()->renderCameraFrustum(data, *_savedCamera);
|
||||
@@ -174,43 +180,36 @@ namespace openspace {
|
||||
//LDEBUG(ChunkNode::renderedChunks << " / " << ChunkNode::chunkNodeCount << " chunks rendered");
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::renderChunkTree(ChunkNode* node, const RenderData& data) const {
|
||||
if (renderSmallChunksFirst) {
|
||||
node->renderReversedBreadthFirst(data);
|
||||
}
|
||||
else {
|
||||
node->renderDepthFirst(data);
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::renderChunkBounds(const RenderData& data) const {
|
||||
// Calculate the MVP matrix
|
||||
dmat4 modelTransform = translate(dmat4(1), data.position.dvec3());
|
||||
dmat4 viewTransform = dmat4(data.camera.combinedViewMatrix());
|
||||
dmat4 vp = dmat4(data.camera.projectionMatrix()) * viewTransform;
|
||||
dmat4 mvp = vp * modelTransform;
|
||||
void ChunkedLodGlobe::debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp) const {
|
||||
if (debugOptions.showChunkBounds || debugOptions.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;
|
||||
|
||||
std::function<void(const ChunkNode&)> chunkDebugRenderer = [&data, &mvp](const ChunkNode& chunkNode) {
|
||||
const Chunk& chunk = chunkNode.getChunk();
|
||||
if (chunkNode.isLeaf() && chunk.isVisible()) {
|
||||
const std::vector<glm::dvec4> modelSpaceCorners = chunk.getBoundingPolyhedronCorners();
|
||||
std::vector<glm::vec4> clippingSpaceCorners(8);
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
clippingSpaceCorners[i] = mvp * modelSpaceCorners[i];
|
||||
}
|
||||
vec3 screenSpaceCorner = (1.0f / clippingSpaceCorner.w) * clippingSpaceCorner.xyz();
|
||||
screenSpaceBounds.expand(screenSpaceCorner);
|
||||
}
|
||||
|
||||
unsigned int colorBits = 1 + chunk.index().level % 6;
|
||||
vec4 color = vec4(colorBits & 1, colorBits & 2, colorBits & 4, 0.3);
|
||||
unsigned int colorBits = 1 + chunk.index().level % 6;
|
||||
vec4 color = vec4(colorBits & 1, colorBits & 2, colorBits & 4, 0.3);
|
||||
|
||||
if (debugOptions.showChunkBounds) {
|
||||
DebugRenderer::ref()->renderNiceBox(clippingSpaceCorners, color);
|
||||
}
|
||||
};
|
||||
|
||||
_leftRoot->depthFirst(chunkDebugRenderer);
|
||||
_rightRoot->depthFirst(chunkDebugRenderer);
|
||||
if (debugOptions.showChunkAABB) {
|
||||
auto& screenSpacePoints = DebugRenderer::ref()->verticesFor(screenSpaceBounds);
|
||||
DebugRenderer::ref()->renderNiceBox(screenSpacePoints, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::update(const UpdateData& data) {
|
||||
_patchRenderer->update();
|
||||
_renderer->update();
|
||||
}
|
||||
|
||||
void ChunkedLodGlobe::setStateMatrix(const glm::dmat3& stateMatrix)
|
||||
|
||||
@@ -65,8 +65,6 @@ namespace openspace {
|
||||
std::shared_ptr<TileProviderManager> tileProviderManager);
|
||||
virtual ~ChunkedLodGlobe();
|
||||
|
||||
ChunkRenderer& getPatchRenderer() const;
|
||||
|
||||
bool initialize() override;
|
||||
bool deinitialize() override;
|
||||
bool isReady() const override;
|
||||
@@ -92,36 +90,35 @@ namespace openspace {
|
||||
std::shared_ptr<TileProviderManager> getTileProviderManager() const;
|
||||
|
||||
|
||||
Camera* getSavedCamera() const { return _savedCamera; }
|
||||
void setSaveCamera(Camera* c) {
|
||||
if (_savedCamera != nullptr) delete _savedCamera;
|
||||
const std::shared_ptr<const Camera> getSavedCamera() const { return _savedCamera; }
|
||||
void setSaveCamera(std::shared_ptr<Camera> c) {
|
||||
_savedCamera = c;
|
||||
}
|
||||
|
||||
|
||||
bool doHorizonCulling = true;
|
||||
bool doFrustumCulling = true;
|
||||
bool mergeInvisible;
|
||||
|
||||
float lodScaleFactor;
|
||||
bool initChunkVisible;
|
||||
bool renderSmallChunksFirst = true;
|
||||
float chunkHeight;
|
||||
|
||||
// Layered rendering
|
||||
std::array<bool, LayeredTextures::NUM_TEXTURE_CATEGORIES>
|
||||
blendProperties;
|
||||
std::array<bool, LayeredTextures::NUM_TEXTURE_CATEGORIES> blendProperties;
|
||||
|
||||
bool atmosphereEnabled;
|
||||
bool showChunkEdges;
|
||||
bool showChunkBounds;
|
||||
bool levelByProjArea;
|
||||
bool limitLevelByAvailableHeightData;
|
||||
|
||||
|
||||
struct DebugOptions {
|
||||
bool showChunkEdges = false;
|
||||
bool showChunkBounds = false;
|
||||
bool showChunkAABB = false;
|
||||
|
||||
bool doHorizonCulling = true;
|
||||
bool doFrustumCulling = true;
|
||||
|
||||
bool limitLevelByAvailableHeightData = true;
|
||||
bool levelByProjAreaElseDistance = true;
|
||||
} debugOptions;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void renderChunkTree(ChunkNode* node, const RenderData& data) const;
|
||||
void renderChunkBounds(const RenderData& data) const;
|
||||
|
||||
void debugRenderChunk(const Chunk& chunk, const glm::dmat4& data) const;
|
||||
|
||||
// Covers all negative longitudes
|
||||
std::unique_ptr<ChunkNode> _leftRoot;
|
||||
@@ -130,7 +127,7 @@ namespace openspace {
|
||||
std::unique_ptr<ChunkNode> _rightRoot;
|
||||
|
||||
// the patch used for actual rendering
|
||||
std::unique_ptr<ChunkRenderer> _patchRenderer;
|
||||
std::unique_ptr<ChunkRenderer> _renderer;
|
||||
|
||||
static const GeodeticPatch LEFT_HEMISPHERE;
|
||||
static const GeodeticPatch RIGHT_HEMISPHERE;
|
||||
@@ -138,7 +135,7 @@ namespace openspace {
|
||||
static const ChunkIndex LEFT_HEMISPHERE_INDEX;
|
||||
static const ChunkIndex RIGHT_HEMISPHERE_INDEX;
|
||||
|
||||
std::vector<ChunkCuller*> _chunkCullers;
|
||||
std::vector<std::unique_ptr<ChunkCuller>> _chunkCullers;
|
||||
|
||||
std::unique_ptr<ChunkLevelEvaluator> _chunkEvaluatorByAvailableTiles;
|
||||
std::unique_ptr<ChunkLevelEvaluator> _chunkEvaluatorByProjectedArea;
|
||||
@@ -147,7 +144,7 @@ namespace openspace {
|
||||
const Ellipsoid& _ellipsoid;
|
||||
glm::dmat3 _stateMatrix;
|
||||
|
||||
Camera* _savedCamera;
|
||||
std::shared_ptr<Camera> _savedCamera;
|
||||
|
||||
std::shared_ptr<TileProviderManager> _tileProviderManager;
|
||||
};
|
||||
|
||||
@@ -41,7 +41,6 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
int ChunkNode::chunkNodeCount = 0;
|
||||
int ChunkNode::renderedChunks = 0;
|
||||
|
||||
ChunkNode::ChunkNode(const Chunk& chunk, ChunkNode* parent)
|
||||
: _chunk(chunk)
|
||||
@@ -107,55 +106,58 @@ void ChunkNode::depthFirst(const std::function<void(const ChunkNode&)>& f) const
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::breadthFirst(const std::function<void(const ChunkNode&)>& f) const {
|
||||
std::queue<const ChunkNode*> Q;
|
||||
|
||||
|
||||
void ChunkNode::renderReversedBreadthFirst(const RenderData& data) {
|
||||
std::stack<ChunkNode*> S;
|
||||
std::queue<ChunkNode*> Q;
|
||||
// Loop through nodes in breadths first order
|
||||
Q.push(this);
|
||||
while (Q.size() > 0) {
|
||||
ChunkNode* node = Q.front();
|
||||
const ChunkNode* node = Q.front();
|
||||
Q.pop();
|
||||
if (node->isLeaf()) {
|
||||
if (node->_chunk.isVisible()) {
|
||||
S.push(node);
|
||||
|
||||
f(*node);
|
||||
|
||||
// Add children to queue, if any
|
||||
if (!node->isLeaf()) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Q.push(node->_children[i].get());
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::reverseBreadthFirst(const std::function<void(const ChunkNode&)>& f) const {
|
||||
std::stack<const ChunkNode*> S;
|
||||
std::queue<const ChunkNode*> Q;
|
||||
|
||||
// Loop through nodes in breadths first order
|
||||
Q.push(this);
|
||||
while (Q.size() > 0) {
|
||||
const ChunkNode* node = Q.front();
|
||||
Q.pop();
|
||||
|
||||
// Add node to future stack
|
||||
S.push(node);
|
||||
|
||||
// Add children to queue, if any
|
||||
if (!node->isLeaf()) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Q.push(node->_children[i].get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all nodes in stack, this will be reversed breadth first
|
||||
while (S.size() > 0) {
|
||||
S.top()->renderThisChunk(data);
|
||||
f(*S.top());
|
||||
S.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::renderThisChunk(const RenderData& data) {
|
||||
_chunk.render(data);
|
||||
ChunkNode::renderedChunks++;
|
||||
}
|
||||
|
||||
void ChunkNode::renderDepthFirst(const RenderData& data) {
|
||||
if (isLeaf()) {
|
||||
if (_chunk.isVisible()) {
|
||||
renderThisChunk(data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
_children[i]->renderDepthFirst(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChunkNode::split(int depth) {
|
||||
if (depth > 0 && isLeaf()) {
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
Chunk chunk(_chunk.owner(), _chunk.index().child((Quad)i), _chunk.owner()->initChunkVisible);
|
||||
Chunk chunk(_chunk.owner(), _chunk.index().child((Quad)i));
|
||||
_children[i] = std::unique_ptr<ChunkNode>(new ChunkNode(chunk, this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,17 +63,15 @@ public:
|
||||
bool isLeaf() const;
|
||||
|
||||
void depthFirst(const std::function<void(const ChunkNode&)>& f) const;
|
||||
void breadthFirst(const std::function<void(const ChunkNode&)>& f) const;
|
||||
void reverseBreadthFirst(const std::function<void(const ChunkNode&)>& f) const;
|
||||
|
||||
const ChunkNode& getChild(Quad quad) const;
|
||||
const Chunk& getChunk() const;
|
||||
|
||||
void renderDepthFirst(const RenderData& data);
|
||||
void renderReversedBreadthFirst(const RenderData& data);
|
||||
void renderThisChunk(const RenderData& data);
|
||||
bool updateChunkTree(const RenderData& data);
|
||||
|
||||
static int chunkNodeCount;
|
||||
static int renderedChunks;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -190,7 +190,7 @@ namespace openspace {
|
||||
layeredTexturePreprocessingData.keyValuePairs.push_back(
|
||||
std::pair<std::string, std::string>(
|
||||
"showChunkEdges",
|
||||
std::to_string(chunk.owner()->showChunkEdges)));
|
||||
std::to_string(chunk.owner()->debugOptions.showChunkEdges)));
|
||||
|
||||
|
||||
// Now the shader program can be accessed
|
||||
@@ -303,20 +303,18 @@ namespace openspace {
|
||||
return;
|
||||
}
|
||||
|
||||
auto heightMapProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::HeightMaps);
|
||||
auto colorTextureProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::ColorTextures);
|
||||
auto nightTextureProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::NightTextures);
|
||||
auto overlayProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::Overlays);
|
||||
auto grayScaleOverlayProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::GrayScaleOverlays);
|
||||
auto waterMaskProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::WaterMasks);
|
||||
const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid();
|
||||
|
||||
if ((heightMapProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::HeightMaps]) ||
|
||||
(colorTextureProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::ColorTextures]) ||
|
||||
(nightTextureProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::NightTextures]) ||
|
||||
(overlayProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::Overlays]) ||
|
||||
(grayScaleOverlayProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::GrayScaleOverlays]) ||
|
||||
(waterMaskProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::WaterMasks])) {
|
||||
bool performAnyBlending = false;
|
||||
auto& categoriesBlendingEnabled = chunk.owner()->blendProperties;
|
||||
for (int i = 0; i < categoriesBlendingEnabled.size(); ++i) {
|
||||
LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory)i;
|
||||
if(categoriesBlendingEnabled[category] && _tileProviderManager->getActivatedLayerCategory(category).size() > 0){
|
||||
performAnyBlending = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(performAnyBlending) {
|
||||
float distanceScaleFactor = chunk.owner()->lodScaleFactor * ellipsoid.minimumRadius();
|
||||
programObject->setUniform("cameraPosition", vec3(data.camera.positionVec3()));
|
||||
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
|
||||
@@ -340,7 +338,7 @@ namespace openspace {
|
||||
programObject->setUniform("lonLatScalingFactor", vec2(patchSize.toLonLatVec2()));
|
||||
programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared()));
|
||||
|
||||
if (nightTextureProviders.size() > 0) {
|
||||
if (_tileProviderManager->getActivatedLayerCategory(LayeredTextures::NightTextures).size() > 0) {
|
||||
programObject->setUniform("modelViewTransform", modelViewTransform);
|
||||
}
|
||||
|
||||
@@ -371,21 +369,19 @@ namespace openspace {
|
||||
|
||||
using namespace glm;
|
||||
|
||||
auto heightMapProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::HeightMaps);
|
||||
auto colorTextureProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::ColorTextures);
|
||||
auto nightTextureProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::NightTextures);
|
||||
auto overlayProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::Overlays);
|
||||
auto grayScaleOverlayProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::GrayScaleOverlays);
|
||||
auto waterMaskProviders = _tileProviderManager->getActivatedLayerCategory(LayeredTextures::WaterMasks);
|
||||
const Ellipsoid& ellipsoid = chunk.owner()->ellipsoid();
|
||||
|
||||
// This information is only needed when doing blending
|
||||
if ((heightMapProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::HeightMaps]) ||
|
||||
(colorTextureProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::ColorTextures]) ||
|
||||
(nightTextureProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::NightTextures]) ||
|
||||
(overlayProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::Overlays]) ||
|
||||
(grayScaleOverlayProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::GrayScaleOverlays]) ||
|
||||
(waterMaskProviders.size() > 0 && chunk.owner()->blendProperties[LayeredTextures::WaterMasks])) {
|
||||
|
||||
bool performAnyBlending = false;
|
||||
auto& categoriesBlendingEnabled = chunk.owner()->blendProperties;
|
||||
for (int i = 0; i < categoriesBlendingEnabled.size(); ++i) {
|
||||
LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory)i;
|
||||
if (categoriesBlendingEnabled[category] && _tileProviderManager->getActivatedLayerCategory(category).size() > 0) {
|
||||
performAnyBlending = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (performAnyBlending) {
|
||||
float distanceScaleFactor = chunk.owner()->lodScaleFactor * chunk.owner()->ellipsoid().minimumRadius();
|
||||
programObject->setUniform("distanceScaleFactor", distanceScaleFactor);
|
||||
programObject->setUniform("chunkLevel", chunk.index().level);
|
||||
@@ -398,32 +394,20 @@ namespace openspace {
|
||||
dmat4 viewTransform = data.camera.combinedViewMatrix();
|
||||
dmat4 modelViewTransform = viewTransform * modelTransform;
|
||||
|
||||
Geodetic2 sw = chunk.surfacePatch().getCorner(Quad::SOUTH_WEST);
|
||||
Geodetic2 se = chunk.surfacePatch().getCorner(Quad::SOUTH_EAST);
|
||||
Geodetic2 nw = chunk.surfacePatch().getCorner(Quad::NORTH_WEST);
|
||||
Geodetic2 ne = chunk.surfacePatch().getCorner(Quad::NORTH_EAST);
|
||||
|
||||
// Get model space positions of the four control points
|
||||
Vec3 patchSwModelSpace = ellipsoid.cartesianSurfacePosition(sw);
|
||||
Vec3 patchSeModelSpace = ellipsoid.cartesianSurfacePosition(se);
|
||||
Vec3 patchNwModelSpace = ellipsoid.cartesianSurfacePosition(nw);
|
||||
Vec3 patchNeModelSpace = ellipsoid.cartesianSurfacePosition(ne);
|
||||
|
||||
// Transform all control points to camera space
|
||||
Vec3 patchSwCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchSwModelSpace, 1));
|
||||
Vec3 patchSeCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchSeModelSpace, 1));
|
||||
Vec3 patchNwCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchNwModelSpace, 1));
|
||||
Vec3 patchNeCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchNeModelSpace, 1));
|
||||
|
||||
// Send control points to shader
|
||||
programObject->setUniform("p00", vec3(patchSwCameraSpace));
|
||||
programObject->setUniform("p10", vec3(patchSeCameraSpace));
|
||||
programObject->setUniform("p01", vec3(patchNwCameraSpace));
|
||||
programObject->setUniform("p11", vec3(patchNeCameraSpace));
|
||||
std::vector<std::string> cornerNames = { "p01", "p11", "p00", "p10" };
|
||||
std::vector<Vec3> cornersCameraSpace(4);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
Quad q = (Quad)i;
|
||||
Geodetic2 corner = chunk.surfacePatch().getCorner(q);
|
||||
Vec3 cornerModelSpace = ellipsoid.cartesianSurfacePosition(corner);
|
||||
Vec3 cornerCameraSpace = Vec3(dmat4(modelViewTransform) * glm::dvec4(cornerModelSpace, 1));
|
||||
cornersCameraSpace[i] = cornerCameraSpace;
|
||||
programObject->setUniform(cornerNames[i], vec3(cornerCameraSpace));
|
||||
}
|
||||
|
||||
vec3 patchNormalCameraSpace = normalize(
|
||||
cross(patchSeCameraSpace - patchSwCameraSpace,
|
||||
patchNwCameraSpace - patchSwCameraSpace));
|
||||
cross(cornersCameraSpace[Quad::SOUTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST],
|
||||
cornersCameraSpace[Quad::NORTH_EAST] - cornersCameraSpace[Quad::SOUTH_WEST]));
|
||||
|
||||
programObject->setUniform("patchNormalCameraSpace", patchNormalCameraSpace);
|
||||
programObject->setUniform("projectionTransform", data.camera.projectionMatrix());
|
||||
|
||||
@@ -57,68 +57,13 @@ namespace openspace {
|
||||
|
||||
RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
|
||||
: _saveOrThrowCamera(properties::BoolProperty("saveOrThrowCamera", "saveOrThrowCamera"))
|
||||
, doFrustumCulling(properties::BoolProperty("doFrustumCulling", "doFrustumCulling"))
|
||||
, doHorizonCulling(properties::BoolProperty("doHorizonCulling", "doHorizonCulling"))
|
||||
, mergeInvisible(properties::BoolProperty("mergeInvisible", "mergeInvisible", true))
|
||||
, lodScaleFactor(properties::FloatProperty("lodScaleFactor", "lodScaleFactor", 5.0f, 1.0f, 50.0f))
|
||||
, initChunkVisible(properties::BoolProperty("initChunkVisible", "initChunkVisible", true))
|
||||
, renderSmallChunksFirst(properties::BoolProperty("renderSmallChunksFirst", "renderSmallChunksFirst", true))
|
||||
, chunkHeight(properties::FloatProperty("chunkHeight", "chunkHeight", 8700.0f, 0.0f, 8700.0f))
|
||||
|
||||
, _baseLayersSelection(properties::SelectionProperty("Base Layers", "Base Layers"))
|
||||
, _nightLayersSelection(properties::SelectionProperty("Night Textures", "Night Textures"))
|
||||
, _heightMapsSelection(properties::SelectionProperty("Height Maps", "Height Maps"))
|
||||
, _waterMasksSelection(properties::SelectionProperty("Water Masks", "Water Masks"))
|
||||
, _overlaysSelection(properties::SelectionProperty("Overlays", "Overlays"))
|
||||
, _grayScaleOverlaysSelection(properties::SelectionProperty("GrayScaleOverlays", "GrayScaleOverlays"))
|
||||
|
||||
, blendHeightMap(properties::BoolProperty("blendHeightMap", "blendHeightMap", true))
|
||||
, blendColorMap(properties::BoolProperty("blendColorMap", "blendColorMap", true))
|
||||
, blendNightTexture(properties::BoolProperty("blendNightTexture", "blendNightTexture", true))
|
||||
, blendOverlay(properties::BoolProperty("blendOverlay", "blendOverlay", true))
|
||||
, blendWaterMask(properties::BoolProperty("blendWaterMask", "blendWaterMask", true))
|
||||
, blendGrayScaleOverlay(properties::BoolProperty("blendGrayScaleOverlay", "blendGrayScaleOverlay", true))
|
||||
, atmosphereEnabled(properties::BoolProperty("atmosphereEnabled", "atmosphereEnabled", false))
|
||||
|
||||
, showChunkEdges(properties::BoolProperty("showChunkEdges", "showChunkEdges", false))
|
||||
, showChunkBounds(properties::BoolProperty("showChunkBounds", "showChunkBounds", false))
|
||||
, levelByProjArea(properties::BoolProperty("levelByProjArea", "levelByProjArea", true))
|
||||
, limitLevelByAvailableHeightData(properties::BoolProperty("limitLevelByAvailableHeightData", "limitLevelByAvailableHeightData", true))
|
||||
, debugSelection(ReferencedBoolSelection("Debug", "Debug"))
|
||||
, atmosphereEnabled(properties::BoolProperty(" Atmosphere", " Atmosphere", false))
|
||||
{
|
||||
setName("RenderableGlobe");
|
||||
|
||||
addProperty(_saveOrThrowCamera);
|
||||
addProperty(doFrustumCulling);
|
||||
addProperty(doHorizonCulling);
|
||||
addProperty(mergeInvisible);
|
||||
addProperty(lodScaleFactor);
|
||||
addProperty(initChunkVisible);
|
||||
addProperty(renderSmallChunksFirst);
|
||||
addProperty(chunkHeight);
|
||||
|
||||
addProperty(_baseLayersSelection);
|
||||
addProperty(_nightLayersSelection);
|
||||
addProperty(_heightMapsSelection);
|
||||
addProperty(_waterMasksSelection);
|
||||
addProperty(_overlaysSelection);
|
||||
addProperty(_grayScaleOverlaysSelection);
|
||||
|
||||
addProperty(blendHeightMap);
|
||||
addProperty(blendColorMap);
|
||||
addProperty(blendNightTexture);
|
||||
addProperty(blendOverlay);
|
||||
addProperty(blendWaterMask);
|
||||
addProperty(blendGrayScaleOverlay);
|
||||
addProperty(atmosphereEnabled);
|
||||
|
||||
addProperty(showChunkEdges);
|
||||
addProperty(showChunkBounds);
|
||||
addProperty(levelByProjArea);
|
||||
addProperty(limitLevelByAvailableHeightData);
|
||||
|
||||
doFrustumCulling.setValue(true);
|
||||
doHorizonCulling.setValue(true);
|
||||
renderSmallChunksFirst.setValue(true);
|
||||
|
||||
|
||||
dictionary.getValue(keyFrame, _frame);
|
||||
|
||||
@@ -138,65 +83,57 @@ namespace openspace {
|
||||
ghoul::Dictionary texturesDictionary;
|
||||
dictionary.getValue(keyTextureInitData, textureInitDataDictionary);
|
||||
dictionary.getValue(keyTextures, texturesDictionary);
|
||||
_tileProviderManager = std::shared_ptr<TileProviderManager>(
|
||||
new TileProviderManager(texturesDictionary, textureInitDataDictionary));
|
||||
|
||||
addToggleLayerProperties(LayeredTextures::ColorTextures, _baseLayersSelection);
|
||||
addToggleLayerProperties(LayeredTextures::NightTextures, _nightLayersSelection);
|
||||
addToggleLayerProperties(LayeredTextures::HeightMaps, _heightMapsSelection);
|
||||
addToggleLayerProperties(LayeredTextures::WaterMasks, _waterMasksSelection);
|
||||
addToggleLayerProperties(LayeredTextures::Overlays, _overlaysSelection);
|
||||
addToggleLayerProperties(LayeredTextures::GrayScaleOverlays, _grayScaleOverlaysSelection);
|
||||
|
||||
_baseLayersSelection.onChange(std::bind(&RenderableGlobe::baseLayerSelectionChanged, this));
|
||||
_nightLayersSelection.onChange(std::bind(&RenderableGlobe::nightLayersSelectionChanged, this));
|
||||
_heightMapsSelection.onChange(std::bind(&RenderableGlobe::heightMapsSelectionChanged, this));
|
||||
_waterMasksSelection.onChange(std::bind(&RenderableGlobe::waterMasksSelectionChanged, this));
|
||||
_overlaysSelection.onChange(std::bind(&RenderableGlobe::overlaysSelectionChanged, this));
|
||||
_grayScaleOverlaysSelection.onChange(std::bind(&RenderableGlobe::grayScaleOverlaysSelectionChanged, this));
|
||||
|
||||
_chunkedLodGlobe = std::shared_ptr<ChunkedLodGlobe>(
|
||||
new ChunkedLodGlobe(_ellipsoid, patchSegments, _tileProviderManager));
|
||||
_tileProviderManager = std::make_shared<TileProviderManager>(
|
||||
texturesDictionary, textureInitDataDictionary);
|
||||
|
||||
_chunkedLodGlobe = std::make_shared<ChunkedLodGlobe>(
|
||||
_ellipsoid, patchSegments, _tileProviderManager);
|
||||
_distanceSwitch.addSwitchValue(_chunkedLodGlobe, 1e12);
|
||||
|
||||
// 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("Culling: Frustum", &_chunkedLodGlobe->debugOptions.doFrustumCulling);
|
||||
debugSelection.addOption("Culling: Horizon", &_chunkedLodGlobe->debugOptions.doHorizonCulling);
|
||||
|
||||
debugSelection.addOption("Level by proj area (else distance)", &_chunkedLodGlobe->debugOptions.levelByProjAreaElseDistance);
|
||||
debugSelection.addOption("Level limited by available data", &_chunkedLodGlobe->debugOptions.limitLevelByAvailableHeightData);
|
||||
|
||||
// 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 = std::to_string(i+1) + ". " + LayeredTextures::TEXTURE_CATEGORY_NAMES[i];
|
||||
auto selection = std::make_unique<ReferencedBoolSelection>(categoryName, categoryName);
|
||||
|
||||
auto& categoryProviders = _tileProviderManager->getLayerCategory(category);
|
||||
for (auto& provider : categoryProviders) {
|
||||
selection->addOption(provider.name, &provider.isActive);
|
||||
}
|
||||
selection->addOption(" - Blend tile levels - ", &_chunkedLodGlobe->blendProperties[category]);
|
||||
|
||||
addProperty(selection.get());
|
||||
_categorySelections.push_back(std::move(selection));
|
||||
}
|
||||
|
||||
addProperty(atmosphereEnabled);
|
||||
addProperty(_saveOrThrowCamera);
|
||||
addProperty(lodScaleFactor);
|
||||
}
|
||||
|
||||
RenderableGlobe::~RenderableGlobe() {
|
||||
|
||||
}
|
||||
|
||||
void RenderableGlobe::addToggleLayerProperties(
|
||||
LayeredTextures::TextureCategory category,
|
||||
properties::SelectionProperty& dest)
|
||||
{
|
||||
auto& categoryProviders = _tileProviderManager->getLayerCategory(category);
|
||||
for (size_t i = 0; i < categoryProviders.size(); i++) {
|
||||
std::string name = categoryProviders[i].name;
|
||||
dest.addOption( { static_cast<int>(i), name });
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::initializeToggleLayerProperties(
|
||||
LayeredTextures::TextureCategory category,
|
||||
properties::SelectionProperty& selectionProperty)
|
||||
{
|
||||
std::vector<int> enabledIndices;
|
||||
auto& categoryProviders = _tileProviderManager->getLayerCategory(category);
|
||||
for (size_t i = 0; i < categoryProviders.size(); i++) {
|
||||
if (categoryProviders[i].isActive)
|
||||
enabledIndices.push_back(i);
|
||||
}
|
||||
selectionProperty.setValue(enabledIndices);
|
||||
}
|
||||
|
||||
|
||||
bool RenderableGlobe::initialize() {
|
||||
initializeToggleLayerProperties(LayeredTextures::ColorTextures, _baseLayersSelection);
|
||||
initializeToggleLayerProperties(LayeredTextures::NightTextures, _nightLayersSelection);
|
||||
initializeToggleLayerProperties(LayeredTextures::HeightMaps, _heightMapsSelection);
|
||||
initializeToggleLayerProperties(LayeredTextures::WaterMasks, _waterMasksSelection);
|
||||
initializeToggleLayerProperties(LayeredTextures::Overlays, _overlaysSelection);
|
||||
initializeToggleLayerProperties(LayeredTextures::GrayScaleOverlays, _grayScaleOverlaysSelection);
|
||||
for (auto& selection : _categorySelections) {
|
||||
selection->initialize();
|
||||
}
|
||||
debugSelection.initialize();
|
||||
|
||||
return _distanceSwitch.initialize();
|
||||
}
|
||||
@@ -215,7 +152,7 @@ namespace openspace {
|
||||
|
||||
if (_chunkedLodGlobe->getSavedCamera() == nullptr) { // save camera
|
||||
LDEBUG("Saving snapshot of camera!");
|
||||
_chunkedLodGlobe->setSaveCamera(new Camera(data.camera));
|
||||
_chunkedLodGlobe->setSaveCamera(std::make_shared<Camera>(data.camera));
|
||||
}
|
||||
else { // throw camera
|
||||
LDEBUG("Throwing away saved camera!");
|
||||
@@ -237,27 +174,9 @@ namespace openspace {
|
||||
_time = data.time;
|
||||
_distanceSwitch.update(data);
|
||||
|
||||
_chunkedLodGlobe->doFrustumCulling = doFrustumCulling.value();
|
||||
_chunkedLodGlobe->doHorizonCulling = doHorizonCulling.value();
|
||||
_chunkedLodGlobe->mergeInvisible = mergeInvisible.value();
|
||||
_chunkedLodGlobe->lodScaleFactor = lodScaleFactor.value();
|
||||
_chunkedLodGlobe->initChunkVisible = initChunkVisible.value();
|
||||
_chunkedLodGlobe->chunkHeight = chunkHeight.value();
|
||||
|
||||
_chunkedLodGlobe->blendProperties[LayeredTextures::HeightMaps] = blendHeightMap.value();
|
||||
_chunkedLodGlobe->blendProperties[LayeredTextures::ColorTextures] = blendColorMap.value();
|
||||
_chunkedLodGlobe->blendProperties[LayeredTextures::NightTextures] = blendNightTexture.value();
|
||||
_chunkedLodGlobe->blendProperties[LayeredTextures::Overlays] = blendOverlay.value();
|
||||
_chunkedLodGlobe->blendProperties[LayeredTextures::WaterMasks] = blendWaterMask.value();
|
||||
_chunkedLodGlobe->blendProperties[LayeredTextures::GrayScaleOverlays] = blendGrayScaleOverlay.value();
|
||||
_chunkedLodGlobe->atmosphereEnabled = atmosphereEnabled.value();
|
||||
|
||||
_chunkedLodGlobe->showChunkEdges = showChunkEdges.value();
|
||||
_chunkedLodGlobe->showChunkBounds = showChunkBounds.value();
|
||||
_chunkedLodGlobe->levelByProjArea = levelByProjArea.value();
|
||||
_chunkedLodGlobe->limitLevelByAvailableHeightData = limitLevelByAvailableHeightData.value();
|
||||
|
||||
// Update this after active layers have been updated
|
||||
_tileProviderManager->prerender();
|
||||
}
|
||||
|
||||
@@ -317,50 +236,5 @@ namespace openspace {
|
||||
return _chunkedLodGlobe;
|
||||
}
|
||||
|
||||
void RenderableGlobe::selectionChanged(
|
||||
properties::SelectionProperty selectionProperty,
|
||||
LayeredTextures::TextureCategory textureCategory)
|
||||
{
|
||||
const std::vector<int>& selectedIndices = selectionProperty;
|
||||
auto& category = _tileProviderManager->getLayerCategory(textureCategory);
|
||||
// First inactivate all of them
|
||||
for (size_t i = 0; i < category.size(); i++) {
|
||||
category[i].isActive = false;
|
||||
}
|
||||
// Activate the selected ones
|
||||
for (size_t i = 0; i < selectedIndices.size(); i++){
|
||||
category[selectedIndices[i]].isActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableGlobe::baseLayerSelectionChanged()
|
||||
{
|
||||
selectionChanged(_baseLayersSelection, LayeredTextures::ColorTextures);
|
||||
}
|
||||
|
||||
void RenderableGlobe::nightLayersSelectionChanged()
|
||||
{
|
||||
selectionChanged(_nightLayersSelection, LayeredTextures::NightTextures);
|
||||
}
|
||||
|
||||
void RenderableGlobe::heightMapsSelectionChanged()
|
||||
{
|
||||
selectionChanged(_heightMapsSelection, LayeredTextures::HeightMaps);
|
||||
}
|
||||
|
||||
void RenderableGlobe::waterMasksSelectionChanged()
|
||||
{
|
||||
selectionChanged(_waterMasksSelection, LayeredTextures::WaterMasks);
|
||||
}
|
||||
|
||||
void RenderableGlobe::overlaysSelectionChanged()
|
||||
{
|
||||
selectionChanged(_overlaysSelection, LayeredTextures::Overlays);
|
||||
}
|
||||
|
||||
void RenderableGlobe::grayScaleOverlaysSelectionChanged()
|
||||
{
|
||||
selectionChanged(_grayScaleOverlaysSelection, LayeredTextures::GrayScaleOverlays);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
|
||||
@@ -56,6 +56,48 @@ namespace opengl {
|
||||
|
||||
namespace openspace {
|
||||
|
||||
struct ReferencedBoolSelection : public properties::SelectionProperty {
|
||||
ReferencedBoolSelection::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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class RenderableGlobe : public Renderable {
|
||||
public:
|
||||
RenderableGlobe(const ghoul::Dictionary& dictionary);
|
||||
@@ -73,76 +115,31 @@ public:
|
||||
double getHeight(glm::dvec3 position);
|
||||
std::shared_ptr<ChunkedLodGlobe> chunkedLodGlobe();
|
||||
|
||||
properties::BoolProperty doFrustumCulling;
|
||||
properties::BoolProperty doHorizonCulling;
|
||||
properties::BoolProperty mergeInvisible;
|
||||
|
||||
// Properties
|
||||
properties::FloatProperty lodScaleFactor;
|
||||
properties::BoolProperty initChunkVisible;
|
||||
properties::BoolProperty renderSmallChunksFirst;
|
||||
properties::FloatProperty chunkHeight;
|
||||
|
||||
// Layered rendering
|
||||
properties::SelectionProperty _baseLayersSelection;
|
||||
properties::SelectionProperty _nightLayersSelection;
|
||||
properties::SelectionProperty _heightMapsSelection;
|
||||
properties::SelectionProperty _waterMasksSelection;
|
||||
properties::SelectionProperty _overlaysSelection;
|
||||
properties::SelectionProperty _grayScaleOverlaysSelection;
|
||||
std::vector<std::unique_ptr<ReferencedBoolSelection>> _categorySelections;
|
||||
|
||||
properties::BoolProperty blendHeightMap;
|
||||
properties::BoolProperty blendColorMap;
|
||||
properties::BoolProperty blendNightTexture;
|
||||
properties::BoolProperty blendOverlay;
|
||||
properties::BoolProperty blendWaterMask;
|
||||
properties::BoolProperty blendGrayScaleOverlay;
|
||||
properties::BoolProperty atmosphereEnabled;
|
||||
|
||||
properties::BoolProperty showChunkEdges;
|
||||
properties::BoolProperty showChunkBounds;
|
||||
properties::BoolProperty levelByProjArea;
|
||||
properties::BoolProperty limitLevelByAvailableHeightData;
|
||||
ReferencedBoolSelection debugSelection;
|
||||
|
||||
properties::BoolProperty _saveOrThrowCamera;
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::string _frame;
|
||||
|
||||
void addToggleLayerProperties(
|
||||
LayeredTextures::TextureCategory category,
|
||||
properties::SelectionProperty& dest
|
||||
);
|
||||
|
||||
void initializeToggleLayerProperties(
|
||||
LayeredTextures::TextureCategory category,
|
||||
properties::SelectionProperty& dest
|
||||
);
|
||||
|
||||
double _time;
|
||||
|
||||
Ellipsoid _ellipsoid;
|
||||
|
||||
//std::vector<std::string> _heightMapKeys;
|
||||
//std::vector<std::string> _colorTextureKeys;
|
||||
|
||||
std::shared_ptr<TileProviderManager> _tileProviderManager;
|
||||
std::shared_ptr<ChunkedLodGlobe> _chunkedLodGlobe;
|
||||
|
||||
properties::BoolProperty _saveOrThrowCamera;
|
||||
|
||||
std::vector<properties::BoolProperty> _activeColorLayers;
|
||||
std::vector<properties::BoolProperty> _activeNightLayers;
|
||||
std::vector<properties::BoolProperty> _activeOverlays;
|
||||
std::vector<properties::BoolProperty> _activeHeightMapLayers;
|
||||
std::vector<properties::BoolProperty> _activeWaterMaskLayers;
|
||||
|
||||
void selectionChanged(
|
||||
properties::SelectionProperty selectionProperty,
|
||||
LayeredTextures::TextureCategory textureCategory);
|
||||
void baseLayerSelectionChanged();
|
||||
void nightLayersSelectionChanged();
|
||||
void heightMapsSelectionChanged();
|
||||
void waterMasksSelectionChanged();
|
||||
void overlaysSelectionChanged();
|
||||
void grayScaleOverlaysSelectionChanged();
|
||||
|
||||
DistanceSwitch _distanceSwitch;
|
||||
};
|
||||
|
||||
@@ -120,24 +120,15 @@ namespace openspace {
|
||||
throw ghoul::RuntimeError("Unable to parse XML:\n" + file);
|
||||
}
|
||||
if (std::string(node->pszValue) == "OpenSpaceTemporalGDALDataset") {
|
||||
tileProvider = std::shared_ptr<TileProvider>(
|
||||
new TemporalTileProvider(file, initData));
|
||||
tileProvider = std::make_shared<TemporalTileProvider>(file, initData);
|
||||
return tileProvider;
|
||||
}
|
||||
|
||||
std::shared_ptr<TileDataset> tileDataset = std::shared_ptr<TileDataset>(
|
||||
new TileDataset(file, initData.minimumPixelSize, initData.preprocessTiles));
|
||||
|
||||
std::shared_ptr<ThreadPool> threadPool = std::shared_ptr<ThreadPool>(
|
||||
new ThreadPool(1));
|
||||
|
||||
std::shared_ptr<AsyncTileDataProvider> tileReader = std::shared_ptr<AsyncTileDataProvider>(
|
||||
new AsyncTileDataProvider(tileDataset, threadPool));
|
||||
|
||||
std::shared_ptr<TileCache> tileCache = std::shared_ptr<TileCache>(new TileCache(initData.cacheSize));
|
||||
|
||||
tileProvider = std::shared_ptr<TileProvider>(
|
||||
new CachingTileProvider(tileReader, tileCache, initData.framesUntilRequestQueueFlush));
|
||||
auto tileDataset = std::make_shared<TileDataset>(file, initData.minimumPixelSize, initData.preprocessTiles);
|
||||
auto threadPool = std::make_shared<ThreadPool>(1);
|
||||
auto tileReader = std::make_shared<AsyncTileDataProvider>(tileDataset, threadPool);
|
||||
auto tileCache = std::make_shared<TileCache>(initData.cacheSize);
|
||||
tileProvider = std::make_shared<CachingTileProvider>(tileReader, tileCache, initData.framesUntilRequestQueueFlush);
|
||||
|
||||
return tileProvider;
|
||||
}
|
||||
|
||||
@@ -183,22 +183,13 @@ namespace openspace {
|
||||
std::shared_ptr<CachingTileProvider> TemporalTileProvider::initTileProvider(TimeKey timekey) {
|
||||
std::string gdalDatasetXml = getGdalDatasetXML(timekey);
|
||||
|
||||
std::shared_ptr<TileDataset> tileDataset = std::shared_ptr<TileDataset>(
|
||||
new TileDataset(gdalDatasetXml,
|
||||
_tileProviderInitData.minimumPixelSize,
|
||||
_tileProviderInitData.preprocessTiles));
|
||||
|
||||
std::shared_ptr<ThreadPool> threadPool = std::shared_ptr<ThreadPool>(
|
||||
new ThreadPool(_tileProviderInitData.threads));
|
||||
|
||||
std::shared_ptr<AsyncTileDataProvider> tileReader = std::shared_ptr<AsyncTileDataProvider>(
|
||||
new AsyncTileDataProvider(tileDataset, threadPool));
|
||||
|
||||
std::shared_ptr<TileCache> tileCache = std::shared_ptr<TileCache>(new TileCache(_tileProviderInitData.cacheSize));
|
||||
|
||||
std::shared_ptr<CachingTileProvider> tileProvider= std::shared_ptr<CachingTileProvider>(
|
||||
new CachingTileProvider(tileReader, tileCache,
|
||||
_tileProviderInitData.framesUntilRequestQueueFlush));
|
||||
auto tileDataset = std::make_shared<TileDataset>(gdalDatasetXml,
|
||||
_tileProviderInitData.minimumPixelSize, _tileProviderInitData.preprocessTiles);
|
||||
auto threadPool = std::make_shared<ThreadPool>(_tileProviderInitData.threads);
|
||||
auto tileReader = std::make_shared<AsyncTileDataProvider>(tileDataset, threadPool);
|
||||
auto tileCache = std::make_shared<TileCache>(_tileProviderInitData.cacheSize);
|
||||
auto tileProvider = std::make_shared<CachingTileProvider>(tileReader, tileCache,
|
||||
_tileProviderInitData.framesUntilRequestQueueFlush);
|
||||
|
||||
return tileProvider;
|
||||
}
|
||||
@@ -240,11 +231,11 @@ namespace openspace {
|
||||
|
||||
bool TimeIdProviderFactory::initialized = false;
|
||||
|
||||
std::unordered_map<std::string, TimeFormat*> TimeIdProviderFactory::_timeIdProviderMap = std::unordered_map<std::string, TimeFormat*>();
|
||||
std::unordered_map<std::string, std::unique_ptr<TimeFormat>> TimeIdProviderFactory::_timeIdProviderMap = std::unordered_map<std::string, std::unique_ptr<TimeFormat>>();
|
||||
|
||||
void TimeIdProviderFactory::init() {
|
||||
_timeIdProviderMap.insert({ "YYYY-MM-DD", new YYYY_MM_DD });
|
||||
_timeIdProviderMap.insert({ "YYYY-MM-DDThh:mm:ssZ", new YYYY_MM_DDThh_mm_ssZ });
|
||||
_timeIdProviderMap.insert({ "YYYY-MM-DD", std::make_unique<YYYY_MM_DD>() });
|
||||
_timeIdProviderMap.insert({ "YYYY-MM-DDThh:mm:ssZ", std::make_unique<YYYY_MM_DDThh_mm_ssZ>() });
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@@ -252,7 +243,9 @@ namespace openspace {
|
||||
if (!initialized) {
|
||||
init();
|
||||
}
|
||||
return _timeIdProviderMap[format];
|
||||
ghoul_assert(_timeIdProviderMap.find(format) != _timeIdProviderMap.end(),
|
||||
"Unsupported Time format: " << format);
|
||||
return _timeIdProviderMap[format].get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace openspace {
|
||||
static TimeFormat* getProvider(const std::string& format);
|
||||
static void init();
|
||||
|
||||
static std::unordered_map<std::string, TimeFormat*> _timeIdProviderMap;
|
||||
static std::unordered_map<std::string, std::unique_ptr<TimeFormat>> _timeIdProviderMap;
|
||||
static bool initialized;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user