diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 5e79f7e67..39ab2351c 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -197,6 +197,47 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor return _eyePointStack.back(); } + + inline float pixelSize(const osg::Vec3& v, float const radius) + { + const osg::Matrix& mvpw = getMVPW(); + if (_windowToModelFactorDirty) + { + _windowToModelFactorDirty=false; + _windowToModelFactor = osg::Vec3(mvpw(0,0),mvpw(1,0),mvpw(2,0)).length(); + } + float W = v.x()*mvpw(0,3)+ + v.y()*mvpw(1,3)+ + v.z()*mvpw(2,3)+ + mvpw(3,3); + + return fabs(radius*_windowToModelFactor/W); + } + + + inline bool isCulled(const osg::BoundingSphere& sp,CullingMode& mode) + { + if (!sp.isValid()) return true; + + if (!(_modelviewClippingVolumeStack.back().contains(sp,mode))) return true; + + if (mode&SMALL_FEATURE_CULLING) + { + if (pixelSize(sp.center(),sp.radius())<_smallFeatureCullingPixelSize) return true; + } + return false; + } + + inline const bool isCulled(const osg::BoundingBox& bb,CullingMode mode) + { + if (!bb.isValid()) return true; + + return !_modelviewClippingVolumeStack.back().contains(bb,mode); + } + + void setSmallFeatureCullingPixelSize(float s) { _smallFeatureCullingPixelSize=s; } + float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; } + protected: /** prevent unwanted copy construction.*/ @@ -233,30 +274,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor } - inline bool isCulled(const osg::BoundingSphere& sp,CullingMode& mode) const - { - if (!sp.isValid()) return true; - - if (!(_modelviewClippingVolumeStack.back().contains(sp,mode))) return true; - - if (mode&SMALL_FEATURE_CULLING) - { - const float _ratio2 = 0.002f*0.002f; - osg::Vec3 delta(sp._center-getEyeLocal()); - if (sp.radius2() > ViewportStack; ViewportStack _viewportStack; @@ -404,7 +426,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor float _LODBias; - + float _smallFeatureCullingPixelSize; enum ComputeNearFarMode { @@ -430,7 +452,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor MatrixList _reuseMatrixList; unsigned int _currentReuseMatrixIndex; - inline osg::Matrix* createOrReuseMatrix(const osg::Matrix value) + inline osg::Matrix* createOrReuseMatrix(const osg::Matrix& value) { // skip of any already reused matrix. while (_currentReuseMatrixIndex<_reuseMatrixList.size() && diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index a29bc6f27..8ec4b237d 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -105,6 +105,10 @@ CullVisitor::CullVisitor() _numFramesToKeepImpostorSprites = 10; _impostorSpriteManager = osgNew ImpostorSpriteManager; + _windowToModelFactorDirty = true; + _windowToModelFactor = 1.0f; + _smallFeatureCullingPixelSize = 3.0f; + } @@ -159,6 +163,8 @@ void CullVisitor::reset() (*itr)->reset(); } + _windowToModelFactorDirty = true; + _windowToModelFactor = 1.0f; } void CullVisitor::pushClippingVolume() @@ -167,12 +173,16 @@ void CullVisitor::pushClippingVolume() if (!_modelviewStack.empty()) _modelviewClippingVolumeStack.back().transformProvidingInverse(*_modelviewStack.back()); _MVPW_Stack.push_back(0L); + + _windowToModelFactorDirty = true; } void CullVisitor::popClippingVolume() { _modelviewClippingVolumeStack.pop_back(); _MVPW_Stack.pop_back(); + + _windowToModelFactorDirty = true; } void CullVisitor::pushViewport(osg::Viewport* viewport) @@ -436,6 +446,37 @@ void CullVisitor::apply(Geode& node) } } +// osg::Timer timer; +// osg::Timer_t ta = timer.tick(); +// const osg::Matrix& mvpw = getMVPW(); +// osg::Timer_t tb = timer.tick(); +// +// const osg::BoundingSphere& sp = node.getBound(); +// osg::Vec3 v = sp._center; +// float radius = sp._radius; +// osg::Timer_t t1 = timer.tick(); +// bool result1 = pixelSize(v,sp.radius())<4.0f; +// osg::Timer_t t2 = timer.tick(); +// +// const float _ratio2 = 0.002f*0.002f; +// osg::Vec3 delta(v-getEyeLocal()); +// bool result2 = (sp.radius2()