/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 #include #include 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 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& 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