1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
15#define OSG_CullingSet 1
17#include <osg/Polytope>
18#include <osg/ShadowVolumeOccluder>
19#include <osg/Viewport>
26#define COMPILE_WITH_SHADOW_OCCLUSION_CULLING
28/** A CullingSet class which contains a frustum and a list of occluders. */
29class OSG_EXPORT CullingSet : public Referenced
34 typedef std::pair< osg::ref_ptr<osg::StateSet>, osg::Polytope > StateFrustumPair;
35 typedef std::vector< StateFrustumPair > StateFrustumList;
39 CullingSet(const CullingSet& cs):
42 _frustum(cs._frustum),
43 _stateFrustumList(cs._stateFrustumList),
44 _occluderList(cs._occluderList),
45 _pixelSizeVector(cs._pixelSizeVector),
46 _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
50 CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector):
52 _frustum(cs._frustum),
53 _stateFrustumList(cs._stateFrustumList),
54 _occluderList(cs._occluderList),
55 _pixelSizeVector(pixelSizeVector),
56 _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
58 _frustum.transformProvidingInverse(matrix);
59 for(OccluderList::iterator itr=_occluderList.begin();
60 itr!=_occluderList.end();
63 itr->transformProvidingInverse(matrix);
67 CullingSet& operator = (const CullingSet& cs)
69 if (this==&cs) return *this;
72 _frustum = cs._frustum;
73 _stateFrustumList = cs._stateFrustumList;
74 _occluderList = cs._occluderList;
75 _pixelSizeVector = cs._pixelSizeVector;
76 _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
82 inline void set(const CullingSet& cs)
85 _frustum = cs._frustum;
86 _stateFrustumList = cs._stateFrustumList;
87 _occluderList = cs._occluderList;
88 _pixelSizeVector = cs._pixelSizeVector;
89 _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
92 inline void set(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector)
95 _stateFrustumList = cs._stateFrustumList;
96 _occluderList = cs._occluderList;
97 _pixelSizeVector = pixelSizeVector;
98 _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
100 //_frustum = cs._frustum;
101 //_frustum.transformProvidingInverse(matrix);
103 _frustum.setAndTransformProvidingInverse(cs._frustum,matrix);
105 for(StateFrustumList::iterator sitr=_stateFrustumList.begin();
106 sitr!=_stateFrustumList.end();
109 sitr->second.transformProvidingInverse(matrix);
112 for(OccluderList::iterator oitr=_occluderList.begin();
113 oitr!=_occluderList.end();
116 oitr->transformProvidingInverse(matrix);
121 typedef std::vector<ShadowVolumeOccluder> OccluderList;
128 VIEW_FRUSTUM_SIDES_CULLING = 0x1,
129 NEAR_PLANE_CULLING = 0x2,
130 FAR_PLANE_CULLING = 0x4,
131 VIEW_FRUSTUM_CULLING = VIEW_FRUSTUM_SIDES_CULLING|
134 SMALL_FEATURE_CULLING = 0x8,
135 SHADOW_OCCLUSION_CULLING = 0x10,
136 DEFAULT_CULLING = VIEW_FRUSTUM_SIDES_CULLING|
137 SMALL_FEATURE_CULLING|
138 SHADOW_OCCLUSION_CULLING,
139 ENABLE_ALL_CULLING = VIEW_FRUSTUM_CULLING|
140 SMALL_FEATURE_CULLING|
141 SHADOW_OCCLUSION_CULLING
144 void setCullingMask(Mask mask) { _mask = mask; }
145 Mask getCullingMask() const { return _mask; }
147 void setFrustum(Polytope& cv) { _frustum = cv; }
149 Polytope& getFrustum() { return _frustum; }
150 const Polytope& getFrustum() const { return _frustum; }
152 void addStateFrustum(StateSet* stateset, Polytope& polytope) { _stateFrustumList.push_back(StateFrustumPair(stateset,polytope)); }
154 void getStateFrustumList(StateFrustumList& sfl) { _stateFrustumList = sfl; }
155 StateFrustumList& getStateFrustumList() { return _stateFrustumList; }
157 void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); }
159 void setPixelSizeVector(const Vec4& v) { _pixelSizeVector = v; }
161 Vec4& getPixelSizeVector() { return _pixelSizeVector; }
162 const Vec4& getPixelSizeVector() const { return _pixelSizeVector; }
164 /** Threshold at which small features are culled.
165 \param value Bounding volume size in screen space. Default is 2.0. */
166 void setSmallFeatureCullingPixelSize(float value) { _smallFeatureCullingPixelSize=value; }
168 float& getSmallFeatureCullingPixelSize() { return _smallFeatureCullingPixelSize; }
170 float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; }
173 /** Compute the pixel of an object at position v, with specified radius.*/
174 float pixelSize(const Vec3& v,float radius) const { return radius/(v*_pixelSizeVector); }
176 /** Compute the pixel of a bounding sphere.*/
177 float pixelSize(const BoundingSphere& bs) const { return bs.radius()/(bs.center()*_pixelSizeVector); }
179 /** Compute the pixel of an object at position v, with specified radius. fabs()ed to always be positive. */
180 float clampedPixelSize(const Vec3& v,float radius) const { return fabs(pixelSize(v, radius)); }
182 /** Compute the pixel of a bounding sphere. fabs()ed to always be positive. */
183 float clampedPixelSize(const BoundingSphere& bs) const { return fabs(pixelSize(bs)); }
186 inline bool isCulled(const std::vector<Vec3>& vertices)
188 if (_mask&VIEW_FRUSTUM_CULLING)
190 // is it outside the view frustum...
191 if (!_frustum.contains(vertices)) return true;
194 if (_mask&SMALL_FEATURE_CULLING)
198 if (_mask&SHADOW_OCCLUSION_CULLING)
200 // is it in one of the shadow occluder volumes.
201 if (!_occluderList.empty())
203 for(OccluderList::iterator itr=_occluderList.begin();
204 itr!=_occluderList.end();
207 if (itr->contains(vertices)) return true;
215 inline bool isCulled(const BoundingBox& bb)
217 if (_mask&VIEW_FRUSTUM_CULLING)
219 // is it outside the view frustum...
220 if (!_frustum.contains(bb)) return true;
223 if (_mask&SMALL_FEATURE_CULLING)
227 if (_mask&SHADOW_OCCLUSION_CULLING)
229 // is it in one of the shadow occluder volumes.
230 if (!_occluderList.empty())
232 for(OccluderList::iterator itr=_occluderList.begin();
233 itr!=_occluderList.end();
236 if (itr->contains(bb)) return true;
244 inline bool isCulled(const BoundingSphere& bs)
246 if (_mask&VIEW_FRUSTUM_CULLING)
248 // is it outside the view frustum...
249 if (!_frustum.contains(bs)) return true;
252 if (_mask&SMALL_FEATURE_CULLING)
254 if (((bs.center()*_pixelSizeVector)*_smallFeatureCullingPixelSize)>bs.radius()) return true;
256#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
257 if (_mask&SHADOW_OCCLUSION_CULLING)
259 // is it in one of the shadow occluder volumes.
260 if (!_occluderList.empty())
262 for(OccluderList::iterator itr=_occluderList.begin();
263 itr!=_occluderList.end();
266 if (itr->contains(bs)) return true;
274 inline void pushCurrentMask()
276 _frustum.pushCurrentMask();
278 if (!_stateFrustumList.empty())
280 for(StateFrustumList::iterator itr=_stateFrustumList.begin();
281 itr!=_stateFrustumList.end();
284 itr->second.pushCurrentMask();
289#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
290 if (!_occluderList.empty())
292 for(OccluderList::iterator itr=_occluderList.begin();
293 itr!=_occluderList.end();
296 itr->pushCurrentMask();
302 inline void popCurrentMask()
304 _frustum.popCurrentMask();
306 if (!_stateFrustumList.empty())
308 for(StateFrustumList::iterator itr=_stateFrustumList.begin();
309 itr!=_stateFrustumList.end();
312 itr->second.popCurrentMask();
316#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
317 if (!_occluderList.empty())
319 for(OccluderList::iterator itr=_occluderList.begin();
320 itr!=_occluderList.end();
323 itr->popCurrentMask();
329 inline void resetCullingMask()
331 _frustum.setResultMask(_frustum.getCurrentMask());
334 void disableAndPushOccludersCurrentMask(NodePath& nodePath);
336 void popOccludersCurrentMask(NodePath& nodePath);
338 static osg::Vec4 computePixelSizeVector(const Viewport& W, const Matrix& P, const Matrix& M);
340 virtual ~CullingSet();
348 StateFrustumList _stateFrustumList;
349 OccluderList _occluderList;
350 Vec4 _pixelSizeVector;
351 float _smallFeatureCullingPixelSize;