Use the minimum radius in the ellipsoid to determine split level in chunknode.

This commit is contained in:
Kalle Bladin
2016-04-27 13:36:38 -04:00
parent 67de7e1bb8
commit 16116acdc2
6 changed files with 37 additions and 11 deletions
@@ -47,7 +47,8 @@ namespace openspace {
Vec3( // _radiiToTheFourth
_radii.x * _radii.x * _radii.x * _radii.x,
_radii.y * _radii.y * _radii.y * _radii.y,
_radii.z * _radii.z * _radii.z * _radii.z),})
_radii.z * _radii.z * _radii.z * _radii.z),
glm::min(_radii.x, glm::min(_radii.y, _radii.z))})
{
}
@@ -113,6 +114,11 @@ namespace openspace {
sin(geodetic2.lat));
}
Scalar Ellipsoid::minimumRadius() const
{
return _cachedValues._minimumRadius;
}
Geodetic2 Ellipsoid::cartesianToGeodetic2(const Vec3& p) const
{
Vec3 normal = geodeticSurfaceNormal(p);
@@ -69,6 +69,7 @@ public:
Vec3 geodeticSurfaceNormal(const Vec3& p) const;
Vec3 geodeticSurfaceNormal(Geodetic2 geodetic2) const;
Scalar minimumRadius() const;
Geodetic2 cartesianToGeodetic2(const Vec3& p) const;
Vec3 geodetic2ToCartesian(const Geodetic2& geodetic2) const;
@@ -79,6 +80,7 @@ public:
const Vec3 _radiiSquared;
const Vec3 _oneOverRadiiSquared;
const Vec3 _radiiToTheFourth;
const Scalar _minimumRadius;
};
const Vec3 _radii;
@@ -138,7 +138,8 @@ namespace openspace {
Scalar GeodeticPatch::minimalBoundingRadius(const Ellipsoid& ellipsoid) const {
// TODO: THIS FUNCTION IS CURRENTLY ERROR PRONE SINCE THE PATCH IS NOW COVERING
// A PART OF AN ELLIPSOID AND NOT A SPHERE!THIS MUST BE FIXED
// 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));
}
+2 -1
View File
@@ -90,7 +90,8 @@ public:
center point represents a sphere in which the patch is completely contained.
TODO : THIS FUNCTION IS CURRENTLY ERROR PRONE SINCE THE PATCH IS NOW COVERING
A PART OF AN ELLIPSOID AND NOT A SPHERE! THIS MUST BE FIXED
A PART OF AN ELLIPSOID AND NOT A SPHERE! MUST CHECK IF THIS FUNCTION IS STILL
VALID.
*/
Scalar minimalBoundingRadius(const Ellipsoid& ellipsoid) const;
+13 -7
View File
@@ -135,9 +135,11 @@ void ChunkNode::internalRender(const RenderData& data, ChunkIndex& traverseData)
}
}
int ChunkNode::calculateDesiredLevel(const RenderData& data, const ChunkIndex& traverseData) {
int ChunkNode::calculateDesiredLevel(
const RenderData& data,
const ChunkIndex& traverseData) {
/*
Vec3 globePosition = data.position.dvec3();
//Vec3 patchNormal = _patch.center().asUnitCartesian();
Vec3 patchPosition =
@@ -163,7 +165,13 @@ int ChunkNode::calculateDesiredLevel(const RenderData& data, const ChunkIndex& t
//LDEBUG(cosPatchNormalCameraDirection);
double cosAngleToHorizon = _owner.globeRadius / glm::length(globeToCamera);
// Get the minimum radius from the ellipsoid. 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.
Scalar minimumGlobeRadius = _owner.ellipsoid().minimumRadius();
double cosAngleToHorizon = minimumGlobeRadius / glm::length(globeToCamera);
if (cosPatchNormalNormalizedGlobeToCamera < cosAngleToHorizon) {
return traverseData.level - 1;
@@ -173,7 +181,7 @@ int ChunkNode::calculateDesiredLevel(const RenderData& data, const ChunkIndex& t
// Do frustrum culling
FrustrumCuller& culler = _owner.getFrustrumCuller();
if (!culler.isVisible(data, _patch, _owner.globeRadius)) {
if (!culler.isVisible(data, _patch, _owner.ellipsoid())) {
return traverseData.level - 1;
}
@@ -181,12 +189,10 @@ int ChunkNode::calculateDesiredLevel(const RenderData& data, const ChunkIndex& t
Scalar distance = glm::length(cameraToChunk);
_owner.minDistToCamera = fmin(_owner.minDistToCamera, distance);
Scalar scaleFactor = 100 * _owner.globeRadius;
Scalar scaleFactor = 100 * minimumGlobeRadius;
Scalar projectedScaleFactor = scaleFactor / distance;
int desiredLevel = floor( log2(projectedScaleFactor) );
return desiredLevel;
*/
return _owner.minSplitDepth;
}
+11 -1
View File
@@ -91,7 +91,17 @@ private:
void internalRender(const RenderData& data, ChunkIndex&);
bool internalUpdateChunkTree(const RenderData& data, ChunkIndex&);
int calculateDesiredLevel(const RenderData& data, const ChunkIndex&);
/**
Uses horizon culling, frustum culling and distance to camera to determine a
desired level.
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.
*/
int calculateDesiredLevel(const RenderData& data, const ChunkIndex& traverseData);
ChunkNode* _parent;