FrustumCuller and HorizonCullers implements virtual ChunkCuller and managed by ChunkedLodGlobe

This commit is contained in:
Erik Broberg
2016-06-08 19:59:45 -04:00
parent 1f1c02d42a
commit 37b500b001
5 changed files with 66 additions and 54 deletions

View File

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

View File

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

View File

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

View File

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

View File

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