OpenSceneGraph/include/osg/CullingSet
Robert Osfield f36bc69c58 Made the more of the OSG's referenced object desctructors protected to ensure
that they arn't created on the stack inappropriately.

Split the implemention of Matrix up so that it is a simple no referenced counted
class and can be safefly created on the stack.  To support referenced counting a
seperate subclass now exists, this is RefMatrix which inherits from both Matrix and
Object.
2003-01-10 09:25:42 +00:00

216 lines
6.5 KiB
Plaintext

//C++ header - Open Scene Graph - Copyright (C) 1998-2002 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/ShadowVolumeOccluder>
#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 Matrix& matrix, const Vec4& pixelSizeVector):
_mask(cs._mask),
_frustum(cs._frustum),
_occluderList(cs._occluderList),
_pixelSizeVector(pixelSizeVector),
_smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
{
_frustum.transformProvidingInverse(matrix);
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->transformProvidingInverse(matrix);
}
}
typedef std::vector<ShadowVolumeOccluder> 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) { _frustum = cv; }
Polytope& getFrustum() { return _frustum; }
const Polytope& getFrustum() const { return _frustum; }
void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); }
void setPixelSizeVector(const Vec4& v) { _pixelSizeVector = v; }
Vec4& getPixelSizeVector() { return _pixelSizeVector; }
const Vec4& getPixelSizeVector() const { return _pixelSizeVector; }
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 radius/(v*_pixelSizeVector); }
/** Compute the pixel of an bounding sphere.*/
float pixelSize(const BoundingSphere& bs) const { return bs.radius()/(bs.center()*_pixelSizeVector); }
inline bool isCulled(const std::vector<Vec3>& vertices)
{
if (_mask&VIEW_FRUSTUM_CULLING)
{
// is it outside the view frustum...
if (!_frustum.contains(vertices)) 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(vertices)) return true;
}
}
}
return false;
}
inline bool isCulled(const BoundingBox& bb)
{
if (_mask&VIEW_FRUSTUM_CULLING)
{
// is it outside the view frustum...
if (!_frustum.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 (!_frustum.contains(bs)) return true;
}
if (_mask&SMALL_FEATURE_CULLING)
{
if (((bs.center()*_pixelSizeVector)*_smallFeatureCullingPixelSize)>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()
{
_frustum.pushCurrentMask();
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->pushCurrentMask();
}
}
}
inline void popCurrentMask()
{
_frustum.popCurrentMask();
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->popCurrentMask();
}
}
}
void disableAndPushOccludersCurrentMask(NodePath& nodePath);
void popOccludersCurrentMask(NodePath& nodePath);
protected:
virtual ~CullingSet();
Mask _mask;
Polytope _frustum;
OccluderList _occluderList;
Vec4 _pixelSizeVector;
float _smallFeatureCullingPixelSize;
};
} // end of namespace
#endif