diff --git a/include/osg/CullStack b/include/osg/CullStack index 56cdb589b..973f57148 100644 --- a/include/osg/CullStack +++ b/include/osg/CullStack @@ -65,6 +65,18 @@ class OSG_EXPORT CullStack : public osg::CullSettings return pixelSize(bs.center(),bs.radius()); } + /** Compute the pixel size of an object at position v, with specified radius. fabs()ed to always be positive. */ + float clampedPixelSize(const Vec3& v,float radius) const + { + return getCurrentCullingSet().clampedPixelSize(v,radius); + } + + /** Compute the pixel size of the bounding sphere. fabs()ed to always be positive. */ + float clampedPixelSize(const BoundingSphere& bs) const + { + return clampedPixelSize(bs.center(),bs.radius()); + } + inline void disableAndPushOccludersCurrentMask(NodePath& nodePath) { getCurrentCullingSet().disableAndPushOccludersCurrentMask(nodePath); diff --git a/include/osg/CullingSet b/include/osg/CullingSet index 14f24d031..5bcf8776f 100644 --- a/include/osg/CullingSet +++ b/include/osg/CullingSet @@ -18,6 +18,8 @@ #include #include +#include + namespace osg { @@ -172,6 +174,12 @@ class OSG_EXPORT CullingSet : public Referenced /** Compute the pixel of a bounding sphere.*/ float pixelSize(const BoundingSphere& bs) const { return bs.radius()/(bs.center()*_pixelSizeVector); } + /** Compute the pixel of an object at position v, with specified radius. fabs()ed to always be positive. */ + float clampedPixelSize(const Vec3& v,float radius) const { return fabs(pixelSize(v, radius)); } + + /** Compute the pixel of a bounding sphere. fabs()ed to always be positive. */ + float clampedPixelSize(const BoundingSphere& bs) const { return fabs(pixelSize(bs)); } + inline bool isCulled(const std::vector& vertices) { diff --git a/include/osg/LOD b/include/osg/LOD index 3aa5ec4b3..7dda09c9f 100644 --- a/include/osg/LOD +++ b/include/osg/LOD @@ -55,17 +55,17 @@ class OSG_EXPORT LOD : public Group typedef std::pair MinMaxPair; typedef std::vector RangeList; - /** Modes which control how the center of object should be determined when computed which child is active.*/ + /** Modes which control how the center of object should be determined when computing which child is active.*/ enum CenterMode { USE_BOUNDING_SPHERE_CENTER, USER_DEFINED_CENTER }; - /** Set how the center of object should be determined when computed which child is active.*/ + /** Set how the center of object should be determined when computing which child is active.*/ void setCenterMode(CenterMode mode) { _centerMode=mode; } - /** Get how the center of object should be determined when computed which child is active.*/ + /** Get how the center of object should be determined when computing which child is active.*/ CenterMode getCenterMode() const { return _centerMode; } /** Sets the object-space point which defines the center of the osg::LOD. diff --git a/src/osg/LOD.cpp b/src/osg/LOD.cpp index 1ebc3690d..af0999481 100644 --- a/src/osg/LOD.cpp +++ b/src/osg/LOD.cpp @@ -54,7 +54,7 @@ void LOD::traverse(NodeVisitor& nv) osg::CullStack* cullStack = dynamic_cast(&nv); if (cullStack) { - required_range = cullStack->pixelSize(getBound()); + required_range = cullStack->clampedPixelSize(getBound()); } else { @@ -104,7 +104,7 @@ bool LOD::addChild( Node *child ) if (_children.size()>_rangeList.size()) { float maxRange = !_rangeList.empty()? - _rangeList.back().second : 0.0f; + maxRange=_rangeList.back().second : 0.0f; _rangeList.resize(_children.size(),MinMaxPair(maxRange,maxRange)); } diff --git a/src/osg/PagedLOD.cpp b/src/osg/PagedLOD.cpp index 95ba6fac6..a55a7e029 100644 --- a/src/osg/PagedLOD.cpp +++ b/src/osg/PagedLOD.cpp @@ -126,7 +126,7 @@ void PagedLOD::traverse(NodeVisitor& nv) osg::CullStack* cullStack = dynamic_cast(&nv); if (cullStack) { - required_range = cullStack->pixelSize(getBound()); + required_range = cullStack->clampedPixelSize(getBound()); } else { @@ -170,12 +170,18 @@ void PagedLOD::traverse(NodeVisitor& nv) _children[numChildren-1]->accept(nv); } - // now request the loading of the next unload child. + // now request the loading of the next unloaded child. if (nv.getDatabaseRequestHandler() && numChildren<_perRangeDataList.size()) { // compute priority from where abouts in the required range the distance falls. float priority = (_rangeList[numChildren].second-required_range)/(_rangeList[numChildren].second-_rangeList[numChildren].first); + // invert priority for PIXEL_SIZE_ON_SCREEN mode + if(_rangeMode==PIXEL_SIZE_ON_SCREEN) + { + priority = -priority; + } + // modify the priority according to the child's priority offset and scale. priority = _perRangeDataList[numChildren]._priorityOffset + priority * _perRangeDataList[numChildren]._priorityScale; @@ -185,7 +191,7 @@ void PagedLOD::traverse(NodeVisitor& nv) } else { - // prepend the databasePath to the childs filename. + // prepend the databasePath to the child's filename. nv.getDatabaseRequestHandler()->requestNodeFile(_databasePath+_perRangeDataList[numChildren]._filename,this,priority,nv.getFrameStamp()); } }