Hi Robert,With refernce to email "[osg-users] Strategies for reducing visual terrain-tile-popping with osgTerrain" (2012-04-24), I've made a small patch that can alleviate some of the worst "in-your-face" popping by adding CullSettings::setMaxPagedLODLevel(unsigned int). In conjunction with LODScale, this setting can be tuned to minimize terrain tile popping for flight paths that do not vary to much in altitude.
The changes are made against the 3.0.1 tag. Note that the changes have only been tested in SingleTreaded mode
If the addition/changes are acceptable, please feel free to make the changes you deem necessary for inclusion in OSG:-) Would have preferred not to introduce a dynamic_cast in PageLOD::traverse()....
Best regards, John -- This email was Anti Virus checked by Astaro Security Gateway. http://www.astaro.com
Index: include/osgUtil/CullVisitor
===================================================================
--- include/osgUtil/CullVisitor (revision 13078)
+++ include/osgUtil/CullVisitor (working copy)
@@ -100,6 +100,7 @@
virtual void apply(osg::Projection& node);
virtual void apply(osg::Switch& node);
virtual void apply(osg::LOD& node);
+ virtual void apply(osg::PagedLOD& node);
virtual void apply(osg::ClearNode& node);
virtual void apply(osg::Camera& node);
virtual void apply(osg::OccluderNode& node);
Index: include/osg/CullStack
===================================================================
--- include/osg/CullStack (revision 13078)
+++ include/osg/CullStack (working copy)
@@ -160,7 +160,9 @@
return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2));
}
+ unsigned int getCurrentPagedLODLevel() const { return
_currentPagedLODLevel;}
+
protected:
// base set of shadow volume occluder to use in culling.
@@ -202,7 +204,8 @@
inline osg::RefMatrix* createOrReuseMatrix(const osg::Matrix& value);
-
+ unsigned int _currentPagedLODLevel;
+
};
inline osg::Viewport* CullStack::getViewport()
Index: include/osg/CullSettings
===================================================================
--- include/osg/CullSettings (revision 13078)
+++ include/osg/CullSettings (working copy)
@@ -77,6 +77,7 @@
LIGHT = (0x1 << 16),
DRAW_BUFFER = (0x1 << 17),
READ_BUFFER = (0x1 << 18),
+ MAX_PAGEDLOD = (0x1 << 19),
NO_VARIABLES = 0x00000000,
ALL_VARIABLES = 0x7FFFFFFF
@@ -216,6 +217,12 @@
/** Get the LOD bias.*/
float getLODScale() const { return _LODScale; }
+ /** Set a PagedLOD cap for the CullVisitor to request.*/
+ void setMaxPagedLODLevel(unsigned int max) { _maxPagedLODLevel = max;
applyMaskAction(MAX_PAGEDLOD); }
+
+ /** Get the PagedLOD cap.*/
+ unsigned int getMaxPagedLODLevel() const { return _maxPagedLODLevel; }
+
/** Set the Small Feature Culling Pixel Size.*/
void setSmallFeatureCullingPixelSize(float value) {
_smallFeatureCullingPixelSize=value;
applyMaskAction(SMALL_FEATURE_CULLING_PIXEL_SIZE); }
@@ -252,6 +259,7 @@
ComputeNearFarMode _computeNearFar;
CullingMode _cullingMode;
float _LODScale;
+ unsigned int _maxPagedLODLevel;
float
_smallFeatureCullingPixelSize;
ref_ptr<ClampProjectionMatrixCallback>
_clampProjectionMatrixCallback;
Index: src/osgUtil/CullVisitor.cpp
===================================================================
--- src/osgUtil/CullVisitor.cpp (revision 13078)
+++ src/osgUtil/CullVisitor.cpp (working copy)
@@ -14,6 +14,7 @@
#include <osg/Projection>
#include <osg/Geode>
#include <osg/LOD>
+#include <osg/PagedLOD>
#include <osg/Billboard>
#include <osg/LightSource>
#include <osg/ClipNode>
@@ -1235,6 +1236,31 @@
popCurrentMask();
}
+void CullVisitor::apply(osg::PagedLOD& node)
+{
+ if (isCulled(node)) return;
+ if (_currentPagedLODLevel > getMaxPagedLODLevel()) return;
+
+ ++_currentPagedLODLevel;
+
+ // push the culling mode.
+ pushCurrentMask();
+
+ // push the node's state.
+ StateSet* node_state = node.getStateSet();
+ if (node_state) pushStateSet(node_state);
+
+ handle_cull_callbacks_and_traverse(node);
+
+ // pop the node's state off the render graph stack.
+ if (node_state) popStateSet();
+
+ // pop the culling mode.
+ popCurrentMask();
+
+ --_currentPagedLODLevel;
+}
+
void CullVisitor::apply(osg::ClearNode& node)
{
// simply override the current earth sky.
Index: src/osg/PagedLOD.cpp
===================================================================
--- src/osg/PagedLOD.cpp (revision 13078)
+++ src/osg/PagedLOD.cpp (working copy)
@@ -118,18 +118,27 @@
void PagedLOD::traverse(NodeVisitor& nv)
{
+ double timeStamp =
nv.getFrameStamp()?nv.getFrameStamp()->getReferenceTime():0.0;
+ unsigned int frameNumber =
nv.getFrameStamp()?nv.getFrameStamp()->getFrameNumber():0;
+
// set the frame number of the traversal so that external nodes can find
out how active this
// node is.
if (nv.getFrameStamp() &&
nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
{
setFrameNumberOfLastTraversal(nv.getFrameStamp()->getFrameNumber());
+
+ osg::CullStack* cullStack = dynamic_cast<osg::CullStack*>(&nv);
+ if (cullStack->getCurrentPagedLODLevel() ==
cullStack->getMaxPagedLODLevel() && _children.size() > 0)
+ {
+ // At Max LOD Level: Travers only the child representing this LOD
level
+ _perRangeDataList[0]._timeStamp=timeStamp;
+ _perRangeDataList[0]._frameNumber=frameNumber;
+ _children[0]->accept(nv);
+ return;
+ }
}
- double timeStamp =
nv.getFrameStamp()?nv.getFrameStamp()->getReferenceTime():0.0;
- unsigned int frameNumber =
nv.getFrameStamp()?nv.getFrameStamp()->getFrameNumber():0;
- bool updateTimeStamp = nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR;
-
switch(nv.getTraversalMode())
{
case(NodeVisitor::TRAVERSE_ALL_CHILDREN):
@@ -162,6 +171,8 @@
int lastChildTraversed = -1;
bool needToLoadChild = false;
+ bool updateTimeStamp =
nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR;
+
for(unsigned int i=0;i<_rangeList.size();++i)
{
if (_rangeList[i].first<=required_range &&
required_range<_rangeList[i].second)
Index: src/osg/CullSettings.cpp
===================================================================
--- src/osg/CullSettings.cpp (revision 13078)
+++ src/osg/CullSettings.cpp (working copy)
@@ -12,6 +12,7 @@
*/
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include <osg/CullSettings>
#include <osg/ArgumentParser>
@@ -32,6 +33,7 @@
_inheritanceMaskActionOnAttributeSetting =
DISABLE_ASSOCIATED_INHERITANCE_MASK_BIT;
_cullingMode = DEFAULT_CULLING;
_LODScale = 1.0f;
+ _maxPagedLODLevel = UINT_MAX;
_smallFeatureCullingPixelSize = 2.0f;
_computeNearFar = COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
@@ -57,6 +59,7 @@
_computeNearFar = rhs._computeNearFar;
_cullingMode = rhs._cullingMode;
_LODScale = rhs._LODScale;
+ _maxPagedLODLevel = rhs._maxPagedLODLevel;
_smallFeatureCullingPixelSize = rhs._smallFeatureCullingPixelSize;
_clampProjectionMatrixCallback = rhs._clampProjectionMatrixCallback;
@@ -85,6 +88,7 @@
if (inheritanceMask & CULL_MASK_RIGHT) _cullMaskRight =
settings._cullMaskRight;
if (inheritanceMask & CULLING_MODE) _cullingMode = settings._cullingMode;
if (inheritanceMask & LOD_SCALE) _LODScale = settings._LODScale;
+ if (inheritanceMask & MAX_PAGEDLOD) _maxPagedLODLevel =
settings._maxPagedLODLevel;
if (inheritanceMask & SMALL_FEATURE_CULLING_PIXEL_SIZE)
_smallFeatureCullingPixelSize = settings._smallFeatureCullingPixelSize;
if (inheritanceMask & CLAMP_PROJECTION_MATRIX_CALLBACK)
_clampProjectionMatrixCallback = settings._clampProjectionMatrixCallback;
}
@@ -156,6 +160,7 @@
out<<" _computeNearFar = "<<_computeNearFar<<std::endl;
out<<" _cullingMode = "<<_cullingMode<<std::endl;
out<<" _LODScale = "<<_LODScale<<std::endl;
+ out<<" _maxPagedLODLevel = "<<_maxPagedLODLevel<<std::endl;
out<<" _smallFeatureCullingPixelSize =
"<<_smallFeatureCullingPixelSize<<std::endl;
out<<" _clampProjectionMatrixCallback =
"<<_clampProjectionMatrixCallback.get()<<std::endl;
out<<" _nearFarRatio = "<<_nearFarRatio<<std::endl;
Index: src/osg/CullStack.cpp
===================================================================
--- src/osg/CullStack.cpp (revision 13078)
+++ src/osg/CullStack.cpp (working copy)
@@ -18,32 +18,31 @@
using namespace osg;
-CullStack::CullStack()
+CullStack::CullStack():
+ CullSettings(),
+ _index_modelviewCullingStack(0),
+ _back_modelviewCullingStack(0),
+ _frustumVolume(-1.0f),
+ _bbCornerNear(0),
+ _bbCornerFar(7),
+ _identity(new RefMatrix()),
+ _currentReuseMatrixIndex(0),
+ _currentPagedLODLevel(0)
{
- _frustumVolume=-1.0f;
- _bbCornerNear = 0;
- _bbCornerFar = 7;
- _currentReuseMatrixIndex=0;
- _identity = new RefMatrix();
-
- _index_modelviewCullingStack = 0;
- _back_modelviewCullingStack = 0;
-
_referenceViewPoints.push_back(osg::Vec3(0.0f,0.0f,0.0f));
}
CullStack::CullStack(const CullStack& cs):
- CullSettings(cs)
-{
- _frustumVolume=-1.0f;
- _bbCornerNear = 0;
- _bbCornerFar = 7;
- _currentReuseMatrixIndex=0;
- _identity = new RefMatrix();
-
- _index_modelviewCullingStack = 0;
- _back_modelviewCullingStack = 0;
-
+ CullSettings(cs),
+ _index_modelviewCullingStack(0),
+ _back_modelviewCullingStack(0),
+ _frustumVolume(-1.0f),
+ _bbCornerNear(0),
+ _bbCornerFar(7),
+ _identity(new RefMatrix()),
+ _currentReuseMatrixIndex(0),
+ _currentPagedLODLevel(cs._currentPagedLODLevel)
+{
_referenceViewPoints.push_back(osg::Vec3(0.0f,0.0f,0.0f));
}
@@ -86,6 +85,7 @@
_bbCornerNear = (~_bbCornerFar)&7;
_currentReuseMatrixIndex=0;
+ _currentPagedLODLevel = 0;
}
max_pagedlod_level_svn13078.tgz
Description: application/compressed-tar
_______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
