From 348419219d23cec47804b13bdc137182d0a9297c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 10 Jun 2002 11:21:21 +0000 Subject: [PATCH] Created new helper class osg::CullStack to handle the accumulation of projection, modelview and culling sets, to be used during travesal of the scene graph, such as the cull traversal. --- VisualStudio/osg/osg.dsp | 8 + include/osg/CullStack | 260 +++++++++++++++++++++++++++++++ include/osg/CullingSet | 24 +-- include/osg/ShadowOccluderVolume | 38 ++--- include/osgUtil/CullVisitor | 235 +--------------------------- src/osg/CullStack.cpp | 187 ++++++++++++++++++++++ src/osg/Makefile | 1 + src/osg/ShadowOccluderVolume.cpp | 22 +-- src/osgUtil/CullVisitor.cpp | 177 +-------------------- 9 files changed, 500 insertions(+), 452 deletions(-) create mode 100644 include/osg/CullStack create mode 100644 src/osg/CullStack.cpp diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index e8bf13f7f..623919008 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -149,6 +149,10 @@ SOURCE=..\..\src\osg\CullFace.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\CullStack.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\CullingSet.cpp # End Source File # Begin Source File @@ -433,6 +437,10 @@ SOURCE=..\..\Include\Osg\CullFace # End Source File # Begin Source File +SOURCE=..\..\Include\Osg\CullStack +# End Source File +# Begin Source File + SOURCE=..\..\Include\Osg\CullingSet # End Source File # Begin Source File diff --git a/include/osg/CullStack b/include/osg/CullStack new file mode 100644 index 000000000..1d2890b55 --- /dev/null +++ b/include/osg/CullStack @@ -0,0 +1,260 @@ +//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield +//Distributed under the terms of the GNU Library General Public License (LGPL) +//as published by the Free Software Foundation. + +#ifndef OSG_CULLSTACK +#define OSG_CULLSTACK 1 + +#include +#include +#include +#include + +namespace osg { + +/** A CullStack class which accumulates the current project, modelview matrices +and the CullingSet. */ +class SG_EXPORT CullStack +{ + + public: + + + CullStack(); + + ~CullStack(); + + typedef std::vector OccluderList; + + enum CullingModeValues + { + NO_CULLING = 0x00, + VIEW_FRUSTUM_CULLING = 0x1, + SMALL_FEATURE_CULLING = 0x2, + SHADOW_OCCLUSION_CULLING = 0x4, + ENABLE_ALL_CULLING = 0xffffffff + }; + + typedef unsigned int CullingMode; + + /** Sets the current CullingMode.*/ + void setCullingMode(CullingMode mode) { _cullingMode = mode; } + + /** Returns the current CullingMode.*/ + CullingMode getCullingMode() const { return _cullingMode; } + + void reset(); + + void pushViewport(osg::Viewport* viewport); + void popViewport(); + + void pushProjectionMatrix(osg::Matrix* matrix); + void popProjectionMatrix(); + + void pushModelViewMatrix(osg::Matrix* matrix); + void popModelViewMatrix(); + + void setSmallFeatureCullingPixelSize(float value) { _smallFeatureCullingPixelSize=value; } + float& getSmallFeatureCullingPixelSize() { return _smallFeatureCullingPixelSize; } + float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; } + + + /** Compute the pixel of an object at position v, with specified radius.*/ + float pixelSize(const Vec3& v,float radius) const + { + return _modelviewCullingStack.back()->pixelSize(v,radius); + } + + /** Compute the pixel of an bounding sphere.*/ + float pixelSize(const BoundingSphere& bs) const + { + return pixelSize(bs.center(),bs.radius()); + } + + inline void disableOccluder(NodePath& nodePath) + { + _modelviewCullingStack.back()->disableOccluder(nodePath); + } + + inline bool isCulled(const BoundingBox& bb) + { + return bb.isValid() && _modelviewCullingStack.back()->isCulled(bb); + } + + inline bool isCulled(const BoundingSphere& bs) + { + return _modelviewCullingStack.back()->isCulled(bs); + } + + inline bool isCulled(const osg::Node& node) + { + return node.isCullingActive() && _modelviewCullingStack.back()->isCulled(node.getBound()); + } + + inline void pushCurrentMask() + { + _modelviewCullingStack.back()->pushCurrentMask(); + } + + inline void popCurrentMask() + { + _modelviewCullingStack.back()->popCurrentMask(); + } + + + inline osg::Viewport* getViewport(); + inline osg::Matrix& getModelViewMatrix(); + inline osg::Matrix& getProjectionMatrix(); + inline const osg::Matrix getWindowMatrix(); + inline const osg::Matrix& getMVPW(); + + inline const osg::Vec3& getEyeLocal() const { return _eyePointStack.back(); } + + inline const osg::Vec3 getUpLocal() const + { + const osg::Matrix& matrix = *_modelviewStack.back(); + return osg::Vec3(matrix(0,1),matrix(1,1),matrix(2,1)); + } + + inline const osg::Vec3 getLookVectorLocal() const + { + const osg::Matrix& matrix = *_modelviewStack.back(); + return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2)); + } + + protected: + + void pushCullingSet(); + void popCullingSet(); + + CullingMode _cullingMode; + float _smallFeatureCullingPixelSize; + + typedef fast_back_stack< ref_ptr > MatrixStack; + + MatrixStack _projectionStack; + + MatrixStack _modelviewStack; + MatrixStack _MVPW_Stack; + + typedef fast_back_stack > ViewportStack; + ViewportStack _viewportStack; + + typedef fast_back_stack EyePointStack; + EyePointStack _eyePointStack; + + typedef fast_back_stack > CullingStack; + CullingStack _clipspaceCullingStack; + CullingStack _projectionCullingStack; + CullingStack _modelviewCullingStack; + + unsigned int _bbCornerNear; + unsigned int _bbCornerFar; + + osg::Matrix _identity; + + typedef std::vector< osg::ref_ptr > MatrixList; + MatrixList _reuseMatrixList; + unsigned int _currentReuseMatrixIndex; + + inline osg::Matrix* createOrReuseMatrix(const osg::Matrix& value); + + +}; + +inline osg::Viewport* CullStack::getViewport() +{ + if (!_viewportStack.empty()) + { + return _viewportStack.back().get(); + } + else + { + return 0L; + } +} + +inline osg::Matrix& CullStack::getModelViewMatrix() +{ + if (!_modelviewStack.empty()) + { + return *_modelviewStack.back(); + } + else + { + return _identity; + } +} + +inline osg::Matrix& CullStack::getProjectionMatrix() +{ + if (!_projectionStack.empty()) + { + return *_projectionStack.back(); + } + else + { + return _identity; + } +} + +inline const osg::Matrix CullStack::getWindowMatrix() +{ + if (!_viewportStack.empty()) + { + osg::Viewport* viewport = _viewportStack.back().get(); + return viewport->computeWindowMatrix(); + } + else + { + return _identity; + } +} + +inline const osg::Matrix& CullStack::getMVPW() +{ + if (!_MVPW_Stack.empty()) + { + if (!_MVPW_Stack.back()) + { + _MVPW_Stack.back() = createOrReuseMatrix(getModelViewMatrix()); + (*_MVPW_Stack.back()) *= getProjectionMatrix(); + (*_MVPW_Stack.back()) *= getWindowMatrix(); + } + return *_MVPW_Stack.back(); + } + else + { + return _identity; + } +} + +inline Matrix* CullStack::createOrReuseMatrix(const osg::Matrix& value) +{ + // skip of any already reused matrix. + while (_currentReuseMatrixIndex<_reuseMatrixList.size() && + _reuseMatrixList[_currentReuseMatrixIndex]->referenceCount()>1) + { + notify(osg::NOTICE)<<"Warning:createOrReuseMatrix() skipping multiply refrenced entry."<< std::endl; + ++_currentReuseMatrixIndex; + } + + // if still within list, element must be singularly referenced + // there return it to be reused. + if (_currentReuseMatrixIndex<_reuseMatrixList.size()) + { + Matrix* matrix = _reuseMatrixList[_currentReuseMatrixIndex++].get(); + matrix->set(value); + return matrix; + } + + // otherwise need to create new matrix. + osg::Matrix* matrix = osgNew Matrix(value); + _reuseMatrixList.push_back(matrix); + ++_currentReuseMatrixIndex; + return matrix; +} + +} // end of namespace + +#endif diff --git a/include/osg/CullingSet b/include/osg/CullingSet index 566ccba4e..a0b275c83 100644 --- a/include/osg/CullingSet +++ b/include/osg/CullingSet @@ -21,12 +21,12 @@ class SG_EXPORT CullingSet : public Referenced CullingSet(); CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector): _mask(cs._mask), - _clippingVolume(cs._clippingVolume), + _frustum(cs._frustum), _occluderList(cs._occluderList), _pixelSizeVector(pixelSizeVector), _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize) { - _clippingVolume.transformProvidingInverse(matrix); + _frustum.transformProvidingInverse(matrix); for(OccluderList::iterator itr=_occluderList.begin(); itr!=_occluderList.end(); ++itr) @@ -37,7 +37,7 @@ class SG_EXPORT CullingSet : public Referenced ~CullingSet(); - typedef std::vector OccluderList; + typedef std::vector OccluderList; typedef unsigned int Mask; @@ -51,12 +51,12 @@ class SG_EXPORT CullingSet : public Referenced void setCullingMask(Mask mask) { _mask = mask; } - void setFrustum(Polytope& cv) { _clippingVolume = cv; } + void setFrustum(Polytope& cv) { _frustum = cv; } - Polytope& getFrustum() { return _clippingVolume; } - const Polytope& getFrustum() const { return _clippingVolume; } + Polytope& getFrustum() { return _frustum; } + const Polytope& getFrustum() const { return _frustum; } - void addOccluder(ShadowOccluderVolume& cv) { _occluderList.push_back(cv); } + void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); } void setPixelSizeVector(const Vec4& v) { _pixelSizeVector = v; } @@ -99,7 +99,7 @@ class SG_EXPORT CullingSet : public Referenced if (_mask&VIEW_FRUSTUM_CULLING) { // is it outside the view frustum... - if (!_clippingVolume.contains(bb)) return true; + if (!_frustum.contains(bb)) return true; } if (_mask&SMALL_FEATURE_CULLING) @@ -128,7 +128,7 @@ class SG_EXPORT CullingSet : public Referenced if (_mask&VIEW_FRUSTUM_CULLING) { // is it outside the view frustum... - if (!_clippingVolume.contains(bs)) return true; + if (!_frustum.contains(bs)) return true; } if (_mask&SMALL_FEATURE_CULLING) @@ -155,7 +155,7 @@ class SG_EXPORT CullingSet : public Referenced inline void pushCurrentMask() { - _clippingVolume.pushCurrentMask(); + _frustum.pushCurrentMask(); if (!_occluderList.empty()) { @@ -170,7 +170,7 @@ class SG_EXPORT CullingSet : public Referenced inline void popCurrentMask() { - _clippingVolume.popCurrentMask(); + _frustum.popCurrentMask(); if (!_occluderList.empty()) { @@ -187,7 +187,7 @@ class SG_EXPORT CullingSet : public Referenced protected: Mask _mask; - Polytope _clippingVolume; + Polytope _frustum; OccluderList _occluderList; Vec4 _pixelSizeVector; float _smallFeatureCullingPixelSize; diff --git a/include/osg/ShadowOccluderVolume b/include/osg/ShadowOccluderVolume index 7063efad2..0f2e813ca 100644 --- a/include/osg/ShadowOccluderVolume +++ b/include/osg/ShadowOccluderVolume @@ -2,8 +2,8 @@ //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. -#ifndef OSG_SHADOWOCCLUDERVOLUME -#define OSG_SHADOWOCCLUDERVOLUME 1 +#ifndef OSG_SHADOWVOLUMEOCCLUDER +#define OSG_SHADOWVOLUMEOCCLUDER 1 #include #include @@ -12,8 +12,8 @@ namespace osg { -/** ShadowOccluderVolume is a helper class for implementating shadow occlusion culling. */ -class SG_EXPORT ShadowOccluderVolume +/** ShadowVolumeOccluder is a helper class for implementating shadow occlusion culling. */ +class SG_EXPORT ShadowVolumeOccluder { public: @@ -21,15 +21,21 @@ class SG_EXPORT ShadowOccluderVolume typedef std::vector HoleList; - ShadowOccluderVolume(const ShadowOccluderVolume& soc): + ShadowVolumeOccluder(const ShadowVolumeOccluder& soc): + _quality(soc._quality), _nodePath(soc._nodePath), _occluderVolume(soc._occluderVolume), _holeList(soc._holeList) {} - ShadowOccluderVolume(const ShadowOccluderVolume& soc,Matrix& MVP); - - ShadowOccluderVolume(const ConvexPlanerOccluder& occluder,Matrix& MVP); + ShadowVolumeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MVP) + { + computeOccluder(nodePath,occluder,MVP); + } + + /** compute the shadow volume occluder. */ + void computeOccluder(const NodePath& nodePath,const ConvexPlanerOccluder& occluder,const Matrix& MVP); + inline void disableResultMasks(); inline void pushCurrentMask(); @@ -41,15 +47,8 @@ class SG_EXPORT ShadowOccluderVolume inline NodePath& getNodePath() { return _nodePath; } inline const NodePath& getNodePath() const { return _nodePath; } + float quality() { return _quality; } - /** Convert shadow occluder into local coords by multiplying the - * clip space occluder by the ModelViewProjectionMatrix.*/ - void set(const ShadowOccluderVolume& soc,Matrix& MVP); - - /** Initialize a ShadowOccluderVolume to a ConvexPlanerOccluder - * transformed into clipspace.*/ - void set(const ConvexPlanerOccluder& occluder,Matrix& MVP); - /** return true if the specified bounding sphere is contaned entirely * within this shadow occluder volume.*/ bool contains(const BoundingSphere& bound); @@ -72,12 +71,13 @@ class SG_EXPORT ShadowOccluderVolume protected: + float _quality; NodePath _nodePath; Polytope _occluderVolume; HoleList _holeList; }; -inline void ShadowOccluderVolume::disableResultMasks() +inline void ShadowVolumeOccluder::disableResultMasks() { _occluderVolume.setResultMask(0); for(HoleList::iterator itr=_holeList.begin(); @@ -88,7 +88,7 @@ inline void ShadowOccluderVolume::disableResultMasks() } } -inline void ShadowOccluderVolume::pushCurrentMask() +inline void ShadowVolumeOccluder::pushCurrentMask() { _occluderVolume.pushCurrentMask(); if (!_holeList.empty()) @@ -102,7 +102,7 @@ inline void ShadowOccluderVolume::pushCurrentMask() } } -inline void ShadowOccluderVolume::popCurrentMask() +inline void ShadowVolumeOccluder::popCurrentMask() { _occluderVolume.popCurrentMask(); if (!_holeList.empty()) diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 4dd75ea0e..55991ee4b 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -17,8 +17,7 @@ #include #include -#include -#include +#include #include #include @@ -38,27 +37,10 @@ namespace osgUtil { * transparent bin in rendered in order from the furthest osg::Drawable * from the eye to the one nearest the eye. */ -class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor +class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStack { public: - enum - { - NO_CULLING = 0x00, - FRUSTUM_LEFT_CULLING = 0x01, - FRUSTUM_RIGHT_CULLING = 0x02, - FRUSTUM_BOTTOM_CULLING = 0x04, - FRUSTUM_TOP_CULLING = 0x08, - FRUSTUM_NEAR_CULLING = 0x10, - FRUSTUM_FAR_CULLING = 0x20, - VIEW_FRUSTUM_CULLING = 0x3F, - SMALL_FEATURE_CULLING = 0x40, - ENABLE_ALL_CULLING = 0x7F - }; - - typedef unsigned int CullingMode; - - CullVisitor(); virtual ~CullVisitor(); @@ -136,25 +118,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor }; void setTransparencySortMode(TransparencySortMode tsm) { _tsm = tsm; } - - /** Sets the current CullingMode.*/ - void setCullingMode(CullingMode mode); - - /** Returns the current CullingMode.*/ - CullingMode getCullingMode() const; - - void setSmallFeatureCullingPixelSize(float s) { _smallFeatureCullingPixelSize=s; } - float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; } - - void pushViewport(osg::Viewport* viewport); - void popViewport(); - - void pushProjectionMatrix(osg::Matrix* matrix); - void popProjectionMatrix(); - - void pushModelViewMatrix(osg::Matrix* matrix); - void popModelViewMatrix(); - /** Push state set on the current state group. * If the state exists in a child state group of the current * state group then move the current state group to that child. @@ -216,46 +179,10 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor return _currentRenderBin; } - inline osg::Viewport* getViewport(); - inline osg::Matrix& getModelViewMatrix(); - inline osg::Matrix& getProjectionMatrix(); - inline const osg::Matrix getWindowMatrix(); - inline const osg::Matrix& getMVPW(); - - inline const osg::Vec3& getEyeLocal() const - { - return _eyePointStack.back(); - } - inline const float getCalculatedNearPlane() const { return _computed_znear; } inline const float getCalculatedFarPlane() const { return _computed_zfar; } - inline float pixelSize(const osg::Vec3& v, float const radius) - { - return _modelviewCullingStack.back()->pixelSize(v,radius); - } - - inline bool isCulled(const osg::Node& node) - { - return node.isCullingActive() && _modelviewCullingStack.back()->isCulled(node.getBound()); - } - - inline const bool isCulled(const osg::BoundingBox& bb) - { - return bb.isValid() && _modelviewCullingStack.back()->isCulled(bb); - } - - inline void pushCurrentMask() - { - _modelviewCullingStack.back()->pushCurrentMask(); - } - - inline void popCurrentMask() - { - _modelviewCullingStack.back()->popCurrentMask(); - } - void updateCalculatedNearFar(const osg::Matrix& matrix,const osg::Drawable& drawable) { updateCalculatedNearFar(matrix,drawable.getBound()); } void updateCalculatedNearFar(const osg::Matrix& matrix,const osg::BoundingBox& bb); void updateCalculatedNearFar(const osg::Vec3& pos); @@ -269,10 +196,13 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor /** Add an attribute which is positioned related to the modelview matrix.*/ inline void addPositionedAttribute(osg::Matrix* matrix,const osg::StateAttribute* attr); + /** reimplement CullStack's popProjectionMatrix() adding clamping of the projection matrix to the computed near and far.*/ + void popProjectionMatrix(); + protected: /** prevent unwanted copy construction.*/ - CullVisitor(const CullVisitor&):osg::NodeVisitor() {} + CullVisitor(const CullVisitor&):osg::NodeVisitor(),osg::CullStack() {} /** prevent unwanted copy operator.*/ CullVisitor& operator = (const CullVisitor&) { return *this; } @@ -291,61 +221,11 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor else acceptNode->accept(*this); } - - inline const osg::Vec3 getUpLocal() const - { - const osg::Matrix& matrix = *_modelviewStack.back(); - return osg::Vec3(matrix(0,1),matrix(1,1),matrix(2,1)); - } - - inline const osg::Vec3 getLookVectorLocal() const - { - const osg::Matrix& matrix = *_modelviewStack.back(); - return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2)); - } - - - - /** create an impostor sprite by setting up a pre-rendering stage * to generate the impostor texture. */ osg::ImpostorSprite* createImpostorSprite(osg::Impostor& node); - - - void pushCullingSet(); - void popCullingSet(); - - - typedef osg::fast_back_stack PolytopeStack; - typedef osg::fast_back_stack< osg::ref_ptr > MatrixStack; - - MatrixStack _projectionStack; - MatrixStack _PW_Stack; - - MatrixStack _modelviewStack; - MatrixStack _MVPW_Stack; - - typedef osg::fast_back_stack > ViewportStack; - ViewportStack _viewportStack; - - typedef osg::fast_back_stack EyePointStack; - EyePointStack _eyePointStack; - - CullingMode _cullingMode; - - typedef osg::fast_back_stack > CullingStack; - CullingStack _clipspaceCullingStack; - CullingStack _projectionCullingStack; - CullingStack _modelviewCullingStack; - - - unsigned int _bbCornerNear; - unsigned int _bbCornerFar; - - osg::Matrix _identity; - osg::ref_ptr _rootRenderGraph; RenderGraph* _currentRenderGraph; @@ -354,8 +234,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor float _LODBias; - float _smallFeatureCullingPixelSize; - ComputeNearFarMode _computeNearFar; float _computed_znear; @@ -370,11 +248,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor float _impostorPixelErrorThreshold; int _numFramesToKeepImpostorSprites; - typedef std::vector< osg::ref_ptr > MatrixList; - MatrixList _reuseMatrixList; - unsigned int _currentReuseMatrixIndex; - - inline osg::Matrix* createOrReuseMatrix(const osg::Matrix& value); typedef std::vector< osg::ref_ptr > RenderLeafList; RenderLeafList _reuseRenderLeafList; @@ -386,75 +259,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor }; - - -inline osg::Viewport* CullVisitor::getViewport() -{ - if (!_viewportStack.empty()) - { - return _viewportStack.back().get(); - } - else - { - return 0L; - } -} - -inline osg::Matrix& CullVisitor::getModelViewMatrix() -{ - if (!_modelviewStack.empty()) - { - return *_modelviewStack.back(); - } - else - { - return _identity; - } -} - -inline osg::Matrix& CullVisitor::getProjectionMatrix() -{ - if (!_projectionStack.empty()) - { - return *_projectionStack.back(); - } - else - { - return _identity; - } -} - -inline const osg::Matrix CullVisitor::getWindowMatrix() -{ - if (!_viewportStack.empty()) - { - osg::Viewport* viewport = _viewportStack.back().get(); - return viewport->computeWindowMatrix(); - } - else - { - return _identity; - } -} - -inline const osg::Matrix& CullVisitor::getMVPW() -{ - if (!_MVPW_Stack.empty()) - { - if (!_MVPW_Stack.back()) - { - _MVPW_Stack.back() = createOrReuseMatrix(getModelViewMatrix()); - (*_MVPW_Stack.back()) *= getProjectionMatrix(); - (*_MVPW_Stack.back()) *= getWindowMatrix(); - } - return *_MVPW_Stack.back(); - } - else - { - return _identity; - } -} - inline void CullVisitor::addDrawable(osg::Drawable* drawable,osg::Matrix* matrix) { if (_currentRenderGraph->leaves_empty()) @@ -488,32 +292,6 @@ inline void CullVisitor::addPositionedAttribute(osg::Matrix* matrix,const osg::S _currentRenderBin->_stage->addPositionedAttribute(matrix,attr); } -inline osg::Matrix* CullVisitor::createOrReuseMatrix(const osg::Matrix& value) -{ - // skip of any already reused matrix. - while (_currentReuseMatrixIndex<_reuseMatrixList.size() && - _reuseMatrixList[_currentReuseMatrixIndex]->referenceCount()>1) - { - osg::notify(osg::NOTICE)<<"Warning:createOrReuseMatrix() skipping multiply refrenced entry."<< std::endl; - ++_currentReuseMatrixIndex; - } - - // if still within list, element must be singularly referenced - // there return it to be reused. - if (_currentReuseMatrixIndex<_reuseMatrixList.size()) - { - osg::Matrix* matrix = _reuseMatrixList[_currentReuseMatrixIndex++].get(); - matrix->set(value); - return matrix; - } - - // otherwise need to create new matrix. - osg::Matrix* matrix = new osg::Matrix(value); - _reuseMatrixList.push_back(matrix); - ++_currentReuseMatrixIndex; - return matrix; -} - inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable,osg::Matrix* projection,osg::Matrix* matrix, float depth) { // skip of any already reused renderleaf. @@ -541,7 +319,6 @@ inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable, } - } #endif diff --git a/src/osg/CullStack.cpp b/src/osg/CullStack.cpp new file mode 100644 index 000000000..0e7d0c3ec --- /dev/null +++ b/src/osg/CullStack.cpp @@ -0,0 +1,187 @@ +#include + +using namespace osg; + +CullStack::CullStack() +{ + + _cullingMode = ENABLE_ALL_CULLING; + _smallFeatureCullingPixelSize = 3.0f; + +} + + +CullStack::~CullStack() +{ + reset(); +} + + +void CullStack::reset() +{ + + // + // first unref all referenced objects and then empty the containers. + // + _projectionStack.clear(); + _modelviewStack.clear(); + _viewportStack.clear(); + _eyePointStack.clear(); + + + _clipspaceCullingStack.clear(); + _projectionCullingStack.clear(); + _modelviewCullingStack.clear(); + + osg::Vec3 lookVector(0.0,0.0,-1.0); + + _bbCornerFar = (lookVector.x()>=0?1:0) | + (lookVector.y()>=0?2:0) | + (lookVector.z()>=0?4:0); + + _bbCornerNear = (~_bbCornerFar)&7; +} + +void CullStack::pushCullingSet() +{ + _MVPW_Stack.push_back(0L); + + if (_modelviewStack.empty()) + { + _modelviewCullingStack.push_back(_projectionCullingStack.back()); + + } + else + { + + const osg::Viewport& W = *_viewportStack.back(); + const osg::Matrix& P = *_projectionStack.back(); + const osg::Matrix& M = *_modelviewStack.back(); + + // pre adjust P00,P20,P23,P33 by multiplying them by the viewport window matrix. + // here we do it in short hand with the knowledge of how the window matrix is formed + // note P23,P33 are multiplied by an implicit 1 which would come from the window matrix. + // Robert Osfield, June 2002. + float P00 = P(0,0)*W.width()*0.5f; + float P20 = P(2,0)*W.width()*0.5f + P(2,3)*W.width()*0.5f; + osg::Vec3 scale(M(0,0)*P00 + M(0,2)*P20, + M(1,0)*P00 + M(1,2)*P20, + M(2,0)*P00 + M(2,2)*P20); + + float P23 = P(2,3); + float P33 = P(3,3); + osg::Vec4 pixelSizeVector2(M(0,2)*P23, + M(1,2)*P23, + M(2,2)*P23, + M(3,2)*P23 + M(3,3)*P33); + + pixelSizeVector2 /= scale.length(); + + //cout << "pixelSizeVector = "<