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

Revision 13041, 11.6 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • 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 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        /** Threshold at which small features are culled.
165        \param value Boulding volume size in screen space. Default is 2.0. */
166        void setSmallFeatureCullingPixelSize(float value) { _smallFeatureCullingPixelSize=value; }
167
168        float& getSmallFeatureCullingPixelSize() { return _smallFeatureCullingPixelSize; }
169
170        float getSmallFeatureCullingPixelSize() const { return _smallFeatureCullingPixelSize; }
171
172
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); }
175
176        /** Compute the pixel of a bounding sphere.*/
177        float pixelSize(const BoundingSphere& bs) const { return bs.radius()/(bs.center()*_pixelSizeVector); }
178
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)); }
181
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)); }
184
185
186        inline bool isCulled(const std::vector<Vec3>& vertices)
187        {
188            if (_mask&VIEW_FRUSTUM_CULLING)
189            {
190                // is it outside the view frustum...
191                if (!_frustum.contains(vertices)) return true;
192            }
193
194            if (_mask&SMALL_FEATURE_CULLING)
195            {
196            }
197
198            if (_mask&SHADOW_OCCLUSION_CULLING)
199            {
200                // is it in one of the shadow occluder volumes.
201                if (!_occluderList.empty())
202                {
203                    for(OccluderList::iterator itr=_occluderList.begin();
204                        itr!=_occluderList.end();
205                        ++itr)
206                    {
207                        if (itr->contains(vertices)) return true;
208                    }
209                }
210            }
211
212            return false;
213        }
214
215        inline bool isCulled(const BoundingBox& bb)
216        {
217            if (_mask&VIEW_FRUSTUM_CULLING)
218            {
219                // is it outside the view frustum...
220                if (!_frustum.contains(bb)) return true;
221            }
222
223            if (_mask&SMALL_FEATURE_CULLING)
224            {
225            }
226
227            if (_mask&SHADOW_OCCLUSION_CULLING)
228            {
229                // is it in one of the shadow occluder volumes.
230                if (!_occluderList.empty())
231                {
232                    for(OccluderList::iterator itr=_occluderList.begin();
233                        itr!=_occluderList.end();
234                        ++itr)
235                    {
236                        if (itr->contains(bb)) return true;
237                    }
238                }
239            }
240
241            return false;
242        }
243
244        inline bool isCulled(const BoundingSphere& bs)
245        {
246            if (_mask&VIEW_FRUSTUM_CULLING)
247            {
248                // is it outside the view frustum...
249                if (!_frustum.contains(bs)) return true;
250            }
251
252            if (_mask&SMALL_FEATURE_CULLING)
253            {
254                if (((bs.center()*_pixelSizeVector)*_smallFeatureCullingPixelSize)>bs.radius()) return true;
255            }
256#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
257            if (_mask&SHADOW_OCCLUSION_CULLING)
258            {
259                // is it in one of the shadow occluder volumes.
260                if (!_occluderList.empty())
261                {
262                    for(OccluderList::iterator itr=_occluderList.begin();
263                        itr!=_occluderList.end();
264                        ++itr)
265                    {
266                        if (itr->contains(bs)) return true;
267                    }
268                }
269            }
270#endif
271            return false;
272        }
273
274        inline void pushCurrentMask()
275        {
276            _frustum.pushCurrentMask();
277
278            if (!_stateFrustumList.empty())
279            {
280                for(StateFrustumList::iterator itr=_stateFrustumList.begin();
281                    itr!=_stateFrustumList.end();
282                    ++itr)
283                {
284                    itr->second.pushCurrentMask();
285                }
286            }
287
288
289#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
290            if (!_occluderList.empty())
291            {
292                for(OccluderList::iterator itr=_occluderList.begin();
293                    itr!=_occluderList.end();
294                    ++itr)
295                {
296                    itr->pushCurrentMask();
297                }
298            }
299#endif
300        }
301
302        inline void popCurrentMask()
303        {
304            _frustum.popCurrentMask();
305
306            if (!_stateFrustumList.empty())
307            {
308                for(StateFrustumList::iterator itr=_stateFrustumList.begin();
309                    itr!=_stateFrustumList.end();
310                    ++itr)
311                {
312                    itr->second.popCurrentMask();
313                }
314            }
315
316#ifdef COMPILE_WITH_SHADOW_OCCLUSION_CULLING
317            if (!_occluderList.empty())
318            {
319                for(OccluderList::iterator itr=_occluderList.begin();
320                    itr!=_occluderList.end();
321                    ++itr)
322                {
323                    itr->popCurrentMask();
324                }
325            }
326#endif
327        }
328
329        void disableAndPushOccludersCurrentMask(NodePath& nodePath);
330
331        void popOccludersCurrentMask(NodePath& nodePath);
332
333        static osg::Vec4 computePixelSizeVector(const Viewport& W, const Matrix& P, const Matrix& M);
334
335        virtual ~CullingSet();
336
337
338    protected:
339
340
341        Mask                _mask;
342        Polytope            _frustum;
343        StateFrustumList    _stateFrustumList;
344        OccluderList        _occluderList;
345        Vec4                _pixelSizeVector;
346        float               _smallFeatureCullingPixelSize;
347
348};
349
350}    // end of namespace
351
352#endif
Note: See TracBrowser for help on using the browser.