/* -*-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 occluders. */ class SG_EXPORT CullingSet : public Referenced { public: CullingSet(); CullingSet(const CullingSet& cs): Referenced(), _mask(cs._mask), _frustum(cs._frustum), _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), _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; _occluderList = cs._occluderList; _pixelSizeVector = cs._pixelSizeVector; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; return *this; } inline void set(const CullingSet& cs) { _mask = cs._mask; _frustum = cs._frustum; _occluderList = cs._occluderList; _pixelSizeVector = cs._pixelSizeVector; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; } inline void set(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector) { _mask = cs._mask; _occluderList = cs._occluderList; _pixelSizeVector = pixelSizeVector; _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize; //_frustum = cs._frustum; //_frustum.transformProvidingInverse(matrix); _frustum.setAndTransformProvidingInverse(cs._frustum,matrix); for(OccluderList::iterator itr=_occluderList.begin(); itr!=_occluderList.end(); ++itr) { itr->transformProvidingInverse(matrix); } } typedef std::vector 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; } 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 a 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); virtual ~CullingSet(); protected: Mask _mask; Polytope _frustum; OccluderList _occluderList; Vec4 _pixelSizeVector; float _smallFeatureCullingPixelSize; }; } // end of namespace #endif