Updates to shadow occlusion culling code.

This commit is contained in:
Robert Osfield
2002-06-03 17:49:28 +00:00
parent 3f84849210
commit db78726acf
5 changed files with 208 additions and 10 deletions

165
include/osg/CullingSet Normal file
View File

@@ -0,0 +1,165 @@
//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_CullingSet
#define OSG_CullingSet 1
#include <osg/Polytope>
#include <osg/ShadowOccluderVolume>
#include <osg/Referenced>
namespace osg {
/** A CullingSet class which contains a frustum and a list of occluder. */
class SG_EXPORT CullingSet : public Referenced
{
public:
CullingSet();
CullingSet(const CullingSet& cs,const osg::Matrix& matrix):
_mask(cs._mask),
_clippingVolume(cs._clippingVolume),
_occluderList(cs._occluderList),
_pixelSizeOffset(cs._pixelSizeOffset),
_pixelSizeVector(cs._pixelSizeVector)
{
_clippingVolume.transformProvidingInverse(matrix);
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->transformProvidingInverse(matrix);
}
}
~CullingSet();
typedef std::vector<ShadowOccluderVolume> OccluderList;
typedef unsigned int Mask;
enum MaskValues
{
VIEW_FRUSTUM_CULLING = 0x1,
SMALL_FEATURE_CULLING = 0x2,
SHADOW_OCCLUSION_CULLING = 0x4,
ALL_CULLING = 0xffffffff
};
void setCullingMask(Mask mask) { _mask = mask; }
void setFrustum(Polytope& cv) { _clippingVolume = cv; }
Polytope& getFrustum() { return _clippingVolume; }
void addOccluder(ShadowOccluderVolume& cv) { _occluderList.push_back(cv); }
inline bool isCulled(const BoundingBox& bb)
{
if (_mask&VIEW_FRUSTUM_CULLING)
{
// is it outside the view frustum...
if (!_clippingVolume.contains(bb)) return true;
}
if (_mask&SMALL_FEATURE_CULLING)
{
}
if (_mask&SHADOW_OCCLUSION_CULLING)
{
// is it in one of the shadow occluder volumes.
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
if (itr->contains(bb)) return true;
}
}
}
return false;
}
inline bool isCulled(const BoundingSphere& bs)
{
if (_mask&VIEW_FRUSTUM_CULLING)
{
// is it outside the view frustum...
if (!_clippingVolume.contains(bs)) return true;
}
if (_mask&SMALL_FEATURE_CULLING)
{
if ((bs.center()*_pixelSizeVector+_pixelSizeOffset)>bs.radius()) return true;
}
if (_mask&SHADOW_OCCLUSION_CULLING)
{
// is it in one of the shadow occluder volumes.
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
if (itr->contains(bs)) return true;
}
}
}
return false;
}
inline void pushCurrentMask()
{
_clippingVolume.pushCurrentMask();
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->pushCurrentMask();
}
}
}
inline void popCurrentMask()
{
_clippingVolume.popCurrentMask();
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->popCurrentMask();
}
}
}
protected:
Mask _mask;
Polytope _clippingVolume;
OccluderList _occluderList;
float _pixelSizeOffset;
Vec3 _pixelSizeVector;
};
} // end of namespace
#endif

View File

@@ -43,6 +43,18 @@ class SG_EXPORT ShadowOccluderVolume
* within this shadow occluder volume.*/
bool contains(const BoundingBox& bound);
inline void transformProvidingInverse(const osg::Matrix& matrix)
{
_occluderVolume.transformProvidingInverse(matrix);
for(HoleList::iterator itr=_holeList.begin();
itr!=_holeList.end();
++itr)
{
itr->transformProvidingInverse(matrix);
}
}
protected:
Polytope _occluderVolume;

View File

@@ -348,8 +348,8 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
void pushPolytope();
void popPolytope();
void pushCullingSet();
void popCullingSet();
// typedef std::vector<osg::Polytope> PolytopeStack;
@@ -380,8 +380,10 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
typedef osg::fast_back_stack<CullingMode> CullingModeStack;
CullingModeStack _cullingModeStack;
typedef osg::fast_back_stack<osg::ref_ptr<osg::CullingSet> > ClippingStack;
ClippingStack _clippingSet;
typedef osg::fast_back_stack<osg::ref_ptr<osg::CullingSet> > CullingStack;
CullingStack _clipspaceCullingStack;
CullingStack _projectionCullingStack;
CullingStack _modelviewCullingStack;
unsigned int _bbCornerNear;

View File

@@ -4,6 +4,7 @@ using namespace osg;
CullingSet::CullingSet()
{
_mask = ALL_CULLING;
}
CullingSet::~CullingSet()

View File

@@ -166,7 +166,7 @@ void CullVisitor::reset()
_windowToModelFactor = 1.0f;
}
void CullVisitor::pushPolytope()
void CullVisitor::pushCullingSet()
{
_modelviewPolytopeStack.push_back();
osg::Polytope& cv = _modelviewPolytopeStack.back();
@@ -177,14 +177,20 @@ void CullVisitor::pushPolytope()
_MVPW_Stack.push_back(0L);
_windowToModelFactorDirty = true;
_modelviewCullingStack.push_back(osgNew osg::CullingSet(*_projectionCullingStack.back(),*_modelviewStack.back()));
}
void CullVisitor::popPolytope()
void CullVisitor::popCullingSet()
{
_modelviewPolytopeStack.pop_back();
_MVPW_Stack.pop_back();
_windowToModelFactorDirty = true;
_modelviewCullingStack.pop_back();
}
void CullVisitor::pushViewport(osg::Viewport* viewport)
@@ -207,7 +213,17 @@ void CullVisitor::pushProjectionMatrix(Matrix* matrix)
_projectionPolytopeStack.back().setToUnitFrustumWithoutNearFar();
_projectionPolytopeStack.back().transformProvidingInverse(*matrix);
pushPolytope();
osg::CullingSet* cullingSet = osgNew osg::CullingSet();
cullingSet->getFrustum().setToUnitFrustumWithoutNearFar();
cullingSet->getFrustum().transformProvidingInverse(*matrix);
_projectionCullingStack.push_back(cullingSet);
//_projectionCullingStack.push_back(osgNew osg::CullingSet(*_clipspaceCullingStack.back(),*matrix));
pushCullingSet();
}
void CullVisitor::popProjectionMatrix()
@@ -241,14 +257,16 @@ void CullVisitor::popProjectionMatrix()
_projectionStack.pop_back();
_projectionPolytopeStack.pop_back();
popPolytope();
_projectionCullingStack.pop_back();
popCullingSet();
}
void CullVisitor::pushModelViewMatrix(Matrix* matrix)
{
_modelviewStack.push_back(matrix);
pushPolytope();
pushCullingSet();
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
const float x_0 = (*matrix)(0,0);
@@ -285,7 +303,7 @@ void CullVisitor::popModelViewMatrix()
{
_modelviewStack.pop_back();
_eyePointStack.pop_back();
popPolytope();
popCullingSet();
osg::Vec3 lookVector(0.0f,0.0f,-1.0f);