root/OpenSceneGraph/trunk/include/osg/CullingSet @ 5328

Revision 5328, 11.8 kB (checked in by robert, 8 years ago)

Updated copyright years.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
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.
7 *
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.
12*/
13
14#ifndef OSG_CullingSet
15#define OSG_CullingSet 1
16
17#include <osg/Polytope>
18#include <osg/ShadowVolumeOccluder>
19#include <osg/Viewport>
20
21#include <math.h>
22
23
24namespace osg {
25
26#define COMPILE_WITH_SHADOW_OCCLUSION_CULLING
27
28/** A CullingSet class which contains a frustum and a list of occluders. */
29class OSG_EXPORT CullingSet : public Referenced
30{
31
32    public:
33
34        typedef std::pair< osg::ref_ptr<osg::StateSet>, osg::Polytope > StateFrustumPair;
35        typedef std::vector< StateFrustumPair > StateFrustumList;   
36   
37        CullingSet();
38
39        CullingSet(const CullingSet& cs):
40            Referenced(),
41            _mask(cs._mask),
42            _frustum(cs._frustum),
43            _stateFrustumList(cs._stateFrustumList),
44            _occluderList(cs._occluderList),
45            _pixelSizeVector(cs._pixelSizeVector),
46            _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
47        {
48        }
49
50        CullingSet(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector):
51            _mask(cs._mask),
52            _frustum(cs._frustum),
53            _stateFrustumList(cs._stateFrustumList),
54            _occluderList(cs._occluderList),
55            _pixelSizeVector(pixelSizeVector),
56            _smallFeatureCullingPixelSize(cs._smallFeatureCullingPixelSize)
57        {
58            _frustum.transformProvidingInverse(matrix);
59            for(OccluderList::iterator itr=_occluderList.begin();
60                itr!=_occluderList.end();
61                ++itr)
62            {
63                itr->transformProvidingInverse(matrix);
64            }
65        }
66       
67        CullingSet& operator = (const CullingSet& cs)
68        {
69            if (this==&cs) return *this;
70           
71            _mask = cs._mask;
72            _frustum = cs._frustum;
73            _stateFrustumList = cs._stateFrustumList;
74            _occluderList = cs._occluderList;
75            _pixelSizeVector = cs._pixelSizeVector;
76            _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
77           
78            return *this;
79        }
80
81
82        inline void set(const CullingSet& cs)
83        {
84            _mask = cs._mask;
85            _frustum = cs._frustum;
86            _stateFrustumList = cs._stateFrustumList;
87            _occluderList = cs._occluderList;
88            _pixelSizeVector = cs._pixelSizeVector;
89            _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
90        }
91       
92        inline void set(const CullingSet& cs,const Matrix& matrix, const Vec4& pixelSizeVector)
93        {
94            _mask = cs._mask;
95            _stateFrustumList = cs._stateFrustumList;
96            _occluderList = cs._occluderList;
97            _pixelSizeVector = pixelSizeVector;
98            _smallFeatureCullingPixelSize = cs._smallFeatureCullingPixelSize;
99
100            //_frustum = cs._frustum;
101            //_frustum.transformProvidingInverse(matrix);
102           
103            _frustum.setAndTransformProvidingInverse(cs._frustum,matrix);
104           
105            for(StateFrustumList::iterator sitr=_stateFrustumList.begin();
106                sitr!=_stateFrustumList.end();
107                ++sitr)
108            {
109                sitr->second.transformProvidingInverse(matrix);
110            }
111
112            for(OccluderList::iterator oitr=_occluderList.begin();
113                oitr!=_occluderList.end();
114                ++oitr)
115            {
116                oitr->transformProvidingInverse(matrix);
117            }
118       
119        }
120       
121        typedef std::vector<ShadowVolumeOccluder>   OccluderList;
122
123        typedef unsigned int Mask;
124
125        enum MaskValues
126        {
127            NO_CULLING                  = 0x0,
128            VIEW_FRUSTUM_SIDES_CULLING  = 0x1,
129            NEAR_PLANE_CULLING          = 0x2,
130            FAR_PLANE_CULLING           = 0x4,
131            VIEW_FRUSTUM_CULLING        = VIEW_FRUSTUM_SIDES_CULLING|
132                                          NEAR_PLANE_CULLING|
133                                          FAR_PLANE_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
142        };
143       
144        void setCullingMask(Mask mask) { _mask = mask; }
145        Mask getCullingMask() const { return _mask; }
146
147        void setFrustum(Polytope& cv) { _frustum = cv; }
148
149        Polytope& getFrustum() { return _frustum; }
150        const Polytope& getFrustum() const { return _frustum; }   
151       
152        void addStateFrustum(StateSet* stateset, Polytope& polytope) { _stateFrustumList.push_back(StateFrustumPair(stateset,polytope)); }
153       
154        void getStateFrustumList(StateFrustumList& sfl) { _stateFrustumList = sfl; }
155        StateFrustumList& getStateFrustumList() { return _stateFrustumList; }
156
157        void addOccluder(ShadowVolumeOccluder& cv) { _occluderList.push_back(cv); }
158
159        void setPixelSizeVector(const Vec4& v) { _pixelSizeVector = v; }
160
161        Vec4& getPixelSizeVector() { return _pixelSizeVector; }
162        const Vec4& getPixelSizeVector() const { return _pixelSizeVector; }
163
164        void setSmallFeatureCullingPixelSize(float value) { _smallFeatureCullingPixelSize=value; }
165       
166        float& getSmallFeatureCullingPixelSize() { return _smallFeatureCullingPixelSize; }
167
168        float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; }
169   
170   
171        /** Compute the pixel of an object at position v, with specified radius.*/
172        float pixelSize(const Vec3& v,float radius) const { return radius/(v*_pixelSizeVector); }
173
174        /** Compute the pixel of a bounding sphere.*/
175        float pixelSize(const BoundingSphere& bs) const { return bs.radius()/(bs.center()*_pixelSizeVector); }
176
177        /** Compute the pixel of an object at position v, with specified radius. fabs()ed to always be positive. */
178        float clampedPixelSize(const Vec3& v,float radius) const { return fabs(pixelSize(v, radius)); }
179
180        /** Compute the pixel of a bounding sphere. fabs()ed to always be positive. */
181        float clampedPixelSize(const BoundingSphere& bs) const { return fabs(pixelSize(bs)); }
182
183
184        inline bool isCulled(const std::vector<Vec3>& vertices)
185        {
186            if (_mask&VIEW_FRUSTUM_CULLING)
187            {
188                // is it outside the view frustum...
189                if (!_frustum.contains(vertices)) return true;
190            }
191           
192            if (_mask&SMALL_FEATURE_CULLING)
193            {
194            }
195
196            if (_mask&SHADOW_OCCLUSION_CULLING)
197            {
198                // is it in one of the shadow occluder volumes.
199                if (!_occluderList.empty())
200                {
201                    for(OccluderList::iterator itr=_occluderList.begin();
202                        itr!=_occluderList.end();
203                        ++itr)
204                    {
205                        if (itr->contains(vertices)) return true;
206                    }
207                }
208            }
209                       
210            return false;
211        }
212       
213        inline bool isCulled(const BoundingBox& bb)
214        {
215            if (_mask&VIEW_FRUSTUM_CULLING)
216            {
217                // is it outside the view frustum...
218                if (!_frustum.contains(bb)) return true;
219            }
220           
221            if (_mask&SMALL_FEATURE_CULLING)
222            {
223            }
224
225            if (_mask&SHADOW_OCCLUSION_CULLING)
226            {
227                // is it in one of the shadow occluder volumes.
228                if (!_occluderList.empty())
229                {
230                    for(OccluderList::iterator itr=_occluderList.begin();
231                        itr!=_occluderList.end();
232                        ++itr)
233                    {
234                        if (itr->contains(bb)) return true;
235                    }
236                }
237            }
238                       
239            return false;
240        }
241       
242        inline bool isCulled(const BoundingSphere& bs)
243        {
244            if (_mask&VIEW_FRUSTUM_CULLING)
245            {
246                // is it outside the view frustum...
247                if (!_frustum.contains(bs)) return true;
248            }
249           
250            if (_mask&SMALL_FEATURE_CULLING)
251            {
252                if (((bs.center()*_pixelSizeVector)*_smallFeatureCullingPixelSize)>bs.radius()) return true;
253            }
254#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
255            if (_mask&SHADOW_OCCLUSION_CULLING)
256            {
257                // is it in one of the shadow occluder volumes.
258                if (!_occluderList.empty())
259                {
260                    for(OccluderList::iterator itr=_occluderList.begin();
261                        itr!=_occluderList.end();
262                        ++itr)
263                    {
264                        if (itr->contains(bs)) return true;
265                    }
266                }
267            }
268#endif           
269            return false;
270        }
271       
272        inline void pushCurrentMask()
273        {
274            _frustum.pushCurrentMask();
275           
276            if (!_stateFrustumList.empty())
277            {
278                for(StateFrustumList::iterator itr=_stateFrustumList.begin();
279                    itr!=_stateFrustumList.end();
280                    ++itr)
281                {
282                    itr->second.pushCurrentMask();
283                }
284            }
285
286
287#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
288            if (!_occluderList.empty())
289            {
290                for(OccluderList::iterator itr=_occluderList.begin();
291                    itr!=_occluderList.end();
292                    ++itr)
293                {
294                    itr->pushCurrentMask();
295                }
296            }
297#endif
298        }
299       
300        inline void popCurrentMask()
301        {
302            _frustum.popCurrentMask();
303
304            if (!_stateFrustumList.empty())
305            {
306                for(StateFrustumList::iterator itr=_stateFrustumList.begin();
307                    itr!=_stateFrustumList.end();
308                    ++itr)
309                {
310                    itr->second.popCurrentMask();
311                }
312            }
313
314#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
315            if (!_occluderList.empty())
316            {
317                for(OccluderList::iterator itr=_occluderList.begin();
318                    itr!=_occluderList.end();
319                    ++itr)
320                {
321                    itr->popCurrentMask();
322                }
323            }
324#endif
325        }
326       
327        void disableAndPushOccludersCurrentMask(NodePath& nodePath);
328
329        void popOccludersCurrentMask(NodePath& nodePath);
330       
331        static osg::Vec4 computePixelSizeVector(const Viewport& W, const Matrix& P, const Matrix& M);
332
333        virtual ~CullingSet();
334       
335
336    protected:
337   
338
339        Mask                _mask;
340        Polytope            _frustum;
341        StateFrustumList    _stateFrustumList;       
342        OccluderList        _occluderList;       
343        Vec4                _pixelSizeVector;
344        float               _smallFeatureCullingPixelSize;
345
346};
347
348}    // end of namespace
349
350#endif
Note: See TracBrowser for help on using the browser.