Files
OpenSceneGraph/include/osg/CullingSet
Robert Osfield 1e508d432b Added SmokeTrailEffect which renders created particles as single quad or line
strip, in the case of the quad strip the strip is aligned to the be orthogonal with
the eye point.
2005-10-12 18:42:36 +00:00

351 lines
12 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_CullingSet
#define OSG_CullingSet 1
#include <osg/Polytope>
#include <osg/ShadowVolumeOccluder>
#include <osg/Viewport>
#include <math.h>
namespace osg {
#define COMPILE_WITH_SHADOW_OCCLUSION_CULLING
/** A CullingSet class which contains a frustum and a list of occluders. */
class OSG_EXPORT CullingSet : public Referenced
{
public:
typedef std::pair< osg::ref_ptr<osg::StateSet>, osg::Polytope > StateFrustumPair;
typedef std::vector< StateFrustumPair > StateFrustumList;
CullingSet();
CullingSet(const CullingSet& cs):
Referenced(),
_mask(cs._mask),
_frustum(cs._frustum),
_stateFrustumList(cs._stateFrustumList),
_occluderList(cs._occluderList),
_pixelSizeVector(cs._pixelSizeVector),
_smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
{
}
CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector):
_mask(cs._mask),
_frustum(cs._frustum),
_stateFrustumList(cs._stateFrustumList),
_occluderList(cs._occluderList),
_pixelSizeVector(pixelSizeVector),
_smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
{
_frustum.transformProvidingInverse(matrix);
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->transformProvidingInverse(matrix);
}
}
CullingSet& operator = (const CullingSet& cs)
{
if (this==&cs) return *this;
_mask = cs._mask;
_frustum = cs._frustum;
_stateFrustumList = cs._stateFrustumList;
_occluderList = cs._occluderList;
_pixelSizeVector = cs._pixelSizeVector;
_smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
return *this;
}
inline void set(const CullingSet& cs)
{
_mask = cs._mask;
_frustum = cs._frustum;
_stateFrustumList = cs._stateFrustumList;
_occluderList = cs._occluderList;
_pixelSizeVector = cs._pixelSizeVector;
_smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
}
inline void set(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector)
{
_mask = cs._mask;
_stateFrustumList = cs._stateFrustumList;
_occluderList = cs._occluderList;
_pixelSizeVector = pixelSizeVector;
_smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
//_frustum = cs._frustum;
//_frustum.transformProvidingInverse(matrix);
_frustum.setAndTransformProvidingInverse(cs._frustum,matrix);
for(StateFrustumList::iterator itr=_stateFrustumList.begin();
itr!=_stateFrustumList.end();
++itr)
{
itr->second.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
{
NO_CULLING = 0x0,
VIEW_FRUSTUM_SIDES_CULLING = 0x1,
NEAR_PLANE_CULLING = 0x2,
FAR_PLANE_CULLING = 0x4,
VIEW_FRUSTUM_CULLING = VIEW_FRUSTUM_SIDES_CULLING|
NEAR_PLANE_CULLING|
FAR_PLANE_CULLING,
SMALL_FEATURE_CULLING = 0x8,
SHADOW_OCCLUSION_CULLING = 0x10,
DEFAULT_CULLING = VIEW_FRUSTUM_SIDES_CULLING|
SMALL_FEATURE_CULLING|
SHADOW_OCCLUSION_CULLING,
ENABLE_ALL_CULLING = VIEW_FRUSTUM_CULLING|
SMALL_FEATURE_CULLING|
SHADOW_OCCLUSION_CULLING
};
void setCullingMask(Mask mask) { _mask = mask; }
Mask getCullingMask() const { return _mask; }
void setFrustum(Polytope& cv) { _frustum = cv; }
Polytope& getFrustum() { return _frustum; }
const Polytope& getFrustum() const { return _frustum; }
void addStateFrustum(StateSet* stateset, Polytope& polytope) { _stateFrustumList.push_back(StateFrustumPair(stateset,polytope)); }
void getStateFrustumList(StateFrustumList& sfl) { _stateFrustumList = sfl; }
StateFrustumList& getStateFrustumList() { return _stateFrustumList; }
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 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<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;
}
#ifdef COMPILE_WITH_SHADOW_OCCLUSION_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(bs)) return true;
}
}
}
#endif
return false;
}
inline void pushCurrentMask()
{
_frustum.pushCurrentMask();
if (!_stateFrustumList.empty())
{
for(StateFrustumList::iterator itr=_stateFrustumList.begin();
itr!=_stateFrustumList.end();
++itr)
{
itr->second.pushCurrentMask();
}
}
#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->pushCurrentMask();
}
}
#endif
}
inline void popCurrentMask()
{
_frustum.popCurrentMask();
if (!_stateFrustumList.empty())
{
for(StateFrustumList::iterator itr=_stateFrustumList.begin();
itr!=_stateFrustumList.end();
++itr)
{
itr->second.popCurrentMask();
}
}
#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
if (!_occluderList.empty())
{
for(OccluderList::iterator itr=_occluderList.begin();
itr!=_occluderList.end();
++itr)
{
itr->popCurrentMask();
}
}
#endif
}
void disableAndPushOccludersCurrentMask(NodePath& nodePath);
void popOccludersCurrentMask(NodePath& nodePath);
static osg::Vec4 computePixelSizeVector(const Viewport& W, const Matrix& P, const Matrix& M);
virtual ~CullingSet();
protected:
Mask _mask;
Polytope _frustum;
StateFrustumList _stateFrustumList;
OccluderList _occluderList;
Vec4 _pixelSizeVector;
float _smallFeatureCullingPixelSize;
};
} // end of namespace
#endif