Added AABB class, doing frustum culling based screen space AABB based on chunks 8 extreme points (min/max height per corner)

This commit is contained in:
Erik Broberg
2016-05-13 15:15:08 -04:00
parent 4c3604420e
commit ca968b8589
20 changed files with 376 additions and 72 deletions
+2
View File
@@ -46,6 +46,7 @@ set(HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/patchrenderer.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/culling.h
${CMAKE_CURRENT_SOURCE_DIR}/rendering/aabb.h
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.h
${CMAKE_CURRENT_SOURCE_DIR}/other/texturetileset.h
@@ -81,6 +82,7 @@ set(SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/rendering/patchrenderer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/culling.cpp
${CMAKE_CURRENT_SOURCE_DIR}/rendering/aabb.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/distanceswitch.cpp
${CMAKE_CURRENT_SOURCE_DIR}/other/texturetileset.cpp
@@ -66,13 +66,13 @@ namespace openspace {
Vec3 Ellipsoid::scaleToGeocentricSurface(const Vec3& p) const
Vec3 Ellipsoid::geocentricSurfaceProjection(const Vec3& p) const
{
Scalar beta = 1.0 / sqrt(dot(p * p, _cached._oneOverRadiiSquared));
return beta * p;
}
Vec3 Ellipsoid::scaleToGeodeticSurface(const Vec3& p) const
Vec3 Ellipsoid::geodeticSurfaceProjection(const Vec3& p) const
{
Scalar beta = 1.0 / sqrt(dot(p * p, _cached._oneOverRadiiSquared));
Scalar n = glm::length(beta * p * _cached._oneOverRadiiSquared);
@@ -100,7 +100,7 @@ namespace openspace {
return p / d;
}
Vec3 Ellipsoid::geodeticSurfaceNormal(const Vec3& p) const
Vec3 Ellipsoid::geodeticSurfaceNormalForGeocentricallyProjectedPoint(const Vec3& p) const
{
Vec3 normal = p * _cached._oneOverRadiiSquared;
return glm::normalize(normal);
@@ -143,19 +143,19 @@ namespace openspace {
Geodetic2 Ellipsoid::cartesianToGeodetic2(const Vec3& p) const
{
Vec3 normal = geodeticSurfaceNormal(p);
Vec3 normal = geodeticSurfaceNormalForGeocentricallyProjectedPoint(p);
return Geodetic2(
asin(normal.z / length(normal)), // Latitude
atan2(normal.y, normal.x)); // Longitude
}
Vec3 Ellipsoid::geodetic2ToCartesian(const Geodetic2& geodetic2) const
Vec3 Ellipsoid::cartesianSurfacePosition(const Geodetic2& geodetic2) const
{
// Position on surface : height = 0
return geodetic3ToCartesian(Geodetic3({ geodetic2, 0 }));
return cartesianPosition(Geodetic3({ geodetic2, 0 }));
}
Vec3 Ellipsoid::geodetic3ToCartesian(const Geodetic3& geodetic3) const
Vec3 Ellipsoid::cartesianPosition(const Geodetic3& geodetic3) const
{
Vec3 normal = geodeticSurfaceNormal(geodetic3.geodetic2);
Vec3 k = _cached._radiiSquared * normal;
+5 -5
View File
@@ -62,7 +62,7 @@ public:
\param p is a point in the cartesian coordinate system to be placed on the surface
of the Ellipsoid
*/
Vec3 scaleToGeocentricSurface(const Vec3& p) const;
Vec3 geocentricSurfaceProjection(const Vec3& p) const;
/**
@@ -71,9 +71,9 @@ public:
\param p is a point in the cartesian coordinate system to be placed on the surface
of the Ellipsoid
*/
Vec3 scaleToGeodeticSurface(const Vec3& p) const;
Vec3 geodeticSurfaceProjection(const Vec3& p) const;
Vec3 geodeticSurfaceNormal(const Vec3& p) const;
Vec3 geodeticSurfaceNormalForGeocentricallyProjectedPoint(const Vec3& p) const;
Vec3 geodeticSurfaceNormal(Geodetic2 geodetic2) const;
Vec3 radiiSquared() const;
@@ -84,8 +84,8 @@ public:
Scalar maximumRadius() const;
Geodetic2 cartesianToGeodetic2(const Vec3& p) const;
Vec3 geodetic2ToCartesian(const Geodetic2& geodetic2) const;
Vec3 geodetic3ToCartesian(const Geodetic3& geodetic3) const;
Vec3 cartesianSurfacePosition(const Geodetic2& geodetic2) const;
Vec3 cartesianPosition(const Geodetic3& geodetic3) const;
private:
struct EllipsoidCache {
+10 -1
View File
@@ -139,7 +139,7 @@ namespace openspace {
// A PART OF AN ELLIPSOID AND NOT A SPHERE!MUST CHECK IF THIS FUNCTION IS STILL
// VALID.
const Geodetic2& cornerNearEquator = _center.lat > 0 ? southWestCorner() : northWestCorner();
return glm::length(ellipsoid.geodetic2ToCartesian(_center) - ellipsoid.geodetic2ToCartesian(cornerNearEquator));
return glm::length(ellipsoid.cartesianSurfacePosition(_center) - ellipsoid.cartesianSurfacePosition(cornerNearEquator));
}
/*
Scalar GeodeticPatch::unitArea() const {
@@ -172,6 +172,15 @@ namespace openspace {
return Geodetic2(2 * _halfSize.lat, 2 * _halfSize.lon);
}
Geodetic2 GeodeticPatch::getCorner(Quad q) const {
switch (q) {
case NORTH_WEST: return northWestCorner();
case NORTH_EAST: return northEastCorner();
case SOUTH_WEST: return southWestCorner();
case SOUTH_EAST: return southEastCorner();
}
}
Geodetic2 GeodeticPatch::northWestCorner() const{
return Geodetic2(_center.lat + _halfSize.lat, _center.lon - _halfSize.lon);
}
@@ -125,6 +125,7 @@ public:
*/
// Scalar unitArea() const;
Geodetic2 getCorner(Quad q) const;
Geodetic2 northWestCorner() const;
Geodetic2 northEastCorner() const;
+22 -17
View File
@@ -38,11 +38,11 @@ namespace {
namespace openspace {
Chunk::Chunk(ChunkedLodGlobe* owner, const ChunkIndex& chunkIndex)
Chunk::Chunk(ChunkedLodGlobe* owner, const ChunkIndex& chunkIndex, bool initVisible)
: _owner(owner)
, _surfacePatch(chunkIndex)
, _index(chunkIndex)
, _isVisible(true)
, _isVisible(initVisible)
{
}
@@ -90,33 +90,38 @@ namespace openspace {
const Ellipsoid& ellipsoid = _owner->ellipsoid();
// Do horizon culling
const int maxHeight = 8700; // should be read from gdal dataset or mod file
_isVisible = HorizonCuller::isVisible(myRenderData, _surfacePatch, ellipsoid, maxHeight);
if (!_isVisible) {
return WANT_MERGE;
}
// Do frustum culling
_isVisible = FrustumCuller::isVisible(myRenderData, _surfacePatch, ellipsoid);
if (!_isVisible) {
return WANT_MERGE;
const int maxHeight = 8700; // 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);
}
auto center = _surfacePatch.center();
Vec3 globePosition = myRenderData.position.dvec3();
Vec3 patchPosition = globePosition + ellipsoid.geodetic2ToCartesian(center);
Vec3 patchPosition = globePosition + ellipsoid.cartesianSurfacePosition(center);
Vec3 cameraPosition = myRenderData.camera.position().dvec3();
Vec3 cameraToChunk = patchPosition - cameraPosition;
Scalar minimumGlobeRadius = ellipsoid.minimumRadius();
// Calculate desired level based on distance
Scalar distance = glm::length(cameraToChunk);
_owner->minDistToCamera = fmin(_owner->minDistToCamera, distance);
Scalar scaleFactor = 10 * minimumGlobeRadius;
Scalar scaleFactor = _owner->lodScaleFactor * ellipsoid.minimumRadius();;
Scalar projectedScaleFactor = scaleFactor / distance;
int desiredLevel = floor(log2(projectedScaleFactor));
+1 -1
View File
@@ -50,7 +50,7 @@ namespace openspace {
WANT_SPLIT,
};
Chunk(ChunkedLodGlobe* owner, const ChunkIndex& chunkIndex);
Chunk(ChunkedLodGlobe* owner, const ChunkIndex& chunkIndex, bool initVisible = true);
/// Updates chunk internally and returns a desired level
Status update(const RenderData& data);
@@ -95,7 +95,7 @@ namespace openspace {
void ChunkedLodGlobe::render(const RenderData& data){
minDistToCamera = INFINITY;
ChunkNode::renderedPatches = 0;
ChunkNode::renderedPatches = 0;
_leftRoot->render(data);
_rightRoot->render(data);
@@ -85,6 +85,13 @@ namespace openspace {
}
bool doHorizonCulling = true;
bool doFrustumCulling = true;
int numPosZthres;
float lodScaleFactor;
bool initChunkVisible;
private:
// Covers all negative longitudes
+3 -1
View File
@@ -126,7 +126,8 @@ void ChunkNode::internalRender(const RenderData& 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 chunk(_chunk.owner(), _chunk.index().child((Quad)i), _chunk.owner()->initChunkVisible);
_children[i] = std::unique_ptr<ChunkNode>(new ChunkNode(chunk, this));
}
}
@@ -145,6 +146,7 @@ void ChunkNode::merge() {
}
_children[i] = nullptr;
}
ghoul_assert(isLeaf(), "ChunkNode must be leaf after merge");
}
const ChunkNode& ChunkNode::getChild(Quad quad) const {
@@ -110,7 +110,7 @@ namespace openspace {
{
Scalar minimumRadius = _ellipsoid.minimumRadius();
Vec3 cameraPosition = data.camera.position().dvec3();
Vec3 cameraPositionOnSurface = _ellipsoid.scaleToGeodeticSurface(cameraPosition);
Vec3 cameraPositionOnSurface = _ellipsoid.geodeticSurfaceProjection(cameraPosition);
Scalar h = glm::length(cameraPosition - cameraPositionOnSurface);
Scalar cosAngleToHorizon = minimumRadius / (minimumRadius + h);
Scalar angleToHorizon = glm::acos(cosAngleToHorizon);
@@ -46,19 +46,33 @@ namespace {
const std::string keyHeightMaps = "HeightMaps";
}
namespace openspace {
RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
: _tileProviderManager(std::shared_ptr<TileProviderManager>(new TileProviderManager))
, _saveOrThrowCamera(properties::BoolProperty("saveOrThrowCamera", "saveOrThrowCamera"))
, doFrustumCulling(properties::BoolProperty("doFrustumCulling", "doFrustumCulling"))
, doHorizonCulling(properties::BoolProperty("doHorizonCulling", "doHorizonCulling"))
, numPosZthres(properties::IntProperty("numPosZthres", "numPosZthres", 0, 0, 9))
, lodScaleFactor(properties::FloatProperty("lodScaleFactor", "lodScaleFactor", 10.0f, 0.0f, 100.0f))
, initChunkVisible(properties::BoolProperty("initChunkVisible", "initChunkVisible", true))
{
setName("RenderableGlobe");
addProperty(_saveOrThrowCamera);
addProperty(_saveOrThrowCamera);
addProperty(doFrustumCulling);
addProperty(doHorizonCulling);
addProperty(numPosZthres);
addProperty(lodScaleFactor);
addProperty(initChunkVisible);
doFrustumCulling.setValue(true);
doHorizonCulling.setValue(true);
// Read the radii in to its own dictionary
Vec3 radii;
@@ -142,6 +156,11 @@ namespace openspace {
_chunkedLodGlobe->setSaveCamera(nullptr);
}
}
_chunkedLodGlobe->doFrustumCulling = doFrustumCulling.value();
_chunkedLodGlobe->doHorizonCulling = doHorizonCulling.value();
_chunkedLodGlobe->numPosZthres = numPosZthres.value();
_chunkedLodGlobe->lodScaleFactor= lodScaleFactor.value();
_chunkedLodGlobe->initChunkVisible = initChunkVisible.value();
_distanceSwitch.render(data);
}
@@ -31,6 +31,7 @@
#include <openspace/rendering/renderable.h>
#include <openspace/properties/stringproperty.h>
#include <openspace/properties/optionproperty.h>
#include <openspace/util/updatestructures.h>
#include <modules/globebrowsing/meshes/trianglesoup.h>
@@ -62,7 +63,11 @@ public:
void render(const RenderData& data) override;
void update(const UpdateData& data) override;
properties::BoolProperty doFrustumCulling;
properties::BoolProperty doHorizonCulling;
properties::IntProperty numPosZthres;
properties::FloatProperty lodScaleFactor;
properties::BoolProperty initChunkVisible;
private:
double _time;
+102
View File
@@ -0,0 +1,102 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <modules/globebrowsing/rendering/aabb.h>
#include <string>
namespace {
const std::string _loggerCat = "AABB";
}
namespace openspace {
AABB2::AABB2() : min(1e35), max(-1e35) { }
AABB2::AABB2(const vec2& min, const vec2& max) : min(min), max(max) { }
void AABB2::expand(const vec2& p) {
min.x = glm::min(min.x, p.x);
min.y = glm::min(min.y, p.y);
max.x = glm::max(max.x, p.x);
max.y = glm::max(max.y, p.y);
}
vec2 AABB2::center() const {
return 0.5f * (min + max);
}
vec2 AABB2::size() const {
return max - min;
}
bool AABB2::intersects(const vec2& p) const {
return (min.x < p.x) && (p.x < max.x)
&& (min.y < p.y) && (p.y < max.y);
}
bool AABB2::intersects(const AABB2& o) const {
return (min.x < o.max.x) && (o.min.x < max.x)
&& (min.y < o.max.y) && (o.min.y < max.y);
}
AABB3::AABB3() : min(1e35), max(-1e35) { }
AABB3::AABB3(const vec3& min, const vec3& max) : min(min), max(max) { }
void AABB3::expand(const vec3 p) {
min.x = glm::min(min.x, p.x);
min.y = glm::min(min.y, p.y);
min.z = glm::min(min.z, p.z);
max.x = glm::max(max.x, p.x);
max.y = glm::max(max.y, p.y);
max.z = glm::max(max.z, p.z);
}
vec3 AABB3::center() const {
return 0.5f * (min + max);
}
vec3 AABB3::size() const {
return max - min;
}
bool AABB3::intersects(const vec3& p) const {
return (min.x < p.x) && (p.x < max.x)
&& (min.y < p.y) && (p.y < max.y)
&& (min.z < p.z) && (p.z < max.z);
}
bool AABB3::intersects(const AABB3& o) const {
return (min.x < o.max.x) && (o.min.x < max.x)
&& (min.y < o.max.y) && (o.min.y < max.y)
&& (min.z < o.max.z) && (o.min.z < max.z);
}
} // namespace openspace
+71
View File
@@ -0,0 +1,71 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2016 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __AABB_H__
#define __AABB_H__
#include <memory>
#include <glm/glm.hpp>
// open space includes
namespace openspace {
using namespace glm;
struct AABB2 {
AABB2();
AABB2(const vec2& min, const vec2& max);
void expand(const vec2& p);
vec2 center() const;
vec2 size() const;
bool intersects(const vec2& p) const;
bool intersects(const AABB2& o) const;
vec2 min;
vec2 max;
};
struct AABB3 {
AABB3();
AABB3(const vec3& min, const vec3& max);
void expand(const vec3 p);
vec3 center() const;
vec3 size() const;
bool intersects(const vec3& p) const;
bool intersects(const AABB3& o) const;
vec3 min;
vec3 max;
};
} // namespace openspace
#endif // __AABB_H__
+84 -10
View File
@@ -24,9 +24,12 @@
#include <modules/globebrowsing/rendering/culling.h>
#include <modules/globebrowsing/rendering/aabb.h>
#include <modules/globebrowsing/geodetics/ellipsoid.h>
#include <modules/globebrowsing/meshes/trianglesoup.h>
namespace {
const std::string _loggerCat = "FrustrumCuller";
}
@@ -59,10 +62,10 @@ namespace openspace {
return testPoint(pointScreenSpace, vec2(0));
}
bool FrustumCuller::isVisible(
const RenderData& data,
const GeodeticPatch& patch,
const Ellipsoid& ellipsoid) {
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
@@ -78,7 +81,7 @@ namespace openspace {
// Calculate the patch's center point in screen space
vec4 patchCenterModelSpace =
vec4(ellipsoid.geodetic2ToCartesian(patch.center()), 1);
vec4(ellipsoid.cartesianSurfacePosition(patch.center()), 1);
vec4 patchCenterClippingSpace =
modelViewProjectionTransform * patchCenterModelSpace;
vec2 pointScreenSpace =
@@ -93,17 +96,88 @@ namespace openspace {
(1.0f / patchCenterClippingSpace.w) * marginClippingSpace.xy();
// Test the bounding box by testing the center point and the corresponding margin
return testPoint(pointScreenSpace, marginScreenSpace);
PointLocation res = testPoint(pointScreenSpace, marginScreenSpace);
return res == PointLocation::Inside;
}
bool FrustumCuller::testPoint(const glm::vec2& pointScreenSpace,
bool FrustumCuller::isVisible(const RenderData& data, const GeodeticPatch& patch,
const Ellipsoid& ellipsoid, const Scalar maxHeight)
{
// Calculate the MVP matrix
mat4 modelTransform = translate(mat4(1), data.position.vec3());
mat4 viewTransform = data.camera.combinedViewMatrix();
mat4 modelViewProjectionTransform = data.camera.projectionMatrix()
* viewTransform * modelTransform;
double centerRadius = ellipsoid.maximumRadius();
//double centerRadius = glm::length(ellipsoid.cartesianSurfacePosition(patch.center()));
double maxCenterRadius = centerRadius + maxHeight;
double maximumPatchSide = max(patch.halfSize().lat, patch.halfSize().lon);
double maxHeightOffset = maxCenterRadius / cos(maximumPatchSide) - centerRadius;
double minHeightOffset = 0; // for now
/*
Geodetic3 centerGeodetic = { patch.center(), 0};
vec4 centerModelSpace = vec4(ellipsoid.cartesianPosition(centerGeodetic), 1);
vec4 centerClippingSpace = modelViewProjectionTransform * centerModelSpace;
vec3 centerScreenSpace = (1.0f / glm::abs(centerClippingSpace.w)) * centerClippingSpace.xyz();
AABB3 viewFrustum(vec3(-1, -1, 0), vec3(1, 1, 1e35));
return viewFrustum.intersects(centerScreenSpace);
*/
// Create a bounding box that fits the patch corners
AABB3 bounds; // in screen space
int numPositiveZ = 0;
for (size_t i = 0; i < 8; i++) {
Quad q = (Quad) (i%4);
double offset = i < 4 ? minHeightOffset : maxHeightOffset;
Geodetic3 cornerGeodetic = { patch.getCorner(q), offset };
vec4 cornerModelSpace = vec4(ellipsoid.cartesianPosition(cornerGeodetic), 1);
vec4 cornerClippingSpace = modelViewProjectionTransform * cornerModelSpace;
vec3 cornerScreenSpace = (1.0f / glm::abs(cornerClippingSpace.w)) * cornerClippingSpace.xyz();
bounds.expand(cornerScreenSpace);
}
AABB3 viewFrustum(vec3(-1, -1, 0), vec3(1, 1, 1e35));
return bounds.intersects(viewFrustum);
/*
vec2 center = bounds.center();
vec2 margin = 0.5f * bounds.size();
return testPoint(center, margin) == PointLocation::Inside;
*/
}
PointLocation FrustumCuller::testPoint(const glm::vec2& pointScreenSpace,
const glm::vec2& marginScreenSpace)
{
const vec2& p = pointScreenSpace;
vec2 cullBounds = vec2(1) + marginScreenSpace;
return ((-cullBounds.x < p.x && p.x < cullBounds.x) &&
(-cullBounds.y < p.y && p.y < cullBounds.y));
int x = p.x <= -cullBounds.x ? 0 : p.x < cullBounds.x ? 1 : 2;
int y = p.y <= -cullBounds.y ? 0 : p.y < cullBounds.y ? 1 : 2;
PointLocation res = (PointLocation) (3 * y + x);
return res;
}
bool FrustumCuller::testPoint(const glm::vec3& pointScreenSpace,
const glm::vec3& marginScreenSpace)
{
const vec3& p = pointScreenSpace;
vec3 cullBounds = vec3(1) + marginScreenSpace;
int x = p.x <= -cullBounds.x ? 0 : p.x < cullBounds.x ? 1 : 2;
int y = p.y <= -cullBounds.y ? 0 : p.y < cullBounds.y ? 1 : 2;
int z = p.z <= -cullBounds.z ? 0 : p.z < cullBounds.z ? 1 : 2;
return x == 1 && y == 1 && z == 1;
}
glm::vec2 FrustumCuller::transformToScreenSpace(const vec3& point,
@@ -167,7 +241,7 @@ namespace openspace {
return HorizonCuller::isVisible(
cameraPosition,
globePosition,
ellipsoid.geodetic2ToCartesian(closestPatchPoint),
ellipsoid.cartesianSurfacePosition(closestPatchPoint),
height,
minimumGlobeRadius);
}
+21 -14
View File
@@ -42,21 +42,17 @@ namespace openspace {
enum PointLocation {
AboveLeft = 0, Above, AboveRight, // 0, 1, 2
Left, Inside, Right, // 3, 4, 5
BelowLeft, Below, BelowRight // 6, 7, 8
};
class FrustumCuller {
public:
enum PointTestResult : int {
Inside = 0,
Above,
AboveRight,
Right,
BelowRight,
Below,
BelowLeft,
Left,
AboveLeft
};
FrustumCuller();
@@ -72,6 +68,7 @@ namespace openspace {
const RenderData& data,
const vec3& point);
/**
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.
@@ -81,16 +78,26 @@ namespace openspace {
const GeodeticPatch& patch,
const Ellipsoid& ellipsoid);
static bool isVisible(
const RenderData& data,
const GeodeticPatch& patch,
const Ellipsoid& ellipsoid,
const Scalar maxHeight);
private:
/**
Returns true if the point in screen space is inside the view frustrum.
The optional screen space margin vector is used to resize area defining
what is considered to be inside the view frustrum.
*/
static bool testPoint(
static PointLocation testPoint(
const glm::vec2& pointScreenSpace,
const glm::vec2& marginScreenSpace);
const glm::vec2& marginScreenSpace = vec2(0));
static bool testPoint(
const glm::vec3& pointScreenSpace,
const glm::vec3& marginScreenSpace = vec3(0));
static glm::vec2 transformToScreenSpace(
@@ -243,10 +243,10 @@ namespace openspace {
Geodetic2 ne = chunk.surfacePatch().northEastCorner();
// Get model space positions of the four control points
Vec3 patchSwModelSpace = ellipsoid.geodetic2ToCartesian(sw);
Vec3 patchSeModelSpace = ellipsoid.geodetic2ToCartesian(se);
Vec3 patchNwModelSpace = ellipsoid.geodetic2ToCartesian(nw);
Vec3 patchNeModelSpace = ellipsoid.geodetic2ToCartesian(ne);
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));
@@ -530,10 +530,10 @@ namespace openspace {
ivec2 contraction = ivec2(intSnapCoord.y % 2, intSnapCoord.x % 2);
// Get global positions of the four control points
Vec3 patchSw = ellipsoid.geodetic2ToCartesian(newPatch.southWestCorner());
Vec3 patchSe = ellipsoid.geodetic2ToCartesian(newPatch.southEastCorner());
Vec3 patchNw = ellipsoid.geodetic2ToCartesian(newPatch.northWestCorner());
Vec3 patchNe = ellipsoid.geodetic2ToCartesian(newPatch.northEastCorner());
Vec3 patchSw = ellipsoid.cartesianSurfacePosition(newPatch.southWestCorner());
Vec3 patchSe = ellipsoid.cartesianSurfacePosition(newPatch.southEastCorner());
Vec3 patchNw = ellipsoid.cartesianSurfacePosition(newPatch.northWestCorner());
Vec3 patchNe = ellipsoid.cartesianSurfacePosition(newPatch.northEastCorner());
// Transform all control points to camera space
patchSw = Vec3(dmat4(modelViewTransform) * glm::dvec4(patchSw, 1));
@@ -55,7 +55,7 @@ Fragment getFragment() {
//frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1);
// Border overlay
//frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.depth = vs_position.w;
@@ -51,7 +51,7 @@ Fragment getFragment() {
//frag.color = frag.color * 0.9 + 0.2*vec4(samplePos, 0, 1);
// Border overlay
//frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.color = frag.color + borderOverlay(fs_uv, vec3(0.5, 0.5, 0.5), 0.02);
frag.depth = fs_position.w;