mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-26 23:08:55 -06:00
FrustumCuller and HorizonCullers implements virtual ChunkCuller and managed by ChunkedLodGlobe
This commit is contained in:
@@ -77,36 +77,14 @@ namespace openspace {
|
||||
const Camera& camRef = savedCamera != nullptr ? *savedCamera : data.camera;
|
||||
RenderData myRenderData = { camRef, data.position, data.doPerformanceMeasurement };
|
||||
|
||||
//In the current implementation of the horizon culling and the distance to the
|
||||
//camera, the closer the ellipsoid is to a
|
||||
//sphere, the better this will make the splitting. Using the minimum radius to
|
||||
//be safe. This means that if the ellipsoid has high difference between radii,
|
||||
//splitting might accur even though it is not needed.
|
||||
|
||||
|
||||
|
||||
_isVisible = true;
|
||||
|
||||
const Ellipsoid& ellipsoid = _owner->ellipsoid();
|
||||
|
||||
|
||||
|
||||
const int maxHeight = _owner->chunkHeight; // should be read from gdal dataset or mod file
|
||||
|
||||
|
||||
if (_owner->doFrustumCulling) {
|
||||
_isVisible &= FrustumCuller::isVisible(myRenderData, _surfacePatch, ellipsoid, maxHeight);
|
||||
}
|
||||
|
||||
if (_owner->doHorizonCulling) {
|
||||
_isVisible &= HorizonCuller::isVisible(myRenderData, _surfacePatch, ellipsoid, maxHeight);
|
||||
}
|
||||
|
||||
if (!_isVisible && owner()->mergeInvisible) {
|
||||
if (_owner->testIfCullable(*this, myRenderData)) {
|
||||
_isVisible = false;
|
||||
return Status::WANT_MERGE;
|
||||
}
|
||||
|
||||
|
||||
const Ellipsoid& ellipsoid = _owner->ellipsoid();
|
||||
Vec3 cameraPosition = myRenderData.camera.positionVec3();
|
||||
Geodetic2 pointOnPatch = _surfacePatch.closestPoint(
|
||||
ellipsoid.cartesianToGeodetic2(cameraPosition));
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
|
||||
#include <modules/globebrowsing/meshes/skirtedgrid.h>
|
||||
#include <modules/globebrowsing/rendering/culling.h>
|
||||
|
||||
// open space includes
|
||||
#include <openspace/engine/openspaceengine.h>
|
||||
@@ -70,6 +71,9 @@ namespace openspace {
|
||||
TriangleSoup::TextureCoordinates::Yes,
|
||||
TriangleSoup::Normals::No));
|
||||
|
||||
_chunkCullers.push_back(new FrustumCuller(AABB3(vec3(-1, -1, 0), vec3(1, 1, 1e35))));
|
||||
_chunkCullers.push_back(new HorizonCuller());
|
||||
|
||||
_patchRenderer.reset(new ChunkRenderer(geometry, tileProviderManager));
|
||||
}
|
||||
|
||||
@@ -94,6 +98,17 @@ namespace openspace {
|
||||
return *_patchRenderer;
|
||||
}
|
||||
|
||||
bool ChunkedLodGlobe::testIfCullable(const Chunk& chunk, const RenderData& renderData) {
|
||||
if (doFrustumCulling && _chunkCullers[0]->isCullable(chunk, renderData)) {
|
||||
return true;
|
||||
}
|
||||
if (doHorizonCulling && _chunkCullers[1]->isCullable(chunk, renderData)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ChunkedLodGlobe::render(const RenderData& data){
|
||||
minDistToCamera = INFINITY;
|
||||
ChunkNode::renderedChunks = 0;
|
||||
|
||||
@@ -71,6 +71,8 @@ namespace openspace {
|
||||
|
||||
void setStateMatrix(const glm::dmat3& stateMatrix);
|
||||
|
||||
bool testIfCullable(const Chunk& chunk, const RenderData& renderData);
|
||||
|
||||
double minDistToCamera;
|
||||
|
||||
//Scalar globeRadius;
|
||||
@@ -120,6 +122,8 @@ namespace openspace {
|
||||
static const ChunkIndex LEFT_HEMISPHERE_INDEX;
|
||||
static const ChunkIndex RIGHT_HEMISPHERE_INDEX;
|
||||
|
||||
std::vector<ChunkCuller*> _chunkCullers;
|
||||
|
||||
const Ellipsoid& _ellipsoid;
|
||||
glm::dmat3 _stateMatrix;
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
|
||||
#include <modules/globebrowsing/rendering/culling.h>
|
||||
|
||||
#include <modules/globebrowsing/globes/chunkedlodglobe.h>
|
||||
#include <modules/globebrowsing/geodetics/ellipsoid.h>
|
||||
|
||||
#include <modules/globebrowsing/globes/chunk.h>
|
||||
#include <modules/globebrowsing/meshes/trianglesoup.h>
|
||||
|
||||
namespace {
|
||||
@@ -38,7 +38,8 @@ namespace openspace {
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// FRUSTUM CULLER //
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
FrustumCuller::FrustumCuller() {
|
||||
FrustumCuller::FrustumCuller(const AABB3 viewFrustum)
|
||||
: _viewFrustum(viewFrustum){
|
||||
|
||||
}
|
||||
|
||||
@@ -46,9 +47,9 @@ namespace openspace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
const AABB3 FrustumCuller::viewFrustum(vec3(-1, -1, 0), vec3(1, 1, 1e35));
|
||||
|
||||
bool FrustumCuller::isCullable(const Chunk& chunk, const RenderData& renderData) {
|
||||
return !isVisible(renderData, chunk.surfacePatch(), chunk.owner()->ellipsoid(), chunk.owner()->chunkHeight);
|
||||
}
|
||||
|
||||
bool FrustumCuller::isVisible(
|
||||
const RenderData& data,
|
||||
@@ -68,12 +69,6 @@ namespace openspace {
|
||||
bool FrustumCuller::isVisible(const RenderData& data, const GeodeticPatch& patch,
|
||||
const Ellipsoid& ellipsoid)
|
||||
{
|
||||
// An axis aligned bounding box based on the patch's minimum boudning sphere is
|
||||
// used for testnig
|
||||
|
||||
//mat4 viewTransform = glm::lookAt(vec3(6378137.0 + 1000, 0, 0), vec3(0, 5e6, 1e7), vec3(0, 0, 1)); //data.camera.combinedViewMatrix
|
||||
//Vec3 cameraPosition = vec3(inverse(viewTransform) * vec4(0, 0, 0, 1));// data.camera.position().dvec3();
|
||||
|
||||
|
||||
// Calculate the MVP matrix
|
||||
dmat4 modelTransform = translate(dmat4(1), data.position.dvec3());
|
||||
@@ -132,9 +127,7 @@ namespace openspace {
|
||||
bounds.expand(cornerScreenSpace);
|
||||
}
|
||||
|
||||
|
||||
return bounds.intersects(FrustumCuller::viewFrustum);
|
||||
|
||||
return bounds.intersects(_viewFrustum);
|
||||
}
|
||||
|
||||
|
||||
@@ -185,6 +178,10 @@ namespace openspace {
|
||||
|
||||
}
|
||||
|
||||
bool HorizonCuller::isCullable(const Chunk& chunk, const RenderData& renderData) {
|
||||
return !isVisible(renderData, chunk.surfacePatch(), chunk.owner()->ellipsoid(), chunk.owner()->chunkHeight);
|
||||
}
|
||||
|
||||
bool HorizonCuller::isVisible(
|
||||
const Vec3& cameraPosition,
|
||||
const Vec3& globePosition,
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
// open space includes
|
||||
|
||||
#include <openspace/rendering/renderable.h>
|
||||
|
||||
#include <modules/globebrowsing/geodetics/geodetic2.h>
|
||||
#include <modules/globebrowsing/geodetics/ellipsoid.h>
|
||||
#include <modules/globebrowsing/rendering/aabb.h>
|
||||
@@ -43,6 +42,13 @@ namespace openspace {
|
||||
using namespace glm;
|
||||
|
||||
|
||||
class Chunk;
|
||||
|
||||
class ChunkCuller {
|
||||
public:
|
||||
virtual void update() { }
|
||||
virtual bool isCullable(const Chunk& chunk, const RenderData& renderData) = 0;
|
||||
};
|
||||
|
||||
enum PointLocation {
|
||||
AboveLeft = 0, Above, AboveRight, // 0, 1, 2
|
||||
@@ -53,13 +59,13 @@ namespace openspace {
|
||||
|
||||
|
||||
|
||||
class FrustumCuller {
|
||||
class FrustumCuller : public ChunkCuller {
|
||||
public:
|
||||
|
||||
FrustumCuller();
|
||||
FrustumCuller(const AABB3 viewFrustum);
|
||||
~FrustumCuller();
|
||||
|
||||
static const AABB3 viewFrustum;
|
||||
virtual bool isCullable(const Chunk& chunk, const RenderData& renderData);
|
||||
|
||||
/**
|
||||
Returns true if the point is inside the view frustrum defined in RenderData.
|
||||
@@ -67,7 +73,7 @@ namespace openspace {
|
||||
boundaries. E.g. for marginScreenSpace = {0.2, 0.2}, all points with
|
||||
1.2 < x,y < 1.2 would cause isVisible to return true.
|
||||
*/
|
||||
static bool isVisible(
|
||||
bool isVisible(
|
||||
const RenderData& data,
|
||||
const dvec3& point);
|
||||
|
||||
@@ -76,52 +82,64 @@ namespace openspace {
|
||||
Returns false if the patch element is guaranteed to be outside the view
|
||||
frustrum, and true is the patch element MAY be inside the view frustrum.
|
||||
*/
|
||||
static bool isVisible(
|
||||
bool isVisible(
|
||||
const RenderData& data,
|
||||
const GeodeticPatch& patch,
|
||||
const Ellipsoid& ellipsoid);
|
||||
|
||||
|
||||
static bool isVisible(
|
||||
bool isVisible(
|
||||
const RenderData& data,
|
||||
const GeodeticPatch& patch,
|
||||
const Ellipsoid& ellipsoid,
|
||||
const Scalar maxHeight);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
The optional screen space margin vector is used to resize area defining
|
||||
what is considered to be inside the view frustrum.
|
||||
*/
|
||||
static PointLocation testPoint(
|
||||
PointLocation testPoint(
|
||||
const glm::vec2& pointScreenSpace,
|
||||
const glm::vec2& marginScreenSpace = dvec2(0));
|
||||
|
||||
static bool testPoint(
|
||||
bool testPoint(
|
||||
const glm::vec3& pointScreenSpace,
|
||||
const glm::vec3& marginScreenSpace = dvec3(0));
|
||||
|
||||
|
||||
static glm::vec2 transformToScreenSpace(
|
||||
glm::vec2 transformToScreenSpace(
|
||||
const dvec3& point,
|
||||
const dmat4x4& modelViewProjection);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
const AABB3 _viewFrustum;
|
||||
|
||||
};
|
||||
|
||||
class HorizonCuller {
|
||||
|
||||
//In the current implementation of the horizon culling and the distance to the
|
||||
//camera, the closer the ellipsoid is to a
|
||||
//sphere, the better this will make the splitting. Using the minimum radius to
|
||||
//be safe. This means that if the ellipsoid has high difference between radii,
|
||||
//splitting might accur even though it is not needed.
|
||||
class HorizonCuller : public ChunkCuller {
|
||||
public:
|
||||
HorizonCuller();
|
||||
~HorizonCuller();
|
||||
|
||||
static bool isVisible(
|
||||
virtual bool isCullable(const Chunk& chunk, const RenderData& renderData);
|
||||
|
||||
bool isVisible(
|
||||
const Vec3& cameraPosition,
|
||||
const Vec3& globePosition,
|
||||
const Vec3& objectPosition,
|
||||
Scalar objectBoundingSphereRadius,
|
||||
Scalar minimumGlobeRadius);
|
||||
|
||||
static bool isVisible(
|
||||
bool isVisible(
|
||||
const RenderData& data,
|
||||
const GeodeticPatch& patch,
|
||||
const Ellipsoid& ellipsoid,
|
||||
|
||||
Reference in New Issue
Block a user